menu.monkey2 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. Namespace mojox
  2. #rem monkeydoc @hidden
  3. #end
  4. Class MenuSeparator Extends View
  5. Method New()
  6. Style=GetStyle( "MenuSeparator" )
  7. End
  8. End
  9. #rem monkeydoc @hidden
  10. #end
  11. Class MenuButton Extends Button
  12. Method New( text:String )
  13. Super.New( text )
  14. Style=GetStyle( "MenuButton" )
  15. TextGravity=New Vec2f( 0,.5 )
  16. Layout="fill-x"
  17. ' MinSize=New Vec2i( 100,0 )
  18. End
  19. Method New( action:Action )
  20. Super.New( action )
  21. Style=GetStyle( "MenuButton" )
  22. TextGravity=New Vec2f( 0,.5 )
  23. Layout="fill-x"
  24. ' MinSize=New Vec2i( 100,0 )
  25. _action=action
  26. End
  27. Method OnMeasure:Vec2i() Override
  28. Local size:=Super.OnMeasure()
  29. If _action
  30. Local hotKey:=_action.HotKeyText
  31. If hotKey size.x+=RenderStyle.Font.TextWidth( " "+hotKey )
  32. Endif
  33. Return size
  34. End
  35. Method OnRender( canvas:Canvas ) Override
  36. Super.OnRender( canvas )
  37. If _action
  38. Local hotKey:=_action.HotKeyText
  39. If hotKey
  40. Local w:=RenderStyle.Font.TextWidth( hotKey )
  41. Local tx:=(Width-w)
  42. Local ty:=(Height-MeasuredSize.y) * TextGravity.y
  43. canvas.DrawText( hotKey,tx,ty )
  44. Endif
  45. Endif
  46. End
  47. Field _action:Action
  48. End
  49. #rem monkeydoc The Menu class.
  50. #end
  51. Class Menu Extends DockingView
  52. #rem monkeydoc Creates a new menu.
  53. #end
  54. Method New( text:String="" )
  55. Style=GetStyle( "Menu" )
  56. Visible=False
  57. Layout="float"
  58. Gravity=New Vec2f( 0,0 )
  59. _text=text
  60. End
  61. #rem monkeydoc Menu text
  62. #end
  63. Property Text:String()
  64. Return _text
  65. End
  66. #rem monkeydoc Clears all items from the menu.
  67. #end
  68. Method Clear()
  69. Super.RemoveAllViews()
  70. End
  71. #rem monkeydoc Adds a view to the menu.
  72. #end
  73. Method AddView( view:View )
  74. AddView( view,"top" )
  75. End
  76. #rem monkeydoc Adds an action to the menu.
  77. #end
  78. Method AddAction( action:Action )
  79. Local button:=New MenuButton( action )
  80. button.Clicked=Lambda()
  81. CloseAll()
  82. '
  83. 'a bit gnarly, but makes sure menu is *really* closed...
  84. '
  85. App.RequestRender()
  86. App.Idle+=action.Trigger
  87. End
  88. AddView( button )
  89. End
  90. Method AddAction:Action( text:String )
  91. Local action:=New Action( text )
  92. AddAction( action )
  93. Return action
  94. End
  95. #rem monkeydoc Adds a separator to the menu.
  96. #end
  97. Method AddSeparator()
  98. AddView( New MenuSeparator,"top" )
  99. End
  100. #rem monkeydoc Adds a submenu to the menu.
  101. #end
  102. Method AddSubMenu( menu:Menu )
  103. Local button:=New MenuButton( menu.Text )
  104. button.Clicked=Lambda()
  105. If menu.Visible
  106. menu.Close()
  107. Else
  108. Local location:=New Vec2i( button.Bounds.Right,button.Bounds.Top )
  109. menu.Open( location,button,Self )
  110. Endif
  111. End
  112. AddView( button,"top" )
  113. End
  114. #rem monkeydoc Opens the menu.
  115. #end
  116. Method Open()
  117. Open( App.MouseLocation,App.ActiveWindow,Null )
  118. End
  119. #rem monkeydoc @hidden
  120. #end
  121. Method Open( view:View )
  122. Open( view.MouseLocation,view )
  123. End
  124. #rem monkeydoc @hidden
  125. #end
  126. Method Open( location:Vec2i,view:View )
  127. Open( location,view,view )
  128. End
  129. #rem monkeydoc @hidden
  130. #end
  131. Method Open( location:Vec2i,view:View,owner:View )
  132. Assert( Not Visible )
  133. While Not _open.Empty And _open.Top<>owner
  134. _open.Top.Close()
  135. Wend
  136. If _open.Empty
  137. _filter=App.MouseEventFilter
  138. App.MouseEventFilter=MouseEventFilter
  139. Endif
  140. Local window:=view.Window
  141. location=view.TransformPointToView( location,window )
  142. window.AddChildView( Self )
  143. Offset=location
  144. Visible=True
  145. _owner=owner
  146. _open.Push( Self )
  147. End
  148. #rem monkeydoc @hidden
  149. #end
  150. Method Close()
  151. Assert( Visible )
  152. While Not _open.Empty
  153. Local menu:=_open.Pop()
  154. menu.Parent.RemoveChildView( menu )
  155. menu.Visible=False
  156. menu._owner=Null
  157. If menu=Self Exit
  158. Wend
  159. If Not _open.Empty Return
  160. App.MouseEventFilter=_filter
  161. _filter=Null
  162. End
  163. Private
  164. Field _text:String
  165. Field _owner:View
  166. Global _open:=New Stack<Menu>
  167. Global _filter:Void( MouseEvent )
  168. Function CloseAll()
  169. _open[0].Close()
  170. End
  171. Function MouseEventFilter( event:MouseEvent )
  172. If event.Eaten Return
  173. Local view:=event.View
  174. If view<>_open[0]._owner
  175. For Local menu:=Eachin _open
  176. If view.IsChildOf( menu ) Return
  177. Next
  178. If view.IsChildOf( _open[0]._owner ) Return
  179. Endif
  180. If event.Type=EventType.MouseDown
  181. CloseAll()
  182. Else
  183. event.Eat()
  184. Endif
  185. End
  186. End
  187. Class MenuBar Extends ToolBar
  188. Method New()
  189. Style=GetStyle( "MenuBar" )
  190. Layout="fill-x"
  191. Gravity=New Vec2f( 0,0 )
  192. End
  193. Method AddMenu( menu:Menu )
  194. Local button:=New MenuButton( menu.Text )
  195. button.Clicked=Lambda()
  196. If menu.Visible
  197. menu.Close()
  198. Else
  199. Local location:=New Vec2i( button.Bounds.Left,button.Bounds.Bottom )
  200. menu.Open( location,button,Self )
  201. Endif
  202. End
  203. AddView( button )
  204. End
  205. End