glimmer-dsl-libui 0.0.28 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +712 -21
- data/VERSION +1 -1
- data/examples/area_gallery.rb +52 -0
- data/examples/basic_area.rb +17 -0
- data/examples/basic_area2.rb +19 -0
- data/examples/dynamic_area.rb +99 -0
- data/examples/dynamic_area2.rb +97 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +1 -1
- data/lib/glimmer/dsl/libui/dsl.rb +1 -0
- data/lib/glimmer/dsl/libui/property_expression.rb +5 -1
- data/lib/glimmer/dsl/libui/shape_expression.rb +56 -0
- data/lib/glimmer/fiddle_consumer.rb +33 -0
- data/lib/glimmer/libui/arc.rb +40 -0
- data/lib/glimmer/libui/area_proxy.rb +105 -0
- data/lib/glimmer/libui/bezier.rb +35 -0
- data/lib/glimmer/libui/button_column_proxy.rb +6 -1
- data/lib/glimmer/libui/control_proxy.rb +10 -6
- data/lib/glimmer/libui/figure.rb +51 -0
- data/lib/glimmer/libui/line.rb +35 -0
- data/lib/glimmer/libui/path_proxy.rb +169 -0
- data/lib/glimmer/libui/rectangle.rb +35 -0
- data/lib/glimmer/libui/shape.rb +129 -0
- data/lib/glimmer/libui/square.rb +35 -0
- data/lib/glimmer/libui/table_proxy.rb +8 -15
- data/lib/glimmer/libui/window_proxy.rb +7 -1
- metadata +20 -4
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
|
+
# [<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.3
|
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
|
-
|
22
|
+
Hello, World!
|
23
23
|
|
24
24
|
```ruby
|
25
25
|
require 'glimmer-dsl-libui'
|
@@ -32,6 +32,98 @@ 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
|
+
horizontal_box {
|
52
|
+
table {
|
53
|
+
text_column('Task')
|
54
|
+
progress_bar_column('Progress')
|
55
|
+
|
56
|
+
cell_rows data
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}.show
|
60
|
+
```
|
61
|
+
|
62
|
+
![glimmer-dsl-libui-mac-basic-table-progress-bar.png](images/glimmer-dsl-libui-mac-basic-table-progress-bar.png)
|
63
|
+
![glimmer-dsl-libui-linux-basic-table-progress-bar.png](images/glimmer-dsl-libui-linux-basic-table-progress-bar.png)
|
64
|
+
|
65
|
+
Area Gallery
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
require 'glimmer-dsl-libui'
|
69
|
+
|
70
|
+
include Glimmer
|
71
|
+
|
72
|
+
window('Area Gallery', 400, 400) {
|
73
|
+
vertical_box {
|
74
|
+
area {
|
75
|
+
path { # declarative stable path
|
76
|
+
square(0, 0, 100)
|
77
|
+
square(100, 100, 400)
|
78
|
+
|
79
|
+
fill r: 102, g: 102, b: 204
|
80
|
+
}
|
81
|
+
path { # declarative stable path
|
82
|
+
rectangle(0, 100, 100, 400)
|
83
|
+
rectangle(100, 0, 400, 100)
|
84
|
+
|
85
|
+
fill r: 204, g: 102, b: 204
|
86
|
+
}
|
87
|
+
path { # declarative stable path
|
88
|
+
figure(100, 100) {
|
89
|
+
line(100, 400)
|
90
|
+
line(400, 100)
|
91
|
+
line(400, 400)
|
92
|
+
|
93
|
+
closed true
|
94
|
+
}
|
95
|
+
|
96
|
+
fill r: 202, g: 102, b: 104, a: 0.5
|
97
|
+
stroke thickness: 1, r: 0, g: 0, b: 0
|
98
|
+
}
|
99
|
+
path { # declarative stable path
|
100
|
+
figure(0, 0) {
|
101
|
+
bezier(200, 100, 100, 200, 400, 100)
|
102
|
+
bezier(300, 100, 100, 300, 100, 400)
|
103
|
+
bezier(100, 300, 300, 100, 400, 400)
|
104
|
+
|
105
|
+
closed true
|
106
|
+
}
|
107
|
+
|
108
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
109
|
+
stroke thickness: 2, r: 0, g: 0, b: 0
|
110
|
+
}
|
111
|
+
path { # declarative stable path
|
112
|
+
arc(200, 200, 90, 0, 360, false)
|
113
|
+
|
114
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
115
|
+
stroke thickness: 2, r: 0, g: 0, b: 0
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}.show
|
120
|
+
```
|
121
|
+
|
122
|
+
![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png)
|
123
|
+
![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
|
124
|
+
|
125
|
+
[Check Out Many More Examples Over Here!](#examples)
|
126
|
+
|
35
127
|
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
128
|
|
37
129
|
Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interested in:
|
@@ -43,9 +135,10 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
43
135
|
|
44
136
|
## Table of Contents
|
45
137
|
|
46
|
-
- [Glimmer DSL for LibUI 0.
|
138
|
+
- [Glimmer DSL for LibUI 0.1.3](#-glimmer-dsl-for-libui-013)
|
47
139
|
- [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
|
48
140
|
- [Usage](#usage)
|
141
|
+
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
49
142
|
- [API](#api)
|
50
143
|
- [Supported Controls](#supported-controls)
|
51
144
|
- [Common Control Properties](#common-control-properties)
|
@@ -53,11 +146,11 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
53
146
|
- [Extra Dialogs](#extra-dialogs)
|
54
147
|
- [Extra Operations](#extra-operations)
|
55
148
|
- [Table API](#table-api)
|
149
|
+
- [Area API](#area-api)
|
56
150
|
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
57
151
|
- [API Gotchas](#api-gotchas)
|
58
152
|
- [Original API](#original-api)
|
59
153
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
60
|
-
- [Girb (Glimmer IRB)](#girb-glimmer-irb)
|
61
154
|
- [Examples](#examples)
|
62
155
|
- [Basic Window](#basic-window)
|
63
156
|
- [Basic Button](#basic-button)
|
@@ -80,6 +173,9 @@ Other [Glimmer](https://rubygems.org/gems/glimmer) DSL gems you might be interes
|
|
80
173
|
- [Basic Table Checkbox Text](#basic-table-checkbox-text)
|
81
174
|
- [Basic Table Progress Bar](#basic-table-progress-bar)
|
82
175
|
- [Form Table](#form-table)
|
176
|
+
- [Basic Area](#basic-area)
|
177
|
+
- [Dynamic Area](#dynamic-area)
|
178
|
+
- [Area Gallery](#area-gallery)
|
83
179
|
- [Contributing to glimmer-dsl-libui](#contributing-to-glimmer-dsl-libui)
|
84
180
|
- [Help](#help)
|
85
181
|
- [Issues](#issues)
|
@@ -167,7 +263,7 @@ gem install glimmer-dsl-libui
|
|
167
263
|
Or install via Bundler `Gemfile`:
|
168
264
|
|
169
265
|
```ruby
|
170
|
-
gem 'glimmer-dsl-libui', '~> 0.
|
266
|
+
gem 'glimmer-dsl-libui', '~> 0.1.3'
|
171
267
|
```
|
172
268
|
|
173
269
|
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.
|
@@ -194,6 +290,24 @@ end
|
|
194
290
|
Application.new.launch
|
195
291
|
```
|
196
292
|
|
293
|
+
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.
|
294
|
+
|
295
|
+
## Girb (Glimmer IRB)
|
296
|
+
|
297
|
+
You can run the `girb` command (`bin/girb` if you cloned the project locally) to do some quick and dirty experimentation and learning:
|
298
|
+
|
299
|
+
```
|
300
|
+
girb
|
301
|
+
```
|
302
|
+
|
303
|
+
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.
|
304
|
+
|
305
|
+
![glimmer-dsl-libui-girb.png](images/glimmer-dsl-libui-girb.png)
|
306
|
+
|
307
|
+
For a more advanced code editing tool, check out the [Meta-Example (The Example of Examples)](#examples).
|
308
|
+
|
309
|
+
Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
|
310
|
+
|
197
311
|
## API
|
198
312
|
|
199
313
|
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`).
|
@@ -223,17 +337,21 @@ w.libui # => #<Fiddle::Pointer:0x00007fde53997980 ptr=0x00007fde51352a60 size=0
|
|
223
337
|
Control(Args) | Properties | Listeners
|
224
338
|
------------- | ---------- | ---------
|
225
339
|
`about_menu_item` | None | `on_clicked`
|
340
|
+
`area` | None | `on_draw`
|
341
|
+
`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
|
342
|
+
`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
|
226
343
|
`button(text as String)` | `text` (`String`) | `on_clicked`
|
227
344
|
`button_column(name as String)` | `enabled` (Boolean) | None
|
228
345
|
`checkbox(text as String)` | `checked` (Boolean), `text` (`String`) | `on_toggled`
|
229
|
-
`checkbox_column(name as String)` | `editable` (Boolean)
|
230
|
-
`checkbox_text_column(name as String)` | `editable` (Boolean)
|
346
|
+
`checkbox_column(name as String)` | `editable` (Boolean) | None
|
347
|
+
`checkbox_text_column(name as String)` | `editable` (Boolean), `editable_checkbox` (Boolean), `editable_text` (Boolean) | None
|
231
348
|
`combobox` | `items` (`Array` of `String`), `selected` (`Integer`) | `on_selected`
|
232
349
|
`color_button` | `color` (Array of `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float`), `red` as `Float`, `green` as `Float`, `blue` as `Float`, `alpha` as `Float` | `on_changed`
|
233
350
|
`date_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`
|
234
351
|
`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`
|
235
352
|
`editable_combobox` | `items` (`Array` of `String`), `text` (`String`) | `on_changed`
|
236
353
|
`entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
354
|
+
`figure(x as Numeric, y as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `closed` (Boolean) | None
|
237
355
|
`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`
|
238
356
|
`form` | `padded` (Boolean) | None
|
239
357
|
`grid` | `padded` (Boolean) | None
|
@@ -245,19 +363,23 @@ Control(Args) | Properties | Listeners
|
|
245
363
|
`image_column(name as String)` | None | None
|
246
364
|
`image_text_column(name as String)` | None | None
|
247
365
|
`label(text as String)` | `text` (`String`) | None
|
366
|
+
`line(x as Numeric, y as Numeric)` | `x` (`Numeric`), `y` (`Numeric`) | None
|
248
367
|
`menu(text as String)` | None | None
|
249
368
|
`menu_item(text as String)` | `checked` (Boolean) | `on_clicked`
|
250
369
|
`multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
251
370
|
`msg_box(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
252
371
|
`msg_box_error(window as Glimmer::LibUI::WindowProxy, title as String, description as String)` | None | None
|
253
372
|
`non_wrapping_multiline_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
373
|
+
`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
|
254
374
|
`preferences_menu_item` | None | `on_clicked`
|
255
375
|
`progress_bar` | `value` (`Numeric`) | None
|
256
376
|
`progress_bar_column(name as String)` | None | None
|
257
377
|
`quit_menu_item` | None | `on_clicked`
|
258
378
|
`radio_buttons` | `selected` (`Integer`) | `on_selected`
|
379
|
+
`rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `width` (`Numeric`), `height` (`Numeric`) | None
|
259
380
|
`slider(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
260
381
|
`spinbox(min as Numeric, max as Numeric)` | `value` (`Numeric`) | `on_changed`
|
382
|
+
`square(x as Numeric, y as Numeric, length as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `length` (`Numeric`) | None
|
261
383
|
`tab` | `margined` (Boolean), `num_pages` (`Integer`) | None
|
262
384
|
`tab_item(name as String)` | `index` [read-only] (`Integer`), `margined` (Boolean), `name` [read-only] (`String`) | None
|
263
385
|
`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
|
@@ -302,6 +424,7 @@ Control(Args) | Properties | Listeners
|
|
302
424
|
- `ControlProxy::image_proxies`: returns all instantiated `image` proxies in the application
|
303
425
|
- `ControlProxy::main_window_proxy`: returns the first window proxy instantiated in the application
|
304
426
|
- `ControlProxy#window_proxy`: returns the window proxy parent for a control
|
427
|
+
- `ControlProxy#content {...}`: re-opens control's content to add more nested controls or properties
|
305
428
|
|
306
429
|
### Table API
|
307
430
|
|
@@ -321,6 +444,148 @@ Note that the `cell_rows` property declaration results in "implicit data-binding
|
|
321
444
|
- Inserting cell rows: Calling `Array#<<`, `Array#push`, `Array#prepend`, or any insertion/addition `Array` method automatically inserts rows in actual `table` control
|
322
445
|
- Changing cell rows: Calling `Array#[]=`, `Array#map!`, or any update `Array` method automatically updates rows in actual `table` control
|
323
446
|
|
447
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
require 'glimmer-dsl-libui'
|
451
|
+
|
452
|
+
include Glimmer
|
453
|
+
|
454
|
+
data = [
|
455
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
|
456
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
|
457
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
|
458
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
|
459
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
|
460
|
+
]
|
461
|
+
|
462
|
+
window('Contacts', 600, 600) { |w|
|
463
|
+
margined true
|
464
|
+
|
465
|
+
vertical_box {
|
466
|
+
form {
|
467
|
+
stretchy false
|
468
|
+
|
469
|
+
@name_entry = entry {
|
470
|
+
label 'Name'
|
471
|
+
}
|
472
|
+
@email_entry = entry {
|
473
|
+
label 'Email'
|
474
|
+
}
|
475
|
+
@phone_entry = entry {
|
476
|
+
label 'Phone'
|
477
|
+
}
|
478
|
+
@city_entry = entry {
|
479
|
+
label 'City'
|
480
|
+
}
|
481
|
+
@state_entry = entry {
|
482
|
+
label 'State'
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
486
|
+
button('Save Contact') {
|
487
|
+
stretchy false
|
488
|
+
|
489
|
+
on_clicked do
|
490
|
+
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
491
|
+
if new_row.include?('')
|
492
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
493
|
+
else
|
494
|
+
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
495
|
+
@name_entry.text = ''
|
496
|
+
@email_entry.text = ''
|
497
|
+
@phone_entry.text = ''
|
498
|
+
@city_entry.text = ''
|
499
|
+
@state_entry.text = ''
|
500
|
+
end
|
501
|
+
end
|
502
|
+
}
|
503
|
+
|
504
|
+
table {
|
505
|
+
text_column('Name')
|
506
|
+
text_column('Email')
|
507
|
+
text_column('Phone')
|
508
|
+
text_column('City')
|
509
|
+
text_column('State')
|
510
|
+
|
511
|
+
cell_rows data # implicit data-binding
|
512
|
+
}
|
513
|
+
}
|
514
|
+
}.show
|
515
|
+
```
|
516
|
+
|
517
|
+
![glimmer-dsl-libui-linux-form-table.png](images/glimmer-dsl-libui-linux-form-table.png)
|
518
|
+
|
519
|
+
Learn more by checking out [examples](#examples).
|
520
|
+
|
521
|
+
### Area API
|
522
|
+
|
523
|
+
The `area` control can be used in one of two ways:
|
524
|
+
- 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).
|
525
|
+
- 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.
|
526
|
+
|
527
|
+
Here is an example of a declarative `area` with a stable path (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
528
|
+
|
529
|
+
```ruby
|
530
|
+
require 'glimmer-dsl-libui'
|
531
|
+
|
532
|
+
include Glimmer
|
533
|
+
|
534
|
+
window('Basic Area', 400, 400) {
|
535
|
+
margined true
|
536
|
+
|
537
|
+
vertical_box {
|
538
|
+
area {
|
539
|
+
path { # a stable path is added declaratively
|
540
|
+
rectangle(0, 0, 400, 400)
|
541
|
+
|
542
|
+
fill r: 102, g: 102, b: 204, a: 1.0
|
543
|
+
}
|
544
|
+
}
|
545
|
+
}
|
546
|
+
}.show
|
547
|
+
```
|
548
|
+
|
549
|
+
![glimmer-dsl-libui-mac-basic-area.png](images/glimmer-dsl-libui-mac-basic-area.png)
|
550
|
+
|
551
|
+
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)):
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
require 'glimmer-dsl-libui'
|
555
|
+
|
556
|
+
include Glimmer
|
557
|
+
|
558
|
+
window('Basic Area', 400, 400) {
|
559
|
+
margined true
|
560
|
+
|
561
|
+
vertical_box {
|
562
|
+
area {
|
563
|
+
on_draw do |area_draw_params|
|
564
|
+
path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
|
565
|
+
rectangle(0, 0, 400, 400)
|
566
|
+
|
567
|
+
fill r: 102, g: 102, b: 204, a: 1.0
|
568
|
+
}
|
569
|
+
end
|
570
|
+
}
|
571
|
+
}
|
572
|
+
}.show
|
573
|
+
```
|
574
|
+
|
575
|
+
Check [examples/dynamic_area.rb](#dynamic-area) for a more detailed semi-declarative example.
|
576
|
+
|
577
|
+
Available nested `path` shapes:
|
578
|
+
- `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)`
|
579
|
+
- `square(x as Numeric, y as Numeric, length as Numeric)`
|
580
|
+
- `arc(x_center as Numeric, y_center as Numeric, radius as Numeric, start_angle as Numeric, sweep as Numeric, is_negative as Boolean)`
|
581
|
+
- `line(x as Numeric, y as Numeric)`
|
582
|
+
- `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)`
|
583
|
+
- `figure(x as Numeric, y as Numeric)` (composite that can contain other shapes) (can set `closed true` to connect last point to first point automatically)
|
584
|
+
|
585
|
+
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.
|
586
|
+
|
587
|
+
To redraw an `area`, you may call `#queue_redraw_all` method.
|
588
|
+
|
324
589
|
### Smart Defaults and Conventions
|
325
590
|
|
326
591
|
- `horizontal_box`, `vertical_box`, `grid`, and `form` controls have `padded` as `true` upon instantiation to ensure more user-friendly GUI by default
|
@@ -349,11 +614,14 @@ Note that the `cell_rows` property declaration results in "implicit data-binding
|
|
349
614
|
- Table `cell_rows` data has implicit data-binding to table cell values for deletion, insertion, and change (done by diffing `cell_rows` value before and after change and auto-informing `table` of deletions [`LibUI.table_model_row_deleted`], insertions [`LibUI.table_model_row_deleted`], and changes [`LibUI.table_model_row_changed`]). When deleting data rows from `cell_rows` array, then actual rows from the `table` are automatically deleted. When inserting data rows into `cell_rows` array, then actual `table` rows are automatically inserted. When updating data rows in `cell_rows` array, then actual `table` rows are automatically updated.
|
350
615
|
- `image` instances are automatically freed from memory after `window` is destroyed.
|
351
616
|
- `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`
|
617
|
+
- `area` paths are specified declaratively with figures underneath (e.g. `rectangle`) and `area` draw listener is automatically generated
|
618
|
+
- Observe figure properties (e.g. `rectangle` `width`) for changes and automatically redraw containing area accordingly
|
619
|
+
- Observe `path` `fill` and `stroke` hashes for changes and automatically redraw containing area accordingly
|
352
620
|
|
353
621
|
### API Gotchas
|
354
622
|
|
355
623
|
- 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`).
|
356
|
-
- `table` `checkbox_column` and `checkbox_text_column` checkbox editing
|
624
|
+
- `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).
|
357
625
|
|
358
626
|
### Original API
|
359
627
|
|
@@ -369,21 +637,9 @@ check out the [libui C headers](https://github.com/andlabs/libui/blob/master/ui.
|
|
369
637
|
- 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.
|
370
638
|
- 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.
|
371
639
|
|
372
|
-
## Girb (Glimmer IRB)
|
373
|
-
|
374
|
-
You can run the `girb` command (`bin/girb` if you cloned the project locally):
|
375
|
-
|
376
|
-
```
|
377
|
-
girb
|
378
|
-
```
|
379
|
-
|
380
|
-
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.
|
381
|
-
|
382
|
-
Gotcha: On the Mac, when you close a window opened in `girb`, it remains open until you enter `exit` or open another GUI window.
|
383
|
-
|
384
640
|
## Examples
|
385
641
|
|
386
|
-
|
642
|
+
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.
|
387
643
|
|
388
644
|
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.
|
389
645
|
|
@@ -2581,6 +2837,441 @@ window('Contacts', 600, 600) { |w|
|
|
2581
2837
|
}.show
|
2582
2838
|
```
|
2583
2839
|
|
2840
|
+
### Basic Area
|
2841
|
+
|
2842
|
+
[examples/basic_area.rb](examples/basic_area.rb)
|
2843
|
+
|
2844
|
+
Run with this command from the root of the project if you cloned the project:
|
2845
|
+
|
2846
|
+
```
|
2847
|
+
ruby -r './lib/glimmer-dsl-libui' examples/basic_area.rb
|
2848
|
+
```
|
2849
|
+
|
2850
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2851
|
+
|
2852
|
+
```
|
2853
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/basic_area'"
|
2854
|
+
```
|
2855
|
+
|
2856
|
+
Mac
|
2857
|
+
|
2858
|
+
![glimmer-dsl-libui-mac-basic-area.png](images/glimmer-dsl-libui-mac-basic-area.png)
|
2859
|
+
|
2860
|
+
Linux
|
2861
|
+
|
2862
|
+
![glimmer-dsl-libui-linux-basic-area.png](images/glimmer-dsl-libui-linux-basic-area.png)
|
2863
|
+
|
2864
|
+
[LibUI](https://github.com/kojix2/LibUI) Original Version:
|
2865
|
+
|
2866
|
+
```ruby
|
2867
|
+
require 'libui'
|
2868
|
+
|
2869
|
+
UI = LibUI
|
2870
|
+
|
2871
|
+
UI.init
|
2872
|
+
|
2873
|
+
handler = UI::FFI::AreaHandler.malloc
|
2874
|
+
area = UI.new_area(handler)
|
2875
|
+
brush = UI::FFI::DrawBrush.malloc
|
2876
|
+
|
2877
|
+
handler_draw_event = Fiddle::Closure::BlockCaller.new(0, [1, 1, 1]) do |_, _, area_draw_params|
|
2878
|
+
path = UI.draw_new_path(0)
|
2879
|
+
UI.draw_path_add_rectangle(path, 0, 0, 400, 400)
|
2880
|
+
UI.draw_path_end(path)
|
2881
|
+
brush.Type = 0
|
2882
|
+
brush.R = 0.4
|
2883
|
+
brush.G = 0.4
|
2884
|
+
brush.B = 0.8
|
2885
|
+
brush.A = 1.0
|
2886
|
+
area_draw_params = UI::FFI::AreaDrawParams.new(area_draw_params)
|
2887
|
+
UI.draw_fill(area_draw_params.Context, path, brush.to_ptr)
|
2888
|
+
UI.draw_free_path(path)
|
2889
|
+
end
|
2890
|
+
|
2891
|
+
handler.Draw = handler_draw_event
|
2892
|
+
handler.MouseEvent = Fiddle::Closure::BlockCaller.new(0, [0]) {}
|
2893
|
+
handler.MouseCrossed = Fiddle::Closure::BlockCaller.new(0, [0]) {}
|
2894
|
+
handler.DragBroken = Fiddle::Closure::BlockCaller.new(0, [0]) {}
|
2895
|
+
handler.KeyEvent = Fiddle::Closure::BlockCaller.new(0, [0]) {}
|
2896
|
+
|
2897
|
+
box = UI.new_vertical_box
|
2898
|
+
UI.box_set_padded(box, 1)
|
2899
|
+
UI.box_append(box, area, 1)
|
2900
|
+
|
2901
|
+
main_window = UI.new_window('Basic Area', 400, 400, 1)
|
2902
|
+
UI.window_set_margined(main_window, 1)
|
2903
|
+
UI.window_set_child(main_window, box)
|
2904
|
+
|
2905
|
+
UI.window_on_closing(main_window) do
|
2906
|
+
UI.control_destroy(main_window)
|
2907
|
+
UI.quit
|
2908
|
+
0
|
2909
|
+
end
|
2910
|
+
UI.control_show(main_window)
|
2911
|
+
|
2912
|
+
UI.main
|
2913
|
+
UI.quit
|
2914
|
+
```
|
2915
|
+
|
2916
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
2917
|
+
|
2918
|
+
```ruby
|
2919
|
+
require 'glimmer-dsl-libui'
|
2920
|
+
|
2921
|
+
include Glimmer
|
2922
|
+
|
2923
|
+
window('Basic Area', 400, 400) {
|
2924
|
+
margined true
|
2925
|
+
|
2926
|
+
vertical_box {
|
2927
|
+
area {
|
2928
|
+
path { # a stable path is added declaratively
|
2929
|
+
rectangle(0, 0, 400, 400)
|
2930
|
+
|
2931
|
+
fill r: 102, g: 102, b: 204, a: 1.0
|
2932
|
+
}
|
2933
|
+
}
|
2934
|
+
}
|
2935
|
+
}.show
|
2936
|
+
```
|
2937
|
+
|
2938
|
+
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
2939
|
+
|
2940
|
+
```ruby
|
2941
|
+
require 'glimmer-dsl-libui'
|
2942
|
+
|
2943
|
+
include Glimmer
|
2944
|
+
|
2945
|
+
window('Basic Area', 400, 400) {
|
2946
|
+
margined true
|
2947
|
+
|
2948
|
+
vertical_box {
|
2949
|
+
area {
|
2950
|
+
on_draw do |area_draw_params|
|
2951
|
+
path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
|
2952
|
+
rectangle(0, 0, 400, 400)
|
2953
|
+
|
2954
|
+
fill r: 102, g: 102, b: 204, a: 1.0
|
2955
|
+
}
|
2956
|
+
end
|
2957
|
+
}
|
2958
|
+
}
|
2959
|
+
}.show
|
2960
|
+
```
|
2961
|
+
|
2962
|
+
### Dynamic Area
|
2963
|
+
|
2964
|
+
[examples/dynamic_area.rb](examples/dynamic_area.rb)
|
2965
|
+
|
2966
|
+
Run with this command from the root of the project if you cloned the project:
|
2967
|
+
|
2968
|
+
```
|
2969
|
+
ruby -r './lib/glimmer-dsl-libui' examples/dynamic_area.rb
|
2970
|
+
```
|
2971
|
+
|
2972
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2973
|
+
|
2974
|
+
```
|
2975
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/dynamic_area'"
|
2976
|
+
```
|
2977
|
+
|
2978
|
+
Mac
|
2979
|
+
|
2980
|
+
![glimmer-dsl-libui-mac-dynamic-area.png](images/glimmer-dsl-libui-mac-dynamic-area.png)
|
2981
|
+
![glimmer-dsl-libui-mac-dynamic-area-updated.png](images/glimmer-dsl-libui-mac-dynamic-area-updated.png)
|
2982
|
+
|
2983
|
+
Linux
|
2984
|
+
|
2985
|
+
![glimmer-dsl-libui-linux-dynamic-area.png](images/glimmer-dsl-libui-linux-dynamic-area.png)
|
2986
|
+
![glimmer-dsl-libui-linux-dynamic-area-updated.png](images/glimmer-dsl-libui-linux-dynamic-area-updated.png)
|
2987
|
+
|
2988
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
2989
|
+
|
2990
|
+
```ruby
|
2991
|
+
require 'glimmer-dsl-libui'
|
2992
|
+
|
2993
|
+
include Glimmer
|
2994
|
+
|
2995
|
+
window('Dynamic Area', 240, 500) {
|
2996
|
+
margined true
|
2997
|
+
|
2998
|
+
vertical_box {
|
2999
|
+
label('Rectangle Properties') {
|
3000
|
+
stretchy false
|
3001
|
+
}
|
3002
|
+
|
3003
|
+
form {
|
3004
|
+
stretchy false
|
3005
|
+
|
3006
|
+
@x_spinbox = spinbox(0, 1000) {
|
3007
|
+
label 'x'
|
3008
|
+
value 25
|
3009
|
+
|
3010
|
+
on_changed do
|
3011
|
+
@area.queue_redraw_all
|
3012
|
+
end
|
3013
|
+
}
|
3014
|
+
|
3015
|
+
@y_spinbox = spinbox(0, 1000) {
|
3016
|
+
label 'y'
|
3017
|
+
value 25
|
3018
|
+
|
3019
|
+
on_changed do
|
3020
|
+
@area.queue_redraw_all
|
3021
|
+
end
|
3022
|
+
}
|
3023
|
+
|
3024
|
+
@width_spinbox = spinbox(0, 1000) {
|
3025
|
+
label 'width'
|
3026
|
+
value 150
|
3027
|
+
|
3028
|
+
on_changed do
|
3029
|
+
@area.queue_redraw_all
|
3030
|
+
end
|
3031
|
+
}
|
3032
|
+
|
3033
|
+
@height_spinbox = spinbox(0, 1000) {
|
3034
|
+
label 'height'
|
3035
|
+
value 150
|
3036
|
+
|
3037
|
+
on_changed do
|
3038
|
+
@area.queue_redraw_all
|
3039
|
+
end
|
3040
|
+
}
|
3041
|
+
|
3042
|
+
@red_spinbox = spinbox(0, 255) {
|
3043
|
+
label 'red'
|
3044
|
+
value 102
|
3045
|
+
|
3046
|
+
on_changed do
|
3047
|
+
@area.queue_redraw_all
|
3048
|
+
end
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
@green_spinbox = spinbox(0, 255) {
|
3052
|
+
label 'green'
|
3053
|
+
value 102
|
3054
|
+
|
3055
|
+
on_changed do
|
3056
|
+
@area.queue_redraw_all
|
3057
|
+
end
|
3058
|
+
}
|
3059
|
+
|
3060
|
+
@blue_spinbox = spinbox(0, 255) {
|
3061
|
+
label 'blue'
|
3062
|
+
value 204
|
3063
|
+
|
3064
|
+
on_changed do
|
3065
|
+
@area.queue_redraw_all
|
3066
|
+
end
|
3067
|
+
}
|
3068
|
+
|
3069
|
+
@alpha_spinbox = spinbox(0, 100) {
|
3070
|
+
label 'alpha'
|
3071
|
+
value 100
|
3072
|
+
|
3073
|
+
on_changed do
|
3074
|
+
@area.queue_redraw_all
|
3075
|
+
end
|
3076
|
+
}
|
3077
|
+
}
|
3078
|
+
|
3079
|
+
@area = area {
|
3080
|
+
on_draw do |area_draw_params|
|
3081
|
+
path(area_draw_params) { # a dynamic path is added semi-declaratively inside on_draw block
|
3082
|
+
rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
|
3083
|
+
|
3084
|
+
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
3085
|
+
}
|
3086
|
+
end
|
3087
|
+
}
|
3088
|
+
}
|
3089
|
+
}.show
|
3090
|
+
```
|
3091
|
+
|
3092
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
3093
|
+
|
3094
|
+
```ruby
|
3095
|
+
require 'glimmer-dsl-libui'
|
3096
|
+
|
3097
|
+
include Glimmer
|
3098
|
+
|
3099
|
+
window('Dynamic Area', 240, 600) {
|
3100
|
+
margined true
|
3101
|
+
|
3102
|
+
vertical_box {
|
3103
|
+
label('Rectangle Properties') {
|
3104
|
+
stretchy false
|
3105
|
+
}
|
3106
|
+
|
3107
|
+
form {
|
3108
|
+
stretchy false
|
3109
|
+
|
3110
|
+
@x_spinbox = spinbox(0, 1000) {
|
3111
|
+
label 'x'
|
3112
|
+
value 25
|
3113
|
+
|
3114
|
+
on_changed do
|
3115
|
+
@rectangle.x = @x_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
3116
|
+
end
|
3117
|
+
}
|
3118
|
+
|
3119
|
+
@y_spinbox = spinbox(0, 1000) {
|
3120
|
+
label 'y'
|
3121
|
+
value 25
|
3122
|
+
|
3123
|
+
on_changed do
|
3124
|
+
@rectangle.y = @y_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
3125
|
+
end
|
3126
|
+
}
|
3127
|
+
|
3128
|
+
@width_spinbox = spinbox(0, 1000) {
|
3129
|
+
label 'width'
|
3130
|
+
value 150
|
3131
|
+
|
3132
|
+
on_changed do
|
3133
|
+
@rectangle.width = @width_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
3134
|
+
end
|
3135
|
+
}
|
3136
|
+
|
3137
|
+
@height_spinbox = spinbox(0, 1000) {
|
3138
|
+
label 'height'
|
3139
|
+
value 150
|
3140
|
+
|
3141
|
+
on_changed do
|
3142
|
+
@rectangle.height = @height_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
3143
|
+
end
|
3144
|
+
}
|
3145
|
+
|
3146
|
+
@red_spinbox = spinbox(0, 255) {
|
3147
|
+
label 'red'
|
3148
|
+
value 102
|
3149
|
+
|
3150
|
+
on_changed do
|
3151
|
+
@path.fill[:r] = @red_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
3152
|
+
end
|
3153
|
+
}
|
3154
|
+
|
3155
|
+
@green_spinbox = spinbox(0, 255) {
|
3156
|
+
label 'green'
|
3157
|
+
value 102
|
3158
|
+
|
3159
|
+
on_changed do
|
3160
|
+
@path.fill[:g] = @green_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
3161
|
+
end
|
3162
|
+
}
|
3163
|
+
|
3164
|
+
@blue_spinbox = spinbox(0, 255) {
|
3165
|
+
label 'blue'
|
3166
|
+
value 204
|
3167
|
+
|
3168
|
+
on_changed do
|
3169
|
+
@path.fill[:b] = @blue_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
3170
|
+
end
|
3171
|
+
}
|
3172
|
+
|
3173
|
+
@alpha_spinbox = spinbox(0, 100) {
|
3174
|
+
label 'alpha'
|
3175
|
+
value 100
|
3176
|
+
|
3177
|
+
on_changed do
|
3178
|
+
@path.fill[:a] = @alpha_spinbox.value / 100.0 # updating hash properties automatically triggers area.queue_redraw_all
|
3179
|
+
end
|
3180
|
+
}
|
3181
|
+
}
|
3182
|
+
|
3183
|
+
area {
|
3184
|
+
@path = path { # stable path
|
3185
|
+
@rectangle = rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value)
|
3186
|
+
|
3187
|
+
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
3188
|
+
}
|
3189
|
+
}
|
3190
|
+
}
|
3191
|
+
}.show
|
3192
|
+
```
|
3193
|
+
|
3194
|
+
### Area Gallery
|
3195
|
+
|
3196
|
+
[examples/area_gallery.rb](examples/area_gallery.rb)
|
3197
|
+
|
3198
|
+
Run with this command from the root of the project if you cloned the project:
|
3199
|
+
|
3200
|
+
```
|
3201
|
+
ruby -r './lib/glimmer-dsl-libui' examples/area_gallery.rb
|
3202
|
+
```
|
3203
|
+
|
3204
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
3205
|
+
|
3206
|
+
```
|
3207
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/area_gallery'"
|
3208
|
+
```
|
3209
|
+
|
3210
|
+
Mac
|
3211
|
+
|
3212
|
+
![glimmer-dsl-libui-mac-area-gallery.png](images/glimmer-dsl-libui-mac-area-gallery.png)
|
3213
|
+
|
3214
|
+
Linux
|
3215
|
+
|
3216
|
+
![glimmer-dsl-libui-linux-area-gallery.png](images/glimmer-dsl-libui-linux-area-gallery.png)
|
3217
|
+
|
3218
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
3219
|
+
|
3220
|
+
```ruby
|
3221
|
+
require 'glimmer-dsl-libui'
|
3222
|
+
|
3223
|
+
include Glimmer
|
3224
|
+
|
3225
|
+
window('Area Gallery', 400, 400) {
|
3226
|
+
vertical_box {
|
3227
|
+
area {
|
3228
|
+
path { # declarative stable path
|
3229
|
+
square(0, 0, 100)
|
3230
|
+
square(100, 100, 400)
|
3231
|
+
|
3232
|
+
fill r: 102, g: 102, b: 204
|
3233
|
+
}
|
3234
|
+
path { # declarative stable path
|
3235
|
+
rectangle(0, 100, 100, 400)
|
3236
|
+
rectangle(100, 0, 400, 100)
|
3237
|
+
|
3238
|
+
fill r: 204, g: 102, b: 204
|
3239
|
+
}
|
3240
|
+
path { # declarative stable path
|
3241
|
+
figure(100, 100) {
|
3242
|
+
line(100, 400)
|
3243
|
+
line(400, 100)
|
3244
|
+
line(400, 400)
|
3245
|
+
|
3246
|
+
closed true
|
3247
|
+
}
|
3248
|
+
|
3249
|
+
fill r: 202, g: 102, b: 104, a: 0.5
|
3250
|
+
stroke thickness: 1, r: 0, g: 0, b: 0
|
3251
|
+
}
|
3252
|
+
path { # declarative stable path
|
3253
|
+
figure(0, 0) {
|
3254
|
+
bezier(200, 100, 100, 200, 400, 100)
|
3255
|
+
bezier(300, 100, 100, 300, 100, 400)
|
3256
|
+
bezier(100, 300, 300, 100, 400, 400)
|
3257
|
+
|
3258
|
+
closed true
|
3259
|
+
}
|
3260
|
+
|
3261
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
3262
|
+
stroke thickness: 2, r: 0, g: 0, b: 0
|
3263
|
+
}
|
3264
|
+
path { # declarative stable path
|
3265
|
+
arc(200, 200, 90, 0, 360, false)
|
3266
|
+
|
3267
|
+
fill r: 202, g: 102, b: 204, a: 0.5
|
3268
|
+
stroke thickness: 2, r: 0, g: 0, b: 0
|
3269
|
+
}
|
3270
|
+
}
|
3271
|
+
}
|
3272
|
+
}.show
|
3273
|
+
```
|
3274
|
+
|
2584
3275
|
## Contributing to glimmer-dsl-libui
|
2585
3276
|
|
2586
3277
|
- Check out the latest master to make sure the feature hasn't been
|