glimmer-dsl-libui 0.5.22 → 0.5.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +24 -7
- data/VERSION +1 -1
- data/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md +167 -2707
- data/examples/gpt2_notepad.rb +107 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/custom_control/refined_table.rb +1 -1
- metadata +4 -3
@@ -11,6 +11,7 @@
|
|
11
11
|
- [Editable Column Table](#editable-column-table)
|
12
12
|
- [Editable Table](#editable-table)
|
13
13
|
- [Form Table](#form-table)
|
14
|
+
- [GPT2 Notepad](#gpt2-notepad)
|
14
15
|
- [Paginated Refined Table](#paginated-refined-table)
|
15
16
|
- [Grid](#grid)
|
16
17
|
- [Histogram](#histogram)
|
@@ -45,2815 +46,274 @@ Mac | Windows | Linux
|
|
45
46
|
----|---------|------
|
46
47
|
 |  | 
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
```ruby
|
51
|
-
require 'glimmer-dsl-libui'
|
52
|
-
|
53
|
-
include Glimmer
|
54
|
-
|
55
|
-
window('Area Gallery', 400, 400) {
|
56
|
-
area {
|
57
|
-
path { # declarative stable path (explicit path syntax for multiple shapes sharing attributes)
|
58
|
-
square(0, 0, 100)
|
59
|
-
square(100, 100, 400)
|
60
|
-
|
61
|
-
fill r: 102, g: 102, b: 204
|
62
|
-
}
|
63
|
-
|
64
|
-
path { # declarative stable path (explicit path syntax for multiple shapes sharing attributes)
|
65
|
-
rectangle(0, 100, 100, 400)
|
66
|
-
rectangle(100, 0, 400, 100)
|
67
|
-
|
68
|
-
# linear gradient (has x0, y0, x1, y1, and stops)
|
69
|
-
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
70
|
-
}
|
71
|
-
|
72
|
-
polygon(100, 100, 100, 400, 400, 100, 400, 400) { # declarative stable path (implicit path syntax for a single shape nested directly under area)
|
73
|
-
fill r: 202, g: 102, b: 104, a: 0.5
|
74
|
-
stroke r: 0, g: 0, b: 0
|
75
|
-
}
|
76
|
-
|
77
|
-
polybezier(0, 0,
|
78
|
-
200, 100, 100, 200, 400, 100,
|
79
|
-
300, 100, 100, 300, 100, 400,
|
80
|
-
100, 300, 300, 100, 400, 400) { # declarative stable path (implicit path syntax for a single shape nested directly under area)
|
81
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
82
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
83
|
-
}
|
84
|
-
|
85
|
-
polyline(100, 100, 400, 100, 100, 400, 400, 400, 0, 0) { # declarative stable path (implicit path syntax for a single shape nested directly under area)
|
86
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
87
|
-
}
|
88
|
-
|
89
|
-
arc(404, 216, 190, 90, 90, false) { # declarative stable path (implicit path syntax for a single shape nested directly under area)
|
90
|
-
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
91
|
-
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
92
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
93
|
-
}
|
94
|
-
|
95
|
-
circle(200, 200, 90) { # declarative stable path (implicit path syntax for a single shape nested directly under area)
|
96
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
97
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
98
|
-
}
|
99
|
-
|
100
|
-
text(161, 40, 100) { # declarative stable text
|
101
|
-
string('Area Gallery') {
|
102
|
-
font family: 'Arial', size: (OS.mac? ? 14 : 11)
|
103
|
-
color :black
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
|
-
on_mouse_event do |area_mouse_event|
|
108
|
-
p area_mouse_event
|
109
|
-
end
|
110
|
-
|
111
|
-
on_mouse_moved do |area_mouse_event|
|
112
|
-
puts 'moved'
|
113
|
-
end
|
114
|
-
|
115
|
-
on_mouse_down do |area_mouse_event|
|
116
|
-
puts 'mouse down'
|
117
|
-
end
|
118
|
-
|
119
|
-
on_mouse_up do |area_mouse_event|
|
120
|
-
puts 'mouse up'
|
121
|
-
end
|
122
|
-
|
123
|
-
on_mouse_drag_started do |area_mouse_event|
|
124
|
-
puts 'drag started'
|
125
|
-
end
|
126
|
-
|
127
|
-
on_mouse_dragged do |area_mouse_event|
|
128
|
-
puts 'dragged'
|
129
|
-
end
|
130
|
-
|
131
|
-
on_mouse_dropped do |area_mouse_event|
|
132
|
-
puts 'dropped'
|
133
|
-
end
|
134
|
-
|
135
|
-
on_mouse_entered do
|
136
|
-
puts 'entered'
|
137
|
-
end
|
138
|
-
|
139
|
-
on_mouse_exited do
|
140
|
-
puts 'exited'
|
141
|
-
end
|
142
|
-
|
143
|
-
on_key_event do |area_key_event|
|
144
|
-
p area_key_event
|
145
|
-
end
|
146
|
-
|
147
|
-
on_key_up do |area_key_event|
|
148
|
-
puts 'key up'
|
149
|
-
end
|
150
|
-
|
151
|
-
on_key_down do |area_key_event|
|
152
|
-
puts 'key down'
|
153
|
-
end
|
154
|
-
}
|
155
|
-
}.show
|
156
|
-
```
|
157
|
-
|
158
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (setting shape properties instead of arguments):
|
159
|
-
|
160
|
-
```ruby
|
161
|
-
require 'glimmer-dsl-libui'
|
162
|
-
|
163
|
-
include Glimmer
|
164
|
-
|
165
|
-
window('Area Gallery', 400, 400) {
|
166
|
-
area {
|
167
|
-
path { # declarative stable path with explicit attributes (explicit path syntax for multiple shapes sharing attributes)
|
168
|
-
square {
|
169
|
-
x 0
|
170
|
-
y 0
|
171
|
-
length 100
|
172
|
-
}
|
173
|
-
|
174
|
-
square {
|
175
|
-
x 100
|
176
|
-
y 100
|
177
|
-
length 400
|
178
|
-
}
|
179
|
-
|
180
|
-
fill r: 102, g: 102, b: 204
|
181
|
-
}
|
182
|
-
|
183
|
-
path { # declarative stable path with explicit attributes (explicit path syntax for multiple shapes sharing attributes)
|
184
|
-
rectangle {
|
185
|
-
x 0
|
186
|
-
y 100
|
187
|
-
width 100
|
188
|
-
height 400
|
189
|
-
}
|
190
|
-
|
191
|
-
rectangle {
|
192
|
-
x 100
|
193
|
-
y 0
|
194
|
-
width 400
|
195
|
-
height 100
|
196
|
-
}
|
197
|
-
|
198
|
-
# linear gradient (has x0, y0, x1, y1, and stops)
|
199
|
-
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
200
|
-
}
|
201
|
-
|
202
|
-
figure { # declarative stable path with explicit attributes (implicit path syntax for a single shape nested directly under area)
|
203
|
-
x 100
|
204
|
-
y 100
|
205
|
-
|
206
|
-
line {
|
207
|
-
x 100
|
208
|
-
y 400
|
209
|
-
}
|
210
|
-
|
211
|
-
line {
|
212
|
-
x 400
|
213
|
-
y 100
|
214
|
-
}
|
215
|
-
|
216
|
-
line {
|
217
|
-
x 400
|
218
|
-
y 400
|
219
|
-
}
|
220
|
-
|
221
|
-
closed true # polygon figure is closed (last point forms a line with first point)
|
222
|
-
fill r: 202, g: 102, b: 104, a: 0.5
|
223
|
-
stroke r: 0, g: 0, b: 0
|
224
|
-
}
|
225
|
-
|
226
|
-
figure { # declarative stable path with explicit attributes (implicit path syntax for a single shape nested directly under area)
|
227
|
-
x 0
|
228
|
-
y 0
|
229
|
-
|
230
|
-
bezier {
|
231
|
-
c1_x 200
|
232
|
-
c1_y 100
|
233
|
-
c2_x 100
|
234
|
-
c2_y 200
|
235
|
-
end_x 400
|
236
|
-
end_y 100
|
237
|
-
}
|
238
|
-
|
239
|
-
bezier {
|
240
|
-
c1_x 300
|
241
|
-
c1_y 100
|
242
|
-
c2_x 100
|
243
|
-
c2_y 300
|
244
|
-
end_x 100
|
245
|
-
end_y 400
|
246
|
-
}
|
247
|
-
|
248
|
-
bezier {
|
249
|
-
c1_x 100
|
250
|
-
c1_y 300
|
251
|
-
c2_x 300
|
252
|
-
c2_y 100
|
253
|
-
end_x 400
|
254
|
-
end_y 400
|
255
|
-
}
|
256
|
-
|
257
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
258
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
259
|
-
}
|
260
|
-
|
261
|
-
figure { # declarative stable path with explicit attributes (implicit path syntax for a single shape nested directly under area)
|
262
|
-
x 100
|
263
|
-
y 100
|
264
|
-
|
265
|
-
line {
|
266
|
-
x 400
|
267
|
-
y 100
|
268
|
-
}
|
269
|
-
|
270
|
-
line {
|
271
|
-
x 100
|
272
|
-
y 400
|
273
|
-
}
|
274
|
-
|
275
|
-
line {
|
276
|
-
x 400
|
277
|
-
y 400
|
278
|
-
}
|
279
|
-
|
280
|
-
line {
|
281
|
-
x 0
|
282
|
-
y 0
|
283
|
-
}
|
284
|
-
|
285
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
286
|
-
}
|
287
|
-
|
288
|
-
arc { # declarative stable path with explicit attributes (implicit path syntax for a single shape nested directly under area)
|
289
|
-
x_center 404
|
290
|
-
y_center 216
|
291
|
-
radius 190
|
292
|
-
start_angle 90
|
293
|
-
sweep 90
|
294
|
-
is_negative false
|
295
|
-
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
296
|
-
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
297
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
298
|
-
}
|
299
|
-
|
300
|
-
circle { # declarative stable path with explicit attributes (implicit path syntax for a single shape nested directly under area)
|
301
|
-
x_center 200
|
302
|
-
y_center 200
|
303
|
-
radius 90
|
304
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
305
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
306
|
-
}
|
307
|
-
|
308
|
-
text { # declarative stable text with explicit attributes
|
309
|
-
x 161
|
310
|
-
y 40
|
311
|
-
width 100
|
312
|
-
|
313
|
-
string {
|
314
|
-
font family: 'Arial', size: (OS.mac? ? 14 : 11)
|
315
|
-
color :black
|
316
|
-
|
317
|
-
'Area Gallery'
|
318
|
-
}
|
319
|
-
}
|
320
|
-
|
321
|
-
on_mouse_event do |area_mouse_event|
|
322
|
-
p area_mouse_event
|
323
|
-
end
|
324
|
-
|
325
|
-
on_mouse_moved do |area_mouse_event|
|
326
|
-
puts 'moved'
|
327
|
-
end
|
328
|
-
|
329
|
-
on_mouse_down do |area_mouse_event|
|
330
|
-
puts 'mouse down'
|
331
|
-
end
|
332
|
-
|
333
|
-
on_mouse_up do |area_mouse_event|
|
334
|
-
puts 'mouse up'
|
335
|
-
end
|
336
|
-
|
337
|
-
on_mouse_drag_started do |area_mouse_event|
|
338
|
-
puts 'drag started'
|
339
|
-
end
|
340
|
-
|
341
|
-
on_mouse_dragged do |area_mouse_event|
|
342
|
-
puts 'dragged'
|
343
|
-
end
|
344
|
-
|
345
|
-
on_mouse_dropped do |area_mouse_event|
|
346
|
-
puts 'dropped'
|
347
|
-
end
|
348
|
-
|
349
|
-
on_mouse_entered do
|
350
|
-
puts 'entered'
|
351
|
-
end
|
352
|
-
|
353
|
-
on_mouse_exited do
|
354
|
-
puts 'exited'
|
355
|
-
end
|
356
|
-
|
357
|
-
on_key_event do |area_key_event|
|
358
|
-
p area_key_event
|
359
|
-
end
|
360
|
-
|
361
|
-
on_key_up do |area_key_event|
|
362
|
-
puts 'key up'
|
363
|
-
end
|
364
|
-
|
365
|
-
on_key_down do |area_key_event|
|
366
|
-
puts 'key down'
|
367
|
-
end
|
368
|
-
}
|
369
|
-
}.show
|
370
|
-
```
|
371
|
-
|
372
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3 (semi-declarative `on_draw` dynamic `path` approach):
|
373
|
-
|
374
|
-
```ruby
|
375
|
-
require 'glimmer-dsl-libui'
|
376
|
-
|
377
|
-
include Glimmer
|
378
|
-
|
379
|
-
window('Area Gallery', 400, 400) {
|
380
|
-
area {
|
381
|
-
on_draw do |area_draw_params|
|
382
|
-
path { # dynamic path, added semi-declaratively inside on_draw block
|
383
|
-
square(0, 0, 100)
|
384
|
-
square(100, 100, 400)
|
385
|
-
|
386
|
-
fill r: 102, g: 102, b: 204
|
387
|
-
}
|
388
|
-
|
389
|
-
path { # dynamic path, added semi-declaratively inside on_draw block
|
390
|
-
rectangle(0, 100, 100, 400)
|
391
|
-
rectangle(100, 0, 400, 100)
|
392
|
-
|
393
|
-
# linear gradient (has x0, y0, x1, y1, and stops)
|
394
|
-
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
395
|
-
}
|
396
|
-
|
397
|
-
polygon(100, 100, 100, 400, 400, 100, 400, 400) { # dynamic path, added semi-declaratively inside on_draw block
|
398
|
-
fill r: 202, g: 102, b: 104, a: 0.5
|
399
|
-
stroke r: 0, g: 0, b: 0
|
400
|
-
}
|
401
|
-
|
402
|
-
polybezier(0, 0,
|
403
|
-
200, 100, 100, 200, 400, 100,
|
404
|
-
300, 100, 100, 300, 100, 400,
|
405
|
-
100, 300, 300, 100, 400, 400) { # dynamic path, added semi-declaratively inside on_draw block
|
406
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
407
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
408
|
-
}
|
409
|
-
|
410
|
-
polyline(100, 100, 400, 100, 100, 400, 400, 400, 0, 0) { # dynamic path, added semi-declaratively inside on_draw block
|
411
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
412
|
-
}
|
413
|
-
|
414
|
-
arc(404, 216, 190, 90, 90, false) { # dynamic path, added semi-declaratively inside on_draw block
|
415
|
-
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
416
|
-
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
417
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
418
|
-
}
|
419
|
-
|
420
|
-
circle(200, 200, 90) { # dynamic path, added semi-declaratively inside on_draw block
|
421
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
422
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
423
|
-
}
|
424
|
-
|
425
|
-
text(161, 40, 100) { # dynamic text added semi-declaratively inside on_draw block
|
426
|
-
string('Area Gallery') {
|
427
|
-
font family: 'Arial', size: (OS.mac? ? 14 : 11)
|
428
|
-
color :black
|
429
|
-
}
|
430
|
-
}
|
431
|
-
end
|
432
|
-
|
433
|
-
on_mouse_event do |area_mouse_event|
|
434
|
-
p area_mouse_event
|
435
|
-
end
|
436
|
-
|
437
|
-
on_mouse_moved do |area_mouse_event|
|
438
|
-
puts 'moved'
|
439
|
-
end
|
440
|
-
|
441
|
-
on_mouse_down do |area_mouse_event|
|
442
|
-
puts 'mouse down'
|
443
|
-
end
|
444
|
-
|
445
|
-
on_mouse_up do |area_mouse_event|
|
446
|
-
puts 'mouse up'
|
447
|
-
end
|
448
|
-
|
449
|
-
on_mouse_drag_started do |area_mouse_event|
|
450
|
-
puts 'drag started'
|
451
|
-
end
|
452
|
-
|
453
|
-
on_mouse_dragged do |area_mouse_event|
|
454
|
-
puts 'dragged'
|
455
|
-
end
|
456
|
-
|
457
|
-
on_mouse_dropped do |area_mouse_event|
|
458
|
-
puts 'dropped'
|
459
|
-
end
|
460
|
-
|
461
|
-
on_mouse_entered do
|
462
|
-
puts 'entered'
|
463
|
-
end
|
464
|
-
|
465
|
-
on_mouse_exited do
|
466
|
-
puts 'exited'
|
467
|
-
end
|
468
|
-
|
469
|
-
on_key_event do |area_key_event|
|
470
|
-
p area_key_event
|
471
|
-
end
|
472
|
-
|
473
|
-
on_key_up do |area_key_event|
|
474
|
-
puts 'key up'
|
475
|
-
end
|
476
|
-
|
477
|
-
on_key_down do |area_key_event|
|
478
|
-
puts 'key down'
|
479
|
-
end
|
480
|
-
}
|
481
|
-
}.show
|
482
|
-
```
|
483
|
-
|
484
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 4 (setting shape properties instead of arguments with semi-declarative `on_draw` dynamic `path` approach):
|
485
|
-
|
486
|
-
```ruby
|
487
|
-
require 'glimmer-dsl-libui'
|
488
|
-
|
489
|
-
include Glimmer
|
490
|
-
|
491
|
-
window('Area Gallery', 400, 400) {
|
492
|
-
area {
|
493
|
-
on_draw do |area_draw_params|
|
494
|
-
path { # dynamic path, added semi-declaratively inside on_draw block
|
495
|
-
square {
|
496
|
-
x 0
|
497
|
-
y 0
|
498
|
-
length 100
|
499
|
-
}
|
500
|
-
|
501
|
-
square {
|
502
|
-
x 100
|
503
|
-
y 100
|
504
|
-
length 400
|
505
|
-
}
|
506
|
-
|
507
|
-
fill r: 102, g: 102, b: 204
|
508
|
-
}
|
509
|
-
|
510
|
-
path { # dynamic path, added semi-declaratively inside on_draw block
|
511
|
-
rectangle {
|
512
|
-
x 0
|
513
|
-
y 100
|
514
|
-
width 100
|
515
|
-
height 400
|
516
|
-
}
|
517
|
-
|
518
|
-
rectangle {
|
519
|
-
x 100
|
520
|
-
y 0
|
521
|
-
width 400
|
522
|
-
height 100
|
523
|
-
}
|
524
|
-
|
525
|
-
# linear gradient (has x0, y0, x1, y1, and stops)
|
526
|
-
fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
|
527
|
-
}
|
528
|
-
|
529
|
-
figure { # dynamic path, added semi-declaratively inside on_draw block
|
530
|
-
x 100
|
531
|
-
y 100
|
532
|
-
|
533
|
-
line {
|
534
|
-
x 100
|
535
|
-
y 400
|
536
|
-
}
|
537
|
-
|
538
|
-
line {
|
539
|
-
x 400
|
540
|
-
y 100
|
541
|
-
}
|
542
|
-
|
543
|
-
line {
|
544
|
-
x 400
|
545
|
-
y 400
|
546
|
-
}
|
547
|
-
|
548
|
-
closed true # polygon figure is closed (last point forms a line with first point)
|
549
|
-
fill r: 202, g: 102, b: 104, a: 0.5
|
550
|
-
stroke r: 0, g: 0, b: 0
|
551
|
-
}
|
552
|
-
|
553
|
-
figure { # dynamic path, added semi-declaratively inside on_draw block
|
554
|
-
x 0
|
555
|
-
y 0
|
556
|
-
|
557
|
-
bezier {
|
558
|
-
c1_x 200
|
559
|
-
c1_y 100
|
560
|
-
c2_x 100
|
561
|
-
c2_y 200
|
562
|
-
end_x 400
|
563
|
-
end_y 100
|
564
|
-
}
|
565
|
-
|
566
|
-
bezier {
|
567
|
-
c1_x 300
|
568
|
-
c1_y 100
|
569
|
-
c2_x 100
|
570
|
-
c2_y 300
|
571
|
-
end_x 100
|
572
|
-
end_y 400
|
573
|
-
}
|
574
|
-
|
575
|
-
bezier {
|
576
|
-
c1_x 100
|
577
|
-
c1_y 300
|
578
|
-
c2_x 300
|
579
|
-
c2_y 100
|
580
|
-
end_x 400
|
581
|
-
end_y 400
|
582
|
-
}
|
583
|
-
|
584
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
585
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
586
|
-
}
|
587
|
-
|
588
|
-
figure { # dynamic path, added semi-declaratively inside on_draw block
|
589
|
-
x 100
|
590
|
-
y 100
|
591
|
-
|
592
|
-
line {
|
593
|
-
x 400
|
594
|
-
y 100
|
595
|
-
}
|
596
|
-
|
597
|
-
line {
|
598
|
-
x 100
|
599
|
-
y 400
|
600
|
-
}
|
601
|
-
|
602
|
-
line {
|
603
|
-
x 400
|
604
|
-
y 400
|
605
|
-
}
|
606
|
-
|
607
|
-
line {
|
608
|
-
x 0
|
609
|
-
y 0
|
610
|
-
}
|
611
|
-
|
612
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
613
|
-
}
|
614
|
-
|
615
|
-
arc { # dynamic path, added semi-declaratively inside on_draw block
|
616
|
-
x_center 404
|
617
|
-
y_center 216
|
618
|
-
radius 190
|
619
|
-
start_angle 90
|
620
|
-
sweep 90
|
621
|
-
is_negative false
|
622
|
-
# radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
|
623
|
-
fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
|
624
|
-
stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
|
625
|
-
}
|
626
|
-
|
627
|
-
circle { # dynamic path, added semi-declaratively inside on_draw block
|
628
|
-
x_center 200
|
629
|
-
y_center 200
|
630
|
-
radius 90
|
631
|
-
fill r: 202, g: 102, b: 204, a: 0.5
|
632
|
-
stroke r: 0, g: 0, b: 0, thickness: 2
|
633
|
-
}
|
634
|
-
|
635
|
-
text { # dynamic path, added semi-declaratively inside on_draw block
|
636
|
-
x 161
|
637
|
-
y 40
|
638
|
-
width 100
|
639
|
-
|
640
|
-
string {
|
641
|
-
font family: 'Arial', size: (OS.mac? ? 14 : 11)
|
642
|
-
color :black
|
643
|
-
|
644
|
-
'Area Gallery'
|
645
|
-
}
|
646
|
-
}
|
647
|
-
end
|
648
|
-
|
649
|
-
on_mouse_event do |area_mouse_event|
|
650
|
-
p area_mouse_event
|
651
|
-
end
|
652
|
-
|
653
|
-
on_mouse_moved do |area_mouse_event|
|
654
|
-
puts 'moved'
|
655
|
-
end
|
656
|
-
|
657
|
-
on_mouse_down do |area_mouse_event|
|
658
|
-
puts 'mouse down'
|
659
|
-
end
|
660
|
-
|
661
|
-
on_mouse_up do |area_mouse_event|
|
662
|
-
puts 'mouse up'
|
663
|
-
end
|
664
|
-
|
665
|
-
on_mouse_drag_started do |area_mouse_event|
|
666
|
-
puts 'drag started'
|
667
|
-
end
|
668
|
-
|
669
|
-
on_mouse_dragged do |area_mouse_event|
|
670
|
-
puts 'dragged'
|
671
|
-
end
|
672
|
-
|
673
|
-
on_mouse_dropped do |area_mouse_event|
|
674
|
-
puts 'dropped'
|
675
|
-
end
|
676
|
-
|
677
|
-
on_mouse_entered do
|
678
|
-
puts 'entered'
|
679
|
-
end
|
680
|
-
|
681
|
-
on_mouse_exited do
|
682
|
-
puts 'exited'
|
683
|
-
end
|
684
|
-
|
685
|
-
on_key_event do |area_key_event|
|
686
|
-
p area_key_event
|
687
|
-
end
|
688
|
-
|
689
|
-
on_key_up do |area_key_event|
|
690
|
-
puts 'key up'
|
691
|
-
end
|
692
|
-
|
693
|
-
on_key_down do |area_key_event|
|
694
|
-
puts 'key down'
|
695
|
-
end
|
696
|
-
}
|
697
|
-
}.show
|
698
|
-
```
|
699
|
-
|
700
|
-
## Button Counter
|
701
|
-
|
702
|
-
[examples/button_counter.rb](/examples/button_counter.rb)
|
703
|
-
|
704
|
-
Run with this command from the root of the project if you cloned the project:
|
705
|
-
|
706
|
-
```
|
707
|
-
ruby -r './lib/glimmer-dsl-libui' examples/button_counter.rb
|
708
|
-
```
|
709
|
-
|
710
|
-
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
711
|
-
|
712
|
-
```
|
713
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/button_counter'"
|
714
|
-
```
|
715
|
-
|
716
|
-
Mac | Windows | Linux
|
717
|
-
----|---------|------
|
718
|
-
 |  | 
|
719
|
-
|
720
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
721
|
-
|
722
|
-
```ruby
|
723
|
-
require 'glimmer-dsl-libui'
|
724
|
-
|
725
|
-
class ButtonCounter
|
726
|
-
include Glimmer
|
727
|
-
|
728
|
-
attr_accessor :count
|
729
|
-
|
730
|
-
def initialize
|
731
|
-
@count = 0
|
732
|
-
end
|
733
|
-
|
734
|
-
def launch
|
735
|
-
window('Hello, Button!') {
|
736
|
-
button {
|
737
|
-
# data-bind button text to self count, converting to string on read.
|
738
|
-
text <= [self, :count, on_read: ->(count) {"Count: #{count}"}]
|
739
|
-
|
740
|
-
on_clicked do
|
741
|
-
self.count += 1
|
742
|
-
end
|
743
|
-
}
|
744
|
-
}.show
|
745
|
-
end
|
746
|
-
end
|
747
|
-
|
748
|
-
ButtonCounter.new.launch
|
749
|
-
```
|
750
|
-
|
751
|
-
## Color The Circles
|
752
|
-
|
753
|
-
[examples/color_the_circles.rb](/examples/color_the_circles.rb)
|
754
|
-
|
755
|
-
Run with this command from the root of the project if you cloned the project:
|
756
|
-
|
757
|
-
```
|
758
|
-
ruby -r './lib/glimmer-dsl-libui' examples/color_the_circles.rb
|
759
|
-
```
|
760
|
-
|
761
|
-
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
762
|
-
|
763
|
-
```
|
764
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/color_the_circles'"
|
765
|
-
```
|
766
|
-
|
767
|
-
Mac | Windows | Linux
|
768
|
-
----|---------|------
|
769
|
-
   |    |   
|
770
|
-
|
771
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
772
|
-
|
773
|
-
```ruby
|
774
|
-
require 'glimmer-dsl-libui'
|
775
|
-
|
776
|
-
class ColorTheCircles
|
777
|
-
include Glimmer
|
778
|
-
|
779
|
-
WINDOW_WIDTH = 800
|
780
|
-
WINDOW_HEIGHT = 600
|
781
|
-
SHAPE_MIN_SIZE = 15
|
782
|
-
SHAPE_MAX_SIZE = 75
|
783
|
-
MARGIN_WIDTH = 55
|
784
|
-
MARGIN_HEIGHT = 155
|
785
|
-
TIME_MAX_EASY = 4
|
786
|
-
TIME_MAX_MEDIUM = 3
|
787
|
-
TIME_MAX_HARD = 2
|
788
|
-
TIME_MAX_INSANE = 1
|
789
|
-
|
790
|
-
attr_accessor :score
|
791
|
-
|
792
|
-
def initialize
|
793
|
-
@circles_data = []
|
794
|
-
@score = 0
|
795
|
-
@time_max = TIME_MAX_HARD
|
796
|
-
@game_over = false
|
797
|
-
register_observers
|
798
|
-
setup_circle_factory
|
799
|
-
end
|
800
|
-
|
801
|
-
def register_observers
|
802
|
-
# observe automatically enhances self to become Glimmer::DataBinding::ObservableModel and notify observer block of score attribute changes
|
803
|
-
observe(self, :score) do |new_score|
|
804
|
-
Glimmer::LibUI.queue_main do
|
805
|
-
@score_label.text = new_score.to_s
|
806
|
-
if new_score == -20
|
807
|
-
@game_over = true
|
808
|
-
msg_box('You Lost!', 'Sorry! Your score reached -20')
|
809
|
-
restart_game
|
810
|
-
elsif new_score == 0
|
811
|
-
@game_over = true
|
812
|
-
msg_box('You Won!', 'Congratulations! Your score reached 0')
|
813
|
-
restart_game
|
814
|
-
end
|
815
|
-
end
|
816
|
-
end
|
817
|
-
end
|
818
|
-
|
819
|
-
def setup_circle_factory
|
820
|
-
consumer = Proc.new do
|
821
|
-
unless @game_over
|
822
|
-
if @circles_data.empty?
|
823
|
-
# start with 3 circles to make more challenging
|
824
|
-
add_circle until @circles_data.size > 3
|
825
|
-
else
|
826
|
-
add_circle
|
827
|
-
end
|
828
|
-
end
|
829
|
-
delay = rand * @time_max
|
830
|
-
Glimmer::LibUI.timer(delay, repeat: false, &consumer)
|
831
|
-
end
|
832
|
-
Glimmer::LibUI.queue_main(&consumer)
|
833
|
-
end
|
834
|
-
|
835
|
-
def add_circle
|
836
|
-
circle_x = rand * (WINDOW_WIDTH - MARGIN_WIDTH - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
|
837
|
-
circle_y = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
|
838
|
-
circle_size = rand * (SHAPE_MAX_SIZE - SHAPE_MIN_SIZE) + SHAPE_MIN_SIZE
|
839
|
-
stroke_color = Glimmer::LibUI.x11_colors.sample
|
840
|
-
@circles_data << {
|
841
|
-
args: [circle_x, circle_y, circle_size],
|
842
|
-
fill: nil,
|
843
|
-
stroke: stroke_color
|
844
|
-
}
|
845
|
-
@area.queue_redraw_all
|
846
|
-
self.score -= 1 # notifies score observers automatically of change
|
847
|
-
end
|
848
|
-
|
849
|
-
def restart_game
|
850
|
-
@score = 0 # update variable directly to avoid notifying observers
|
851
|
-
@circles_data.clear
|
852
|
-
@game_over = false
|
853
|
-
end
|
854
|
-
|
855
|
-
def color_circle(x, y)
|
856
|
-
clicked_circle_data = @circles_data.find do |circle_data|
|
857
|
-
circle_data[:fill].nil? && circle_data[:circle]&.contain?(x, y)
|
858
|
-
end
|
859
|
-
if clicked_circle_data
|
860
|
-
clicked_circle_data[:fill] = clicked_circle_data[:stroke]
|
861
|
-
push_colored_circle_behind_uncolored_circles(clicked_circle_data)
|
862
|
-
@area.queue_redraw_all
|
863
|
-
self.score += 1 # notifies score observers automatically of change
|
864
|
-
end
|
865
|
-
end
|
866
|
-
|
867
|
-
def push_colored_circle_behind_uncolored_circles(colored_circle_data)
|
868
|
-
removed_colored_circle_data = @circles_data.delete(colored_circle_data)
|
869
|
-
last_colored_circle_data = @circles_data.select {|cd| cd[:fill]}.last
|
870
|
-
last_colored_circle_data_index = @circles_data.index(last_colored_circle_data) || -1
|
871
|
-
@circles_data.insert(last_colored_circle_data_index + 1, removed_colored_circle_data)
|
872
|
-
end
|
873
|
-
|
874
|
-
def launch
|
875
|
-
menu('Actions') {
|
876
|
-
menu_item('Restart') {
|
877
|
-
on_clicked do
|
878
|
-
restart_game
|
879
|
-
end
|
880
|
-
}
|
881
|
-
|
882
|
-
quit_menu_item
|
883
|
-
}
|
884
|
-
|
885
|
-
menu('Difficulty') {
|
886
|
-
radio_menu_item('Easy') {
|
887
|
-
on_clicked do
|
888
|
-
@time_max = TIME_MAX_EASY
|
889
|
-
end
|
890
|
-
}
|
891
|
-
|
892
|
-
radio_menu_item('Medium') {
|
893
|
-
on_clicked do
|
894
|
-
@time_max = TIME_MAX_MEDIUM
|
895
|
-
end
|
896
|
-
}
|
897
|
-
|
898
|
-
radio_menu_item('Hard') {
|
899
|
-
checked true
|
900
|
-
|
901
|
-
on_clicked do
|
902
|
-
@time_max = TIME_MAX_HARD
|
903
|
-
end
|
904
|
-
}
|
905
|
-
|
906
|
-
radio_menu_item('Insane') {
|
907
|
-
on_clicked do
|
908
|
-
@time_max = TIME_MAX_INSANE
|
909
|
-
end
|
910
|
-
}
|
911
|
-
}
|
912
|
-
|
913
|
-
menu('Help') {
|
914
|
-
menu_item('Instructions') {
|
915
|
-
on_clicked do
|
916
|
-
msg_box('Instructions', "Score goes down as circles are added.\nIf it reaches -20, you lose!\n\nClick circles to color and score!\nOnce score reaches 0, you win!\n\nBeware of concealed light-colored circles!\nThey are revealed once darker circles intersect them.\n\nThere are four levels of difficulty.\nChange via difficulty menu if the game gets too tough.")
|
917
|
-
end
|
918
|
-
}
|
919
|
-
}
|
920
|
-
|
921
|
-
window('Color The Circles', WINDOW_WIDTH, WINDOW_HEIGHT) {
|
922
|
-
margined true
|
923
|
-
|
924
|
-
grid {
|
925
|
-
button('Restart') {
|
926
|
-
left 0
|
927
|
-
top 0
|
928
|
-
halign :center
|
929
|
-
|
930
|
-
on_clicked do
|
931
|
-
restart_game
|
932
|
-
end
|
933
|
-
}
|
934
|
-
|
935
|
-
label('Score goes down as circles are added. If it reaches -20, you lose!') {
|
936
|
-
left 0
|
937
|
-
top 1
|
938
|
-
halign :center
|
939
|
-
}
|
940
|
-
|
941
|
-
label('Click circles to color and score! Once score reaches 0, you win!') {
|
942
|
-
left 0
|
943
|
-
top 2
|
944
|
-
halign :center
|
945
|
-
}
|
946
|
-
|
947
|
-
horizontal_box {
|
948
|
-
left 0
|
949
|
-
top 3
|
950
|
-
halign :center
|
951
|
-
|
952
|
-
label('Score:') {
|
953
|
-
stretchy false
|
954
|
-
}
|
955
|
-
|
956
|
-
@score_label = label(@score.to_s) {
|
957
|
-
stretchy false
|
958
|
-
}
|
959
|
-
}
|
960
|
-
|
961
|
-
@area = area {
|
962
|
-
left 0
|
963
|
-
top 4
|
964
|
-
hexpand true
|
965
|
-
vexpand true
|
966
|
-
halign :fill
|
967
|
-
valign :fill
|
968
|
-
|
969
|
-
on_draw do |area_draw_params|
|
970
|
-
path {
|
971
|
-
rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
|
972
|
-
|
973
|
-
fill :white
|
974
|
-
}
|
975
|
-
|
976
|
-
@circles_data.each do |circle_data|
|
977
|
-
circle_data[:circle] = circle(*circle_data[:args]) {
|
978
|
-
fill circle_data[:fill]
|
979
|
-
stroke circle_data[:stroke]
|
980
|
-
}
|
981
|
-
end
|
982
|
-
end
|
983
|
-
|
984
|
-
on_mouse_down do |area_mouse_event|
|
985
|
-
color_circle(area_mouse_event[:x], area_mouse_event[:y])
|
986
|
-
end
|
987
|
-
}
|
988
|
-
}
|
989
|
-
}.show
|
990
|
-
end
|
991
|
-
end
|
992
|
-
|
993
|
-
ColorTheCircles.new.launch
|
994
|
-
```
|
995
|
-
|
996
|
-
## Control Gallery
|
997
|
-
|
998
|
-
[examples/control_gallery.rb](/examples/control_gallery.rb)
|
999
|
-
|
1000
|
-
Run with this command from the root of the project if you cloned the project:
|
1001
|
-
|
1002
|
-
```
|
1003
|
-
ruby -r './lib/glimmer-dsl-libui' examples/control_gallery.rb
|
1004
|
-
```
|
1005
|
-
|
1006
|
-
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
1007
|
-
|
1008
|
-
```
|
1009
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/control_gallery'"
|
1010
|
-
```
|
1011
|
-
|
1012
|
-
Mac | Windows | Linux
|
1013
|
-
----|---------|------
|
1014
|
-
 |  | 
|
1015
|
-
|
1016
|
-
[LibUI](https://github.com/kojix2/LibUI) Original Version:
|
1017
|
-
|
1018
|
-
```ruby
|
1019
|
-
require 'libui'
|
1020
|
-
UI = LibUI
|
1021
|
-
|
1022
|
-
UI.init
|
1023
|
-
|
1024
|
-
should_quit = proc do
|
1025
|
-
puts 'Bye Bye'
|
1026
|
-
UI.control_destroy(MAIN_WINDOW)
|
1027
|
-
UI.quit
|
1028
|
-
0
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
# File menu
|
1032
|
-
menu = UI.new_menu('File')
|
1033
|
-
open_menu_item = UI.menu_append_item(menu, 'Open')
|
1034
|
-
UI.menu_item_on_clicked(open_menu_item) do
|
1035
|
-
pt = UI.open_file(MAIN_WINDOW)
|
1036
|
-
puts pt unless pt.null?
|
1037
|
-
end
|
1038
|
-
save_menu_item = UI.menu_append_item(menu, 'Save')
|
1039
|
-
UI.menu_item_on_clicked(save_menu_item) do
|
1040
|
-
pt = UI.save_file(MAIN_WINDOW)
|
1041
|
-
puts pt unless pt.null?
|
1042
|
-
end
|
1043
|
-
|
1044
|
-
UI.menu_append_quit_item(menu)
|
1045
|
-
UI.on_should_quit(should_quit)
|
1046
|
-
|
1047
|
-
# Edit menu
|
1048
|
-
edit_menu = UI.new_menu('Edit')
|
1049
|
-
UI.menu_append_check_item(edit_menu, 'Checkable Item_')
|
1050
|
-
UI.menu_append_separator(edit_menu)
|
1051
|
-
disabled_item = UI.menu_append_item(edit_menu, 'Disabled Item_')
|
1052
|
-
UI.menu_item_disable(disabled_item)
|
1053
|
-
|
1054
|
-
preferences = UI.menu_append_preferences_item(menu)
|
1055
|
-
|
1056
|
-
# Help menu
|
1057
|
-
help_menu = UI.new_menu('Help')
|
1058
|
-
UI.menu_append_item(help_menu, 'Help')
|
1059
|
-
UI.menu_append_about_item(help_menu)
|
1060
|
-
|
1061
|
-
# Main Window
|
1062
|
-
MAIN_WINDOW = UI.new_window('Control Gallery', 600, 500, 1)
|
1063
|
-
UI.window_set_margined(MAIN_WINDOW, 1)
|
1064
|
-
UI.window_on_closing(MAIN_WINDOW, should_quit)
|
1065
|
-
|
1066
|
-
vbox = UI.new_vertical_box
|
1067
|
-
UI.window_set_child(MAIN_WINDOW, vbox)
|
1068
|
-
hbox = UI.new_horizontal_box
|
1069
|
-
UI.box_set_padded(vbox, 1)
|
1070
|
-
UI.box_set_padded(hbox, 1)
|
1071
|
-
|
1072
|
-
UI.box_append(vbox, hbox, 1)
|
1073
|
-
|
1074
|
-
# Group - Basic Controls
|
1075
|
-
group = UI.new_group('Basic Controls')
|
1076
|
-
UI.group_set_margined(group, 1)
|
1077
|
-
UI.box_append(hbox, group, 1) # OSX bug?
|
1078
|
-
|
1079
|
-
inner = UI.new_vertical_box
|
1080
|
-
UI.box_set_padded(inner, 1)
|
1081
|
-
UI.group_set_child(group, inner)
|
1082
|
-
|
1083
|
-
# Button
|
1084
|
-
button = UI.new_button('Button')
|
1085
|
-
UI.button_on_clicked(button) do
|
1086
|
-
UI.msg_box(MAIN_WINDOW, 'Information', 'You clicked the button')
|
1087
|
-
end
|
1088
|
-
UI.box_append(inner, button, 0)
|
1089
|
-
|
1090
|
-
# Checkbox
|
1091
|
-
checkbox = UI.new_checkbox('Checkbox')
|
1092
|
-
UI.checkbox_on_toggled(checkbox) do |ptr|
|
1093
|
-
checked = UI.checkbox_checked(ptr) == 1
|
1094
|
-
UI.window_set_title(MAIN_WINDOW, "Checkbox is #{checked}")
|
1095
|
-
UI.checkbox_set_text(ptr, "I am the checkbox (#{checked})")
|
1096
|
-
end
|
1097
|
-
UI.box_append(inner, checkbox, 0)
|
1098
|
-
|
1099
|
-
# Label
|
1100
|
-
UI.box_append(inner, UI.new_label('Label'), 0)
|
1101
|
-
|
1102
|
-
# Separator
|
1103
|
-
UI.box_append(inner, UI.new_horizontal_separator, 0)
|
1104
|
-
|
1105
|
-
# Date Picker
|
1106
|
-
UI.box_append(inner, UI.new_date_picker, 0)
|
1107
|
-
|
1108
|
-
# Time Picker
|
1109
|
-
UI.box_append(inner, UI.new_time_picker, 0)
|
1110
|
-
|
1111
|
-
# Date Time Picker
|
1112
|
-
UI.box_append(inner, UI.new_date_time_picker, 0)
|
1113
|
-
|
1114
|
-
# Font Button
|
1115
|
-
UI.box_append(inner, UI.new_font_button, 0)
|
1116
|
-
|
1117
|
-
# Color Button
|
1118
|
-
UI.box_append(inner, UI.new_color_button, 0)
|
1119
|
-
|
1120
|
-
inner2 = UI.new_vertical_box
|
1121
|
-
UI.box_set_padded(inner2, 1)
|
1122
|
-
UI.box_append(hbox, inner2, 1)
|
1123
|
-
|
1124
|
-
# Group - Numbers
|
1125
|
-
group = UI.new_group('Numbers')
|
1126
|
-
UI.group_set_margined(group, 1)
|
1127
|
-
UI.box_append(inner2, group, 0)
|
1128
|
-
|
1129
|
-
inner = UI.new_vertical_box
|
1130
|
-
UI.box_set_padded(inner, 1)
|
1131
|
-
UI.group_set_child(group, inner)
|
1132
|
-
|
1133
|
-
# Spinbox
|
1134
|
-
spinbox = UI.new_spinbox(0, 100)
|
1135
|
-
UI.spinbox_set_value(spinbox, 42)
|
1136
|
-
UI.spinbox_on_changed(spinbox) do |ptr|
|
1137
|
-
puts "New Spinbox value: #{UI.spinbox_value(ptr)}"
|
1138
|
-
end
|
1139
|
-
UI.box_append(inner, spinbox, 0)
|
1140
|
-
|
1141
|
-
# Slider
|
1142
|
-
slider = UI.new_slider(0, 100)
|
1143
|
-
UI.box_append(inner, slider, 0)
|
1144
|
-
|
1145
|
-
# Progressbar
|
1146
|
-
progressbar = UI.new_progress_bar
|
1147
|
-
UI.box_append(inner, progressbar, 0)
|
1148
|
-
|
1149
|
-
UI.slider_on_changed(slider) do |ptr|
|
1150
|
-
v = UI.slider_value(ptr)
|
1151
|
-
puts "New Slider value: #{v}"
|
1152
|
-
UI.progress_bar_set_value(progressbar, v)
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
# Group - Lists
|
1156
|
-
group = UI.new_group('Lists')
|
1157
|
-
UI.group_set_margined(group, 1)
|
1158
|
-
UI.box_append(inner2, group, 0)
|
1159
|
-
|
1160
|
-
inner = UI.new_vertical_box
|
1161
|
-
UI.box_set_padded(inner, 1)
|
1162
|
-
UI.group_set_child(group, inner)
|
1163
|
-
|
1164
|
-
# Combobox
|
1165
|
-
cbox = UI.new_combobox
|
1166
|
-
UI.combobox_append(cbox, 'combobox Item 1')
|
1167
|
-
UI.combobox_append(cbox, 'combobox Item 2')
|
1168
|
-
UI.combobox_append(cbox, 'combobox Item 3')
|
1169
|
-
UI.box_append(inner, cbox, 0)
|
1170
|
-
UI.combobox_on_selected(cbox) do |ptr|
|
1171
|
-
puts "New combobox selection: #{UI.combobox_selected(ptr)}"
|
1172
|
-
end
|
1173
|
-
|
1174
|
-
# Editable Combobox
|
1175
|
-
ebox = UI.new_editable_combobox
|
1176
|
-
UI.editable_combobox_append(ebox, 'Editable Item 1')
|
1177
|
-
UI.editable_combobox_append(ebox, 'Editable Item 2')
|
1178
|
-
UI.editable_combobox_append(ebox, 'Editable Item 3')
|
1179
|
-
UI.box_append(inner, ebox, 0)
|
1180
|
-
|
1181
|
-
# Radio Buttons
|
1182
|
-
rb = UI.new_radio_buttons
|
1183
|
-
UI.radio_buttons_append(rb, 'Radio Button 1')
|
1184
|
-
UI.radio_buttons_append(rb, 'Radio Button 2')
|
1185
|
-
UI.radio_buttons_append(rb, 'Radio Button 3')
|
1186
|
-
UI.box_append(inner, rb, 1)
|
1187
|
-
|
1188
|
-
# Tab
|
1189
|
-
tab = UI.new_tab
|
1190
|
-
hbox1 = UI.new_horizontal_box
|
1191
|
-
hbox2 = UI.new_horizontal_box
|
1192
|
-
UI.tab_append(tab, 'Page 1', hbox1)
|
1193
|
-
UI.tab_append(tab, 'Page 2', hbox2)
|
1194
|
-
UI.tab_append(tab, 'Page 3', UI.new_horizontal_box)
|
1195
|
-
UI.box_append(inner2, tab, 1)
|
1196
|
-
|
1197
|
-
# Text Entry
|
1198
|
-
text_entry = UI.new_entry
|
1199
|
-
UI.entry_set_text text_entry, 'Please enter your feelings'
|
1200
|
-
UI.entry_on_changed(text_entry) do |ptr|
|
1201
|
-
puts "Current textbox data: '#{UI.entry_text(ptr)}'"
|
1202
|
-
end
|
1203
|
-
UI.box_append(hbox1, text_entry, 1)
|
1204
|
-
|
1205
|
-
UI.control_show(MAIN_WINDOW)
|
1206
|
-
|
1207
|
-
UI.main
|
1208
|
-
UI.quit
|
1209
|
-
```
|
1210
|
-
|
1211
|
-
[Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
1212
|
-
|
1213
|
-
```ruby
|
1214
|
-
require 'glimmer-dsl-libui'
|
1215
|
-
|
1216
|
-
include Glimmer
|
1217
|
-
|
1218
|
-
menu('File') {
|
1219
|
-
menu_item('Open') {
|
1220
|
-
on_clicked do
|
1221
|
-
file = open_file
|
1222
|
-
puts file unless file.nil?
|
1223
|
-
end
|
1224
|
-
}
|
1225
|
-
|
1226
|
-
menu_item('Save') {
|
1227
|
-
on_clicked do
|
1228
|
-
file = save_file
|
1229
|
-
puts file unless file.nil?
|
1230
|
-
end
|
1231
|
-
}
|
1232
|
-
|
1233
|
-
quit_menu_item {
|
1234
|
-
on_clicked do
|
1235
|
-
puts 'Bye Bye'
|
1236
|
-
end
|
1237
|
-
}
|
1238
|
-
|
1239
|
-
preferences_menu_item # Can optionally contain an on_clicked listener
|
1240
|
-
}
|
1241
|
-
|
1242
|
-
menu('Edit') {
|
1243
|
-
check_menu_item('Checkable Item_')
|
1244
|
-
separator_menu_item
|
1245
|
-
menu_item('Disabled Item_') {
|
1246
|
-
enabled false
|
1247
|
-
}
|
1248
|
-
}
|
1249
|
-
|
1250
|
-
menu('Help') {
|
1251
|
-
menu_item('Help')
|
1252
|
-
|
1253
|
-
about_menu_item # Can optionally contain an on_clicked listener
|
1254
|
-
}
|
1255
|
-
|
1256
|
-
MAIN_WINDOW = window('Control Gallery', 600, 500) {
|
1257
|
-
margined true
|
1258
|
-
|
1259
|
-
on_closing do
|
1260
|
-
puts 'Bye Bye'
|
1261
|
-
end
|
1262
|
-
|
1263
|
-
vertical_box {
|
1264
|
-
horizontal_box {
|
1265
|
-
group('Basic Controls') {
|
1266
|
-
vertical_box {
|
1267
|
-
button('Button') {
|
1268
|
-
stretchy false
|
1269
|
-
|
1270
|
-
on_clicked do
|
1271
|
-
msg_box('Information', 'You clicked the button')
|
1272
|
-
end
|
1273
|
-
}
|
1274
|
-
|
1275
|
-
checkbox('Checkbox') {
|
1276
|
-
stretchy false
|
1277
|
-
|
1278
|
-
on_toggled do |c|
|
1279
|
-
checked = c.checked?
|
1280
|
-
MAIN_WINDOW.title = "Checkbox is #{checked}"
|
1281
|
-
c.text = "I am the checkbox (#{checked})"
|
1282
|
-
end
|
1283
|
-
}
|
1284
|
-
|
1285
|
-
label('Label') { stretchy false }
|
1286
|
-
|
1287
|
-
horizontal_separator { stretchy false }
|
1288
|
-
|
1289
|
-
date_picker { stretchy false }
|
1290
|
-
|
1291
|
-
time_picker { stretchy false }
|
1292
|
-
|
1293
|
-
date_time_picker { stretchy false }
|
1294
|
-
|
1295
|
-
font_button { stretchy false }
|
1296
|
-
|
1297
|
-
color_button { stretchy false }
|
1298
|
-
}
|
1299
|
-
}
|
1300
|
-
|
1301
|
-
vertical_box {
|
1302
|
-
group('Numbers') {
|
1303
|
-
stretchy false
|
1304
|
-
|
1305
|
-
vertical_box {
|
1306
|
-
spinbox(0, 100) {
|
1307
|
-
stretchy false
|
1308
|
-
value 42
|
1309
|
-
|
1310
|
-
on_changed do |s|
|
1311
|
-
puts "New Spinbox value: #{s.value}"
|
1312
|
-
end
|
1313
|
-
}
|
1314
|
-
|
1315
|
-
slider(0, 100) {
|
1316
|
-
stretchy false
|
1317
|
-
|
1318
|
-
on_changed do |s|
|
1319
|
-
v = s.value
|
1320
|
-
puts "New Slider value: #{v}"
|
1321
|
-
@progress_bar.value = v
|
1322
|
-
end
|
1323
|
-
}
|
1324
|
-
|
1325
|
-
@progress_bar = progress_bar { stretchy false }
|
1326
|
-
}
|
1327
|
-
}
|
1328
|
-
|
1329
|
-
group('Lists') {
|
1330
|
-
stretchy false
|
1331
|
-
|
1332
|
-
vertical_box {
|
1333
|
-
combobox {
|
1334
|
-
stretchy false
|
1335
|
-
items 'combobox Item 1', 'combobox Item 2', 'combobox Item 3' # also accepts a single array argument
|
1336
|
-
|
1337
|
-
on_selected do |c|
|
1338
|
-
puts "New combobox selection: #{c.selected}"
|
1339
|
-
end
|
1340
|
-
}
|
1341
|
-
|
1342
|
-
editable_combobox {
|
1343
|
-
stretchy false
|
1344
|
-
items 'Editable Item 1', 'Editable Item 2', 'Editable Item 3' # also accepts a single array argument
|
1345
|
-
}
|
1346
|
-
|
1347
|
-
radio_buttons {
|
1348
|
-
items 'Radio Button 1', 'Radio Button 2', 'Radio Button 3' # also accepts a single array argument
|
1349
|
-
}
|
1350
|
-
}
|
1351
|
-
}
|
1352
|
-
|
1353
|
-
tab {
|
1354
|
-
tab_item('Page 1') {
|
1355
|
-
horizontal_box {
|
1356
|
-
entry {
|
1357
|
-
text 'Please enter your feelings'
|
1358
|
-
|
1359
|
-
on_changed do |e|
|
1360
|
-
puts "Current textbox data: '#{e.text}'"
|
1361
|
-
end
|
1362
|
-
}
|
1363
|
-
}
|
1364
|
-
}
|
1365
|
-
|
1366
|
-
tab_item('Page 2') {
|
1367
|
-
horizontal_box
|
1368
|
-
}
|
1369
|
-
|
1370
|
-
tab_item('Page 3') {
|
1371
|
-
horizontal_box
|
1372
|
-
}
|
1373
|
-
}
|
1374
|
-
}
|
1375
|
-
}
|
1376
|
-
}
|
1377
|
-
}
|
1378
|
-
|
1379
|
-
MAIN_WINDOW.show
|
1380
|
-
```
|
1381
|
-
|
1382
|
-
## CPU Percentage
|
1383
|
-
|
1384
|
-
This example shows CPU usage percentage second by second.
|
1385
|
-
|
1386
|
-
Note that it is highly dependent on low-level OS terminal commands, so if anything changes in their output formatting, the code could break. Please report any issues you might encounter.
|
1387
|
-
|
1388
|
-
[examples/cpu_percentage.rb](/examples/cpu_percentage.rb)
|
1389
|
-
|
1390
|
-
Run with this command from the root of the project if you cloned the project:
|
1391
|
-
|
1392
|
-
```
|
1393
|
-
ruby -r './lib/glimmer-dsl-libui' examples/cpu_percentage.rb
|
1394
|
-
```
|
1395
|
-
|
1396
|
-
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
1397
|
-
|
1398
|
-
```
|
1399
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/cpu_percentage'"
|
1400
|
-
```
|
1401
|
-
|
1402
|
-
Mac | Windows | Linux
|
1403
|
-
----|---------|------
|
1404
|
-
 |  | 
|
1405
|
-
|
1406
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
1407
|
-
|
1408
|
-
```ruby
|
1409
|
-
require 'glimmer-dsl-libui'
|
1410
|
-
require 'bigdecimal'
|
1411
|
-
|
1412
|
-
include Glimmer
|
1413
|
-
|
1414
|
-
data = [
|
1415
|
-
['CPU', '0%', 0],
|
1416
|
-
]
|
1417
|
-
|
1418
|
-
Glimmer::LibUI.timer(1) do
|
1419
|
-
cpu_percentage_value = nil
|
1420
|
-
if OS.windows?
|
1421
|
-
cpu_percentage_raw_value = `wmic cpu get loadpercentage`
|
1422
|
-
cpu_percentage_value = cpu_percentage_raw_value.split("\n").map(&:strip).find {|l| l.match(/^\d+$/)}.to_i
|
1423
|
-
elsif OS.mac?
|
1424
|
-
cpu_percentage_value = `ps -A -o %cpu | awk '{s+=$1} END {print s}'`.to_i
|
1425
|
-
elsif OS.linux?
|
1426
|
-
stats = `top -n 1`
|
1427
|
-
idle_percentage = stats.split("\n")[2].match(/ni,.* (.*) .*id/)[1]
|
1428
|
-
cpu_percentage_value = (BigDecimal(100) - BigDecimal(idle_percentage)).to_i
|
1429
|
-
end
|
1430
|
-
data[0][1] = "#{cpu_percentage_value}%"
|
1431
|
-
data[0][2] = cpu_percentage_value
|
1432
|
-
end
|
1433
|
-
|
1434
|
-
window('CPU Percentage', 400, 50) {
|
1435
|
-
vertical_box {
|
1436
|
-
table {
|
1437
|
-
text_column('Name')
|
1438
|
-
text_column('Value')
|
1439
|
-
progress_bar_column('Percentage')
|
1440
|
-
|
1441
|
-
cell_rows data # implicit data-binding
|
1442
|
-
}
|
1443
|
-
}
|
1444
|
-
}.show
|
1445
|
-
```
|
1446
|
-
|
1447
|
-
## Custom Draw Text
|
1448
|
-
|
1449
|
-
[examples/custom_draw_text.rb](/examples/custom_draw_text.rb)
|
1450
|
-
|
1451
|
-
Run with this command from the root of the project if you cloned the project:
|
1452
|
-
|
1453
|
-
```
|
1454
|
-
ruby -r './lib/glimmer-dsl-libui' examples/custom_draw_text.rb
|
1455
|
-
```
|
1456
|
-
|
1457
|
-
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
1458
|
-
|
1459
|
-
```
|
1460
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/custom_draw_text'"
|
1461
|
-
```
|
1462
|
-
|
1463
|
-
Mac | Windows | Linux
|
1464
|
-
----|---------|------
|
1465
|
-
  |   |  
|
1466
|
-
|
1467
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
1468
|
-
|
1469
|
-
```ruby
|
1470
|
-
require 'glimmer-dsl-libui'
|
1471
|
-
|
1472
|
-
# Michael Ende (1929-1995)
|
1473
|
-
# The Neverending Story is a fantasy novel by German writer Michael Ende,
|
1474
|
-
# The English version, translated by Ralph Manheim, was published in 1983.
|
1475
|
-
class CustomDrawText
|
1476
|
-
include Glimmer
|
1477
|
-
|
1478
|
-
def launch
|
1479
|
-
window('Michael Ende (1929-1995) The Neverending Story', 600, 500) {
|
1480
|
-
margined true
|
1481
|
-
|
1482
|
-
vertical_box {
|
1483
|
-
form {
|
1484
|
-
stretchy false
|
1485
|
-
|
1486
|
-
font_button { |fb|
|
1487
|
-
label 'Font'
|
1488
|
-
|
1489
|
-
on_changed do
|
1490
|
-
@string.font = fb.font
|
1491
|
-
end
|
1492
|
-
}
|
1493
|
-
|
1494
|
-
color_button { |cb|
|
1495
|
-
label 'Color'
|
1496
|
-
|
1497
|
-
on_changed do
|
1498
|
-
@string.color = cb.color
|
1499
|
-
end
|
1500
|
-
}
|
1501
|
-
|
1502
|
-
unless OS.windows?
|
1503
|
-
color_button { |cb|
|
1504
|
-
label 'Background'
|
1505
|
-
|
1506
|
-
on_changed do
|
1507
|
-
@string.background = cb.color
|
1508
|
-
end
|
1509
|
-
}
|
1510
|
-
end
|
1511
|
-
|
1512
|
-
combobox { |c|
|
1513
|
-
label 'Underline'
|
1514
|
-
items Glimmer::LibUI.enum_symbols(:underline).map(&:to_s).map {|word| word.split('_').map(&:capitalize).join(' ')}
|
1515
|
-
selected 'None'
|
1516
|
-
|
1517
|
-
on_selected do
|
1518
|
-
@string.underline = c.selected_item.underscore
|
1519
|
-
end
|
1520
|
-
}
|
1521
|
-
|
1522
|
-
combobox { |c|
|
1523
|
-
label 'Underline Built-In Color'
|
1524
|
-
items Glimmer::LibUI.enum_symbols(:underline_color).map(&:to_s).map(&:capitalize)
|
1525
|
-
selected 'Custom'
|
1526
|
-
|
1527
|
-
on_selected do
|
1528
|
-
@underline_custom_color_button.enabled = c.selected_item == 'Custom'
|
1529
|
-
if c.selected_item == 'Custom'
|
1530
|
-
@string.underline_color = @underline_custom_color_button.color
|
1531
|
-
else
|
1532
|
-
@string.underline_color = c.selected_item.underscore
|
1533
|
-
@underline_custom_color_button.color = :black
|
1534
|
-
end
|
1535
|
-
end
|
1536
|
-
}
|
1537
|
-
|
1538
|
-
@underline_custom_color_button = color_button {
|
1539
|
-
label 'Underline Custom Color'
|
1540
|
-
|
1541
|
-
on_changed do
|
1542
|
-
@string.underline_color = @underline_custom_color_button.color
|
1543
|
-
end
|
1544
|
-
}
|
1545
|
-
}
|
1546
|
-
|
1547
|
-
area {
|
1548
|
-
text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width] - 2*x)
|
1549
|
-
# align :left # default alignment
|
1550
|
-
|
1551
|
-
@string = string {
|
1552
|
-
' At last Ygramul sensed that something was coming toward ' \
|
1553
|
-
'her. With the speed of lightning, she turned about, confronting ' \
|
1554
|
-
'Atreyu with an enormous steel-blue face. Her single eye had a ' \
|
1555
|
-
'vertical pupil, which stared at Atreyu with inconceivable malignancy. ' \
|
1556
|
-
"\n\n" \
|
1557
|
-
' A cry of fear escaped Bastian. ' \
|
1558
|
-
"\n\n" \
|
1559
|
-
' A cry of terror passed through the ravine and echoed from ' \
|
1560
|
-
'side to side. Ygramul turned her eye to left and right, to see if ' \
|
1561
|
-
'someone else had arrived, for that sound could not have been ' \
|
1562
|
-
'made by the boy who stood there as though paralyzed with ' \
|
1563
|
-
'horror. ' \
|
1564
|
-
"\n\n" \
|
1565
|
-
' Could she have heard my cry? Bastion wondered in alarm. ' \
|
1566
|
-
"But that's not possible. " \
|
1567
|
-
"\n\n" \
|
1568
|
-
' And then Atreyu heard Ygramuls voice. It was very high ' \
|
1569
|
-
'and slightly hoarse, not at all the right kind of voice for that ' \
|
1570
|
-
'enormous face. Her lips did not move as she spoke. It was the ' \
|
1571
|
-
'buzzing of a great swarm of hornets that shaped itself into ' \
|
1572
|
-
'words. ' \
|
1573
|
-
"\n\n"
|
1574
|
-
}
|
1575
|
-
}
|
1576
|
-
}
|
1577
|
-
}
|
1578
|
-
}.show
|
1579
|
-
end
|
1580
|
-
end
|
1581
|
-
|
1582
|
-
CustomDrawText.new.launch
|
1583
|
-
```
|
1584
|
-
|
1585
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
1586
|
-
|
1587
|
-
```ruby
|
1588
|
-
require 'glimmer-dsl-libui'
|
1589
|
-
|
1590
|
-
# Michael Ende (1929-1995)
|
1591
|
-
# The Neverending Story is a fantasy novel by German writer Michael Ende,
|
1592
|
-
# The English version, translated by Ralph Manheim, was published in 1983.
|
1593
|
-
class CustomDrawText
|
1594
|
-
include Glimmer
|
1595
|
-
|
1596
|
-
def launch
|
1597
|
-
window('Michael Ende (1929-1995) The Neverending Story', 600, 500) {
|
1598
|
-
margined true
|
1599
|
-
|
1600
|
-
vertical_box {
|
1601
|
-
form {
|
1602
|
-
stretchy false
|
1603
|
-
|
1604
|
-
font_button { |fb|
|
1605
|
-
label 'Font'
|
1606
|
-
|
1607
|
-
on_changed do
|
1608
|
-
@font = fb.font
|
1609
|
-
@area.queue_redraw_all
|
1610
|
-
end
|
1611
|
-
}
|
1612
|
-
|
1613
|
-
color_button { |cb|
|
1614
|
-
label 'Color'
|
1615
|
-
|
1616
|
-
on_changed do
|
1617
|
-
@color = cb.color
|
1618
|
-
@area.queue_redraw_all
|
1619
|
-
end
|
1620
|
-
}
|
1621
|
-
|
1622
|
-
unless OS.windows?
|
1623
|
-
color_button { |cb|
|
1624
|
-
label 'Background'
|
1625
|
-
|
1626
|
-
on_changed do
|
1627
|
-
@background = cb.color
|
1628
|
-
@area.queue_redraw_all
|
1629
|
-
end
|
1630
|
-
}
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
combobox { |c|
|
1634
|
-
label 'Underline'
|
1635
|
-
items Glimmer::LibUI.enum_symbols(:underline).map(&:to_s).map {|word| word.split('_').map(&:capitalize).join(' ')}
|
1636
|
-
selected 'None'
|
1637
|
-
|
1638
|
-
on_selected do
|
1639
|
-
@underline = c.selected_item.underscore
|
1640
|
-
@area.queue_redraw_all
|
1641
|
-
end
|
1642
|
-
}
|
1643
|
-
|
1644
|
-
combobox { |c|
|
1645
|
-
label 'Underline Built-In Color'
|
1646
|
-
items Glimmer::LibUI.enum_symbols(:underline_color).map(&:to_s).map(&:capitalize)
|
1647
|
-
selected 'Custom'
|
1648
|
-
|
1649
|
-
on_selected do
|
1650
|
-
@underline_custom_color_button.enabled = c.selected_item == 'Custom'
|
1651
|
-
if c.selected_item == 'Custom'
|
1652
|
-
@underline_color = @underline_custom_color_button.color
|
1653
|
-
else
|
1654
|
-
@underline_color = c.selected_item.underscore
|
1655
|
-
@underline_custom_color_button.color = :black
|
1656
|
-
end
|
1657
|
-
@area.queue_redraw_all
|
1658
|
-
end
|
1659
|
-
}
|
1660
|
-
|
1661
|
-
@underline_custom_color_button = color_button {
|
1662
|
-
label 'Underline Custom Color'
|
1663
|
-
|
1664
|
-
on_changed do
|
1665
|
-
@underline_color = @underline_custom_color_button.color
|
1666
|
-
@area.queue_redraw_all
|
1667
|
-
end
|
1668
|
-
}
|
1669
|
-
}
|
1670
|
-
|
1671
|
-
@area = area {
|
1672
|
-
on_draw do |area_draw_params|
|
1673
|
-
text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width] - 2*x)
|
1674
|
-
# align :left # default alignment
|
1675
|
-
|
1676
|
-
string {
|
1677
|
-
font @font
|
1678
|
-
color @color
|
1679
|
-
background @background
|
1680
|
-
underline @underline
|
1681
|
-
underline_color @underline_color
|
1682
|
-
|
1683
|
-
' At last Ygramul sensed that something was coming toward ' \
|
1684
|
-
'her. With the speed of lightning, she turned about, confronting ' \
|
1685
|
-
'Atreyu with an enormous steel-blue face. Her single eye had a ' \
|
1686
|
-
'vertical pupil, which stared at Atreyu with inconceivable malignancy. ' \
|
1687
|
-
"\n\n" \
|
1688
|
-
' A cry of fear escaped Bastian. ' \
|
1689
|
-
"\n\n" \
|
1690
|
-
' A cry of terror passed through the ravine and echoed from ' \
|
1691
|
-
'side to side. Ygramul turned her eye to left and right, to see if ' \
|
1692
|
-
'someone else had arrived, for that sound could not have been ' \
|
1693
|
-
'made by the boy who stood there as though paralyzed with ' \
|
1694
|
-
'horror. ' \
|
1695
|
-
"\n\n" \
|
1696
|
-
' Could she have heard my cry? Bastion wondered in alarm. ' \
|
1697
|
-
"But that's not possible. " \
|
1698
|
-
"\n\n" \
|
1699
|
-
' And then Atreyu heard Ygramuls voice. It was very high ' \
|
1700
|
-
'and slightly hoarse, not at all the right kind of voice for that ' \
|
1701
|
-
'enormous face. Her lips did not move as she spoke. It was the ' \
|
1702
|
-
'buzzing of a great swarm of hornets that shaped itself into ' \
|
1703
|
-
'words. ' \
|
1704
|
-
"\n\n"
|
1705
|
-
}
|
1706
|
-
}
|
1707
|
-
end
|
1708
|
-
}
|
1709
|
-
}
|
1710
|
-
}.show
|
1711
|
-
end
|
1712
|
-
end
|
1713
|
-
|
1714
|
-
CustomDrawText.new.launch
|
1715
|
-
```
|
49
|
+
Version 1:
|
1716
50
|
|
1717
|
-
|
51
|
+
[examples/area_gallery.rb](/examples/area_gallery.rb)
|
1718
52
|
|
1719
|
-
|
53
|
+
Version 2 (setting shape properties instead of arguments):
|
1720
54
|
|
1721
|
-
|
55
|
+
[examples/area_gallery2.rb](/examples/area_gallery2.rb)
|
1722
56
|
|
1723
|
-
|
1724
|
-
ruby -r './lib/glimmer-dsl-libui' examples/dynamic_area.rb
|
1725
|
-
```
|
57
|
+
Version 3 (semi-declarative `on_draw` dynamic `path` approach):
|
1726
58
|
|
1727
|
-
|
59
|
+
[examples/area_gallery3.rb](/examples/area_gallery3.rb)
|
1728
60
|
|
1729
|
-
|
1730
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/dynamic_area'"
|
1731
|
-
```
|
61
|
+
Version 4 (setting shape properties instead of arguments with semi-declarative `on_draw` dynamic `path` approach):
|
1732
62
|
|
1733
|
-
|
1734
|
-
----|---------|------
|
1735
|
-
  |   |  
|
63
|
+
[examples/area_gallery4.rb](/examples/area_gallery4.rb)
|
1736
64
|
|
1737
|
-
|
65
|
+
## Button Counter
|
1738
66
|
|
1739
|
-
|
1740
|
-
require 'glimmer-dsl-libui'
|
67
|
+
[examples/button_counter.rb](/examples/button_counter.rb)
|
1741
68
|
|
1742
|
-
|
1743
|
-
include Glimmer
|
1744
|
-
|
1745
|
-
attr_accessor :rectangle_x, :rectangle_y, :rectangle_width, :rectangle_height, :rectangle_red, :rectangle_green, :rectangle_blue, :rectangle_alpha
|
1746
|
-
|
1747
|
-
def initialize
|
1748
|
-
@rectangle_x = 25
|
1749
|
-
@rectangle_y = 25
|
1750
|
-
@rectangle_width = 150
|
1751
|
-
@rectangle_height = 150
|
1752
|
-
@rectangle_red = 102
|
1753
|
-
@rectangle_green = 102
|
1754
|
-
@rectangle_blue = 204
|
1755
|
-
@rectangle_alpha = 100
|
1756
|
-
end
|
1757
|
-
|
1758
|
-
def launch
|
1759
|
-
window('Dynamic Area', 240, 600) {
|
1760
|
-
margined true
|
1761
|
-
|
1762
|
-
vertical_box {
|
1763
|
-
label('Rectangle Properties') {
|
1764
|
-
stretchy false
|
1765
|
-
}
|
1766
|
-
|
1767
|
-
form {
|
1768
|
-
stretchy false
|
1769
|
-
|
1770
|
-
spinbox(0, 1000) {
|
1771
|
-
label 'x'
|
1772
|
-
value <=> [self, :rectangle_x, after_write: -> {@area.queue_redraw_all}]
|
1773
|
-
}
|
1774
|
-
|
1775
|
-
spinbox(0, 1000) {
|
1776
|
-
label 'y'
|
1777
|
-
value <=> [self, :rectangle_y, after_write: -> {@area.queue_redraw_all}]
|
1778
|
-
}
|
1779
|
-
|
1780
|
-
spinbox(0, 1000) {
|
1781
|
-
label 'width'
|
1782
|
-
value <=> [self, :rectangle_width, after_write: -> {@area.queue_redraw_all}]
|
1783
|
-
}
|
1784
|
-
|
1785
|
-
spinbox(0, 1000) {
|
1786
|
-
label 'height'
|
1787
|
-
value <=> [self, :rectangle_height, after_write: -> {@area.queue_redraw_all}]
|
1788
|
-
}
|
1789
|
-
|
1790
|
-
spinbox(0, 255) {
|
1791
|
-
label 'red'
|
1792
|
-
value <=> [self, :rectangle_red, after_write: -> {@area.queue_redraw_all}]
|
1793
|
-
}
|
1794
|
-
|
1795
|
-
spinbox(0, 255) {
|
1796
|
-
label 'green'
|
1797
|
-
value <=> [self, :rectangle_green, after_write: -> {@area.queue_redraw_all}]
|
1798
|
-
}
|
1799
|
-
|
1800
|
-
spinbox(0, 255) {
|
1801
|
-
label 'blue'
|
1802
|
-
value <=> [self, :rectangle_blue, after_write: -> {@area.queue_redraw_all}]
|
1803
|
-
}
|
1804
|
-
|
1805
|
-
spinbox(0, 100) {
|
1806
|
-
label 'alpha'
|
1807
|
-
value <=> [self, :rectangle_alpha, after_write: -> {@area.queue_redraw_all}]
|
1808
|
-
}
|
1809
|
-
}
|
1810
|
-
|
1811
|
-
@area = area {
|
1812
|
-
on_draw do |area_draw_params|
|
1813
|
-
rectangle(rectangle_x, rectangle_y, rectangle_width, rectangle_height) { # a dynamic path is added semi-declaratively inside on_draw block
|
1814
|
-
fill r: rectangle_red, g: rectangle_green, b: rectangle_blue, a: rectangle_alpha / 100.0
|
1815
|
-
}
|
1816
|
-
end
|
1817
|
-
}
|
1818
|
-
}
|
1819
|
-
}.show
|
1820
|
-
end
|
1821
|
-
end
|
69
|
+
Run with this command from the root of the project if you cloned the project:
|
1822
70
|
|
1823
|
-
DynamicArea.new.launch
|
1824
71
|
```
|
1825
|
-
|
1826
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (without [data-binding](#data-binding)):
|
1827
|
-
|
1828
|
-
```ruby
|
1829
|
-
require 'glimmer-dsl-libui'
|
1830
|
-
|
1831
|
-
include Glimmer
|
1832
|
-
|
1833
|
-
window('Dynamic Area', 240, 600) {
|
1834
|
-
margined true
|
1835
|
-
|
1836
|
-
vertical_box {
|
1837
|
-
label('Rectangle Properties') {
|
1838
|
-
stretchy false
|
1839
|
-
}
|
1840
|
-
|
1841
|
-
form {
|
1842
|
-
stretchy false
|
1843
|
-
|
1844
|
-
@x_spinbox = spinbox(0, 1000) {
|
1845
|
-
label 'x'
|
1846
|
-
value 25
|
1847
|
-
|
1848
|
-
on_changed do
|
1849
|
-
@area.queue_redraw_all
|
1850
|
-
end
|
1851
|
-
}
|
1852
|
-
|
1853
|
-
@y_spinbox = spinbox(0, 1000) {
|
1854
|
-
label 'y'
|
1855
|
-
value 25
|
1856
|
-
|
1857
|
-
on_changed do
|
1858
|
-
@area.queue_redraw_all
|
1859
|
-
end
|
1860
|
-
}
|
1861
|
-
|
1862
|
-
@width_spinbox = spinbox(0, 1000) {
|
1863
|
-
label 'width'
|
1864
|
-
value 150
|
1865
|
-
|
1866
|
-
on_changed do
|
1867
|
-
@area.queue_redraw_all
|
1868
|
-
end
|
1869
|
-
}
|
1870
|
-
|
1871
|
-
@height_spinbox = spinbox(0, 1000) {
|
1872
|
-
label 'height'
|
1873
|
-
value 150
|
1874
|
-
|
1875
|
-
on_changed do
|
1876
|
-
@area.queue_redraw_all
|
1877
|
-
end
|
1878
|
-
}
|
1879
|
-
|
1880
|
-
@red_spinbox = spinbox(0, 255) {
|
1881
|
-
label 'red'
|
1882
|
-
value 102
|
1883
|
-
|
1884
|
-
on_changed do
|
1885
|
-
@area.queue_redraw_all
|
1886
|
-
end
|
1887
|
-
}
|
1888
|
-
|
1889
|
-
@green_spinbox = spinbox(0, 255) {
|
1890
|
-
label 'green'
|
1891
|
-
value 102
|
1892
|
-
|
1893
|
-
on_changed do
|
1894
|
-
@area.queue_redraw_all
|
1895
|
-
end
|
1896
|
-
}
|
1897
|
-
|
1898
|
-
@blue_spinbox = spinbox(0, 255) {
|
1899
|
-
label 'blue'
|
1900
|
-
value 204
|
1901
|
-
|
1902
|
-
on_changed do
|
1903
|
-
@area.queue_redraw_all
|
1904
|
-
end
|
1905
|
-
}
|
1906
|
-
|
1907
|
-
@alpha_spinbox = spinbox(0, 100) {
|
1908
|
-
label 'alpha'
|
1909
|
-
value 100
|
1910
|
-
|
1911
|
-
on_changed do
|
1912
|
-
@area.queue_redraw_all
|
1913
|
-
end
|
1914
|
-
}
|
1915
|
-
}
|
1916
|
-
|
1917
|
-
@area = area {
|
1918
|
-
on_draw do |area_draw_params|
|
1919
|
-
rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value) { # a dynamic path is added semi-declaratively inside on_draw block
|
1920
|
-
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
1921
|
-
}
|
1922
|
-
end
|
1923
|
-
}
|
1924
|
-
}
|
1925
|
-
}.show
|
72
|
+
ruby -r './lib/glimmer-dsl-libui' examples/button_counter.rb
|
1926
73
|
```
|
1927
74
|
|
1928
|
-
|
1929
|
-
|
1930
|
-
```ruby
|
1931
|
-
require 'glimmer-dsl-libui'
|
1932
|
-
|
1933
|
-
class DynamicArea
|
1934
|
-
include Glimmer
|
1935
|
-
|
1936
|
-
attr_accessor :rectangle_x, :rectangle_y, :rectangle_width, :rectangle_height, :rectangle_red, :rectangle_green, :rectangle_blue, :rectangle_alpha
|
1937
|
-
|
1938
|
-
def initialize
|
1939
|
-
@rectangle_x = 25
|
1940
|
-
@rectangle_y = 25
|
1941
|
-
@rectangle_width = 150
|
1942
|
-
@rectangle_height = 150
|
1943
|
-
@rectangle_red = 102
|
1944
|
-
@rectangle_green = 102
|
1945
|
-
@rectangle_blue = 204
|
1946
|
-
@rectangle_alpha = 100
|
1947
|
-
end
|
1948
|
-
|
1949
|
-
def rectangle_fill
|
1950
|
-
{ r: rectangle_red, g: rectangle_green, b: rectangle_blue, a: rectangle_alpha / 100.0 }
|
1951
|
-
end
|
1952
|
-
|
1953
|
-
def launch
|
1954
|
-
window('Dynamic Area', 240, 600) {
|
1955
|
-
margined true
|
1956
|
-
|
1957
|
-
vertical_box {
|
1958
|
-
label('Rectangle Properties') {
|
1959
|
-
stretchy false
|
1960
|
-
}
|
1961
|
-
|
1962
|
-
form {
|
1963
|
-
stretchy false
|
1964
|
-
|
1965
|
-
@x_spinbox = spinbox(0, 1000) {
|
1966
|
-
label 'x'
|
1967
|
-
value <=> [self, :rectangle_x]
|
1968
|
-
}
|
1969
|
-
|
1970
|
-
@y_spinbox = spinbox(0, 1000) {
|
1971
|
-
label 'y'
|
1972
|
-
value <=> [self, :rectangle_y]
|
1973
|
-
}
|
1974
|
-
|
1975
|
-
@width_spinbox = spinbox(0, 1000) {
|
1976
|
-
label 'width'
|
1977
|
-
value <=> [self, :rectangle_width]
|
1978
|
-
}
|
1979
|
-
|
1980
|
-
@height_spinbox = spinbox(0, 1000) {
|
1981
|
-
label 'height'
|
1982
|
-
value <=> [self, :rectangle_height]
|
1983
|
-
}
|
1984
|
-
|
1985
|
-
@red_spinbox = spinbox(0, 255) {
|
1986
|
-
label 'red'
|
1987
|
-
value <=> [self, :rectangle_red]
|
1988
|
-
}
|
1989
|
-
|
1990
|
-
@green_spinbox = spinbox(0, 255) {
|
1991
|
-
label 'green'
|
1992
|
-
value <=> [self, :rectangle_green]
|
1993
|
-
}
|
1994
|
-
|
1995
|
-
@blue_spinbox = spinbox(0, 255) {
|
1996
|
-
label 'blue'
|
1997
|
-
value <=> [self, :rectangle_blue]
|
1998
|
-
}
|
1999
|
-
|
2000
|
-
@alpha_spinbox = spinbox(0, 100) {
|
2001
|
-
label 'alpha'
|
2002
|
-
value <=> [self, :rectangle_alpha]
|
2003
|
-
}
|
2004
|
-
}
|
2005
|
-
|
2006
|
-
area {
|
2007
|
-
@rectangle = rectangle { # stable implicit path shape
|
2008
|
-
x <= [self, :rectangle_x]
|
2009
|
-
y <= [self, :rectangle_y]
|
2010
|
-
width <= [self, :rectangle_width]
|
2011
|
-
height <= [self, :rectangle_height]
|
2012
|
-
fill <= [self, :rectangle_fill, computed_by: [:rectangle_red, :rectangle_green, :rectangle_blue, :rectangle_alpha]]
|
2013
|
-
}
|
2014
|
-
}
|
2015
|
-
}
|
2016
|
-
}.show
|
2017
|
-
end
|
2018
|
-
end
|
75
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2019
76
|
|
2020
|
-
DynamicArea.new.launch
|
2021
77
|
```
|
2022
|
-
|
2023
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 4 (declarative stable `path` approach without [data-binding](#data-binding)):
|
2024
|
-
|
2025
|
-
```ruby
|
2026
|
-
require 'glimmer-dsl-libui'
|
2027
|
-
|
2028
|
-
include Glimmer
|
2029
|
-
|
2030
|
-
window('Dynamic Area', 240, 600) {
|
2031
|
-
margined true
|
2032
|
-
|
2033
|
-
vertical_box {
|
2034
|
-
label('Rectangle Properties') {
|
2035
|
-
stretchy false
|
2036
|
-
}
|
2037
|
-
|
2038
|
-
form {
|
2039
|
-
stretchy false
|
2040
|
-
|
2041
|
-
@x_spinbox = spinbox(0, 1000) {
|
2042
|
-
label 'x'
|
2043
|
-
value 25
|
2044
|
-
|
2045
|
-
on_changed do
|
2046
|
-
@rectangle.x = @x_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2047
|
-
end
|
2048
|
-
}
|
2049
|
-
|
2050
|
-
@y_spinbox = spinbox(0, 1000) {
|
2051
|
-
label 'y'
|
2052
|
-
value 25
|
2053
|
-
|
2054
|
-
on_changed do
|
2055
|
-
@rectangle.y = @y_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2056
|
-
end
|
2057
|
-
}
|
2058
|
-
|
2059
|
-
@width_spinbox = spinbox(0, 1000) {
|
2060
|
-
label 'width'
|
2061
|
-
value 150
|
2062
|
-
|
2063
|
-
on_changed do
|
2064
|
-
@rectangle.width = @width_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2065
|
-
end
|
2066
|
-
}
|
2067
|
-
|
2068
|
-
@height_spinbox = spinbox(0, 1000) {
|
2069
|
-
label 'height'
|
2070
|
-
value 150
|
2071
|
-
|
2072
|
-
on_changed do
|
2073
|
-
@rectangle.height = @height_spinbox.value # updating properties automatically triggers area.queue_redraw_all
|
2074
|
-
end
|
2075
|
-
}
|
2076
|
-
|
2077
|
-
@red_spinbox = spinbox(0, 255) {
|
2078
|
-
label 'red'
|
2079
|
-
value 102
|
2080
|
-
|
2081
|
-
on_changed do
|
2082
|
-
@rectangle.fill[:r] = @red_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2083
|
-
end
|
2084
|
-
}
|
2085
|
-
|
2086
|
-
@green_spinbox = spinbox(0, 255) {
|
2087
|
-
label 'green'
|
2088
|
-
value 102
|
2089
|
-
|
2090
|
-
on_changed do
|
2091
|
-
@rectangle.fill[:g] = @green_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2092
|
-
end
|
2093
|
-
}
|
2094
|
-
|
2095
|
-
@blue_spinbox = spinbox(0, 255) {
|
2096
|
-
label 'blue'
|
2097
|
-
value 204
|
2098
|
-
|
2099
|
-
on_changed do
|
2100
|
-
@rectangle.fill[:b] = @blue_spinbox.value # updating hash properties automatically triggers area.queue_redraw_all
|
2101
|
-
end
|
2102
|
-
}
|
2103
|
-
|
2104
|
-
@alpha_spinbox = spinbox(0, 100) {
|
2105
|
-
label 'alpha'
|
2106
|
-
value 100
|
2107
|
-
|
2108
|
-
on_changed do
|
2109
|
-
@rectangle.fill[:a] = @alpha_spinbox.value / 100.0 # updating hash properties automatically triggers area.queue_redraw_all
|
2110
|
-
end
|
2111
|
-
}
|
2112
|
-
}
|
2113
|
-
|
2114
|
-
area {
|
2115
|
-
@rectangle = rectangle(@x_spinbox.value, @y_spinbox.value, @width_spinbox.value, @height_spinbox.value) { # stable implicit path shape
|
2116
|
-
fill r: @red_spinbox.value, g: @green_spinbox.value, b: @blue_spinbox.value, a: @alpha_spinbox.value / 100.0
|
2117
|
-
}
|
2118
|
-
}
|
2119
|
-
}
|
2120
|
-
}.show
|
78
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/button_counter'"
|
2121
79
|
```
|
2122
80
|
|
2123
|
-
|
81
|
+
Mac | Windows | Linux
|
82
|
+
----|---------|------
|
83
|
+
 |  | 
|
84
|
+
|
85
|
+
## Color The Circles
|
2124
86
|
|
2125
|
-
[examples/
|
87
|
+
[examples/color_the_circles.rb](/examples/color_the_circles.rb)
|
2126
88
|
|
2127
89
|
Run with this command from the root of the project if you cloned the project:
|
2128
90
|
|
2129
91
|
```
|
2130
|
-
ruby -r './lib/glimmer-dsl-libui' examples/
|
92
|
+
ruby -r './lib/glimmer-dsl-libui' examples/color_the_circles.rb
|
2131
93
|
```
|
2132
94
|
|
2133
95
|
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2134
96
|
|
2135
97
|
```
|
2136
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/
|
98
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/color_the_circles'"
|
2137
99
|
```
|
2138
100
|
|
2139
101
|
Mac | Windows | Linux
|
2140
102
|
----|---------|------
|
2141
|
-
   |    |   
|
2142
104
|
|
2143
|
-
|
105
|
+
## Control Gallery
|
2144
106
|
|
2145
|
-
|
2146
|
-
require 'glimmer-dsl-libui'
|
107
|
+
[examples/control_gallery.rb](/examples/control_gallery.rb)
|
2147
108
|
|
2148
|
-
|
109
|
+
Run with this command from the root of the project if you cloned the project:
|
2149
110
|
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2153
|
-
%w[chicken bird cock-a-doodle-doo],
|
2154
|
-
%w[horse fast neigh],
|
2155
|
-
%w[cow slow moo]
|
2156
|
-
]
|
111
|
+
```
|
112
|
+
ruby -r './lib/glimmer-dsl-libui' examples/control_gallery.rb
|
113
|
+
```
|
2157
114
|
|
2158
|
-
|
2159
|
-
horizontal_box {
|
2160
|
-
table {
|
2161
|
-
text_column('Animal')
|
2162
|
-
text_column('Description')
|
2163
|
-
text_column('Sound (Editable)') {
|
2164
|
-
editable true
|
2165
|
-
}
|
115
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2166
116
|
|
2167
|
-
|
2168
|
-
|
2169
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2170
|
-
puts "Row #{row} edited: #{row_data}"
|
2171
|
-
$stdout.flush
|
2172
|
-
end
|
2173
|
-
}
|
2174
|
-
}
|
2175
|
-
|
2176
|
-
on_closing do
|
2177
|
-
puts 'Bye Bye'
|
2178
|
-
end
|
2179
|
-
}.show
|
117
|
+
```
|
118
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/control_gallery'"
|
2180
119
|
```
|
2181
120
|
|
2182
|
-
|
121
|
+
Mac | Windows | Linux
|
122
|
+
----|---------|------
|
123
|
+
 |  | 
|
2183
124
|
|
2184
|
-
|
125
|
+
## CPU Percentage
|
126
|
+
|
127
|
+
This example shows CPU usage percentage second by second.
|
128
|
+
|
129
|
+
Note that it is highly dependent on low-level OS terminal commands, so if anything changes in their output formatting, the code could break. Please report any issues you might encounter.
|
130
|
+
|
131
|
+
[examples/cpu_percentage.rb](/examples/cpu_percentage.rb)
|
2185
132
|
|
2186
133
|
Run with this command from the root of the project if you cloned the project:
|
2187
134
|
|
2188
135
|
```
|
2189
|
-
ruby -r './lib/glimmer-dsl-libui' examples/
|
136
|
+
ruby -r './lib/glimmer-dsl-libui' examples/cpu_percentage.rb
|
2190
137
|
```
|
2191
138
|
|
2192
139
|
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2193
140
|
|
2194
141
|
```
|
2195
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/
|
142
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/cpu_percentage'"
|
2196
143
|
```
|
2197
144
|
|
2198
145
|
Mac | Windows | Linux
|
2199
146
|
----|---------|------
|
2200
|
-
 |  | 
|
2201
148
|
|
2202
|
-
|
149
|
+
## Custom Draw Text
|
2203
150
|
|
2204
|
-
|
2205
|
-
require 'glimmer-dsl-libui'
|
151
|
+
[examples/custom_draw_text.rb](/examples/custom_draw_text.rb)
|
2206
152
|
|
2207
|
-
|
153
|
+
Run with this command from the root of the project if you cloned the project:
|
2208
154
|
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
%w[chicken cock-a-doodle-doo],
|
2213
|
-
%w[horse neigh],
|
2214
|
-
%w[cow moo]
|
2215
|
-
]
|
155
|
+
```
|
156
|
+
ruby -r './lib/glimmer-dsl-libui' examples/custom_draw_text.rb
|
157
|
+
```
|
2216
158
|
|
2217
|
-
|
2218
|
-
horizontal_box {
|
2219
|
-
table {
|
2220
|
-
text_column('Animal')
|
2221
|
-
text_column('Description')
|
159
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2222
160
|
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
on_changed do |row, type, row_data| # fires on all changes (even ones happening through data array)
|
2227
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2228
|
-
end
|
2229
|
-
|
2230
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2231
|
-
puts "Row #{row} edited: #{row_data}"
|
2232
|
-
end
|
2233
|
-
}
|
2234
|
-
}
|
2235
|
-
|
2236
|
-
on_closing do
|
2237
|
-
puts 'Bye Bye'
|
2238
|
-
end
|
2239
|
-
}.show
|
161
|
+
```
|
162
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/custom_draw_text'"
|
2240
163
|
```
|
2241
164
|
|
2242
|
-
|
165
|
+
Mac | Windows | Linux
|
166
|
+
----|---------|------
|
167
|
+
  |   |  
|
2243
168
|
|
2244
|
-
|
169
|
+
Version 1:
|
170
|
+
|
171
|
+
[examples/custom_draw_text.rb](/examples/custom_draw_text.rb)
|
172
|
+
|
173
|
+
Version 2 (perform area redraws manually):
|
174
|
+
|
175
|
+
[examples/custom_draw_text2.rb](/examples/custom_draw_text2.rb)
|
176
|
+
|
177
|
+
## Dynamic Area
|
178
|
+
|
179
|
+
[examples/dynamic_area.rb](/examples/dynamic_area.rb)
|
2245
180
|
|
2246
181
|
Run with this command from the root of the project if you cloned the project:
|
2247
182
|
|
2248
183
|
```
|
2249
|
-
ruby -r './lib/glimmer-dsl-libui' examples/
|
184
|
+
ruby -r './lib/glimmer-dsl-libui' examples/dynamic_area.rb
|
2250
185
|
```
|
2251
186
|
|
2252
187
|
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2253
188
|
|
2254
189
|
```
|
2255
|
-
ruby -r glimmer-dsl-libui -e "require 'examples/
|
190
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/dynamic_area'"
|
2256
191
|
```
|
2257
192
|
|
2258
193
|
Mac | Windows | Linux
|
2259
194
|
----|---------|------
|
2260
|
-
  |   |  
|
2261
196
|
|
2262
|
-
|
197
|
+
Version (with [data-binding](#data-binding)):
|
2263
198
|
|
2264
|
-
|
2265
|
-
require 'glimmer-dsl-libui'
|
199
|
+
[examples/dynamic_area.rb](/examples/dynamic_area.rb)
|
2266
200
|
|
2267
|
-
|
2268
|
-
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
2269
|
-
|
2270
|
-
include Glimmer
|
2271
|
-
|
2272
|
-
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
|
2273
|
-
|
2274
|
-
def initialize
|
2275
|
-
@contacts = [
|
2276
|
-
Contact.new('Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'),
|
2277
|
-
Contact.new('Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'),
|
2278
|
-
Contact.new('Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'),
|
2279
|
-
Contact.new('Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'),
|
2280
|
-
Contact.new('Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'),
|
2281
|
-
]
|
2282
|
-
end
|
2283
|
-
|
2284
|
-
def launch
|
2285
|
-
window('Contacts', 600, 600) {
|
2286
|
-
margined true
|
2287
|
-
|
2288
|
-
vertical_box {
|
2289
|
-
form {
|
2290
|
-
stretchy false
|
2291
|
-
|
2292
|
-
entry {
|
2293
|
-
label 'Name'
|
2294
|
-
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
2295
|
-
}
|
2296
|
-
|
2297
|
-
entry {
|
2298
|
-
label 'Email'
|
2299
|
-
text <=> [self, :email]
|
2300
|
-
}
|
2301
|
-
|
2302
|
-
entry {
|
2303
|
-
label 'Phone'
|
2304
|
-
text <=> [self, :phone]
|
2305
|
-
}
|
2306
|
-
|
2307
|
-
entry {
|
2308
|
-
label 'City'
|
2309
|
-
text <=> [self, :city]
|
2310
|
-
}
|
2311
|
-
|
2312
|
-
entry {
|
2313
|
-
label 'State'
|
2314
|
-
text <=> [self, :state]
|
2315
|
-
}
|
2316
|
-
}
|
2317
|
-
|
2318
|
-
button('Save Contact') {
|
2319
|
-
stretchy false
|
2320
|
-
|
2321
|
-
on_clicked do
|
2322
|
-
new_row = [name, email, phone, city, state]
|
2323
|
-
if new_row.map(&:to_s).include?('')
|
2324
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
2325
|
-
else
|
2326
|
-
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
|
2327
|
-
@unfiltered_contacts = @contacts.dup
|
2328
|
-
self.name = '' # automatically clears name entry through explicit data-binding
|
2329
|
-
self.email = ''
|
2330
|
-
self.phone = ''
|
2331
|
-
self.city = ''
|
2332
|
-
self.state = ''
|
2333
|
-
end
|
2334
|
-
end
|
2335
|
-
}
|
2336
|
-
|
2337
|
-
search_entry {
|
2338
|
-
stretchy false
|
2339
|
-
# bidirectional data-binding of text to self.filter_value with after_write option
|
2340
|
-
text <=> [self, :filter_value,
|
2341
|
-
after_write: ->(filter_value) { # execute after write to self.filter_value
|
2342
|
-
@unfiltered_contacts ||= @contacts.dup
|
2343
|
-
# Unfilter first to remove any previous filters
|
2344
|
-
self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
|
2345
|
-
# Now, apply filter if entered
|
2346
|
-
unless filter_value.empty?
|
2347
|
-
self.contacts = @contacts.filter do |contact| # affects table indirectly through explicit data-binding
|
2348
|
-
contact.members.any? do |attribute|
|
2349
|
-
contact[attribute].to_s.downcase.include?(filter_value.downcase)
|
2350
|
-
end
|
2351
|
-
end
|
2352
|
-
end
|
2353
|
-
}
|
2354
|
-
]
|
2355
|
-
}
|
2356
|
-
|
2357
|
-
table {
|
2358
|
-
text_column('Name')
|
2359
|
-
text_column('Email')
|
2360
|
-
text_column('Phone')
|
2361
|
-
text_column('City')
|
2362
|
-
text_column('State')
|
2363
|
-
|
2364
|
-
editable true
|
2365
|
-
cell_rows <=> [self, :contacts] # explicit data-binding to self.contacts Model Array, auto-inferring model attribute names from underscored table column names by convention
|
2366
|
-
|
2367
|
-
on_changed do |row, type, row_data|
|
2368
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2369
|
-
$stdout.flush # for Windows
|
2370
|
-
end
|
2371
|
-
|
2372
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2373
|
-
puts "Row #{row} edited: #{row_data}"
|
2374
|
-
$stdout.flush # for Windows
|
2375
|
-
end
|
2376
|
-
}
|
2377
|
-
}
|
2378
|
-
}.show
|
2379
|
-
end
|
2380
|
-
end
|
201
|
+
Version 2 (without [data-binding](#data-binding)):
|
2381
202
|
|
2382
|
-
|
2383
|
-
```
|
203
|
+
[examples/dynamic_area2.rb](/examples/dynamic_area2.rb)
|
2384
204
|
|
2385
|
-
|
205
|
+
Version 3 (declarative stable `path` approach with [data-binding](#data-binding)):
|
2386
206
|
|
2387
|
-
|
2388
|
-
require 'glimmer-dsl-libui'
|
207
|
+
[examples/dynamic_area3.rb](/examples/dynamic_area3.rb)
|
2389
208
|
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
Contact.new('Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'),
|
2400
|
-
Contact.new('Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'),
|
2401
|
-
Contact.new('Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'),
|
2402
|
-
Contact.new('Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'),
|
2403
|
-
Contact.new('Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'),
|
2404
|
-
]
|
2405
|
-
end
|
2406
|
-
|
2407
|
-
def launch
|
2408
|
-
window('Contacts', 600, 600) {
|
2409
|
-
margined true
|
2410
|
-
|
2411
|
-
vertical_box {
|
2412
|
-
form {
|
2413
|
-
stretchy false
|
2414
|
-
|
2415
|
-
entry {
|
2416
|
-
label 'Name'
|
2417
|
-
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
2418
|
-
}
|
2419
|
-
|
2420
|
-
entry {
|
2421
|
-
label 'Email'
|
2422
|
-
text <=> [self, :email]
|
2423
|
-
}
|
2424
|
-
|
2425
|
-
entry {
|
2426
|
-
label 'Phone'
|
2427
|
-
text <=> [self, :phone]
|
2428
|
-
}
|
2429
|
-
|
2430
|
-
entry {
|
2431
|
-
label 'City'
|
2432
|
-
text <=> [self, :city]
|
2433
|
-
}
|
2434
|
-
|
2435
|
-
entry {
|
2436
|
-
label 'State'
|
2437
|
-
text <=> [self, :state]
|
2438
|
-
}
|
2439
|
-
}
|
2440
|
-
|
2441
|
-
button('Save Contact') {
|
2442
|
-
stretchy false
|
2443
|
-
|
2444
|
-
on_clicked do
|
2445
|
-
new_row = [name, email, phone, city, state]
|
2446
|
-
if new_row.map(&:to_s).include?('')
|
2447
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
2448
|
-
else
|
2449
|
-
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
2450
|
-
@unfiltered_contacts = @contacts.dup
|
2451
|
-
self.name = '' # automatically clears name entry through explicit data-binding
|
2452
|
-
self.email = ''
|
2453
|
-
self.phone = ''
|
2454
|
-
self.city = ''
|
2455
|
-
self.state = ''
|
2456
|
-
end
|
2457
|
-
end
|
2458
|
-
}
|
2459
|
-
|
2460
|
-
search_entry {
|
2461
|
-
stretchy false
|
2462
|
-
# bidirectional data-binding of text to self.filter_value with after_write option
|
2463
|
-
text <=> [self, :filter_value,
|
2464
|
-
after_write: ->(filter_value) { # execute after write to self.filter_value
|
2465
|
-
@unfiltered_contacts ||= @contacts.dup
|
2466
|
-
# Unfilter first to remove any previous filters
|
2467
|
-
self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
|
2468
|
-
# Now, apply filter if entered
|
2469
|
-
unless filter_value.empty?
|
2470
|
-
self.contacts = @contacts.filter do |contact| # affects table indirectly through explicit data-binding
|
2471
|
-
contact.members.any? do |attribute|
|
2472
|
-
contact[attribute].to_s.downcase.include?(filter_value.downcase)
|
2473
|
-
end
|
2474
|
-
end
|
2475
|
-
end
|
2476
|
-
}
|
2477
|
-
]
|
2478
|
-
}
|
2479
|
-
|
2480
|
-
table {
|
2481
|
-
text_column('Name')
|
2482
|
-
text_column('Email')
|
2483
|
-
text_column('Phone')
|
2484
|
-
text_column('City')
|
2485
|
-
text_column('State')
|
2486
|
-
|
2487
|
-
editable true
|
2488
|
-
cell_rows <=> [self, :contacts, column_attributes: {'State' => :state_province}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
|
2489
|
-
|
2490
|
-
on_changed do |row, type, row_data|
|
2491
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2492
|
-
$stdout.flush # for Windows
|
2493
|
-
end
|
2494
|
-
|
2495
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2496
|
-
puts "Row #{row} edited: #{row_data}"
|
2497
|
-
$stdout.flush # for Windows
|
2498
|
-
end
|
2499
|
-
}
|
2500
|
-
}
|
2501
|
-
}.show
|
2502
|
-
end
|
2503
|
-
end
|
209
|
+
Version 4 (declarative stable `path` approach without [data-binding](#data-binding)):
|
210
|
+
|
211
|
+
[examples/dynamic_area4.rb](/examples/dynamic_area4.rb)
|
212
|
+
|
213
|
+
## Editable Column Table
|
214
|
+
|
215
|
+
[examples/editable_column_table.rb](/examples/editable_column_table.rb)
|
216
|
+
|
217
|
+
Run with this command from the root of the project if you cloned the project:
|
2504
218
|
|
2505
|
-
|
219
|
+
```
|
220
|
+
ruby -r './lib/glimmer-dsl-libui' examples/editable_column_table.rb
|
2506
221
|
```
|
2507
222
|
|
2508
|
-
|
223
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2509
224
|
|
2510
|
-
```
|
225
|
+
```
|
226
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/editable_column_table'"
|
227
|
+
```
|
2511
228
|
|
2512
|
-
|
229
|
+
Mac | Windows | Linux
|
230
|
+
----|---------|------
|
231
|
+
  |   |  
|
2513
232
|
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
|
2520
|
-
|
2521
|
-
def initialize
|
2522
|
-
@contacts = [
|
2523
|
-
Contact.new('Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'),
|
2524
|
-
Contact.new('Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'),
|
2525
|
-
Contact.new('Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'),
|
2526
|
-
Contact.new('Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'),
|
2527
|
-
Contact.new('Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'),
|
2528
|
-
]
|
2529
|
-
end
|
2530
|
-
|
2531
|
-
def launch
|
2532
|
-
window('Contacts', 600, 600) {
|
2533
|
-
margined true
|
2534
|
-
|
2535
|
-
vertical_box {
|
2536
|
-
form {
|
2537
|
-
stretchy false
|
2538
|
-
|
2539
|
-
entry {
|
2540
|
-
label 'Name'
|
2541
|
-
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
2542
|
-
}
|
2543
|
-
|
2544
|
-
entry {
|
2545
|
-
label 'Email'
|
2546
|
-
text <=> [self, :email]
|
2547
|
-
}
|
2548
|
-
|
2549
|
-
entry {
|
2550
|
-
label 'Phone'
|
2551
|
-
text <=> [self, :phone]
|
2552
|
-
}
|
2553
|
-
|
2554
|
-
entry {
|
2555
|
-
label 'City'
|
2556
|
-
text <=> [self, :city]
|
2557
|
-
}
|
2558
|
-
|
2559
|
-
entry {
|
2560
|
-
label 'State'
|
2561
|
-
text <=> [self, :state]
|
2562
|
-
}
|
2563
|
-
}
|
2564
|
-
|
2565
|
-
button('Save Contact') {
|
2566
|
-
stretchy false
|
2567
|
-
|
2568
|
-
on_clicked do
|
2569
|
-
new_row = [name, email, phone, city, state]
|
2570
|
-
if new_row.map(&:to_s).include?('')
|
2571
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
2572
|
-
else
|
2573
|
-
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
2574
|
-
@unfiltered_contacts = @contacts.dup
|
2575
|
-
self.name = '' # automatically clears name entry through explicit data-binding
|
2576
|
-
self.email = ''
|
2577
|
-
self.phone = ''
|
2578
|
-
self.city = ''
|
2579
|
-
self.state = ''
|
2580
|
-
end
|
2581
|
-
end
|
2582
|
-
}
|
2583
|
-
|
2584
|
-
search_entry {
|
2585
|
-
stretchy false
|
2586
|
-
# bidirectional data-binding of text to self.filter_value with after_write option
|
2587
|
-
text <=> [self, :filter_value,
|
2588
|
-
after_write: ->(filter_value) { # execute after write to self.filter_value
|
2589
|
-
@unfiltered_contacts ||= @contacts.dup
|
2590
|
-
# Unfilter first to remove any previous filters
|
2591
|
-
self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
|
2592
|
-
# Now, apply filter if entered
|
2593
|
-
unless filter_value.empty?
|
2594
|
-
self.contacts = @contacts.filter do |contact| # affects table indirectly through explicit data-binding
|
2595
|
-
contact.members.any? do |attribute|
|
2596
|
-
contact[attribute].to_s.downcase.include?(filter_value.downcase)
|
2597
|
-
end
|
2598
|
-
end
|
2599
|
-
end
|
2600
|
-
}
|
2601
|
-
]
|
2602
|
-
}
|
2603
|
-
|
2604
|
-
table {
|
2605
|
-
text_column('Name')
|
2606
|
-
text_column('Email')
|
2607
|
-
text_column('Phone')
|
2608
|
-
text_column('City')
|
2609
|
-
text_column('State')
|
2610
|
-
|
2611
|
-
editable true
|
2612
|
-
cell_rows <=> [self, :contacts, column_attributes: [:full_name, :email_address, :phone_number, :city_or_town, :state_or_province]] # explicit data-binding to Model Array with column_attributes mapping for all columns
|
2613
|
-
|
2614
|
-
on_changed do |row, type, row_data|
|
2615
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2616
|
-
$stdout.flush # for Windows
|
2617
|
-
end
|
2618
|
-
|
2619
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2620
|
-
puts "Row #{row} edited: #{row_data}"
|
2621
|
-
$stdout.flush # for Windows
|
2622
|
-
end
|
2623
|
-
}
|
2624
|
-
}
|
2625
|
-
}.show
|
2626
|
-
end
|
2627
|
-
end
|
233
|
+
## Editable Table
|
234
|
+
|
235
|
+
[examples/editable_table.rb](/examples/editable_table.rb)
|
236
|
+
|
237
|
+
Run with this command from the root of the project if you cloned the project:
|
2628
238
|
|
2629
|
-
|
239
|
+
```
|
240
|
+
ruby -r './lib/glimmer-dsl-libui' examples/editable_table.rb
|
2630
241
|
```
|
2631
242
|
|
2632
|
-
|
243
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2633
244
|
|
2634
|
-
```
|
2635
|
-
|
245
|
+
```
|
246
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/editable_table'"
|
247
|
+
```
|
2636
248
|
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2640
|
-
attr_accessor :data, :name, :email, :phone, :city, :state, :filter_value
|
2641
|
-
|
2642
|
-
def initialize
|
2643
|
-
@data = [
|
2644
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
2645
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
2646
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
2647
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
2648
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
2649
|
-
]
|
2650
|
-
end
|
2651
|
-
|
2652
|
-
def launch
|
2653
|
-
window('Contacts', 600, 600) {
|
2654
|
-
margined true
|
2655
|
-
|
2656
|
-
vertical_box {
|
2657
|
-
form {
|
2658
|
-
stretchy false
|
2659
|
-
|
2660
|
-
entry {
|
2661
|
-
label 'Name'
|
2662
|
-
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
2663
|
-
}
|
2664
|
-
|
2665
|
-
entry {
|
2666
|
-
label 'Email'
|
2667
|
-
text <=> [self, :email]
|
2668
|
-
}
|
2669
|
-
|
2670
|
-
entry {
|
2671
|
-
label 'Phone'
|
2672
|
-
text <=> [self, :phone]
|
2673
|
-
}
|
2674
|
-
|
2675
|
-
entry {
|
2676
|
-
label 'City'
|
2677
|
-
text <=> [self, :city]
|
2678
|
-
}
|
2679
|
-
|
2680
|
-
entry {
|
2681
|
-
label 'State'
|
2682
|
-
text <=> [self, :state]
|
2683
|
-
}
|
2684
|
-
}
|
2685
|
-
|
2686
|
-
button('Save Contact') {
|
2687
|
-
stretchy false
|
2688
|
-
|
2689
|
-
on_clicked do
|
2690
|
-
new_row = [name, email, phone, city, state]
|
2691
|
-
if new_row.map(&:to_s).include?('')
|
2692
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
2693
|
-
else
|
2694
|
-
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
2695
|
-
@unfiltered_data = data.dup
|
2696
|
-
self.name = '' # automatically clears name entry through explicit data-binding
|
2697
|
-
self.email = ''
|
2698
|
-
self.phone = ''
|
2699
|
-
self.city = ''
|
2700
|
-
self.state = ''
|
2701
|
-
end
|
2702
|
-
end
|
2703
|
-
}
|
2704
|
-
|
2705
|
-
search_entry {
|
2706
|
-
stretchy false
|
2707
|
-
# bidirectional data-binding of text to self.filter_value with after_write option
|
2708
|
-
text <=> [self, :filter_value,
|
2709
|
-
after_write: ->(filter_value) { # execute after write to self.filter_value
|
2710
|
-
@unfiltered_data ||= data.dup
|
2711
|
-
# Unfilter first to remove any previous filters
|
2712
|
-
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
2713
|
-
# Now, apply filter if entered
|
2714
|
-
unless filter_value.empty?
|
2715
|
-
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
2716
|
-
row_data.any? do |cell|
|
2717
|
-
cell.to_s.downcase.include?(filter_value.downcase)
|
2718
|
-
end
|
2719
|
-
end
|
2720
|
-
end
|
2721
|
-
}
|
2722
|
-
]
|
2723
|
-
}
|
2724
|
-
|
2725
|
-
table {
|
2726
|
-
text_column('Name')
|
2727
|
-
text_column('Email')
|
2728
|
-
text_column('Phone')
|
2729
|
-
text_column('City')
|
2730
|
-
text_column('State')
|
2731
|
-
|
2732
|
-
editable true
|
2733
|
-
cell_rows <=> [self, :data] # explicit data-binding to raw data Array of Arrays
|
2734
|
-
|
2735
|
-
on_changed do |row, type, row_data|
|
2736
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2737
|
-
$stdout.flush # for Windows
|
2738
|
-
end
|
2739
|
-
|
2740
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2741
|
-
puts "Row #{row} edited: #{row_data}"
|
2742
|
-
$stdout.flush # for Windows
|
2743
|
-
end
|
2744
|
-
}
|
2745
|
-
}
|
2746
|
-
}.show
|
2747
|
-
end
|
2748
|
-
end
|
249
|
+
Mac | Windows | Linux
|
250
|
+
----|---------|------
|
251
|
+
   |    |   
|
2749
252
|
|
2750
|
-
|
253
|
+
## Form Table
|
254
|
+
|
255
|
+
[examples/form_table.rb](/examples/form_table.rb)
|
256
|
+
|
257
|
+
Run with this command from the root of the project if you cloned the project:
|
258
|
+
|
259
|
+
```
|
260
|
+
ruby -r './lib/glimmer-dsl-libui' examples/form_table.rb
|
2751
261
|
```
|
2752
262
|
|
2753
|
-
|
263
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2754
264
|
|
2755
|
-
```
|
2756
|
-
|
265
|
+
```
|
266
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/form_table'"
|
267
|
+
```
|
2757
268
|
|
2758
|
-
|
269
|
+
Mac | Windows | Linux
|
270
|
+
----|---------|------
|
271
|
+
   |    |   
|
2759
272
|
|
2760
|
-
data
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
]
|
273
|
+
Version 1 (with explicit [data-binding](#data-binding) and inferred table column attributes):
|
274
|
+
|
275
|
+
[examples/form_table.rb](/examples/form_table.rb)
|
276
|
+
|
277
|
+
Version 2 (with explicit [data-binding](#data-binding) specifying table `column_attributes` mapping hash):
|
278
|
+
|
279
|
+
[examples/form_table2.rb](/examples/form_table2.rb)
|
280
|
+
|
281
|
+
Version 3 (with explicit [data-binding](#data-binding) specifying table `column_attributes` array):
|
282
|
+
|
283
|
+
[examples/form_table3.rb](/examples/form_table3.rb)
|
284
|
+
|
285
|
+
Version 4 (with explicit [data-binding](#data-binding) to raw data):
|
286
|
+
|
287
|
+
[examples/form_table4.rb](/examples/form_table4.rb)
|
288
|
+
|
289
|
+
Version 5 (with implicit [data-binding](#data-binding)):
|
290
|
+
|
291
|
+
[examples/form_table5.rb](/examples/form_table5.rb)
|
292
|
+
|
293
|
+
## GPT2 Notepad
|
294
|
+
|
295
|
+
[examples/gpt2_notepad.rb](/examples/gpt2_notepad.rb)
|
296
|
+
|
297
|
+
This sample requires installing the following additional Ruby gems first:
|
298
|
+
- [onnxruntime](https://rubygems.org/gems/onnxruntime)
|
299
|
+
- [blingfire](https://rubygems.org/gems/blingfire)
|
300
|
+
- [numo-narray](https://rubygems.org/gems/numo-narray)
|
301
|
+
|
302
|
+
It will download GPT2 AI (Artificial Intelligence) models on first run.
|
303
|
+
|
304
|
+
Run with this command from the root of the project if you cloned the project:
|
305
|
+
|
306
|
+
```
|
307
|
+
ruby -r './lib/glimmer-dsl-libui' examples/gpt2_notepad.rb
|
308
|
+
```
|
309
|
+
|
310
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
2767
311
|
|
2768
|
-
window('Contacts', 600, 600) {
|
2769
|
-
margined true
|
2770
|
-
|
2771
|
-
vertical_box {
|
2772
|
-
form {
|
2773
|
-
stretchy false
|
2774
|
-
|
2775
|
-
@name_entry = entry {
|
2776
|
-
label 'Name'
|
2777
|
-
}
|
2778
|
-
|
2779
|
-
@email_entry = entry {
|
2780
|
-
label 'Email'
|
2781
|
-
}
|
2782
|
-
|
2783
|
-
@phone_entry = entry {
|
2784
|
-
label 'Phone'
|
2785
|
-
}
|
2786
|
-
|
2787
|
-
@city_entry = entry {
|
2788
|
-
label 'City'
|
2789
|
-
}
|
2790
|
-
|
2791
|
-
@state_entry = entry {
|
2792
|
-
label 'State'
|
2793
|
-
}
|
2794
|
-
}
|
2795
|
-
|
2796
|
-
button('Save Contact') {
|
2797
|
-
stretchy false
|
2798
|
-
|
2799
|
-
on_clicked do
|
2800
|
-
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
2801
|
-
if new_row.map(&:to_s).include?('')
|
2802
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
2803
|
-
else
|
2804
|
-
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
2805
|
-
@unfiltered_data = data.dup
|
2806
|
-
@name_entry.text = ''
|
2807
|
-
@email_entry.text = ''
|
2808
|
-
@phone_entry.text = ''
|
2809
|
-
@city_entry.text = ''
|
2810
|
-
@state_entry.text = ''
|
2811
|
-
end
|
2812
|
-
end
|
2813
|
-
}
|
2814
|
-
|
2815
|
-
search_entry { |se|
|
2816
|
-
stretchy false
|
2817
|
-
|
2818
|
-
on_changed do
|
2819
|
-
filter_value = se.text
|
2820
|
-
@unfiltered_data ||= data.dup
|
2821
|
-
# Unfilter first to remove any previous filters
|
2822
|
-
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
2823
|
-
# Now, apply filter if entered
|
2824
|
-
unless filter_value.empty?
|
2825
|
-
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
2826
|
-
row_data.any? do |cell|
|
2827
|
-
cell.to_s.downcase.include?(filter_value.downcase)
|
2828
|
-
end
|
2829
|
-
end
|
2830
|
-
end
|
2831
|
-
end
|
2832
|
-
}
|
2833
|
-
|
2834
|
-
table {
|
2835
|
-
text_column('Name')
|
2836
|
-
text_column('Email')
|
2837
|
-
text_column('Phone')
|
2838
|
-
text_column('City')
|
2839
|
-
text_column('State')
|
2840
|
-
|
2841
|
-
editable true
|
2842
|
-
cell_rows data # implicit data-binding to raw data Array of Arrays
|
2843
|
-
|
2844
|
-
on_changed do |row, type, row_data|
|
2845
|
-
puts "Row #{row} #{type}: #{row_data}"
|
2846
|
-
$stdout.flush # for Windows
|
2847
|
-
end
|
2848
|
-
|
2849
|
-
on_edited do |row, row_data| # only fires on direct table editing
|
2850
|
-
puts "Row #{row} edited: #{row_data}"
|
2851
|
-
$stdout.flush # for Windows
|
2852
|
-
end
|
2853
|
-
}
|
2854
|
-
}
|
2855
|
-
}.show
|
2856
312
|
```
|
313
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/gpt2_notepad'"
|
314
|
+
```
|
315
|
+
|
316
|
+
 
|
2857
317
|
|
2858
318
|
## Paginated Refined Table
|
2859
319
|
|