glimmer-dsl-libui 0.1.5 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/README.md +352 -67
  4. data/VERSION +1 -1
  5. data/examples/area_gallery.rb +50 -2
  6. data/examples/area_gallery2.rb +50 -2
  7. data/examples/area_gallery3.rb +50 -2
  8. data/examples/area_gallery4.rb +50 -2
  9. data/examples/basic_button.rb +2 -2
  10. data/examples/basic_entry.rb +2 -2
  11. data/examples/basic_transform.rb +1 -1
  12. data/examples/control_gallery.rb +3 -3
  13. data/examples/form.rb +2 -2
  14. data/examples/histogram.rb +18 -19
  15. data/examples/meta_example.rb +71 -20
  16. data/examples/midi_player.rb +8 -10
  17. data/glimmer-dsl-libui.gemspec +0 -0
  18. data/lib/glimmer/dsl/libui/control_expression.rb +0 -2
  19. data/lib/glimmer/dsl/libui/file_expression.rb +5 -1
  20. data/lib/glimmer/dsl/libui/shape_expression.rb +2 -4
  21. data/lib/glimmer/dsl/libui/tab_item_expression.rb +2 -2
  22. data/lib/glimmer/libui/control_proxy/area_proxy.rb +197 -0
  23. data/lib/glimmer/libui/{menu_item_proxy.rb → control_proxy/box/horizontal_box_proxy.rb} +9 -12
  24. data/lib/glimmer/libui/{horizontal_box_proxy.rb → control_proxy/box/vertical_box_proxy.rb} +10 -6
  25. data/lib/glimmer/libui/{box.rb → control_proxy/box.rb} +31 -27
  26. data/lib/glimmer/libui/{button_proxy.rb → control_proxy/button_proxy.rb} +14 -12
  27. data/lib/glimmer/libui/{checkbox_proxy.rb → control_proxy/checkbox_proxy.rb} +14 -12
  28. data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +118 -0
  29. data/lib/glimmer/libui/control_proxy/column/button_column_proxy.rb +76 -0
  30. data/lib/glimmer/libui/control_proxy/column/checkbox_column_proxy.rb +46 -0
  31. data/lib/glimmer/libui/control_proxy/column/checkbox_text_column_proxy.rb +80 -0
  32. data/lib/glimmer/libui/{radio_buttons_proxy.rb → control_proxy/column/image_column_proxy.rb} +14 -13
  33. data/lib/glimmer/libui/control_proxy/column/image_text_column_proxy.rb +48 -0
  34. data/lib/glimmer/libui/control_proxy/column/progress_bar_column_proxy.rb +44 -0
  35. data/lib/glimmer/libui/{checkbox_column_proxy.rb → control_proxy/column/text_column_proxy.rb} +17 -13
  36. data/lib/glimmer/libui/control_proxy/column.rb +55 -0
  37. data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +45 -0
  38. data/lib/glimmer/libui/control_proxy/date_time_picker_proxy/date_picker_proxy.rb +43 -0
  39. data/lib/glimmer/libui/control_proxy/date_time_picker_proxy/time_picker_proxy.rb +43 -0
  40. data/lib/glimmer/libui/control_proxy/date_time_picker_proxy.rb +72 -0
  41. data/lib/glimmer/libui/control_proxy/dual_column.rb +40 -0
  42. data/lib/glimmer/libui/control_proxy/editable_column.rb +46 -0
  43. data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +45 -0
  44. data/lib/glimmer/libui/{dual_column.rb → control_proxy/enableable_column.rb} +18 -10
  45. data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +70 -0
  46. data/lib/glimmer/libui/{form_proxy.rb → control_proxy/form_proxy.rb} +26 -24
  47. data/lib/glimmer/libui/{grid_proxy.rb → control_proxy/grid_proxy.rb} +29 -27
  48. data/lib/glimmer/libui/{group_proxy.rb → control_proxy/group_proxy.rb} +24 -22
  49. data/lib/glimmer/libui/{image_part_proxy.rb → control_proxy/image_part_proxy.rb} +20 -18
  50. data/lib/glimmer/libui/{image_proxy.rb → control_proxy/image_proxy.rb} +32 -30
  51. data/lib/glimmer/libui/{combobox_proxy.rb → control_proxy/label_proxy.rb} +13 -13
  52. data/lib/glimmer/libui/control_proxy/matrix_proxy.rb +147 -0
  53. data/lib/glimmer/libui/{editable_column.rb → control_proxy/menu_item_proxy/about_menu_item_proxy.rb} +13 -16
  54. data/lib/glimmer/libui/{enableable_column.rb → control_proxy/menu_item_proxy/check_menu_item_proxy.rb} +13 -16
  55. data/lib/glimmer/libui/{date_picker_proxy.rb → control_proxy/menu_item_proxy/preferences_menu_item_proxy.rb} +10 -10
  56. data/lib/glimmer/libui/{quit_menu_item_proxy.rb → control_proxy/menu_item_proxy/quit_menu_item_proxy.rb} +33 -29
  57. data/lib/glimmer/libui/control_proxy/menu_item_proxy/separator_menu_item_proxy.rb +41 -0
  58. data/lib/glimmer/libui/control_proxy/menu_item_proxy.rb +45 -0
  59. data/lib/glimmer/libui/{editable_combobox_proxy.rb → control_proxy/menu_proxy.rb} +13 -13
  60. data/lib/glimmer/libui/{vertical_box_proxy.rb → control_proxy/message_box/msg_box_error_proxy.rb} +9 -6
  61. data/lib/glimmer/libui/{multiline_entry_proxy.rb → control_proxy/message_box/msg_box_proxy.rb} +8 -6
  62. data/lib/glimmer/libui/{time_picker_proxy.rb → control_proxy/message_box.rb} +9 -10
  63. data/lib/glimmer/libui/{rectangle.rb → control_proxy/multiline_entry_proxy/non_wrapping_multiline_entry_proxy.rb} +6 -8
  64. data/lib/glimmer/libui/{progress_bar_column_proxy.rb → control_proxy/multiline_entry_proxy.rb} +10 -11
  65. data/lib/glimmer/libui/control_proxy/path_proxy.rb +190 -0
  66. data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +45 -0
  67. data/lib/glimmer/libui/{button_column_proxy.rb → control_proxy/tab_item_proxy.rb} +37 -40
  68. data/lib/glimmer/libui/control_proxy/table_proxy.rb +182 -0
  69. data/lib/glimmer/libui/{transformable.rb → control_proxy/transformable.rb} +3 -1
  70. data/lib/glimmer/libui/control_proxy/window_proxy.rb +128 -0
  71. data/lib/glimmer/libui/control_proxy.rb +68 -9
  72. data/lib/glimmer/libui/{arc.rb → shape/arc.rb} +13 -11
  73. data/lib/glimmer/libui/shape/bezier.rb +38 -0
  74. data/lib/glimmer/libui/{figure.rb → shape/figure.rb} +23 -21
  75. data/lib/glimmer/libui/{line.rb → shape/line.rb} +9 -7
  76. data/lib/glimmer/libui/{bezier.rb → shape/rectangle.rb} +9 -7
  77. data/lib/glimmer/libui/{square.rb → shape/square.rb} +9 -7
  78. data/lib/glimmer/libui/shape.rb +8 -6
  79. data/lib/glimmer/libui.rb +43 -1
  80. data/lib/glimmer-dsl-libui.rb +2 -0
  81. metadata +74 -57
  82. data/lib/glimmer/libui/about_menu_item_proxy.rb +0 -37
  83. data/lib/glimmer/libui/area_proxy.rb +0 -115
  84. data/lib/glimmer/libui/check_menu_item_proxy.rb +0 -37
  85. data/lib/glimmer/libui/checkbox_text_column_proxy.rb +0 -76
  86. data/lib/glimmer/libui/color_button_proxy.rb +0 -116
  87. data/lib/glimmer/libui/column.rb +0 -51
  88. data/lib/glimmer/libui/date_time_picker_proxy.rb +0 -68
  89. data/lib/glimmer/libui/font_button_proxy.rb +0 -68
  90. data/lib/glimmer/libui/image_column_proxy.rb +0 -40
  91. data/lib/glimmer/libui/image_text_column_proxy.rb +0 -44
  92. data/lib/glimmer/libui/label_proxy.rb +0 -41
  93. data/lib/glimmer/libui/matrix_proxy.rb +0 -145
  94. data/lib/glimmer/libui/menu_proxy.rb +0 -41
  95. data/lib/glimmer/libui/non_wrapping_multiline_entry_proxy.rb +0 -32
  96. data/lib/glimmer/libui/path_proxy.rb +0 -166
  97. data/lib/glimmer/libui/preferences_menu_item_proxy.rb +0 -37
  98. data/lib/glimmer/libui/separator_menu_item_proxy.rb +0 -37
  99. data/lib/glimmer/libui/tab_item_proxy.rb +0 -67
  100. data/lib/glimmer/libui/table_proxy.rb +0 -180
  101. data/lib/glimmer/libui/text_column_proxy.rb +0 -42
  102. data/lib/glimmer/libui/window_proxy.rb +0 -126
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.1.4
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.1.9
2
2
  ## Prerequisite-Free Ruby Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/ce2853efdbecf6ebdc73/maintainability)](https://codeclimate.com/github/AndyObtiva/glimmer-dsl-libui/maintainability)
@@ -115,14 +115,62 @@ window('Area Gallery', 400, 400) {
115
115
  }
116
116
 
117
117
  fill r: 202, g: 102, b: 204, a: 0.5
118
- stroke thickness: 2, r: 0, g: 0, b: 0
118
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
119
119
  }
120
120
  path { # declarative stable path
121
121
  arc(200, 200, 90, 0, 360, false)
122
122
 
123
123
  fill r: 202, g: 102, b: 204, a: 0.5
124
- stroke thickness: 2, r: 0, g: 0, b: 0
124
+ stroke r: 0, g: 0, b: 0, thickness: 2
125
125
  }
126
+
127
+ on_mouse_event do |area_mouse_event|
128
+ p area_mouse_event
129
+ end
130
+
131
+ on_mouse_moved do |area_mouse_event|
132
+ puts 'moved'
133
+ end
134
+
135
+ on_mouse_down do |area_mouse_event|
136
+ puts 'mouse down'
137
+ end
138
+
139
+ on_mouse_up do |area_mouse_event|
140
+ puts 'mouse up'
141
+ end
142
+
143
+ on_mouse_drag_started do |area_mouse_event|
144
+ puts 'drag started'
145
+ end
146
+
147
+ on_mouse_dragged do |area_mouse_event|
148
+ puts 'dragged'
149
+ end
150
+
151
+ on_mouse_dropped do |area_mouse_event|
152
+ puts 'dropped'
153
+ end
154
+
155
+ on_mouse_entered do
156
+ puts 'entered'
157
+ end
158
+
159
+ on_mouse_exited do
160
+ puts 'exited'
161
+ end
162
+
163
+ on_key_event do |area_key_event|
164
+ p area_key_event
165
+ end
166
+
167
+ on_key_up do |area_key_event|
168
+ puts 'key up'
169
+ end
170
+
171
+ on_key_down do |area_key_event|
172
+ puts 'key down'
173
+ end
126
174
  }
127
175
  }.show
128
176
  ```
@@ -143,7 +191,7 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
143
191
 
144
192
  ## Table of Contents
145
193
 
146
- - [Glimmer DSL for LibUI 0.1.4](#-glimmer-dsl-for-libui-014)
194
+ - [Glimmer DSL for LibUI 0.1.9](#-glimmer-dsl-for-libui-019)
147
195
  - [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
148
196
  - [Usage](#usage)
149
197
  - [Girb (Glimmer IRB)](#girb-glimmer-irb)
@@ -249,10 +297,10 @@ require 'glimmer-dsl-libui'
249
297
 
250
298
  include Glimmer
251
299
 
252
- window('hello world', 300, 200) { |w|
300
+ window('hello world', 300, 200) {
253
301
  button('Button') {
254
302
  on_clicked do
255
- msg_box(w, 'Information', 'You clicked the button')
303
+ msg_box('Information', 'You clicked the button')
256
304
  end
257
305
  }
258
306
 
@@ -273,7 +321,7 @@ gem install glimmer-dsl-libui
273
321
  Or install via Bundler `Gemfile`:
274
322
 
275
323
  ```ruby
276
- gem 'glimmer-dsl-libui', '~> 0.1.4'
324
+ gem 'glimmer-dsl-libui', '~> 0.1.9'
277
325
  ```
278
326
 
279
327
  Add `require 'glimmer-dsl-libui'` at the top, and then `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
@@ -347,7 +395,7 @@ w.libui # => #<Fiddle::Pointer:0x00007fde53997980 ptr=0x00007fde51352a60 size=0
347
395
  Control(Args) | Properties | Listeners
348
396
  ------------- | ---------- | ---------
349
397
  `about_menu_item` | None | `on_clicked`
350
- `area` | None | `on_draw`
398
+ `area` | None | `on_draw(area_draw_params)`, `on_mouse_event(area_mouse_event)`, `on_mouse_down(area_mouse_event)`, `on_mouse_up(area_mouse_event)`, `on_mouse_drag_started(area_mouse_event)`, `on_mouse_dragged(area_mouse_event)`, `on_mouse_dropped(area_mouse_event)`, `on_mouse_entered`, `on_mouse_exited`, `on_key_event(area_key_event)`, `on_key_down(area_key_event)`, `on_key_up(area_key_event)`
351
399
  `arc(x_center as Numeric, y_center as Numeric, radius as Numeric, start_angle as Numeric, sweep as Numeric, is_negative as Boolean)` | `x_center` (`Numeric`), `y_center` (`Numeric`), `radius` (`Numeric`), `start_angle` (`Numeric`), `sweep` (`Numeric`), `is_negative` (Boolean) | None
352
400
  `bezier(c1_x as Numeric, c1_y as Numeric, c2_x as Numeric, c2_y as Numeric, end_x as Numeric, end_y as Numeric)` | `c1_x` (`Numeric`), `c1_y` (`Numeric`), `c2_x` (`Numeric`), `c2_y` (`Numeric`), `end_x` (`Numeric`), `end_y` (`Numeric`) | None
353
401
  `button(text as String)` | `text` (`String`) | `on_clicked`
@@ -378,10 +426,10 @@ Control(Args) | Properties | Listeners
378
426
  `menu(text as String)` | None | None
379
427
  `menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
380
428
  `multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
381
- `msg_box(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
382
- `msg_box_error(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
429
+ `msg_box(window = main_window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
430
+ `msg_box_error(window = main_window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
383
431
  `non_wrapping_multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
384
- `path` | `fill` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`), `stroke` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, `:cap` as `Numeric`, `:join` as `Numeric`, `:thickness` as `Numeric`, `:miter_limit` as `Numeric` ) | None
432
+ `path(draw_fill_mode = :winding)` | `fill` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`), `stroke` (`Hash` of `:r` as `0`-`255`, `:g` as `0`-`255`, `:b` as `0`-`255`, `:a` as `0.0`-`1.0`, `:cap` as (`:round`, `:square`, `:flat`), `:join` as (`:miter`, `:round`, `:bevel`), `:thickness` as `Numeric`, `:miter_limit` as `Numeric`, `:dashes` as `Array` of `Numeric` ) | None
385
433
  `preferences_menu_item` | None | `on_clicked`
386
434
  `progress_bar` | `value` (`Numeric`) | None
387
435
  `progress_bar_column(name as String)` | None | None
@@ -395,7 +443,7 @@ Control(Args) | Properties | Listeners
395
443
  `tab_item(name as String)` | `index` [read-only] (`Integer`), `margined` (Boolean), `name` [read-only] (`String`) | None
396
444
  `table` | `cell_rows` (`Array` (rows) of `Arrays` (row columns) of cell values (e.g. `String` values for `text_column` cells or `Array` of `image`/`String` for `image_text_column`)), `editable` as Boolean | None
397
445
  `text_column(name as String)` | `editable` (Boolean) | None
398
- `time_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`, `mday` as `Integer`, `mon` as `Integer`, `year` as `Integer`, `wday` as `Integer`, `yday` as `Integer`, `dst` as Boolean) | `on_changed`
446
+ `time_picker` | `time` (`Hash` of keys: `sec` as `Integer`, `min` as `Integer`, `hour` as `Integer`) | `on_changed`
399
447
  `vertical_box` | `padded` (Boolean) | None
400
448
  `window(title as String, width as Integer, height as Integer, has_menubar as Boolean)` | `borderless` (Boolean), `content_size` (width `Numeric`, height `Numeric`), `fullscreen` (Boolean), `margined` (Boolean), `title` (`String`) | `on_closing`, `on_content_size_changed`, `on_destroy`
401
449
 
@@ -585,6 +633,8 @@ window('Basic Area', 400, 400) {
585
633
 
586
634
  Check [examples/dynamic_area.rb](#dynamic-area) for a more detailed semi-declarative example.
587
635
 
636
+ `path` can receive a `draw_fill_mode` argument that can accept values `:winding` or `:alternate` and defaults to `:winding`.
637
+
588
638
  Available nested `path` shapes:
589
639
  - `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)`
590
640
  - `square(x as Numeric, y as Numeric, length as Numeric)`
@@ -606,6 +656,41 @@ The `area_draw_params` argument for `on_draw` block is a hash consisting of the
606
656
 
607
657
  In general, it is recommended to use declarative stable paths whenever feasible since they require less code and simpler maintenance. But, in more advanced cases, semi-declarative dynamic paths could be used instead, especially if there are thousands of dynamic paths that need maximum performance and low memory footprint.
608
658
 
659
+ `area` supported mouse listeners are:
660
+ - `on_key_event {|area_key_event| ...}`: general catch-all key event (recommend using fine-grained key events below instead)
661
+ - `on_key_down {|area_key_event| ...}`
662
+ - `on_key_up {|area_key_event| ...}`
663
+ - `on_mouse_event {|area_mouse_event| ...}`: general catch-all mouse event (recommend using fine-grained mouse events below instead)
664
+ - `on_mouse_down {|area_mouse_event| ...}`
665
+ - `on_mouse_up {|area_mouse_event| ...}`
666
+ - `on_mouse_drag_started {|area_mouse_event| ...}`
667
+ - `on_mouse_dragged {|area_mouse_event| ...}`
668
+ - `on_mouse_dropped {|area_mouse_event| ...}`
669
+ - `on_mouse_entered {...}`
670
+ - `on_mouse_exited {...}`
671
+ - `on_mouse_crossed {|left| ...}` (NOT RECOMMENDED; it does what `on_mouse_entered` and `on_mouse_exited` do by returning a `left` argument indicating if mouse left `area`)
672
+ - `on_drag_broken {...}` (NOT RECOMMENDED; varies per platforms; use `on_mouse_dropped` instead)
673
+
674
+ The `area_mouse_event` `Hash` argument for mouse events that receive it (e.g. `on_mouse_up`, `on_mouse_dragged`) consist of the following hash keys:
675
+ - `:x`: mouse x location in relation to area's top-left-corner
676
+ - `:y`: mouse y location in relation to area's top-left-corner
677
+ - `:area_width`: area current width
678
+ - `:area_height`: area current height
679
+ - `:down`: mouse pressed button (e.g. `1` is left button, `3` is right button)
680
+ - `:up`: mouse depressed button (e.g. `1` is left button, `3` is right button)
681
+ - `:count`: count of mouse clicks (e.g. `2` for double-click, `1` for single-click)
682
+ - `:modifers`: `Array` of `Symbol`s from one of the following: `[:command, :shift, :alt, :control]`
683
+ - `:held`: mouse held button during dragging (e.g. `1` is left button, `4` is right button)
684
+
685
+ The `area_key_event` `Hash` argument for keyboard events that receive it (e.g. `on_key_up`, `on_key_down`) consist of the following hash keys:
686
+ - `:key`: key character (`String`)
687
+ - `:ext_key`: non-character extra key (`Symbol`) such as `:left`, `:right`, `:escape`, `:insert`
688
+ - `:modifier`: modifier key pressed alone (e.g. `:shift` or `:control`)
689
+ - `:modifiers`: modifier keys pressed simultaneously with `:key`, `:ext_key`, or `:modifier`
690
+ - `:up`: indicates if key has been released or not (Boolean)
691
+
692
+ Note that when nesting an `area` directly underneath `window` (without a layout control like `vertical_box`), it is automatically reparented with `vertical_box` in between the `window` and `area` since it would not show up on Linux otherwise.
693
+
609
694
  To redraw an `area`, you may call the `#queue_redraw_all` method, or simply `#redraw`.
610
695
 
611
696
  A transform `matrix` can be set on a path by building a `matrix(m11 = nil, m12 = nil, m21 = nil, m22 = nil, m31 = nil, m32 = nil) {operations}` proxy object and then setting via `transform` property, or alternatively by building and setting the matrix in one call to `transform(m11 = nil, m12 = nil, m21 = nil, m22 = nil, m31 = nil, m32 = nil) {operations}` passing it the matrix arguments and/or content operations.
@@ -638,7 +723,7 @@ window('Basic Transform', 350, 350) {
638
723
  square(0, 0, 100)
639
724
 
640
725
  fill r: [255 - n*5, 0].max, g: [n*5, 255].min, b: 0, a: 0.5
641
- stroke color: 0, thickness: 2
726
+ stroke :black, thickness: 2
642
727
  transform {
643
728
  skew 0.15, 0.15
644
729
  translate 50, 50
@@ -673,12 +758,18 @@ transform m1
673
758
 
674
759
  Note that `area`, `path`, and nested shapes are all truly declarative, meaning they do not care about the ordering of calls to `fill`, `stroke`, and `transform`. Furthermore, any transform that is applied is reversed at the end of the block, so you never have to worry about the ordering of `transform` calls among different paths. You simply set a transform on the `path`s that need it and it is guaranteed to be called before all its content is drawn, and then undone afterwards to avoid affecting later paths. Matrix `transform` can be set on an entire `area` too, applying to all nested `path`s.
675
760
 
761
+ `fill` and `stroke` accept [X11](https://en.wikipedia.org/wiki/X11_color_names) color `Symbol`s/`String`s like `:skyblue` and `'sandybrown'` or 6-number hex or 3-number hex-shorthand (as `Integer` or `String` with or without `0x` prefix)
762
+
763
+ Check [Basic Transform](#basic-transform) example for use of [X11](https://en.wikipedia.org/wiki/X11_color_names) colors.
764
+
765
+ Check [Histogram](#histogram) example for use of hex colors.
766
+
676
767
  ### Smart Defaults and Conventions
677
768
 
678
769
  - `horizontal_box`, `vertical_box`, `grid`, and `form` controls have `padded` as `true` upon instantiation to ensure more user-friendly GUI by default
679
770
  - `group` controls have `margined` as `true` upon instantiation to ensure more user-friendly GUI by default
680
771
  - All controls nested under a `horizontal_box`, `vertical_box`, and `form` have `stretchy` property (fill maximum space) as `true` by default (passed to `box_append`/`form_append` method)
681
- - `window` instatiation args can be left off, having the following defaults when unspecified: `title` as `''`, `width` as `150`, `height` as `150`, and `has_menubar` as `true`)
772
+ - `window` instatiation args can be left off, having the following defaults when unspecified: `title` as `''`, `width` as `190`, `height` as `150`, and `has_menubar` as `true`)
682
773
  - `window` has an `on_closing` listener by default that quits application upon hitting the close button (can be overridden with a manual `on_closing` implementation that returns integer `0` for success)
683
774
  - `group` has `title` property default to `''` if not specified in instantiation args, so it can be instantiated without args with `title` property specified in nested block (e.g. `group {title 'Address'; ...}`)
684
775
  - `button`, `checkbox`, and `label` have `text` default to `''` if not specified in instantiation args, so they can be instantiated without args with `text` property specified in nested block (e.g. `button {text 'Greet'; on_clicked {puts 'Hello'}}`)
@@ -706,6 +797,9 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
706
797
  - Observe `path` `fill` and `stroke` hashes for changes and automatically redraw containing area accordingly
707
798
  - All controls are protected from garbage collection until no longer needed (explicitly destroyed), so there is no need to worry about surprises.
708
799
  - All resources are freed automatically once no longer needed or left to garbage collection.
800
+ - When nesting an `area` directly underneath `window` (without a layout control like `vertical_box`), it is automatically reparented with `vertical_box` in between the `window` and `area` since it would not show up on Linux otherwise.
801
+ - Colors may be passed in as a hash of `:r`, `:g`, `:b`, `:a`, or `:red`, `:green`, `:blue`, `:alpha`, or [X11](https://en.wikipedia.org/wiki/X11_color_names) color like `:skyblue`, or 6-number hex or 3-number hex (as `Integer` or `String` with or without `0x` prefix)
802
+ - Color alpha value defaults to `1.0` when not specified.
709
803
 
710
804
  ### API Gotchas
711
805
 
@@ -733,6 +827,8 @@ The following examples include reimplementions of the examples in the [LibUI](ht
733
827
 
734
828
  To browse all examples, simply launch the [Meta-Example](examples/meta_example.rb), which lists all examples and displays each example's code when selected. It also enables code editing to facilitate experimentation and learning.
735
829
 
830
+ (note that for examples that emit output to terminal/command-line via `p` or `puts`, you must run them directly to see output)
831
+
736
832
  [examples/meta_example.rb](examples/meta_example.rb)
737
833
 
738
834
  Run with this command from the root of the project if you cloned the project:
@@ -783,7 +879,7 @@ class MetaExample
783
879
  end
784
880
 
785
881
  def launch
786
- window('Meta-Example', 700, 500) { |w|
882
+ window('Meta-Example', 700, 500) {
787
883
  margined true
788
884
 
789
885
  horizontal_box {
@@ -805,7 +901,7 @@ class MetaExample
805
901
  meta_example_file = File.join(Dir.home, '.meta_example.rb')
806
902
  File.write(meta_example_file, @nwme.text)
807
903
  result = `ruby -r #{glimmer_dsl_libui_file} #{meta_example_file} 2>&1`
808
- msg_box(w, 'Error Running Example', result) if result.include?('error')
904
+ msg_box('Error Running Example', result) if result.include?('error')
809
905
  rescue => e
810
906
  puts 'Unable to write code changes! Running original example...'
811
907
  system "ruby -r #{glimmer_dsl_libui_file} #{file_path_for(@examples[@rbs.selected])}"
@@ -970,10 +1066,10 @@ require 'glimmer-dsl-libui'
970
1066
 
971
1067
  include Glimmer
972
1068
 
973
- window('hello world', 300, 200) { |w|
1069
+ window('hello world', 300, 200) {
974
1070
  button('Button') {
975
1071
  on_clicked do
976
- msg_box(w, 'Information', 'You clicked the button')
1072
+ msg_box('Information', 'You clicked the button')
977
1073
  end
978
1074
  }
979
1075
 
@@ -1057,7 +1153,7 @@ require 'glimmer-dsl-libui'
1057
1153
 
1058
1154
  include Glimmer
1059
1155
 
1060
- window('Basic Entry', 300, 50) { |w|
1156
+ window('Basic Entry', 300, 50) {
1061
1157
  horizontal_box {
1062
1158
  e = entry {
1063
1159
  # stretchy true # Smart default option for appending to horizontal_box
@@ -1073,7 +1169,7 @@ window('Basic Entry', 300, 50) { |w|
1073
1169
 
1074
1170
  on_clicked do
1075
1171
  text = e.text
1076
- msg_box(w, 'You entered', text)
1172
+ msg_box('You entered', text)
1077
1173
  end
1078
1174
  }
1079
1175
  }
@@ -1177,12 +1273,12 @@ ruby -r glimmer-dsl-libui -e "require 'examples/midi_player'"
1177
1273
  Mac
1178
1274
 
1179
1275
  ![glimmer-dsl-libui-mac-midi-player.png](images/glimmer-dsl-libui-mac-midi-player.png)
1180
- ![glimmer-dsl-libui-mac-midi-player-version-msg-box.png](images/glimmer-dsl-libui-mac-midi-player-version-msg-box.png)
1276
+ ![glimmer-dsl-libui-mac-midi-player-msg-box.png](images/glimmer-dsl-libui-mac-midi-player-msg-box.png)
1181
1277
 
1182
1278
  Linux
1183
1279
 
1184
1280
  ![glimmer-dsl-libui-linux-midi-player.png](images/glimmer-dsl-libui-linux-midi-player.png)
1185
- ![glimmer-dsl-libui-linux-midi-player-version-msg-box.png](images/glimmer-dsl-libui-linux-midi-player-version-msg-box.png)
1281
+ ![glimmer-dsl-libui-linux-midi-player-msg-box.png](images/glimmer-dsl-libui-linux-midi-player-msg-box.png)
1186
1282
 
1187
1283
  [LibUI](https://github.com/kojix2/LibUI) Original Version:
1188
1284
 
@@ -1328,23 +1424,22 @@ class TinyMidiPlayer
1328
1424
  end
1329
1425
  end
1330
1426
 
1331
- def show_version(main_window)
1332
- msg_box(main_window,
1333
- 'Tiny Midi Player',
1334
- "Written in Ruby\n" \
1335
- "https://github.com/kojix2/libui\n" \
1336
- "Version #{VERSION}")
1427
+ def show_version
1428
+ msg_box('Tiny Midi Player',
1429
+ "Written in Ruby\n" \
1430
+ "https://github.com/kojix2/libui\n" \
1431
+ "Version #{VERSION}")
1337
1432
  end
1338
1433
 
1339
1434
  def create_gui
1340
1435
  menu('Help') { |m|
1341
1436
  menu_item('Version') {
1342
1437
  on_clicked do
1343
- show_version(@main_window)
1438
+ show_version
1344
1439
  end
1345
1440
  }
1346
1441
  }
1347
- @main_window = window('Tiny Midi Player', 200, 50) {
1442
+ window('Tiny Midi Player', 200, 50) {
1348
1443
  horizontal_box {
1349
1444
  vertical_box {
1350
1445
  stretchy false
@@ -1360,7 +1455,7 @@ class TinyMidiPlayer
1360
1455
  end
1361
1456
  }
1362
1457
  }
1363
-
1458
+
1364
1459
  combobox { |c|
1365
1460
  items @midi_files.map { |path| File.basename(path) }
1366
1461
 
@@ -1370,8 +1465,7 @@ class TinyMidiPlayer
1370
1465
  end
1371
1466
  }
1372
1467
  }
1373
- }
1374
- @main_window.show
1468
+ }.show
1375
1469
  end
1376
1470
  end
1377
1471
 
@@ -1607,14 +1701,14 @@ include Glimmer
1607
1701
  menu('File') {
1608
1702
  menu_item('Open') {
1609
1703
  on_clicked do
1610
- file = open_file(MAIN_WINDOW)
1704
+ file = open_file
1611
1705
  puts file unless file.nil?
1612
1706
  end
1613
1707
  }
1614
1708
 
1615
1709
  menu_item('Save') {
1616
1710
  on_clicked do
1617
- file = save_file(MAIN_WINDOW)
1711
+ file = save_file
1618
1712
  puts file unless file.nil?
1619
1713
  end
1620
1714
  }
@@ -1657,7 +1751,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
1657
1751
  stretchy false
1658
1752
 
1659
1753
  on_clicked do
1660
- msg_box(MAIN_WINDOW, 'Information', 'You clicked the button')
1754
+ msg_box('Information', 'You clicked the button')
1661
1755
  end
1662
1756
  }
1663
1757
 
@@ -1665,7 +1759,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
1665
1759
  stretchy false
1666
1760
 
1667
1761
  on_toggled do |c|
1668
- checked = c.checked == 1
1762
+ checked = c.checked?
1669
1763
  MAIN_WINDOW.title = "Checkbox is #{checked}"
1670
1764
  c.text = "I am the checkbox (#{checked})"
1671
1765
  end
@@ -2119,7 +2213,7 @@ require 'glimmer-dsl-libui'
2119
2213
 
2120
2214
  include Glimmer
2121
2215
 
2122
- window('Form') { |w|
2216
+ window('Form') {
2123
2217
  margined true
2124
2218
 
2125
2219
  vertical_box {
@@ -2135,7 +2229,7 @@ window('Form') { |w|
2135
2229
 
2136
2230
  button('Display Name') {
2137
2231
  on_clicked do
2138
- msg_box(w, 'Name', "#{@first_name_entry.text} #{@last_name_entry.text}")
2232
+ msg_box('Name', "#{@first_name_entry.text} #{@last_name_entry.text}")
2139
2233
  end
2140
2234
  }
2141
2235
  }
@@ -3358,14 +3452,62 @@ window('Area Gallery', 400, 400) {
3358
3452
  }
3359
3453
 
3360
3454
  fill r: 202, g: 102, b: 204, a: 0.5
3361
- stroke thickness: 2, r: 0, g: 0, b: 0
3455
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
3362
3456
  }
3363
3457
  path { # declarative stable path
3364
3458
  arc(200, 200, 90, 0, 360, false)
3365
3459
 
3366
3460
  fill r: 202, g: 102, b: 204, a: 0.5
3367
- stroke thickness: 2, r: 0, g: 0, b: 0
3461
+ stroke r: 0, g: 0, b: 0, thickness: 2
3368
3462
  }
3463
+
3464
+ on_mouse_event do |area_mouse_event|
3465
+ p area_mouse_event
3466
+ end
3467
+
3468
+ on_mouse_moved do |area_mouse_event|
3469
+ puts 'moved'
3470
+ end
3471
+
3472
+ on_mouse_down do |area_mouse_event|
3473
+ puts 'mouse down'
3474
+ end
3475
+
3476
+ on_mouse_up do |area_mouse_event|
3477
+ puts 'mouse up'
3478
+ end
3479
+
3480
+ on_mouse_drag_started do |area_mouse_event|
3481
+ puts 'drag started'
3482
+ end
3483
+
3484
+ on_mouse_dragged do |area_mouse_event|
3485
+ puts 'dragged'
3486
+ end
3487
+
3488
+ on_mouse_dropped do |area_mouse_event|
3489
+ puts 'dropped'
3490
+ end
3491
+
3492
+ on_mouse_entered do
3493
+ puts 'entered'
3494
+ end
3495
+
3496
+ on_mouse_exited do
3497
+ puts 'exited'
3498
+ end
3499
+
3500
+ on_key_event do |area_key_event|
3501
+ p area_key_event
3502
+ end
3503
+
3504
+ on_key_up do |area_key_event|
3505
+ puts 'key up'
3506
+ end
3507
+
3508
+ on_key_down do |area_key_event|
3509
+ puts 'key down'
3510
+ end
3369
3511
  }
3370
3512
  }.show
3371
3513
  ```
@@ -3467,7 +3609,7 @@ window('Area Gallery', 400, 400) {
3467
3609
  }
3468
3610
 
3469
3611
  fill r: 202, g: 102, b: 204, a: 0.5
3470
- stroke thickness: 2, r: 0, g: 0, b: 0
3612
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
3471
3613
  }
3472
3614
  path { # declarative stable path
3473
3615
  arc {
@@ -3480,8 +3622,56 @@ window('Area Gallery', 400, 400) {
3480
3622
  }
3481
3623
 
3482
3624
  fill r: 202, g: 102, b: 204, a: 0.5
3483
- stroke thickness: 2, r: 0, g: 0, b: 0
3625
+ stroke r: 0, g: 0, b: 0, thickness: 2
3484
3626
  }
3627
+
3628
+ on_mouse_event do |area_mouse_event|
3629
+ p area_mouse_event
3630
+ end
3631
+
3632
+ on_mouse_moved do |area_mouse_event|
3633
+ puts 'moved'
3634
+ end
3635
+
3636
+ on_mouse_down do |area_mouse_event|
3637
+ puts 'mouse down'
3638
+ end
3639
+
3640
+ on_mouse_up do |area_mouse_event|
3641
+ puts 'mouse up'
3642
+ end
3643
+
3644
+ on_mouse_drag_started do |area_mouse_event|
3645
+ puts 'drag started'
3646
+ end
3647
+
3648
+ on_mouse_dragged do |area_mouse_event|
3649
+ puts 'dragged'
3650
+ end
3651
+
3652
+ on_mouse_dropped do |area_mouse_event|
3653
+ puts 'dropped'
3654
+ end
3655
+
3656
+ on_mouse_entered do
3657
+ puts 'entered'
3658
+ end
3659
+
3660
+ on_mouse_exited do
3661
+ puts 'exited'
3662
+ end
3663
+
3664
+ on_key_event do |area_key_event|
3665
+ p area_key_event
3666
+ end
3667
+
3668
+ on_key_up do |area_key_event|
3669
+ puts 'key up'
3670
+ end
3671
+
3672
+ on_key_down do |area_key_event|
3673
+ puts 'key down'
3674
+ end
3485
3675
  }
3486
3676
  }.show
3487
3677
  ```
@@ -3530,15 +3720,63 @@ window('Area Gallery', 400, 400) {
3530
3720
  }
3531
3721
 
3532
3722
  fill r: 202, g: 102, b: 204, a: 0.5
3533
- stroke thickness: 2, r: 0, g: 0, b: 0
3723
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
3534
3724
  }
3535
3725
  path { # a dynamic path is added semi-declaratively inside on_draw block
3536
3726
  arc(200, 200, 90, 0, 360, false)
3537
3727
 
3538
3728
  fill r: 202, g: 102, b: 204, a: 0.5
3539
- stroke thickness: 2, r: 0, g: 0, b: 0
3729
+ stroke r: 0, g: 0, b: 0, thickness: 2
3540
3730
  }
3541
3731
  end
3732
+
3733
+ on_mouse_event do |area_mouse_event|
3734
+ p area_mouse_event
3735
+ end
3736
+
3737
+ on_mouse_moved do |area_mouse_event|
3738
+ puts 'moved'
3739
+ end
3740
+
3741
+ on_mouse_down do |area_mouse_event|
3742
+ puts 'mouse down'
3743
+ end
3744
+
3745
+ on_mouse_up do |area_mouse_event|
3746
+ puts 'mouse up'
3747
+ end
3748
+
3749
+ on_mouse_drag_started do |area_mouse_event|
3750
+ puts 'drag started'
3751
+ end
3752
+
3753
+ on_mouse_dragged do |area_mouse_event|
3754
+ puts 'dragged'
3755
+ end
3756
+
3757
+ on_mouse_dropped do |area_mouse_event|
3758
+ puts 'dropped'
3759
+ end
3760
+
3761
+ on_mouse_entered do
3762
+ puts 'entered'
3763
+ end
3764
+
3765
+ on_mouse_exited do
3766
+ puts 'exited'
3767
+ end
3768
+
3769
+ on_key_event do |area_key_event|
3770
+ p area_key_event
3771
+ end
3772
+
3773
+ on_key_up do |area_key_event|
3774
+ puts 'key up'
3775
+ end
3776
+
3777
+ on_key_down do |area_key_event|
3778
+ puts 'key down'
3779
+ end
3542
3780
  }
3543
3781
  }.show
3544
3782
  ```
@@ -3641,7 +3879,7 @@ window('Area Gallery', 400, 400) {
3641
3879
  }
3642
3880
 
3643
3881
  fill r: 202, g: 102, b: 204, a: 0.5
3644
- stroke thickness: 2, r: 0, g: 0, b: 0
3882
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
3645
3883
  }
3646
3884
  path { # a dynamic path is added semi-declaratively inside on_draw block
3647
3885
  arc {
@@ -3654,9 +3892,57 @@ window('Area Gallery', 400, 400) {
3654
3892
  }
3655
3893
 
3656
3894
  fill r: 202, g: 102, b: 204, a: 0.5
3657
- stroke thickness: 2, r: 0, g: 0, b: 0
3895
+ stroke r: 0, g: 0, b: 0, thickness: 2
3658
3896
  }
3659
3897
  end
3898
+
3899
+ on_mouse_event do |area_mouse_event|
3900
+ p area_mouse_event
3901
+ end
3902
+
3903
+ on_mouse_moved do |area_mouse_event|
3904
+ puts 'moved'
3905
+ end
3906
+
3907
+ on_mouse_down do |area_mouse_event|
3908
+ puts 'mouse down'
3909
+ end
3910
+
3911
+ on_mouse_up do |area_mouse_event|
3912
+ puts 'mouse up'
3913
+ end
3914
+
3915
+ on_mouse_drag_started do |area_mouse_event|
3916
+ puts 'drag started'
3917
+ end
3918
+
3919
+ on_mouse_dragged do |area_mouse_event|
3920
+ puts 'dragged'
3921
+ end
3922
+
3923
+ on_mouse_dropped do |area_mouse_event|
3924
+ puts 'dropped'
3925
+ end
3926
+
3927
+ on_mouse_entered do
3928
+ puts 'entered'
3929
+ end
3930
+
3931
+ on_mouse_exited do
3932
+ puts 'exited'
3933
+ end
3934
+
3935
+ on_key_event do |area_key_event|
3936
+ p area_key_event
3937
+ end
3938
+
3939
+ on_key_up do |area_key_event|
3940
+ puts 'key up'
3941
+ end
3942
+
3943
+ on_key_down do |area_key_event|
3944
+ puts 'key down'
3945
+ end
3660
3946
  }
3661
3947
  }.show
3662
3948
  ```
@@ -3893,31 +4179,29 @@ Y_OFF_TOP = 20
3893
4179
  X_OFF_RIGHT = 20
3894
4180
  Y_OFF_BOTTOM = 20
3895
4181
  POINT_RADIUS = 5
3896
-
3897
4182
  COLOR_BLUE = 0x1E90FF
3898
4183
 
4184
+ @datapoints = 10.times.map {Random.new.rand(90)}
4185
+
3899
4186
  def graph_size(area_width, area_height)
3900
4187
  graph_width = area_width - X_OFF_LEFT - X_OFF_RIGHT
3901
4188
  graph_height = area_height - Y_OFF_TOP - Y_OFF_BOTTOM
3902
4189
  [graph_width, graph_height]
3903
4190
  end
3904
4191
 
3905
- def point_locations(datapoints, width, height)
4192
+ def point_locations(width, height)
3906
4193
  xincr = width / 9.0 # 10 - 1 to make the last point be at the end
3907
4194
  yincr = height / 100.0
3908
4195
 
3909
- data = []
3910
- datapoints.each_with_index do |dp, i|
3911
- val = 100 - dp.value
3912
- data << [xincr * i, yincr * val]
3913
- i += 1
4196
+ @datapoints.each_with_index.map do |value, i|
4197
+ val = 100 - value
4198
+ [xincr * i, yincr * val]
3914
4199
  end
3915
-
3916
- data
3917
4200
  end
3918
4201
 
3919
- def graph_path(datapoints, width, height, should_extend, &block)
3920
- locations = point_locations(datapoints, width, height)
4202
+ # method-based custom control representing a graph path
4203
+ def graph_path(width, height, should_extend, &block)
4204
+ locations = point_locations(width, height)
3921
4205
  path {
3922
4206
  first_location = locations[0] # x and y
3923
4207
  figure(first_location[0], first_location[1]) {
@@ -3932,7 +4216,7 @@ def graph_path(datapoints, width, height, should_extend, &block)
3932
4216
  end
3933
4217
  }
3934
4218
 
3935
- # now transform the coordinate space so (0, 0) is the top-left corner of the graph
4219
+ # apply a transform to the coordinate space for this path so (0, 0) is the top-left corner of the graph
3936
4220
  transform {
3937
4221
  translate X_OFF_LEFT, Y_OFF_TOP
3938
4222
  }
@@ -3948,12 +4232,13 @@ window('histogram example', 640, 480) {
3948
4232
  vertical_box {
3949
4233
  stretchy false
3950
4234
 
3951
- @datapoints = 10.times.map do
3952
- spinbox(0, 100) { |datapoint|
4235
+ 10.times do |i|
4236
+ spinbox(0, 100) { |sb|
3953
4237
  stretchy false
3954
- value Random.new.rand(90)
4238
+ value @datapoints[i]
3955
4239
 
3956
4240
  on_changed do
4241
+ @datapoints[i] = sb.value
3957
4242
  @area.queue_redraw_all
3958
4243
  end
3959
4244
  }
@@ -3974,7 +4259,7 @@ window('histogram example', 640, 480) {
3974
4259
  path {
3975
4260
  rectangle(0, 0, area_draw_params[:area_width], area_draw_params[:area_height])
3976
4261
 
3977
- fill color: 0xFFFFFF
4262
+ fill 0xFFFFFF
3978
4263
  }
3979
4264
 
3980
4265
  graph_width, graph_height = *graph_size(area_draw_params[:area_width], area_draw_params[:area_height])
@@ -3985,16 +4270,16 @@ window('histogram example', 640, 480) {
3985
4270
  line(X_OFF_LEFT + graph_width, Y_OFF_TOP + graph_height)
3986
4271
  }
3987
4272
 
3988
- stroke color: 0x000000, thickness: 2, miter_limit: 10
4273
+ stroke 0x000000, thickness: 2, miter_limit: 10
3989
4274
  }
3990
4275
 
3991
4276
  # now create the fill for the graph below the graph line
3992
- graph_path(@datapoints, graph_width, graph_height, true) {
4277
+ graph_path(graph_width, graph_height, true) {
3993
4278
  fill @color_button.color.merge(a: 0.5)
3994
4279
  }
3995
4280
 
3996
4281
  # now draw the histogram line
3997
- graph_path(@datapoints, graph_width, graph_height, false) {
4282
+ graph_path(graph_width, graph_height, false) {
3998
4283
  stroke @color_button.color.merge(thickness: 2, miter_limit: 10)
3999
4284
  }
4000
4285
  end
@@ -4046,7 +4331,7 @@ window('Basic Transform', 350, 350) {
4046
4331
  square(0, 0, 100)
4047
4332
 
4048
4333
  fill r: [255 - n*5, 0].max, g: [n*5, 255].min, b: 0, a: 0.5
4049
- stroke color: 0, thickness: 2
4334
+ stroke :black, thickness: 2
4050
4335
  transform {
4051
4336
  skew 0.15, 0.15
4052
4337
  translate 50, 50