listview.monkey2 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. Namespace mojox
  2. Class ListView Extends ScrollableView
  3. #rem monkeydoc Invoked when an item is clicked.
  4. #end
  5. Field ItemClicked:Void( item:Item )
  6. #rem monkeydoc Invoked when an item is double clicked.
  7. #end
  8. Field ItemDoubleClicked:Void( item:Item )
  9. #rem monkeydoc Invoked when an item is right clicked.
  10. #end
  11. Field ItemRightClicked:Void( item:Item )
  12. #rem monkeydoc Invoked when current selected item is changed.
  13. An item can be Null.
  14. #end
  15. Field SelectedChanged:Void( item:Item )
  16. Class Item Extends ViewCell
  17. Method New( text:String,icon:Image,list:ListView )
  18. Super.New( text,icon )
  19. _list=list
  20. End
  21. Private
  22. Field _list:ListView
  23. Field _rect:Recti
  24. End
  25. #rem monkeydoc Creates a new list view.
  26. #end
  27. Method New()
  28. Style=GetStyle( "ListView" )
  29. ContentView.Style=GetStyle( "ListViewContent" )
  30. _itemStyle=GetStyle( "ListViewItem" )
  31. End
  32. #rem monkeydoc Currently selected item.
  33. #end
  34. Property Selected:Item()
  35. Return _selected
  36. Setter( selected:Item )
  37. If selected<>_selected
  38. _selected=selected
  39. _selIndex=IndexOfItem( _selected )
  40. SelectedChanged( _selected )
  41. Endif
  42. If _selected Then EnsureVisible( _selected._rect )
  43. RequestRender()
  44. End
  45. #rem monkeydoc Currently selected index.
  46. #end
  47. Property SelectedIndex:Int()
  48. Return _selIndex
  49. Setter( value:Int )
  50. Selected=ItemAtIndex( value )
  51. End
  52. #rem monkeydoc Items count in the list view.
  53. #end
  54. Property Count:Int()
  55. Return _items.Length
  56. End
  57. #rem monkeydoc Adds an item to the list view.
  58. #end
  59. Method AddItem:Item( text:String,icon:Image=Null )
  60. Return InsertItem( _items.Length,text,icon )
  61. End
  62. #rem monkeydoc Inserts an item to the list view at a given index.
  63. #end
  64. Method InsertItem:Item( index:Int,text:String,icon:Image=Null )
  65. Local item:=New Item( text,icon,Self )
  66. _items.Insert( index,item )
  67. RequestRender()
  68. Return item
  69. End
  70. #rem monkeydoc Removes an item from the list view.
  71. #end
  72. Method RemoveItem( index:Int )
  73. RemoveItems( index,index+1 )
  74. End
  75. #rem monkeydoc Removes an item from the list view.
  76. #end
  77. Method RemoveItem( item:Item )
  78. RemoveItem( IndexOfItem( item ) )
  79. End
  80. #rem monkeydoc Removes a sequence of items from the list view.
  81. #end
  82. Method RemoveItems( index1:Int,index2:Int )
  83. For Local i:=index1 Until index2
  84. If _items[i]<>_selected Continue
  85. Selected=Null
  86. Exit
  87. Next
  88. _items.Erase( index1,index2 )
  89. RequestRender()
  90. End
  91. #rem monkeydoc Removes all items from the list view.
  92. #end
  93. Method RemoveAllItems()
  94. _items.Clear()
  95. Selected=Null
  96. _hover=Null
  97. RequestRender()
  98. End
  99. #rem monkeydoc Returns the index of a given item in the list view.
  100. #end
  101. Method IndexOfItem:Int( item:Item )
  102. For Local i:=0 Until _items.Length
  103. If _items[i]=item Return i
  104. Next
  105. Return -1
  106. End
  107. #rem monkeydoc Returns the item at a point in the list view.
  108. #end
  109. Method ItemAtPoint:Item( point:Vec2i )
  110. Local i:=IndexOfItemAtPoint( point )
  111. If i=-1 Return null
  112. Local item:=_items[i]
  113. If Not item._rect.Contains( point ) Return Null
  114. Return item
  115. End
  116. #rem monkeydoc Returns the item by index in the list view.
  117. #end
  118. Method ItemAtIndex:Item( index:Int )
  119. Return (index>=0 And index<_items.Length) ? _items[index] Else Null
  120. End
  121. Protected
  122. #rem monkeydoc @hidden
  123. #end
  124. Method OnMeasureContent:Vec2i() Override
  125. Local w:=0,h:=0
  126. For Local item:=Eachin _items
  127. Local style:=ItemStyle( item )
  128. Local size:=item.Measure( style )
  129. item._rect=New Recti( 0,h,size.x,h+size.y )
  130. w=Max( w,size.x )
  131. h+=size.y
  132. Next
  133. Return New Vec2i( w,h )
  134. End
  135. #rem monkeydoc @hidden
  136. #end
  137. Method OnRenderContent( canvas:Canvas ) Override
  138. If _items.Empty Return
  139. Local clip:=VisibleRect
  140. Local first:=IndexOfItemAtPoint( New Vec2i( 0,clip.Top ) )
  141. If first=-1 first=0
  142. Local last:=IndexOfItemAtPoint( New Vec2i( 0,clip.Bottom-1 ) )+1
  143. If Not last last=_items.Length
  144. For Local i:=first Until last
  145. Local item:=_items[i]
  146. Local style:=ItemStyle( item )
  147. item.Render( canvas,item._rect,style,New Vec2f( 0,.5 ) )
  148. Next
  149. End
  150. #rem monkeydoc @hidden
  151. #end
  152. Method OnContentMouseEvent( event:MouseEvent ) Override
  153. Select event.Type
  154. Case EventType.MouseDown,EventType.MouseWheel
  155. Return
  156. Case EventType.MouseClick
  157. Local item:=ItemAtPoint( event.Location )
  158. If item
  159. Selected=item
  160. ItemClicked( item )
  161. Endif
  162. Case EventType.MouseRightClick
  163. Local item:=ItemAtPoint( event.Location )
  164. If item
  165. Selected=item
  166. ItemRightClicked( item )
  167. Endif
  168. Case EventType.MouseDoubleClick
  169. Local item:=ItemAtPoint( event.Location )
  170. If item ItemDoubleClicked( item )
  171. Case EventType.MouseMove,EventType.MouseMove
  172. Local item:=ItemAtPoint( event.Location )
  173. If item<>_hover
  174. _hover=item
  175. RequestRender()
  176. Endif
  177. Case EventType.MouseLeave
  178. If _hover
  179. _hover=Null
  180. RequestRender()
  181. Endif
  182. End
  183. event.Eat()
  184. End
  185. Protected
  186. Method OnValidateStyle() Override
  187. _hoverStyle=_itemStyle.GetState( "hover" )
  188. _selectedStyle=_itemStyle.GetState( "selected" )
  189. End
  190. Private
  191. Field _items:=New Stack<Item>
  192. Field _itemStyle:Style
  193. Field _hoverStyle:Style
  194. Field _selectedStyle:Style
  195. Field _hover:Item
  196. Field _selected:Item
  197. Field _selIndex:Int
  198. Field _dirty:Bool
  199. Method ItemStyle:Style( item:Item )
  200. If item=_selected Return _selectedStyle
  201. If item=_hover Return _hoverStyle
  202. Return _itemStyle
  203. End
  204. Method IndexOfItemAtPoint:Int( p:Vec2i )
  205. If _items.Empty Or p.y<_items[0]._rect.Top Or p.y>=_items.Top._rect.Bottom Return -1
  206. Local min:=0,max:=_items.Length-1
  207. Repeat
  208. Local i:=(min+max)/2
  209. If p.y>=_items[i]._rect.Bottom
  210. min=i+1
  211. Else If max-min>1
  212. max=i
  213. Else
  214. Return i
  215. Endif
  216. Forever
  217. Return -1
  218. End
  219. End