dockingview.monkey2 8.3 KB

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