dockingview.monkey2 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. Namespace mojox
  2. #rem monkeydoc @hidden
  3. #end
  4. Class DockKnob Extends View
  5. Field Dragged:Void( v:Vec2i )
  6. Method New()
  7. Style=GetStyle( "DockKnob" )
  8. End
  9. Private
  10. Field _org:Vec2i
  11. Field _drag:Bool
  12. Field _hover:Bool
  13. Method OnMeasure:Vec2i() Override
  14. Return New Vec2i( 0,0 )
  15. End
  16. Method OnMouseEvent( event:MouseEvent ) Override
  17. Select event.Type
  18. Case EventType.MouseDown
  19. _drag=True
  20. _org=event.Location
  21. Case EventType.MouseUp
  22. _drag=False
  23. Case EventType.MouseEnter
  24. _hover=True
  25. Case EventType.MouseLeave
  26. _hover=False
  27. Case EventType.MouseMove
  28. If _drag Dragged( event.Location-_org )
  29. End
  30. If _drag
  31. StyleState="active"
  32. Else If _hover
  33. StyleState="hover"
  34. Else
  35. StyleState=""
  36. Endif
  37. End
  38. End
  39. #rem monkeydoc @hidden
  40. #end
  41. Class DockedView Extends View
  42. Method New( view:View,location:String,size:String,resizable:Bool )
  43. Style=GetStyle( "DockedView" )
  44. _view=view
  45. _location=location
  46. _size=size
  47. _resizable=resizable
  48. If _size.EndsWith( "%" )
  49. _sizeMode=SizeMode.Relative
  50. _relSize=Float( _size.Slice( 0,-1 ) )/100
  51. Else If String( Int( _size ) )=_size
  52. _sizeMode=SizeMode.Absolute
  53. _absSize=Int( _size )
  54. Else
  55. _sizeMode=SizeMode.Natural
  56. Endif
  57. AddChildView( _view )
  58. If _sizeMode=SizeMode.Absolute And _resizable
  59. _knob=New DockKnob
  60. _knob.Dragged=Lambda( v:Vec2i )
  61. Select _location
  62. Case "top"
  63. AbsoluteSize+=v.y
  64. Case "bottom"
  65. AbsoluteSize-=v.y
  66. Case "left"
  67. AbsoluteSize+=v.x
  68. Case "right"
  69. AbsoluteSize-=v.x
  70. End
  71. End
  72. AddChildView( _knob )
  73. Endif
  74. End
  75. Property View:View()
  76. Return _view
  77. Setter( view:View )
  78. If _view RemoveChildView( _view )
  79. _view=view
  80. If _view AddChildView( _view )
  81. End
  82. Property Location:String()
  83. Return _location
  84. End
  85. Property Size:String()
  86. Return _size
  87. Setter( size:String )
  88. If size=_size Return
  89. If size.EndsWith( "%" )
  90. RelativeSize=Float( size.Slice( 0,-1 ) )/100.0
  91. Else If String( Int( size ) )=size
  92. AbsoluteSize=Int( size )
  93. Endif
  94. End
  95. Property Resizable:Bool()
  96. Return _resizable
  97. End
  98. Property RelativeSize:Float()
  99. Return _relSize
  100. Setter( size:Float )
  101. If _sizeMode<>SizeMode.Relative Return
  102. size=Max( size,0.0 )
  103. If size=_relSize Return
  104. _relSize=size
  105. _size=String( Int( _relSize*100.0 ) )+"%"
  106. App.RequestRender()
  107. End
  108. Property AbsoluteSize:Int()
  109. Return _absSize
  110. Setter( size:Int )
  111. If _sizeMode<>SizeMode.Absolute Return
  112. size=Max( size,0 )
  113. If size=_absSize Return
  114. _absSize=size
  115. _size=String( _absSize )
  116. App.RequestRender()
  117. End
  118. Method RealSize:Int( size:Int )
  119. Select _sizeMode
  120. Case SizeMode.Natural,SizeMode.Absolute
  121. If _location="left" Or _location="right" Return LayoutSize.x
  122. Return LayoutSize.y
  123. Case SizeMode.Relative
  124. Return _relSize * size
  125. End
  126. Return 0
  127. End
  128. Private
  129. Field _view:View
  130. Field _knob:DockKnob
  131. Field _location:String
  132. Field _size:String
  133. Field _resizable:Bool
  134. Field _sizeMode:SizeMode
  135. Field _relSize:Float
  136. Field _absSize:Int
  137. Enum SizeMode
  138. Natural
  139. Absolute
  140. Relative
  141. End
  142. Method OnMeasure:Vec2i() Override
  143. Local size:=_view.LayoutSize
  144. If _sizeMode=SizeMode.Absolute
  145. Select _location
  146. Case "top","bottom"
  147. size.y=_absSize
  148. If _knob size.y+=_knob.LayoutSize.y
  149. Case "left","right"
  150. size.x=_absSize
  151. If _knob size.x+=_knob.LayoutSize.x
  152. End
  153. #rem
  154. Else If _sizeMode=SizeMode.Relative
  155. Select _location
  156. Case "top","bottom"
  157. size.y=size.y/_relSize
  158. Case "left","right"
  159. size.x=size.x/_relSize
  160. End
  161. #end
  162. Endif
  163. Return size
  164. End
  165. Method OnLayout:Void() Override
  166. Local rect:=Rect
  167. If _knob
  168. Local w:=_knob.LayoutSize.x
  169. Local h:=_knob.LayoutSize.y
  170. Select _location
  171. Case "top"
  172. _knob.Frame=New Recti( 0,Height-h,Width,Height )
  173. rect.Bottom-=h
  174. Case "bottom"
  175. _knob.Frame=New Recti( 0,0,Width,h )
  176. rect.Top+=h
  177. Case "left"
  178. _knob.Frame=New Recti( Width-w,0,Width,Height )
  179. rect.Right-=w
  180. Case "right"
  181. _knob.Frame=New Recti( 0,0,w,Height )
  182. rect.Left+=w
  183. End
  184. Endif
  185. _view.Frame=rect
  186. End
  187. End
  188. #rem monkeydoc The DockingView class.
  189. #end
  190. Class DockingView Extends View
  191. #rem monkeydoc Creates a new docking view.
  192. #end
  193. Method New()
  194. Style=GetStyle( "DockingView" )
  195. End
  196. #rem monkeydoc The content view.
  197. #end
  198. Property ContentView:View()
  199. Return _contentView
  200. Setter( contentView:View )
  201. If contentView=_contentView Return
  202. If _content RemoveChildView( _content )
  203. _contentView=contentView
  204. _content=ContentViewContainer( _contentView )
  205. If _content AddChildView( _content )
  206. App.RequestRender()
  207. End
  208. #rem monkeydoc Adds a view.
  209. `location` should be one of "left", "right", "top", "bottom".
  210. `size` can be either an integer number of pixels or a percentage. If no size is specified, the view's layout size is used.
  211. If `resizable` is true, the view can be resizable. Note: this must be used with `size` set to a non-0 integer.
  212. #end
  213. Method AddView( view:View,location:String )
  214. AddView( view,location,"",False )
  215. End
  216. Method AddView( view:View,location:String,size:String )
  217. AddView( view,location,size,False )
  218. End
  219. Method AddView( view:View,location:String,size:String,resizable:Bool )
  220. Local dock:=New DockedView( view,location,size,resizable )
  221. _docks.Add( dock )
  222. AddChildView( dock )
  223. End
  224. #rem monkeydoc Removes a view.
  225. #end
  226. Method RemoveView( view:View )
  227. Local dock:=FindView( view )
  228. If Not dock Return
  229. dock.View=Null
  230. _docks.Remove( dock )
  231. RemoveChildView( dock )
  232. End
  233. #rem monkeydoc Gets size of a view.
  234. #end
  235. Method GetViewSize:String( view:View )
  236. Return FindView( view ).Size
  237. End
  238. #rem monkeydoc Sets size of a view.
  239. #end
  240. Method SetViewSize( view:View,size:String )
  241. FindView( view ).Size=size
  242. End
  243. #rem monkeydoc Removes all views.
  244. #end
  245. Method RemoveAllViews()
  246. For Local dock:=Eachin _docks
  247. dock.View=Null
  248. RemoveChildView( dock )
  249. Next
  250. _docks.Clear()
  251. App.RequestRender()
  252. End
  253. Protected
  254. Method OnMeasure:Vec2i() Override
  255. Local size:=New Vec2i
  256. If _content size=_content.LayoutSize
  257. _docksSize=New Vec2i
  258. For Local dock:=Eachin _docks
  259. 'FIXME - silly place to do this...
  260. dock.Visible=dock.View.Visible
  261. If Not dock.Visible Continue
  262. Select dock.Location
  263. Case "top","bottom"
  264. _docksSize.y+=dock.LayoutSize.y
  265. size.x=Max( size.x,dock.LayoutSize.x )
  266. size.y+=dock.LayoutSize.y
  267. Case "left","right"
  268. _docksSize.x+=dock.LayoutSize.x
  269. size.y=Max( size.y,dock.LayoutSize.y )
  270. size.x+=dock.LayoutSize.x
  271. End
  272. Next
  273. Return size
  274. End
  275. Method OnLayout() Override
  276. Local rect:=OnLayoutContent( Rect.Size-_docksSize )
  277. Local fsize:=rect.Size
  278. For Local dock:=Eachin _docks
  279. If Not dock.Visible Continue
  280. Select dock.Location
  281. Case "top"
  282. Local top:=rect.Top+dock.RealSize( fsize.y )
  283. If dock.Resizable And top>rect.Bottom top=rect.Bottom
  284. ' If top>rect.Bottom top=rect.Bottom
  285. dock.Frame=New Recti( rect.Left,rect.Top,rect.Right,top )
  286. rect.Top=top
  287. Case "bottom"
  288. Local bottom:=rect.Bottom-dock.RealSize( fsize.y )
  289. If dock.Resizable And bottom<rect.Top bottom=rect.Top
  290. ' If bottom<rect.Top bottom=rect.Top
  291. dock.Frame=New Recti( rect.Left,bottom,rect.Right,rect.Bottom )
  292. rect.Bottom=bottom
  293. Case "left"
  294. Local left:=rect.Left+dock.RealSize( fsize.x )
  295. If dock.Resizable And left>rect.Right left=rect.Right
  296. ' If left>rect.Right left=rect.Right
  297. dock.Frame=New Recti( rect.Left,rect.Top,left,rect.Bottom )
  298. rect.Left=left
  299. Case "right"
  300. Local right:=rect.Right-dock.RealSize( fsize.x )
  301. If dock.Resizable And right<rect.Left right=rect.Left
  302. ' If right<rect.Left right=rect.Left
  303. dock.Frame=New Recti( right,rect.Top,rect.Right,rect.Bottom )
  304. rect.Right=right
  305. End
  306. Next
  307. If _content _content.Frame=rect
  308. End
  309. Method OnLayoutContent:Recti( contentSize:Vec2i ) Virtual
  310. Return Rect
  311. End
  312. Method ContentViewContainer:View( contentView:View ) Virtual
  313. Return contentView
  314. End
  315. Private
  316. Field _content:View
  317. Field _contentView:View
  318. Field _docksSize:Vec2i
  319. Field _docks:=New Stack<DockedView>
  320. Method FindView:DockedView( view:View )
  321. For Local dock:=Eachin _docks
  322. If dock.View=view Return dock
  323. Next
  324. Return Null
  325. End
  326. End