PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/OnScreen/Test/Notizen.txt.rb

https://bitbucket.org/Aerilius/onscreen-gui
Ruby | 243 lines | 77 code | 22 blank | 144 comment | 20 complexity | 0fe4e6c5c3190845db8c8839eac2390b MD5 | raw file
  1. #!/usr/bin/ruby
  2. =begin
  3. Ruby OnScreen Toolkit:
  4. create meta event :drag data={:pos => currentpos, sourcepos, relpos}
  5. Make sure not to create to many symbols, can't be garbage-collected.
  6. Start better documentation:
  7. How to use widgets: (see bitbucket wiki)
  8. How to create new widgets:
  9. Subclassing existing widget classes or the Widget base class
  10. Compositing widgets
  11. How the internals work (less important, only for contributors)
  12. widget.set_data, widget.get_data; or just keep widget.data[] ?
  13. * display and visibility true/false
  14. * meta-events like :drag, :dragstart, :dragend
  15. * window.stylesheet
  16. * dialog.show/dialog.hide
  17. * widget.show/widget.hide
  18. Widget:
  19. window
  20. parent
  21. draw
  22. sizes and compileLayout
  23. behaviours (Mixins):
  24. layout & style
  25. events (containers don't need this)
  26. children (add, remove; contentsize)
  27. text (text_width, text_height)
  28. Container: specify size of content area?
  29. => to types of containers:
  30. Box: for layout (not visible, no border)
  31. Container: for creating other widgets
  32. How to implement? There is always one set of children, how to separate what is added to the container, and what is internally belonging to it?
  33. Container < Box; contents = Box.new; self.add(bla, bla, contents, bla)
  34. self.add = contents.add # alias or redefine
  35. "Composite Widget":
  36. Maybe special Container class for compositing new widgets. Would maintain it's own layoutCache and compile_layout.
  37. Dialog
  38. Block with title, close button
  39. movable when dragging title
  40. Content area; insert further children here
  41. Border for resizing:
  42. widgets/buttons without style;
  43. force layout align top left?
  44. mousedown => dragging; remember mousedown position (on window level)
  45. move => change size & position: layout[:top] =layout[:left] ?
  46. mouseup => release dragging
  47. So we need to specify a "content area" in a container, or use padding for that?
  48. Since we want to place our own widgets inside, we shouldn't use padding, rather add a child box where new children will be redirected to.
  49. add() adds children into @children which is considered for layout => replace that with childbox.children?
  50. Idea: noStretch = true/false: element size fits content, otherwise 100%
  51. or maybe: get rid of percent; use noStretch; if Stretch then element width = parent element width / amount of children.
  52. WIDGET
  53. - layout&style
  54. - size
  55. - draw
  56. - trigger
  57. - initialize
  58. CONTAINER
  59. - has children, add, remove
  60. WINDOW
  61. - special compile_layout
  62. - special trigger
  63. - special draw
  64. - DrawCache
  65. - keeps track of focus, drag&drop etc.
  66. - has children, add, remove
  67. MIXINs:
  68. [widget]:
  69. @window
  70. @parent
  71. draw
  72. sizes and compile_layout
  73. containable: # requires: widget, events
  74. @children
  75. add
  76. remove
  77. contentsize
  78. innersize (?)
  79. layout & style:
  80. layout=
  81. style=
  82. layout[]
  83. style[]
  84. events:
  85. on
  86. trigger
  87. # important: trigger should only respond to position etc. if the widget is visible/drawable
  88. # eventually event propagation/bubbling
  89. text:
  90. # abstraction for text size estimation (Windows, 96dpi: one character is ~7-9×15px)
  91. text_width
  92. text_height
  93. drawable:
  94. @focus, @hover, @active, @dragging (?), ...
  95. draw
  96. trigger super (adds hover and other states)
  97. invalidate_drawcache for this element (TODO: later add support to drawcache for per-element updates, not clearing the whole cache)
  98. CLASSES:
  99. Layout/Style
  100. Widget
  101. Container
  102. Window
  103. Composite < Widget
  104. # special: maintains a private collection of children
  105. compile_layout
  106. invalidate_layout
  107. =end
  108. class Dialog
  109. @titlebarHeight
  110. self.add(box with width)
  111. Slider=[label, box[start, box[background_start, button, background_end], end] ]
  112. or
  113. Slider=[label, box[start, box[background_start, button, background_end], end] ]
  114. button.on(:drag){ left => ...%, background_start.length = %, background_end.length = % }
  115. examples:
  116. #orientation vertical
  117. #valign top
  118. label
  119. start
  120. slider
  121. end
  122. #valign bottom
  123. start
  124. slider
  125. end
  126. label
  127. #orientation horizontal
  128. #align left
  129. label start slider end
  130. #align right
  131. start slider end label
  132. #align center
  133. #valign bottom
  134. start slider end
  135. label
  136. #align center
  137. #valign top
  138. label
  139. start slider end
  140. def initialize(text="")
  141. hash[:padding] = 0 #?
  142. super(hash)
  143. if text.empty?
  144. slider_box = self
  145. else
  146. # Layouting of label and slider_box
  147. label = Label.new(text)
  148. slider_box = Container.new({:align=>:center, :valign=>:middle})
  149. if @layout[:orientation] == :horizontal && @layout[:align] != :center
  150. if @layout[:align] == :left
  151. @layout[:paddingLeft] ||= 0; @layout[:paddingLeft] += label.text_width
  152. label.layout[:marginLeft] = -label.text_width
  153. else # if @layout[:align] == :right
  154. @layout[:paddingRight] ||= 0; @layout[:paddingRight] += label.text_width
  155. label.layout[:marginRight] = -label.text_width
  156. end
  157. slider_box.layout[:width] = :"100%"
  158. self.add(label, slider_box)
  159. else
  160. if @layout[:orientation] == :horizontal && @layout[:align] == :center
  161. self.layout[:orientation] = :vertical
  162. slider_box.layout[:orientation] = :horizontal
  163. else if @layout[:valign] == :top
  164. @layout[:paddingTop] ||= 0; @layout[:paddingTop] += label.text_height
  165. label.layout[:marginTop] = -label.text_height
  166. else # if @layout[:valign] == :bottom # :middle not implemented, makes no sense
  167. @layout[:paddingBottom] ||= 0; @layout[:paddingBottom] += label.text_height
  168. label.layout[:marginBottom] = -label.text_height
  169. end
  170. slider_box.layout[:height] = :"100%"
  171. self.add(label, slider_box)
  172. end
  173. end
  174. # Layouting of slider labels and slider
  175. label_start = Label.new()
  176. slider_start = Widget.new(@style) # TODO: modify borderRadius
  177. slider_thumb = Button.new("", @style)
  178. slider_end = Widget.new(@style) # TODO: modify borderRadius and borderWidth etc.
  179. label_end = Label.new()
  180. if @layout[:orientation] == :horizontal
  181. slider_start.layout[:width] =
  182. slider_start.layout[:height] =
  183. @layout[:paddingLeft] ||= 0; @layout[:paddingLeft] += label.text_width
  184. label.layout[:marginLeft] = -label.text_width
  185. else # if @layout[:orientation] == :vertical
  186. @layout[:paddingRight] ||= 0; @layout[:paddingRight] += label.text_width
  187. label.layout[:marginRight] = -label.text_width
  188. end
  189. slider_box.add(label_start, slider_start, slider_thumb, slider_end, label_end)
  190. o = @layout[:orientation] == :horizontal # TODO: do this at the beginning
  191. # Make the slider dynamic
  192. slider_thumb.on(:drag){|data|
  193. delta = data[:relpos][o ? 0 : 1] # relative movement since the drag start; maybe call it :delta
  194. slider_start.layout[o ? :width : :height] = delta
  195. slider_end.layout[o ? :width : :height] = delta
  196. # calculate value
  197. # trigger block with value
  198. }
  199. end