2
0

listview.monkey2 5.0 KB

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