import { addWeakEventListener , Builder , ChangedData , CoercibleProperty , CSSType , KeyedTemplate , Label , makeParser , makeValidator , Observable , ObservableArray , PercentLength , Property , removeWeakEventListener , Template , Trace , View } from '@nativescript/core' ; export const ITEMLOADING = 'itemLoading' ; export const LOADMOREITEMS = 'loadMoreItems' ; export const ITEMTAP = 'itemTap' ; export const SCROLLEVENT = 'scroll' ; export const ITEMSELECTED = 'itemSelected' ; export const ITEMSELECTING = 'itemSelecting' ; export const ITEMDESELECTED = 'itemDeselected' ; export const ITEMDESELECTING = 'itemDeselecting' ; export const PULLTOREFRESHINITIATEDEVENT = 'pullToRefreshInitiated' ; export type Orientation = 'horizontal' | 'vertical' ; export namespace knownTemplates { export const itemTemplate = 'itemTemplate' ; } export namespace knownMultiTemplates { export const itemTemplates = 'itemTemplates' ; } export namespace knownCollections { export const items = 'items' ; } export const wearOsListViewTraceCategory = 'ns-wear-os-listview' ; export function WearOsListViewLog ( message ) { Trace . write ( message , wearOsListViewTraceCategory ) ; } export function WearOsListViewError ( message ) { Trace . write ( message , wearOsListViewTraceCategory , Trace . messageType . error ) ; } export interface ItemEventData { eventName : string ; object : any ; index : number ; view : View ; android : any ; ios : any ; } export interface ItemsSource { length : number ; getItem ( index ) : any ; } const autoEffectiveItemHeight = 100 ; const autoEffectiveItemWidth = 100 ; @ CSSType ( 'WearOsListView' ) export abstract class WearOsListViewBase extends View { abstract refresh ( ) ; static knownFunctions = [ 'itemTemplateSelector' , 'itemIdGenerator' ] ; static itemLoadingEvent = ITEMLOADING ; static itemTapEvent = ITEMTAP ; static loadMoreItemsEvent = LOADMOREITEMS ; static scrollEvent = SCROLLEVENT ; hideScrollBar : boolean ; max : PercentLength ; min : PercentLength ; _itemWidth : any ; _itemHeight : any ; itemWidth : PercentLength ; itemHeight : PercentLength ; layoutType : LayoutType ; spanCount : number ; items : any [ ] | ItemsSource ; itemTemplate : string | Template ; pullToRefresh : boolean = false ; _defaultTemplate : KeyedTemplate = { key : 'default' , createView : ( ) => { if ( this . itemTemplate ) { return Builder . parse ( this . itemTemplate , this ) ; } return undefined ; } } ; _itemTemplatesInternal = new Array < KeyedTemplate > ( this . _defaultTemplate ) ; itemTemplates : string | Array < KeyedTemplate > ; _innerWidth : number = 0 ; _innerHeight : number = 0 ; _effectiveItemHeight : number ; _effectiveItemWidth : number ; orientation : Orientation ; itemReorder : boolean = false ; selectionBehavior : 'None' | 'Press' | 'LongPress' = 'None' ; multipleSelection : boolean = false ; private _itemTemplateSelectorBindable = new Label ( ) ; constructor ( ) { super ( ) ; } get itemIdGenerator ( ) : ( item : any , index : number , items : any ) => number { return this . _itemIdGenerator ; } set itemIdGenerator ( generatorFn ) { this . _itemIdGenerator = generatorFn ; } get itemTemplateSelector ( ) : string | ( ( item : any , index : number , items : any ) => string ) { return this . _itemTemplateSelector ; } set itemTemplateSelector ( value ) { if ( typeof value === 'string' ) { this . _itemTemplateSelectorBindable . bind ( { sourceProperty : null , targetProperty : 'templateKey' , expression : value } ) ; this . _itemTemplateSelector = ( item , index , items ) => { item [ '$index' ] = index ; this . _itemTemplateSelectorBindable . bindingContext = item ; return this . _itemTemplateSelectorBindable . get ( 'templateKey' ) ; } ; } else if ( typeof value === 'function' ) { this . _itemTemplateSelector = value ; } } onLayout ( left , top , right , bottom ) { super . onLayout ( left , top , right , bottom ) ; this . _innerWidth = right - left - this . effectivePaddingLeft - this . effectivePaddingRight ; this . _innerHeight = bottom - top - this . effectivePaddingTop - this . effectivePaddingBottom ; this . _effectiveItemWidth = PercentLength . toDevicePixels ( this . itemWidth , autoEffectiveItemWidth , this . _innerWidth ) ; this . _effectiveItemHeight = PercentLength . toDevicePixels ( this . itemHeight , autoEffectiveItemHeight , this . _innerHeight ) ; } _getItemTemplate ( index ) { let templateKey = 'default' ; if ( this . itemTemplateSelector ) { const dataItem = this . _getDataItem ( index ) ; templateKey = this . _itemTemplateSelector ( dataItem , index , this . items ) ; } for ( let i = 0 , length = this . _itemTemplatesInternal . length ; i < length ; i ++ ) { if ( this . _itemTemplatesInternal [ i ] . key === templateKey ) { return this . _itemTemplatesInternal [ i ] ; } } return this . _itemTemplatesInternal [ 0 ] ; } _prepareItem ( item , index ) { if ( item ) { item . bindingContext = this . _getDataItem ( index ) ; } } _getDefaultItemContent ( index ) { const lbl = new Label ( ) ; lbl . bind ( { targetProperty : 'text' , sourceProperty : '$value' } ) ; return lbl ; } _updateNativeItems ( args ) { this . refresh ( ) ; } private _getDataItem ( index ) { const thisItems = < ItemsSource > this . items ; return thisItems && thisItems . getItem ? thisItems . getItem ( index ) : thisItems [ index ] ; } private _itemIdGenerator : ( item : any , index : number , items : any ) => number = ( _item , index ) => index ; private _itemTemplateSelector : ( item : any , index : number , items : any ) => string ; } export type LayoutType = 'grid' | 'linear' | 'staggered' ; export enum LayoutTypeOptions { GRID = 'grid' , LINEAR = 'linear' , STAGGERED = 'staggered' } export const itemsProperty = new Property < WearOsListViewBase , any [ ] | ItemsSource > ( { name : 'items' , valueChanged : ( target , oldValue , newValue ) => { if ( oldValue instanceof Observable ) { removeWeakEventListener ( oldValue , ObservableArray . changeEvent , target . _updateNativeItems , target ) ; } if ( newValue instanceof Observable ) { addWeakEventListener ( newValue , ObservableArray . changeEvent , target . _updateNativeItems , target ) ; } target . refresh ( ) ; } } ) ; itemsProperty . register ( WearOsListViewBase ) ; export const itemTemplateProperty = new Property < WearOsListViewBase , string | Template > ( { name : 'itemTemplate' , affectsLayout : true , valueChanged : target => { target . refresh ( ) ; } } ) ; itemTemplateProperty . register ( WearOsListViewBase ) ; export const itemTemplatesProperty = new Property < WearOsListViewBase , string | Array < KeyedTemplate > > ( { name : 'itemTemplates' , affectsLayout : true , valueConverter : value => { if ( typeof value === 'string' ) { return Builder . parseMultipleTemplates ( value ) ; } return value ; } } ) ; itemTemplatesProperty . register ( WearOsListViewBase ) ; export const layoutTypeProperty = new Property < WearOsListViewBase , LayoutType > ( { name : 'layoutType' , affectsLayout : true } ) ; layoutTypeProperty . register ( WearOsListViewBase ) ; export const spanCountProperty = new Property < WearOsListViewBase , number > ( { name : 'spanCount' , defaultValue : 1 , affectsLayout : true , valueConverter : v => parseInt ( v , 10 ) } ) ; spanCountProperty . register ( WearOsListViewBase ) ; const defaultItemWidth = 'auto' ; export const itemWidthProperty = new CoercibleProperty < WearOsListViewBase , PercentLength > ( { name : 'itemWidth' , affectsLayout : true , defaultValue : { value : 1 , unit : '%' } , equalityComparer : PercentLength . equals , valueConverter : PercentLength . parse , coerceValue : ( target , value ) => { return target . nativeView ? value : defaultItemWidth ; } , valueChanged : ( target , oldValue , newValue ) => { target . _itemWidth = newValue ; target . _effectiveItemWidth = PercentLength . toDevicePixels ( newValue , autoEffectiveItemWidth , target . _innerWidth ) ; target . refresh ( ) ; } } ) ; itemWidthProperty . register ( WearOsListViewBase ) ; const defaultItemHeight = 'auto' ; export const itemHeightProperty = new CoercibleProperty < WearOsListViewBase , PercentLength > ( { name : 'itemHeight' , affectsLayout : true , defaultValue : { value : 0.2 , unit : '%' } , coerceValue : ( target , value ) => { return target . nativeView ? value : defaultItemHeight ; } , equalityComparer : PercentLength . equals , valueConverter : PercentLength . parse , valueChanged : ( target , oldValue , newValue ) => { target . _itemHeight = newValue ; target . _effectiveItemHeight = PercentLength . toDevicePixels ( newValue , autoEffectiveItemHeight , target . _innerHeight ) ; target . refresh ( ) ; } } ) ; itemHeightProperty . register ( WearOsListViewBase ) ; const converter = makeParser < Orientation > ( makeValidator ( 'horizontal' , 'vertical' ) ) ; export const orientationProperty = new Property < WearOsListViewBase , Orientation > ( { name : 'orientation' , defaultValue : 'vertical' , affectsLayout : true , valueChanged : ( target , oldValue , newValue ) => { target . refresh ( ) ; } , valueConverter : converter } ) ; orientationProperty . register ( WearOsListViewBase ) ; export const maxProperty = new Property < WearOsListViewBase , PercentLength > ( { name : 'max' , affectsLayout : true , defaultValue : { value : 1 , unit : '%' } , equalityComparer : PercentLength . equals , valueConverter : PercentLength . parse } ) ; maxProperty . register ( WearOsListViewBase ) ; export const minProperty = new Property < WearOsListViewBase , PercentLength > ( { name : 'min' , affectsLayout : true , defaultValue : { value : 1 / 3 , unit : '%' } , equalityComparer : PercentLength . equals , valueConverter : PercentLength . parse } ) ; minProperty . register ( WearOsListViewBase ) ; export const hideScrollBarProperty = new Property < WearOsListViewBase , boolean > ( { name : 'hideScrollBar' } ) ; hideScrollBarProperty . register ( WearOsListViewBase ) ; export const circularScrollingEnabled = new Property < WearOsListViewBase , boolean > ( { name : 'circularScrollingEnabled' , defaultValue : false } ) ; circularScrollingEnabled . register ( WearOsListViewBase ) ; export const useScalingScroll = new Property < WearOsListViewBase , boolean > ( { name : 'useScalingScroll' , defaultValue : false } ) ; useScalingScroll . register ( WearOsListViewBase ) ;