glimmer-dsl-libui 0.1.0 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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.0
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
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)
@@ -19,7 +19,7 @@ The main trade-off in using [Glimmer DSL for LibUI](https://rubygems.org/gems/gl
19
19
  - Scaffolding for new custom controls, apps, and gems
20
20
  - Native-Executable packaging on Mac, Windows, and Linux.
21
21
 
22
- Example:
22
+ Hello, World!
23
23
 
24
24
  ```ruby
25
25
  require 'glimmer-dsl-libui'
@@ -32,6 +32,108 @@ window('hello world').show
32
32
  ![glimmer-dsl-libui-mac-basic-window.png](images/glimmer-dsl-libui-mac-basic-window.png)
33
33
  ![glimmer-dsl-libui-linux-basic-window.png](images/glimmer-dsl-libui-linux-basic-window.png)
34
34
 
35
+ Basic Table Progress Bar
36
+
37
+ ```ruby
38
+ require 'glimmer-dsl-libui'
39
+
40
+ include Glimmer
41
+
42
+ data = [
43
+ ['task 1', 0],
44
+ ['task 2', 15],
45
+ ['task 3', 100],
46
+ ['task 4', 75],
47
+ ['task 5', -1],
48
+ ]
49
+
50
+ window('Task Progress', 300, 200) {
51
+ vertical_box {
52
+ table {
53
+ text_column('Task')
54
+ progress_bar_column('Progress')
55
+
56
+ cell_rows data # implicit data-binding
57
+ }
58
+
59
+ button('Mark All As Done') {
60
+ stretchy false
61
+
62
+ on_clicked do
63
+ data.each_with_index do |row_data, row|
64
+ data[row] = [row_data[0], 100] # automatically updates table due to implicit data-binding
65
+ end
66
+ end
67
+ }
68
+ }
69
+ }.show
70
+ ```
71
+
72
+ ![glimmer-dsl-libui-mac-basic-table-progress-bar.png](images/glimmer-dsl-libui-mac-basic-table-progress-bar.png)
73
+ ![glimmer-dsl-libui-linux-basic-table-progress-bar.png](images/glimmer-dsl-libui-linux-basic-table-progress-bar.png)
74
+
75
+ Area Gallery
76
+
77
+ ```ruby
78
+ require 'glimmer-dsl-libui'
79
+
80
+ include Glimmer
81
+
82
+ window('Area Gallery', 400, 400) {
83
+ vertical_box {
84
+ area {
85
+ path { # declarative stable path
86
+ square(0, 0, 100)
87
+ square(100, 100, 400)
88
+
89
+ fill r: 102, g: 102, b: 204
90
+ }
91
+ path { # declarative stable path
92
+ rectangle(0, 100, 100, 400)
93
+ rectangle(100, 0, 400, 100)
94
+
95
+ fill r: 204, g: 102, b: 204
96
+ }
97
+ path { # declarative stable path
98
+ figure(100, 100) {
99
+ line(100, 400)
100
+ line(400, 100)
101
+ line(400, 400)
102
+
103
+ closed true
104
+ }
105
+
106
+ fill r: 202, g: 102, b: 104, a: 0.5
107
+ stroke r: 0, g: 0, b: 0
108
+ }
109
+ path { # declarative stable path
110
+ figure(0, 0) {
111
+ bezier(200, 100, 100, 200, 400, 100)
112
+ bezier(300, 100, 100, 300, 100, 400)
113
+ bezier(100, 300, 300, 100, 400, 400)
114
+
115
+ closed true
116
+ }
117
+
118
+ fill r: 202, g: 102, b: 204, a: 0.5
119
+ stroke thickness: 2, r: 0, g: 0, b: 0
120
+ }
121
+ path { # declarative stable path
122
+ arc(200, 200, 90, 0, 360, false)
123
+
124
+ fill r: 202, g: 102, b: 204, a: 0.5
125
+ stroke thickness: 2, r: 0, g: 0, b: 0
126
+ }
127
+ }
128
+ }
129
+ }.show
130
+ ```
131
+
132
+ ![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png)
133
+ ![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
134
+
135
+ [Check Out Many More Examples Over Here!](#examples)
136
+
35
137
  NOTE: [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) is in early alpha mode (only supports included [examples](#examples)). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
36
138
 
37
139
  Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
@@ -43,9 +145,10 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
43
145
 
44
146
  ## Table of Contents
45
147
 
46
- - [Glimmer DSL for LibUI 0.1.0](#-glimmer-dsl-for-libui-010)
148
+ - [Glimmer DSL for LibUI 0.1.4](#-glimmer-dsl-for-libui-014)
47
149
  - [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
48
150
  - [Usage](#usage)
151
+ - [Girb (Glimmer IRB)](#girb-glimmer-irb)
49
152
  - [API](#api)
50
153
  - [Supported Controls](#supported-controls)
51
154
  - [Common Control Properties](#common-control-properties)
@@ -58,7 +161,6 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
58
161
  - [API Gotchas](#api-gotchas)
59
162
  - [Original API](#original-api)
60
163
  - [Glimmer Style Guide](#glimmer-style-guide)
61
- - [Girb (Glimmer IRB)](#girb-glimmer-irb)
62
164
  - [Examples](#examples)
63
165
  - [Basic Window](#basic-window)
64
166
  - [Basic Button](#basic-button)
@@ -82,6 +184,8 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
82
184
  - [Basic Table Progress Bar](#basic-table-progress-bar)
83
185
  - [Form Table](#form-table)
84
186
  - [Basic Area](#basic-area)
187
+ - [Dynamic Area](#dynamic-area)
188
+ - [Area Gallery](#area-gallery)
85
189
  - [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
86
190
  - [Help](#help)
87
191
  - [Issues](#issues)
@@ -169,7 +273,7 @@ gem install glimmer-dsl-libui
169
273
  Or install via Bundler `Gemfile`:
170
274
 
171
275
  ```ruby
172
- gem 'glimmer-dsl-libui', '~> 0.1.0'
276
+ gem 'glimmer-dsl-libui', '~> 0.1.4'
173
277
  ```
174
278
 
175
279
  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.
@@ -196,6 +300,24 @@ end
196
300
  Application.new.launch
197
301
  ```
198
302
 
303
+ If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), check out [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. You may refer to the [API](#api) later on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
304
+
305
+ ## Girb (Glimmer IRB)
306
+
307
+ You can run the `girb` command (`bin/girb` if you cloned the project locally) to do some quick and dirty experimentation and learning:
308
+
309
+ ```
310
+ girb
311
+ ```
312
+
313
+ This gives you `irb` with the `glimmer-dsl-libui` gem loaded and the `Glimmer` module mixed into the main object for easy experimentation with GUI.
314
+
315
+ ![glimmer-dsl-libui-girb.png](images/glimmer-dsl-libui-girb.png)
316
+
317
+ For a more advanced code editing tool, check out the [Meta-Example (The Example of Examples)](#examples).
318
+
319
+ Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
320
+
199
321
  ## API
200
322
 
201
323
  Any control returned by a [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) keyword declaration can be introspected for its properties and updated via object-oriented attributes (standard Ruby `attr`/`attr=` or `set_attr`).
@@ -225,7 +347,9 @@ w.libui # => #<Fiddle::Pointer:0x00007fde53997980 ptr=0x00007fde51352a60 size=0
225
347
  Control(Args) | Properties | Listeners
226
348
  ------------- | ---------- | ---------
227
349
  `about_menu_item` | None | `on_clicked`
228
- `area` | None | None
350
+ `area` | None | `on_draw`
351
+ `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
+ `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
229
353
  `button(text as String)` | `text` (`String`) | `on_clicked`
230
354
  `button_column(name as String)` | `enabled` (Boolean) | None
231
355
  `checkbox(text as String)` | `checked` (Boolean), `text` (`String`) | `on_toggled`
@@ -237,6 +361,7 @@ Control(Args) | Properties | Listeners
237
361
  `date_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`
238
362
  `editable_combobox` | `items` (`Array` of `String`), `text` (`String`) | `on_changed`
239
363
  `entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
364
+ `figure(x=nil as Numeric, y=nil as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `closed` (Boolean) | None
240
365
  `font_button` | `font` [read-only] (`Hash` of keys: `:family`, `:size`, `:weight`, `:italic`, `:stretch`), `family` as `String`, `size` as `Float`, `weight` as `Integer`, `italic` as `Integer`, `stretch` as `Integer` | `on_changed`
241
366
  `form` | `padded` (Boolean) | None
242
367
  `grid` | `padded` (Boolean) | None
@@ -248,6 +373,7 @@ Control(Args) | Properties | Listeners
248
373
  `image_column(name as String)` | None | None
249
374
  `image_text_column(name as String)` | None | None
250
375
  `label(text as String)` | `text` (`String`) | None
376
+ `line(x as Numeric, y as Numeric)` | `x` (`Numeric`), `y` (`Numeric`) | None
251
377
  `menu(text as String)` | None | None
252
378
  `menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
253
379
  `multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
@@ -260,9 +386,10 @@ Control(Args) | Properties | Listeners
260
386
  `progress_bar_column(name as String)` | None | None
261
387
  `quit_menu_item` | None | `on_clicked`
262
388
  `radio_buttons` | `selected` (`Integer`) | `on_selected`
263
- `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | None | None
389
+ `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `width` (`Numeric`), `height` (`Numeric`) | None
264
390
  `slider(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
265
391
  `spinbox(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
392
+ `square(x as Numeric, y as Numeric, length as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `length` (`Numeric`) | None
266
393
  `tab` | `margined` (Boolean), `num_pages` (`Integer`) | None
267
394
  `tab_item(name as String)` | `index` [read-only] (`Integer`), `margined` (Boolean), `name` [read-only] (`String`) | None
268
395
  `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
@@ -307,6 +434,7 @@ Control(Args) | Properties | Listeners
307
434
  - `ControlProxy::image_proxies`: returns all instantiated `image` proxies in the application
308
435
  - `ControlProxy::main_window_proxy`: returns the first window proxy instantiated in the application
309
436
  - `ControlProxy#window_proxy`: returns the window proxy parent for a control
437
+ - `ControlProxy#content {...}`: re-opens control's content to add more nested controls or properties
310
438
 
311
439
  ### Table API
312
440
 
@@ -326,9 +454,147 @@ Note that the `cell_rows` property declaration results in "implicit data-binding
326
454
  - Inserting cell rows: Calling `Array#<<`, `Array#push`, `Array#prepend`, or any insertion/addition `Array` method automatically inserts rows in actual `table` control
327
455
  - Changing cell rows: Calling `Array#[]=`, `Array#map!`, or any update `Array` method automatically updates rows in actual `table` control
328
456
 
457
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
458
+
459
+ ```ruby
460
+ require 'glimmer-dsl-libui'
461
+
462
+ include Glimmer
463
+
464
+ data = [
465
+ ['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
466
+ ['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
467
+ ['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
468
+ ['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
469
+ ['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
470
+ ]
471
+
472
+ window('Contacts', 600, 600) { |w|
473
+ margined true
474
+
475
+ vertical_box {
476
+ form {
477
+ stretchy false
478
+
479
+ @name_entry = entry {
480
+ label 'Name'
481
+ }
482
+ @email_entry = entry {
483
+ label 'Email'
484
+ }
485
+ @phone_entry = entry {
486
+ label 'Phone'
487
+ }
488
+ @city_entry = entry {
489
+ label 'City'
490
+ }
491
+ @state_entry = entry {
492
+ label 'State'
493
+ }
494
+ }
495
+
496
+ button('Save Contact') {
497
+ stretchy false
498
+
499
+ on_clicked do
500
+ new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
501
+ if new_row.include?('')
502
+ msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
503
+ else
504
+ data << new_row # automatically inserts a row into the table due to implicit data-binding
505
+ @name_entry.text = ''
506
+ @email_entry.text = ''
507
+ @phone_entry.text = ''
508
+ @city_entry.text = ''
509
+ @state_entry.text = ''
510
+ end
511
+ end
512
+ }
513
+
514
+ table {
515
+ text_column('Name')
516
+ text_column('Email')
517
+ text_column('Phone')
518
+ text_column('City')
519
+ text_column('State')
520
+
521
+ cell_rows data # implicit data-binding
522
+ }
523
+ }
524
+ }.show
525
+ ```
526
+
527
+ ![glimmer-dsl-libui-linux-form-table.png](images/glimmer-dsl-libui-linux-form-table.png)
528
+
529
+ Learn more by checking out [examples](#examples).
530
+
329
531
  ### Area API
330
532
 
331
- The `area` control can have a `path` nested underneath declaratively, containing figures like `rectangle`, and all the drawing logic is generated automatically from that.
533
+ The `area` control can be used in one of two ways:
534
+ - Declaratively via stable paths: useful for stable paths that will not change later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Paths proxy objects are preserved across redraws assuming there would be few stable paths (mostly for decorative reasons).
535
+ - Semi-declaratively via on_draw listener dynamic paths: useful for more dynamic paths that will definitely change. Open an `on_draw` listener block and nest `path(area_draw_params)` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are destroyed (thrown-away) at the end of drawing, thus having less memory overhead for drawing thousands of dynamic paths.
536
+
537
+ Here is an example of a declarative `area` with a stable path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
538
+
539
+ ```ruby
540
+ require 'glimmer-dsl-libui'
541
+
542
+ include Glimmer
543
+
544
+ window('Basic Area', 400, 400) {
545
+ margined true
546
+
547
+ vertical_box {
548
+ area {
549
+ path { # a stable path is added declaratively
550
+ rectangle(0, 0, 400, 400)
551
+
552
+ fill r: 102, g: 102, b: 204, a: 1.0
553
+ }
554
+ }
555
+ }
556
+ }.show
557
+ ```
558
+
559
+ ![glimmer-dsl-libui-mac-basic-area.png](images/glimmer-dsl-libui-mac-basic-area.png)
560
+
561
+ Here is the same example using a semi-declarative `area` with `on_draw` listener and a dynamic path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
562
+
563
+ ```ruby
564
+ require 'glimmer-dsl-libui'
565
+
566
+ include Glimmer
567
+
568
+ window('Basic Area', 400, 400) {
569
+ margined true
570
+
571
+ vertical_box {
572
+ area {
573
+ on_draw do |area_draw_params|
574
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
575
+ rectangle(0, 0, 400, 400)
576
+
577
+ fill r: 102, g: 102, b: 204, a: 1.0
578
+ }
579
+ end
580
+ }
581
+ }
582
+ }.show
583
+ ```
584
+
585
+ Check [examples/dynamic_area.rb](#dynamic-area) for a more detailed semi-declarative example.
586
+
587
+ Available nested `path` shapes:
588
+ - `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)`
589
+ - `square(x as Numeric, y as Numeric, length as Numeric)`
590
+ - `arc(x_center as Numeric, y_center as Numeric, radius as Numeric, start_angle as Numeric, sweep as Numeric, is_negative as Boolean)`
591
+ - `line(x as Numeric, y as Numeric)`
592
+ - `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)`
593
+ - `figure(x=nil as Numeric, y=nil as Numeric)` (composite that can contain other shapes) (can set `closed true` to connect last point to first point automatically)
594
+
595
+ 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 paths.
596
+
597
+ To redraw an `area`, you may call `#queue_redraw_all` method.
332
598
 
333
599
  ### Smart Defaults and Conventions
334
600
 
@@ -359,11 +625,14 @@ The `area` control can have a `path` nested underneath declaratively, containing
359
625
  - `image` instances are automatically freed from memory after `window` is destroyed.
360
626
  - `image` `width` and `height` can be left off if it has one `image_part` only as they default to the same `width` and `height` of the `image_part`
361
627
  - `area` paths are specified declaratively with figures underneath (e.g. `rectangle`) and `area` draw listener is automatically generated
628
+ - Observe figure properties (e.g. `rectangle` `width`) for changes and automatically redraw containing area accordingly
629
+ - Observe `path` `fill` and `stroke` hashes for changes and automatically redraw containing area accordingly
362
630
 
363
631
  ### API Gotchas
364
632
 
365
633
  - There is no proper way to destroy `grid` children due to [libui](https://github.com/andlabs/libui) not offering any API for deleting them from `grid` (no `grid_delete` similar to `box_delete` for `horizontal_box` and `vertical_box`).
366
634
  - `table` `checkbox_column` and `checkbox_text_column` checkbox editing only works on Windows and Linux (not Mac) due to a current limitation in [libui](https://github.com/andlabs/ui/issues/357).
635
+ - It seems that `arc` `start_angle` and `sweep` properties are ignored by [libui](https://github.com/andlabs/libui) and always set to `0` and `360` respectively, producing a full circle.
367
636
 
368
637
  ### Original API
369
638
 
@@ -379,21 +648,9 @@ check out the [libui C headers](https://github.com/andlabs/libui/blob/master/ui.
379
648
  - Control listeners are always declared starting with on_ prefix and affixing listener event method name afterwards in underscored lowercase form. Their multi-line blocks have a `do; end` style.
380
649
  - Pure logic multi-line blocks that do not constitute GUI DSL view elements have `do; end` style to clearly separate logic code from view code.
381
650
 
382
- ## Girb (Glimmer IRB)
383
-
384
- You can run the `girb` command (`bin/girb` if you cloned the project locally):
385
-
386
- ```
387
- girb
388
- ```
389
-
390
- This gives you `irb` with the `glimmer-dsl-libui` gem loaded and the `Glimmer` module mixed into the main object for easy experimentation with GUI.
391
-
392
- Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
393
-
394
651
  ## Examples
395
652
 
396
- These examples include reimplementions of the examples in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) as well as brand new examples.
653
+ The following examples include reimplementions of the examples in the [LibUI](https://github.com/kojix2/LibUI) project utilizing the [Glimmer GUI DSL](#glimmer-gui-dsl-concepts) as well as brand new examples.
397
654
 
398
655
  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.
399
656
 
@@ -2483,13 +2740,23 @@ data = [
2483
2740
  ['task 5', -1],
2484
2741
  ]
2485
2742
 
2486
- window('Task progress', 300, 200) {
2487
- horizontal_box {
2743
+ window('Task Progress', 300, 200) {
2744
+ vertical_box {
2488
2745
  table {
2489
2746
  text_column('Task')
2490
2747
  progress_bar_column('Progress')
2491
2748
 
2492
- cell_rows data
2749
+ cell_rows data # implicit data-binding
2750
+ }
2751
+
2752
+ button('Mark All As Done') {
2753
+ stretchy false
2754
+
2755
+ on_clicked do
2756
+ data.each_with_index do |row_data, row|
2757
+ data[row] = [row_data[0], 100] # automatically updates table due to implicit data-binding
2758
+ end
2759
+ end
2493
2760
  }
2494
2761
  }
2495
2762
  }.show
@@ -2689,6 +2956,640 @@ window('Basic Area', 400, 400) {
2689
2956
  }.show
2690
2957
  ```
2691
2958
 
2959
+ [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
2960
+
2961
+ ```ruby
2962
+ require 'glimmer-dsl-libui'
2963
+
2964
+ include Glimmer
2965
+
2966
+ window('Basic Area', 400, 400) {
2967
+ margined true
2968
+
2969
+ vertical_box {
2970
+ area {
2971
+ on_draw do |area_draw_params|
2972
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
2973
+ rectangle(0, 0, 400, 400)
2974
+
2975
+ fill r: 102, g: 102, b: 204, a: 1.0
2976
+ }
2977
+ end
2978
+ }
2979
+ }
2980
+ }.show
2981
+ ```
2982
+
2983
+ ### Dynamic Area
2984
+
2985
+ [examples/dynamic_area.rb](examples/dynamic_area.rb)
2986
+
2987
+ Run with this command from the root of the project if you cloned the project:
2988
+
2989
+ ```
2990
+ ruby -r './lib/glimmer-dsl-libui' examples/dynamic_area.rb
2991
+ ```
2992
+
2993
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
2994
+
2995
+ ```
2996
+ ruby -r glimmer-dsl-libui -e "require 'examples/dynamic_area'"
2997
+ ```
2998
+
2999
+ Mac
3000
+
3001
+ ![glimmer-dsl-libui-mac-dynamic-area.png](images/glimmer-dsl-libui-mac-dynamic-area.png)
3002
+ ![glimmer-dsl-libui-mac-dynamic-area-updated.png](images/glimmer-dsl-libui-mac-dynamic-area-updated.png)
3003
+
3004
+ Linux
3005
+
3006
+ ![glimmer-dsl-libui-linux-dynamic-area.png](images/glimmer-dsl-libui-linux-dynamic-area.png)
3007
+ ![glimmer-dsl-libui-linux-dynamic-area-updated.png](images/glimmer-dsl-libui-linux-dynamic-area-updated.png)
3008
+
3009
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
3010
+
3011
+ ```ruby
3012
+ require 'glimmer-dsl-libui'
3013
+
3014
+ include Glimmer
3015
+
3016
+ window('Dynamic Area', 240, 500) {
3017
+ margined true
3018
+
3019
+ vertical_box {
3020
+ label('Rectangle Properties') {
3021
+ stretchy false
3022
+ }
3023
+
3024
+ form {
3025
+ stretchy false
3026
+
3027
+ @x_spinbox = spinbox(0, 1000) {
3028
+ label 'x'
3029
+ value 25
3030
+
3031
+ on_changed do
3032
+ @area.queue_redraw_all
3033
+ end
3034
+ }
3035
+
3036
+ @y_spinbox = spinbox(0, 1000) {
3037
+ label 'y'
3038
+ value 25
3039
+
3040
+ on_changed do
3041
+ @area.queue_redraw_all
3042
+ end
3043
+ }
3044
+
3045
+ @width_spinbox = spinbox(0, 1000) {
3046
+ label 'width'
3047
+ value 150
3048
+
3049
+ on_changed do
3050
+ @area.queue_redraw_all
3051
+ end
3052
+ }
3053
+
3054
+ @height_spinbox = spinbox(0, 1000) {
3055
+ label 'height'
3056
+ value 150
3057
+
3058
+ on_changed do
3059
+ @area.queue_redraw_all
3060
+ end
3061
+ }
3062
+
3063
+ @red_spinbox = spinbox(0, 255) {
3064
+ label 'red'
3065
+ value 102
3066
+
3067
+ on_changed do
3068
+ @area.queue_redraw_all
3069
+ end
3070
+ }
3071
+
3072
+ @green_spinbox = spinbox(0, 255) {
3073
+ label 'green'
3074
+ value 102
3075
+
3076
+ on_changed do
3077
+ @area.queue_redraw_all
3078
+ end
3079
+ }
3080
+
3081
+ @blue_spinbox = spinbox(0, 255) {
3082
+ label 'blue'
3083
+ value 204
3084
+
3085
+ on_changed do
3086
+ @area.queue_redraw_all
3087
+ end
3088
+ }
3089
+
3090
+ @alpha_spinbox = spinbox(0, 100) {
3091
+ label 'alpha'
3092
+ value 100
3093
+
3094
+ on_changed do
3095
+ @area.queue_redraw_all
3096
+ end
3097
+ }
3098
+ }
3099
+
3100
+ @area = area {
3101
+ on_draw do |area_draw_params|
3102
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3103
+ rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
3104
+
3105
+ fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
3106
+ }
3107
+ end
3108
+ }
3109
+ }
3110
+ }.show
3111
+ ```
3112
+
3113
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
3114
+
3115
+ ```ruby
3116
+ require 'glimmer-dsl-libui'
3117
+
3118
+ include Glimmer
3119
+
3120
+ window('Dynamic Area', 240, 600) {
3121
+ margined true
3122
+
3123
+ vertical_box {
3124
+ label('Rectangle Properties') {
3125
+ stretchy false
3126
+ }
3127
+
3128
+ form {
3129
+ stretchy false
3130
+
3131
+ @x_spinbox = spinbox(0, 1000) {
3132
+ label 'x'
3133
+ value 25
3134
+
3135
+ on_changed do
3136
+ @rectangle.x = @x_spinbox.value # updating properties automatically triggers area.queue_redraw_all
3137
+ end
3138
+ }
3139
+
3140
+ @y_spinbox = spinbox(0, 1000) {
3141
+ label 'y'
3142
+ value 25
3143
+
3144
+ on_changed do
3145
+ @rectangle.y = @y_spinbox.value # updating properties automatically triggers area.queue_redraw_all
3146
+ end
3147
+ }
3148
+
3149
+ @width_spinbox = spinbox(0, 1000) {
3150
+ label 'width'
3151
+ value 150
3152
+
3153
+ on_changed do
3154
+ @rectangle.width = @width_spinbox.value # updating properties automatically triggers area.queue_redraw_all
3155
+ end
3156
+ }
3157
+
3158
+ @height_spinbox = spinbox(0, 1000) {
3159
+ label 'height'
3160
+ value 150
3161
+
3162
+ on_changed do
3163
+ @rectangle.height = @height_spinbox.value # updating properties automatically triggers area.queue_redraw_all
3164
+ end
3165
+ }
3166
+
3167
+ @red_spinbox = spinbox(0, 255) {
3168
+ label 'red'
3169
+ value 102
3170
+
3171
+ on_changed do
3172
+ @path.fill[:r] = @red_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
3173
+ end
3174
+ }
3175
+
3176
+ @green_spinbox = spinbox(0, 255) {
3177
+ label 'green'
3178
+ value 102
3179
+
3180
+ on_changed do
3181
+ @path.fill[:g] = @green_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
3182
+ end
3183
+ }
3184
+
3185
+ @blue_spinbox = spinbox(0, 255) {
3186
+ label 'blue'
3187
+ value 204
3188
+
3189
+ on_changed do
3190
+ @path.fill[:b] = @blue_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
3191
+ end
3192
+ }
3193
+
3194
+ @alpha_spinbox = spinbox(0, 100) {
3195
+ label 'alpha'
3196
+ value 100
3197
+
3198
+ on_changed do
3199
+ @path.fill[:a] = @alpha_spinbox.value / 100.0 # updating hash properties automatically triggers area.queue_redraw_all
3200
+ end
3201
+ }
3202
+ }
3203
+
3204
+ area {
3205
+ @path = path { # stable path
3206
+ @rectangle = rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
3207
+
3208
+ fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
3209
+ }
3210
+ }
3211
+ }
3212
+ }.show
3213
+ ```
3214
+
3215
+ ### Area Gallery
3216
+
3217
+ [examples/area_gallery.rb](examples/area_gallery.rb)
3218
+
3219
+ Run with this command from the root of the project if you cloned the project:
3220
+
3221
+ ```
3222
+ ruby -r './lib/glimmer-dsl-libui' examples/area_gallery.rb
3223
+ ```
3224
+
3225
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
3226
+
3227
+ ```
3228
+ ruby -r glimmer-dsl-libui -e "require 'examples/area_gallery'"
3229
+ ```
3230
+
3231
+ Mac
3232
+
3233
+ ![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png)
3234
+
3235
+ Linux
3236
+
3237
+ ![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
3238
+
3239
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
3240
+
3241
+ ```ruby
3242
+ require 'glimmer-dsl-libui'
3243
+
3244
+ include Glimmer
3245
+
3246
+ window('Area Gallery', 400, 400) {
3247
+ vertical_box {
3248
+ area {
3249
+ path { # declarative stable path
3250
+ square(0, 0, 100)
3251
+ square(100, 100, 400)
3252
+
3253
+ fill r: 102, g: 102, b: 204
3254
+ }
3255
+ path { # declarative stable path
3256
+ rectangle(0, 100, 100, 400)
3257
+ rectangle(100, 0, 400, 100)
3258
+
3259
+ fill r: 204, g: 102, b: 204
3260
+ }
3261
+ path { # declarative stable path
3262
+ figure(100, 100) {
3263
+ line(100, 400)
3264
+ line(400, 100)
3265
+ line(400, 400)
3266
+
3267
+ closed true
3268
+ }
3269
+
3270
+ fill r: 202, g: 102, b: 104, a: 0.5
3271
+ stroke r: 0, g: 0, b: 0
3272
+ }
3273
+ path { # declarative stable path
3274
+ figure(0, 0) {
3275
+ bezier(200, 100, 100, 200, 400, 100)
3276
+ bezier(300, 100, 100, 300, 100, 400)
3277
+ bezier(100, 300, 300, 100, 400, 400)
3278
+
3279
+ closed true
3280
+ }
3281
+
3282
+ fill r: 202, g: 102, b: 204, a: 0.5
3283
+ stroke thickness: 2, r: 0, g: 0, b: 0
3284
+ }
3285
+ path { # declarative stable path
3286
+ arc(200, 200, 90, 0, 360, false)
3287
+
3288
+ fill r: 202, g: 102, b: 204, a: 0.5
3289
+ stroke thickness: 2, r: 0, g: 0, b: 0
3290
+ }
3291
+ }
3292
+ }
3293
+ }.show
3294
+ ```
3295
+
3296
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
3297
+
3298
+ ```ruby
3299
+ require 'glimmer-dsl-libui'
3300
+
3301
+ include Glimmer
3302
+
3303
+ window('Area Gallery', 400, 400) {
3304
+ vertical_box {
3305
+ area {
3306
+ path { # declarative stable path
3307
+ square {
3308
+ x 0
3309
+ y 0
3310
+ length 100
3311
+ }
3312
+ square {
3313
+ x 100
3314
+ y 100
3315
+ length 400
3316
+ }
3317
+
3318
+ fill r: 102, g: 102, b: 204
3319
+ }
3320
+ path { # declarative stable path
3321
+ rectangle {
3322
+ x 0
3323
+ y 100
3324
+ width 100
3325
+ height 400
3326
+ }
3327
+ rectangle {
3328
+ x 100
3329
+ y 0
3330
+ width 400
3331
+ height 100
3332
+ }
3333
+
3334
+ fill r: 204, g: 102, b: 204
3335
+ }
3336
+ path { # declarative stable path
3337
+ figure {
3338
+ x 100
3339
+ y 100
3340
+
3341
+ line {
3342
+ x 100
3343
+ y 400
3344
+ }
3345
+ line {
3346
+ x 400
3347
+ y 100
3348
+ }
3349
+ line {
3350
+ x 400
3351
+ y 400
3352
+ }
3353
+
3354
+ closed true
3355
+ }
3356
+
3357
+ fill r: 202, g: 102, b: 104, a: 0.5
3358
+ stroke r: 0, g: 0, b: 0
3359
+ }
3360
+ path { # declarative stable path
3361
+ figure {
3362
+ x 0
3363
+ y 0
3364
+
3365
+ bezier {
3366
+ c1_x 200
3367
+ c1_y 100
3368
+ c2_x 100
3369
+ c2_y 200
3370
+ end_x 400
3371
+ end_y 100
3372
+ }
3373
+ bezier {
3374
+ c1_x 300
3375
+ c1_y 100
3376
+ c2_x 100
3377
+ c2_y 300
3378
+ end_x 100
3379
+ end_y 400
3380
+ }
3381
+ bezier {
3382
+ c1_x 100
3383
+ c1_y 300
3384
+ c2_x 300
3385
+ c2_y 100
3386
+ end_x 400
3387
+ end_y 400
3388
+ }
3389
+
3390
+ closed true
3391
+ }
3392
+
3393
+ fill r: 202, g: 102, b: 204, a: 0.5
3394
+ stroke thickness: 2, r: 0, g: 0, b: 0
3395
+ }
3396
+ path { # declarative stable path
3397
+ arc {
3398
+ x_center 200
3399
+ y_center 200
3400
+ radius 90
3401
+ start_angle 0
3402
+ sweep 360
3403
+ is_negative false
3404
+ }
3405
+
3406
+ fill r: 202, g: 102, b: 204, a: 0.5
3407
+ stroke thickness: 2, r: 0, g: 0, b: 0
3408
+ }
3409
+ }
3410
+ }
3411
+ }.show
3412
+ ```
3413
+
3414
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3:
3415
+
3416
+ ```ruby
3417
+ require 'glimmer-dsl-libui'
3418
+
3419
+ include Glimmer
3420
+
3421
+ window('Area Gallery', 400, 400) {
3422
+ vertical_box {
3423
+ area {
3424
+ on_draw do |area_draw_params|
3425
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3426
+ square(0, 0, 100)
3427
+ square(100, 100, 400)
3428
+
3429
+ fill r: 102, g: 102, b: 204
3430
+ }
3431
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3432
+ rectangle(0, 100, 100, 400)
3433
+ rectangle(100, 0, 400, 100)
3434
+
3435
+ fill r: 204, g: 102, b: 204
3436
+ }
3437
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3438
+ figure(100, 100) {
3439
+ line(100, 400)
3440
+ line(400, 100)
3441
+ line(400, 400)
3442
+
3443
+ closed true
3444
+ }
3445
+
3446
+ fill r: 202, g: 102, b: 104, a: 0.5
3447
+ stroke r: 0, g: 0, b: 0
3448
+ }
3449
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3450
+ figure(0, 0) {
3451
+ bezier(200, 100, 100, 200, 400, 100)
3452
+ bezier(300, 100, 100, 300, 100, 400)
3453
+ bezier(100, 300, 300, 100, 400, 400)
3454
+
3455
+ closed true
3456
+ }
3457
+
3458
+ fill r: 202, g: 102, b: 204, a: 0.5
3459
+ stroke thickness: 2, r: 0, g: 0, b: 0
3460
+ }
3461
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3462
+ arc(200, 200, 90, 0, 360, false)
3463
+
3464
+ fill r: 202, g: 102, b: 204, a: 0.5
3465
+ stroke thickness: 2, r: 0, g: 0, b: 0
3466
+ }
3467
+ end
3468
+ }
3469
+ }
3470
+ }.show
3471
+ ```
3472
+
3473
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 4:
3474
+
3475
+ ```ruby
3476
+ require 'glimmer-dsl-libui'
3477
+
3478
+ include Glimmer
3479
+
3480
+ window('Area Gallery', 400, 400) {
3481
+ vertical_box {
3482
+ area {
3483
+ on_draw do |area_draw_params|
3484
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3485
+ square {
3486
+ x 0
3487
+ y 0
3488
+ length 100
3489
+ }
3490
+ square {
3491
+ x 100
3492
+ y 100
3493
+ length 400
3494
+ }
3495
+
3496
+ fill r: 102, g: 102, b: 204
3497
+ }
3498
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3499
+ rectangle {
3500
+ x 0
3501
+ y 100
3502
+ width 100
3503
+ height 400
3504
+ }
3505
+ rectangle {
3506
+ x 100
3507
+ y 0
3508
+ width 400
3509
+ height 100
3510
+ }
3511
+
3512
+ fill r: 204, g: 102, b: 204
3513
+ }
3514
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3515
+ figure {
3516
+ x 100
3517
+ y 100
3518
+
3519
+ line {
3520
+ x 100
3521
+ y 400
3522
+ }
3523
+ line {
3524
+ x 400
3525
+ y 100
3526
+ }
3527
+ line {
3528
+ x 400
3529
+ y 400
3530
+ }
3531
+
3532
+ closed true
3533
+ }
3534
+
3535
+ fill r: 202, g: 102, b: 104, a: 0.5
3536
+ stroke r: 0, g: 0, b: 0
3537
+ }
3538
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3539
+ figure {
3540
+ x 0
3541
+ y 0
3542
+
3543
+ bezier {
3544
+ c1_x 200
3545
+ c1_y 100
3546
+ c2_x 100
3547
+ c2_y 200
3548
+ end_x 400
3549
+ end_y 100
3550
+ }
3551
+ bezier {
3552
+ c1_x 300
3553
+ c1_y 100
3554
+ c2_x 100
3555
+ c2_y 300
3556
+ end_x 100
3557
+ end_y 400
3558
+ }
3559
+ bezier {
3560
+ c1_x 100
3561
+ c1_y 300
3562
+ c2_x 300
3563
+ c2_y 100
3564
+ end_x 400
3565
+ end_y 400
3566
+ }
3567
+
3568
+ closed true
3569
+ }
3570
+
3571
+ fill r: 202, g: 102, b: 204, a: 0.5
3572
+ stroke thickness: 2, r: 0, g: 0, b: 0
3573
+ }
3574
+ path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
3575
+ arc {
3576
+ x_center 200
3577
+ y_center 200
3578
+ radius 90
3579
+ start_angle 0
3580
+ sweep 360
3581
+ is_negative false
3582
+ }
3583
+
3584
+ fill r: 202, g: 102, b: 204, a: 0.5
3585
+ stroke thickness: 2, r: 0, g: 0, b: 0
3586
+ }
3587
+ end
3588
+ }
3589
+ }
3590
+ }.show
3591
+ ```
3592
+
2692
3593
  ## Contributing to glimmer-dsl-libui
2693
3594
 
2694
3595
  - Check out the latest master to make sure the feature hasn't been