glimmer-dsl-tk 0.0.22 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/README.md +612 -46
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/format_expression.rb +39 -0
- data/lib/glimmer/dsl/tk/message_box_expression.rb +4 -1
- data/lib/glimmer/dsl/tk/root_expression.rb +1 -1
- data/lib/glimmer/dsl/tk/widget_expression.rb +0 -7
- data/lib/glimmer/tk/button_proxy.rb +2 -14
- data/lib/glimmer/tk/checkbutton_proxy.rb +5 -13
- data/lib/glimmer/tk/combobox_proxy.rb +34 -0
- data/lib/glimmer/tk/commandable.rb +42 -0
- data/lib/glimmer/tk/entry_proxy.rb +20 -0
- data/lib/glimmer/tk/frame_proxy.rb +9 -0
- data/lib/glimmer/tk/label_proxy.rb +8 -4
- data/lib/glimmer/tk/notebook_proxy.rb +3 -8
- data/lib/glimmer/tk/radiobutton_proxy.rb +46 -0
- data/lib/glimmer/tk/root_proxy.rb +17 -35
- data/lib/glimmer/tk/spinbox_proxy.rb +52 -0
- data/lib/glimmer/tk/text_proxy.rb +187 -0
- data/lib/glimmer/tk/text_variable_owner.rb +31 -0
- data/lib/glimmer/tk/variable_owner.rb +31 -0
- data/lib/glimmer/tk/widget_proxy.rb +167 -62
- data/lib/glimmer-dsl-tk.rb +1 -0
- data/samples/elaborate/meta_sample.rb +138 -0
- data/samples/hello/hello_checkbutton.rb +58 -17
- data/samples/hello/hello_combobox.rb +2 -1
- data/samples/hello/hello_entry.rb +104 -0
- data/samples/hello/hello_radiobutton.rb +107 -0
- data/samples/hello/hello_spinbox.rb +75 -0
- data/samples/hello/hello_text.rb +101 -0
- metadata +17 -3
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.26
|
2
2
|
## MRI Ruby Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-tk.svg)](http://badge.fury.io/rb/glimmer-dsl-tk)
|
4
4
|
[![Ruby](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml/badge.svg)](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
|
@@ -76,25 +76,28 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
76
76
|
- [Supported Widgets](#supported-widgets)
|
77
77
|
- [Common Attributes](#common-attributes)
|
78
78
|
- [Common Themed Widget States](#common-themed-widget-states)
|
79
|
-
- [Smart Defaults and
|
79
|
+
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
80
80
|
- [Grid Layout](#grid-layout)
|
81
81
|
- [Label/Button Image](#labelbutton-image)
|
82
82
|
- [Notebook Frame](#notebook-frame)
|
83
83
|
- [Icon Photo](#icon-photo)
|
84
84
|
- [The Grid Geometry Manager](#the-grid-geometry-manager)
|
85
|
-
- [
|
85
|
+
- [Data-Binding](#data-binding)
|
86
86
|
- [Label Data-Binding](#label-data-binding)
|
87
87
|
- [Combobox Data-Binding](#combobox-data-binding)
|
88
88
|
- [List Single Selection Data-Binding](#list-single-selection-data-binding)
|
89
89
|
- [List Multi Selection Data-Binding](#list-multi-selection-data-binding)
|
90
90
|
- [Entry Data-Binding](#entry-data-binding)
|
91
|
-
- [
|
91
|
+
- [Spinbox Data-Binding](#spinbox-data-binding)
|
92
|
+
- [Checkbutton Data-Binding](#checkbutton-data-binding)
|
93
|
+
- [Radiobutton Data-Binding](#radiobutton-data-binding)
|
92
94
|
- [Command Callback](#command-callback)
|
93
95
|
- [Gotchas](#gotchas)
|
94
96
|
- [Samples](#samples)
|
95
97
|
- [Hello, World!](#hello-world)
|
96
98
|
- [Hello, Button!](#hello-button)
|
97
99
|
- [Hello, Checkbutton!](#hello-checkbutton)
|
100
|
+
- [Hello, Radiobutton!](#hello-radiobutton)
|
98
101
|
- [Hello, Frame!](#hello-frame)
|
99
102
|
- [Hello, Root!](#hello-root)
|
100
103
|
- [Hello, Notebook!](#hello-notebook)
|
@@ -103,6 +106,9 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
103
106
|
- [Hello, Combobox!](#hello-combobox)
|
104
107
|
- [Hello, List Single Selection!](#hello-list-single-selection)
|
105
108
|
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
109
|
+
- [Hello, Entry!](#hello-entry)
|
110
|
+
- [Hello, Text!](#hello-text)
|
111
|
+
- [Hello, Spinbox!](#hello-spinbox)
|
106
112
|
- [Hello, Computed!](#hello-computed)
|
107
113
|
- [Help](#help)
|
108
114
|
- [Issues](#issues)
|
@@ -140,7 +146,7 @@ gem install glimmer-dsl-tk
|
|
140
146
|
|
141
147
|
Add the following to `Gemfile`:
|
142
148
|
```
|
143
|
-
gem 'glimmer-dsl-tk', '~> 0.0.
|
149
|
+
gem 'glimmer-dsl-tk', '~> 0.0.26'
|
144
150
|
```
|
145
151
|
|
146
152
|
And, then run:
|
@@ -250,15 +256,18 @@ root {
|
|
250
256
|
keyword(args) | attributes | event bindings & callbacks
|
251
257
|
------------- | ---------- | ---------
|
252
258
|
`button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
|
253
|
-
`checkbutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `
|
259
|
+
`checkbutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `onvalue` (default: `1`), `offvalue` (default: `0`) | `command {}`
|
254
260
|
`combobox` | `state`, `text` | `'ComboboxSelected'`
|
255
|
-
`entry` | `width`, `text` |
|
261
|
+
`entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'`, `validatecommand {}`, `invalidcommand {}`
|
262
|
+
`spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
|
256
263
|
`frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
|
257
264
|
`label` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `font` (`'default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip'`), `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`), `justify` (`'left', 'center', 'right'`), `foreground`, `background` | None
|
258
265
|
`list` | `selectmode`, `selection` | None
|
259
266
|
`message_box(type: , message: , detail: , title: , icon: , default: , parent: )` | None | None
|
260
267
|
`notebook` | None | None
|
268
|
+
`radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
|
261
269
|
`root` | `title`, `iconphoto`, `background`, `alpha`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`, `'OPEN_WINDOW'`
|
270
|
+
`text` | `text`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`
|
262
271
|
|
263
272
|
#### Common Attributes
|
264
273
|
|
@@ -308,15 +317,19 @@ keyword(args) | attributes | event bindings & callbacks
|
|
308
317
|
- `invalid?`
|
309
318
|
- `hover?`
|
310
319
|
|
311
|
-
### Smart Defaults and
|
320
|
+
### Smart Defaults and Conventions
|
312
321
|
|
313
322
|
#### Event Bindings
|
314
323
|
|
315
|
-
Any events that normally can be accepted by the Tk `bind` or `protocol` methods can be accepted by the `on(event) {}` listener syntax.
|
324
|
+
Any events that normally can be accepted by the Tk `bind` or `protocol` methods can be accepted by the `on(event) {}` listener syntax. For actual (non-virtual) events, there is no need to surround event name by `<>` as [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) automatically takes care of that when needed and leaves out when not needed.
|
316
325
|
|
317
326
|
#### Grid Layout
|
318
327
|
|
319
|
-
`grid` layout is the default on
|
328
|
+
`grid` layout with `sticky: 'nsew'` is the default on all widgets except toplevel widgets.
|
329
|
+
|
330
|
+
Also, any widget that is the first in a series of siblings has `column_weight` as `1` to automatically resize with window resizing by default.
|
331
|
+
|
332
|
+
To override that behavior, you may set alternative `grid` keyword args if needed (e.g. `grid sticky: '', column_weight: 0` disables the smart defaults).
|
320
333
|
|
321
334
|
#### Label/Button Image
|
322
335
|
|
@@ -350,6 +363,10 @@ root {
|
|
350
363
|
}.open
|
351
364
|
```
|
352
365
|
|
366
|
+
#### Root Background
|
367
|
+
|
368
|
+
`root` `background` color attribute is automatically set to `'#ececec'` on the Mac to avoid having a non-native-looking light-colored background.
|
369
|
+
|
353
370
|
## The Grid Geometry Manager
|
354
371
|
|
355
372
|
The Grid Geometry Manager is supported via the `grid` keyword just as per the [Tk documentation](https://tkdocs.com/tutorial/grid.html), except by nesting under the widget it concerns.
|
@@ -368,9 +385,17 @@ Example:
|
|
368
385
|
}
|
369
386
|
```
|
370
387
|
|
388
|
+
Extra convenience options may be passed to `grid` when using [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk):
|
389
|
+
- `min_width`: alias for `columnminsize` being called on `TkGrid.columnconfigure`
|
390
|
+
- `min_height`: alias for `rowminsize` being called on `TkGrid.rowconfigure`
|
391
|
+
- `column_weight`: alias for `columnweight` being called on `TkGrid.columnconfigure`
|
392
|
+
- `row_weight`: alias for `rowweight` being called on `TkGrid.rowconfigure`
|
393
|
+
|
394
|
+
Note also the [Grid Layout](#grid-layout) conventions (e.g. `column_weight` is automatically set to `1` for the first widget in a series of siblings to automatically have all resize when window resize)
|
395
|
+
|
371
396
|
More details can be found in the [Hello, Computed!](#hello-computed) sample below.
|
372
397
|
|
373
|
-
##
|
398
|
+
## Data-Binding
|
374
399
|
|
375
400
|
Glimmer supports Shine syntax bidirectional data-binding via the `<=>` operator (read-write) and unidirectional data-binding via the `<=` operator (read-only), which takes a model and an attribute (the `bind` keyword may also be used as the old-style of data-binding).
|
376
401
|
|
@@ -400,7 +425,7 @@ This assumes a `Person` model with a `country` attribute representing their curr
|
|
400
425
|
|
401
426
|
```ruby
|
402
427
|
combobox {
|
403
|
-
|
428
|
+
readonly true # this applies to text editing only (item selection still triggers a write to model)
|
404
429
|
text <=> [person, :country]
|
405
430
|
}
|
406
431
|
```
|
@@ -471,9 +496,49 @@ That code binds the `textvariable` value of the `entry` to the `country` attribu
|
|
471
496
|
|
472
497
|
It automatically handles all the Tk plumbing behind the scenes.
|
473
498
|
|
474
|
-
More details can be found in
|
499
|
+
More details can be found in [Hello, Entry!](#hello-entry) and [Hello, Computed!](#hello-computed) samples below.
|
500
|
+
|
501
|
+
### Spinbox Data-Binding
|
502
|
+
|
503
|
+
Example:
|
504
|
+
|
505
|
+
This assumes a `Person` model with a `donation` attribute.
|
506
|
+
|
507
|
+
```ruby
|
508
|
+
spinbox {
|
509
|
+
from 1.0 # minimum value
|
510
|
+
to 150.0 # maximum value
|
511
|
+
increment 5.0 # increment on up and down
|
512
|
+
format '%0.2f'
|
513
|
+
text <=> [person, :country]
|
514
|
+
}
|
515
|
+
```
|
516
|
+
|
517
|
+
That code binds the `textvariable` value of the `spinbox` to the `donation` attribute on the `person` model.
|
518
|
+
|
519
|
+
It automatically handles all the Tk plumbing behind the scenes.
|
520
|
+
|
521
|
+
More details can be found in [Hello, Spinbox!](#hello-spinbox) sample below.
|
522
|
+
|
523
|
+
### Text Data-Binding
|
475
524
|
|
476
|
-
|
525
|
+
Example:
|
526
|
+
|
527
|
+
This assumes a `Person` model with a `address` attribute.
|
528
|
+
|
529
|
+
```ruby
|
530
|
+
text {
|
531
|
+
text <=> [person, :address]
|
532
|
+
}
|
533
|
+
```
|
534
|
+
|
535
|
+
That code binds the text content of `text` to the `address` attribute on the `person` model.
|
536
|
+
|
537
|
+
It automatically handles all the Tk plumbing behind the scenes (including fine-grained inserts and deletes, abstracting them all away).
|
538
|
+
|
539
|
+
More details can be found in [Glimmer Meta-Sample](#samples) below.
|
540
|
+
|
541
|
+
### Checkbutton Data-Binding
|
477
542
|
|
478
543
|
Example:
|
479
544
|
|
@@ -489,11 +554,39 @@ That code binds the `variable` value of the `checkbutton` to the boolean `adult`
|
|
489
554
|
|
490
555
|
It automatically handles all the Tk plumbing behind the scenes.
|
491
556
|
|
557
|
+
If you need to display a half-checked `checkbutton`, bind to `alternate` attribute.
|
558
|
+
|
492
559
|
More details can be found in the [Hello, Checkbutton!](#hello-checkbutton) sample below.
|
493
560
|
|
561
|
+
### Radiobutton Data-Binding
|
562
|
+
|
563
|
+
Example:
|
564
|
+
|
565
|
+
This assumes a `Person` model with boolean `male` and `female` attributes.
|
566
|
+
|
567
|
+
```ruby
|
568
|
+
radiobutton {
|
569
|
+
text 'Male'
|
570
|
+
variable <=> [@person, :male]
|
571
|
+
}
|
572
|
+
|
573
|
+
radiobutton {
|
574
|
+
text 'Female'
|
575
|
+
variable <=> [@person, :female]
|
576
|
+
}
|
577
|
+
```
|
578
|
+
|
579
|
+
That code binds the `variable` value of the `radiobutton` to the boolean `male` and `female` attributes on the `person` model.
|
580
|
+
|
581
|
+
It automatically handles all the Tk plumbing behind the scenes, including setting the `radiobutton` `value` (uses `text` attribute as `value`), enabling an API that works with simple booleans for each `radiobutton`.
|
582
|
+
|
583
|
+
For very rare cases, if you need to display a half-selected `radiobutton`, set `alternate` attribute as `true` when the `variable` value is `false`.
|
584
|
+
|
585
|
+
More details can be found in the [Hello, Radiobutton!](#hello-radiobutton) sample below.
|
586
|
+
|
494
587
|
## Command Callback
|
495
588
|
|
496
|
-
`button` and `checkbutton` can set a `command` block to trigger when the user clicks the button/checkbutton. This may be done with the `command` keyword, passing in a block directly.
|
589
|
+
`button`, `spinbox`, `radiobutton` and `checkbutton` can set a `command` block to trigger when the user clicks the button/checkbutton. This may be done with the `command` keyword, passing in a block directly.
|
497
590
|
|
498
591
|
Example:
|
499
592
|
|
@@ -507,6 +600,18 @@ Example:
|
|
507
600
|
}
|
508
601
|
```
|
509
602
|
|
603
|
+
Alternatively, it can be treated as simply an event for consistency with other event bindings:
|
604
|
+
|
605
|
+
```ruby
|
606
|
+
button {
|
607
|
+
text "Reset Selection"
|
608
|
+
|
609
|
+
on('command') do
|
610
|
+
person.reset_country
|
611
|
+
end
|
612
|
+
}
|
613
|
+
```
|
614
|
+
|
510
615
|
More details can be found in the [Hello, Button!](#hello-button) sample below.
|
511
616
|
|
512
617
|
## Gotchas
|
@@ -515,6 +620,22 @@ More details can be found in the [Hello, Button!](#hello-button) sample below.
|
|
515
620
|
|
516
621
|
## Samples
|
517
622
|
|
623
|
+
The easiest way to run samples is by launching the Glimmer Meta-Sample (the Sample of Samples).
|
624
|
+
|
625
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
626
|
+
|
627
|
+
```
|
628
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/elaborate/meta_sample'"
|
629
|
+
```
|
630
|
+
|
631
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
632
|
+
|
633
|
+
```
|
634
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/elaborate/meta_sample.rb
|
635
|
+
```
|
636
|
+
|
637
|
+
![glimmer dsl tk screenshot sample meta sample](images/glimmer-dsl-tk-screenshot-sample-elaborate-meta-sample.png)
|
638
|
+
|
518
639
|
### Hello, World!
|
519
640
|
|
520
641
|
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
|
@@ -542,7 +663,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_world'"
|
|
542
663
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
543
664
|
|
544
665
|
```
|
545
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
666
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_world.rb
|
546
667
|
```
|
547
668
|
|
548
669
|
Glimmer app:
|
@@ -641,7 +762,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_button'"
|
|
641
762
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
642
763
|
|
643
764
|
```
|
644
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
765
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_button.rb
|
645
766
|
```
|
646
767
|
|
647
768
|
Glimmer app:
|
@@ -657,13 +778,47 @@ require 'glimmer-dsl-tk'
|
|
657
778
|
|
658
779
|
class HelloCheckbutton
|
659
780
|
class Person
|
660
|
-
attr_accessor :skiing, :snowboarding, :snowmobiling, :snowshoeing
|
781
|
+
attr_accessor :skiing, :snowboarding, :snowmobiling, :snowshoeing, :snow_activities, :snow_activities_alternate
|
661
782
|
|
662
783
|
def initialize
|
663
784
|
reset_activities!
|
785
|
+
individual_observer = Glimmer::DataBinding::Observer.proc do
|
786
|
+
unless @updating_group
|
787
|
+
@updating_individual = true
|
788
|
+
if skiing && snowboarding && snowmobiling && snowshoeing
|
789
|
+
self.snow_activities = true
|
790
|
+
self.snow_activities_alternate = false
|
791
|
+
elsif skiing || snowboarding || snowmobiling || snowshoeing
|
792
|
+
self.snow_activities = true
|
793
|
+
self.snow_activities_alternate = true
|
794
|
+
else
|
795
|
+
self.snow_activities = false
|
796
|
+
self.snow_activities_alternate = false
|
797
|
+
end
|
798
|
+
@updating_individual = false
|
799
|
+
end
|
800
|
+
end
|
801
|
+
individual_observer.observe(self, :skiing)
|
802
|
+
individual_observer.observe(self, :snowboarding)
|
803
|
+
individual_observer.observe(self, :snowmobiling)
|
804
|
+
individual_observer.observe(self, :snowshoeing)
|
805
|
+
|
806
|
+
group_observer = Glimmer::DataBinding::Observer.proc do
|
807
|
+
unless @updating_individual
|
808
|
+
@updating_group = true
|
809
|
+
self.skiing = self.snow_activities
|
810
|
+
self.snowboarding = self.snow_activities
|
811
|
+
self.snowmobiling = self.snow_activities
|
812
|
+
self.snowshoeing = self.snow_activities
|
813
|
+
@updating_group = false
|
814
|
+
end
|
815
|
+
end
|
816
|
+
group_observer.observe(self, :snow_activities)
|
664
817
|
end
|
665
818
|
|
666
819
|
def reset_activities!
|
820
|
+
self.snow_activities = true
|
821
|
+
self.snow_activities_alternate = true
|
667
822
|
self.skiing = false
|
668
823
|
self.snowboarding = true
|
669
824
|
self.snowmobiling = false
|
@@ -689,23 +844,31 @@ class HelloCheckbutton
|
|
689
844
|
|
690
845
|
frame {
|
691
846
|
checkbutton {
|
692
|
-
text '
|
693
|
-
variable <=> [@person, :
|
694
|
-
|
695
|
-
|
696
|
-
checkbutton {
|
697
|
-
text 'Snowboarding'
|
698
|
-
variable <=> [@person, :snowboarding]
|
699
|
-
}
|
700
|
-
|
701
|
-
checkbutton {
|
702
|
-
text 'Snowmobiling'
|
703
|
-
variable <=> [@person, :snowmobiling]
|
847
|
+
text 'Snow Activities'
|
848
|
+
variable <=> [@person, :snow_activities]
|
849
|
+
alternate <=> [@person, :snow_activities_alternate] # binds half-checked state
|
704
850
|
}
|
705
851
|
|
706
|
-
|
707
|
-
|
708
|
-
|
852
|
+
frame {
|
853
|
+
checkbutton {
|
854
|
+
text 'Skiing'
|
855
|
+
variable <=> [@person, :skiing]
|
856
|
+
}
|
857
|
+
|
858
|
+
checkbutton {
|
859
|
+
text 'Snowboarding'
|
860
|
+
variable <=> [@person, :snowboarding]
|
861
|
+
}
|
862
|
+
|
863
|
+
checkbutton {
|
864
|
+
text 'Snowmobiling'
|
865
|
+
variable <=> [@person, :snowmobiling]
|
866
|
+
}
|
867
|
+
|
868
|
+
checkbutton {
|
869
|
+
text 'Snowshoeing'
|
870
|
+
variable <=> [@person, :snowshoeing]
|
871
|
+
}
|
709
872
|
}
|
710
873
|
}
|
711
874
|
|
@@ -732,13 +895,127 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_checkbutton'"
|
|
732
895
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
733
896
|
|
734
897
|
```
|
735
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
898
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_checkbutton.rb
|
736
899
|
```
|
737
900
|
|
738
901
|
Glimmer app:
|
739
902
|
|
740
903
|
![glimmer dsl tk screenshot sample hello checkbutton](images/glimmer-dsl-tk-screenshot-sample-hello-checkbutton.png)
|
741
904
|
|
905
|
+
![glimmer dsl tk screenshot sample hello checkbutton](images/glimmer-dsl-tk-screenshot-sample-hello-checkbutton-all-checked.png)
|
906
|
+
|
907
|
+
![glimmer dsl tk screenshot sample hello checkbutton](images/glimmer-dsl-tk-screenshot-sample-hello-checkbutton-none-checked.png)
|
908
|
+
|
909
|
+
### Hello, Radiobutton!
|
910
|
+
|
911
|
+
Glimmer code (from [samples/hello/hello_radiobutton.rb](samples/hello/hello_radiobutton.rb)):
|
912
|
+
|
913
|
+
```ruby
|
914
|
+
require 'glimmer-dsl-tk'
|
915
|
+
|
916
|
+
class HelloRadiobutton
|
917
|
+
class Person
|
918
|
+
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
919
|
+
|
920
|
+
def initialize
|
921
|
+
reset!
|
922
|
+
end
|
923
|
+
|
924
|
+
def reset!
|
925
|
+
self.male = true
|
926
|
+
self.female = nil
|
927
|
+
self.child = nil
|
928
|
+
self.teen = nil
|
929
|
+
self.adult = true
|
930
|
+
self.senior = nil
|
931
|
+
end
|
932
|
+
end
|
933
|
+
|
934
|
+
include Glimmer
|
935
|
+
|
936
|
+
def initialize
|
937
|
+
@person = Person.new
|
938
|
+
end
|
939
|
+
|
940
|
+
def launch
|
941
|
+
root {
|
942
|
+
title 'Hello, Radio!'
|
943
|
+
background '#ececec' if OS.mac?
|
944
|
+
|
945
|
+
label {
|
946
|
+
text 'Gender:'
|
947
|
+
font 'caption'
|
948
|
+
}
|
949
|
+
|
950
|
+
frame {
|
951
|
+
radiobutton {
|
952
|
+
text 'Male'
|
953
|
+
variable <=> [@person, :male]
|
954
|
+
}
|
955
|
+
|
956
|
+
radiobutton {
|
957
|
+
text 'Female'
|
958
|
+
variable <=> [@person, :female]
|
959
|
+
}
|
960
|
+
}
|
961
|
+
|
962
|
+
label {
|
963
|
+
text 'Age Group:'
|
964
|
+
font 'caption'
|
965
|
+
}
|
966
|
+
|
967
|
+
frame {
|
968
|
+
radiobutton {
|
969
|
+
text 'Child'
|
970
|
+
variable <=> [@person, :child]
|
971
|
+
}
|
972
|
+
|
973
|
+
radiobutton {
|
974
|
+
text 'Teen'
|
975
|
+
variable <=> [@person, :teen]
|
976
|
+
}
|
977
|
+
|
978
|
+
radiobutton {
|
979
|
+
text 'Adult'
|
980
|
+
variable <=> [@person, :adult]
|
981
|
+
}
|
982
|
+
|
983
|
+
radiobutton {
|
984
|
+
text 'Senior'
|
985
|
+
variable <=> [@person, :senior]
|
986
|
+
}
|
987
|
+
}
|
988
|
+
|
989
|
+
button {
|
990
|
+
text 'Reset'
|
991
|
+
|
992
|
+
command do
|
993
|
+
@person.reset!
|
994
|
+
end
|
995
|
+
}
|
996
|
+
}.open
|
997
|
+
end
|
998
|
+
end
|
999
|
+
|
1000
|
+
HelloRadiobutton.new.launch
|
1001
|
+
```
|
1002
|
+
|
1003
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1004
|
+
|
1005
|
+
```
|
1006
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_radiobutton'"
|
1007
|
+
```
|
1008
|
+
|
1009
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1010
|
+
|
1011
|
+
```
|
1012
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_radiobutton.rb
|
1013
|
+
```
|
1014
|
+
|
1015
|
+
Glimmer app:
|
1016
|
+
|
1017
|
+
![glimmer dsl tk screenshot sample hello radiobutton](images/glimmer-dsl-tk-screenshot-sample-hello-radiobutton.png)
|
1018
|
+
|
742
1019
|
### Hello, Frame!
|
743
1020
|
|
744
1021
|
Glimmer code (from [samples/hello/hello_frame.rb](samples/hello/hello_frame.rb)):
|
@@ -805,7 +1082,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_frame'"
|
|
805
1082
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
806
1083
|
|
807
1084
|
```
|
808
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1085
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_frame.rb
|
809
1086
|
```
|
810
1087
|
|
811
1088
|
Glimmer app:
|
@@ -855,7 +1132,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_root'"
|
|
855
1132
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
856
1133
|
|
857
1134
|
```
|
858
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1135
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_root.rb
|
859
1136
|
```
|
860
1137
|
|
861
1138
|
Glimmer app:
|
@@ -909,7 +1186,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_notebook'"
|
|
909
1186
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
910
1187
|
|
911
1188
|
```
|
912
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1189
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_notebook.rb
|
913
1190
|
```
|
914
1191
|
|
915
1192
|
Glimmer app:
|
@@ -1022,7 +1299,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_label'"
|
|
1022
1299
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1023
1300
|
|
1024
1301
|
```
|
1025
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1302
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_label.rb
|
1026
1303
|
```
|
1027
1304
|
|
1028
1305
|
Glimmer app:
|
@@ -1124,7 +1401,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_message_box'"
|
|
1124
1401
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1125
1402
|
|
1126
1403
|
```
|
1127
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1404
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_message_box.rb
|
1128
1405
|
```
|
1129
1406
|
|
1130
1407
|
Glimmer app:
|
@@ -1141,12 +1418,12 @@ Glimmer code (from [samples/hello/hello_combobox.rb](samples/hello/hello_combobo
|
|
1141
1418
|
root {
|
1142
1419
|
title 'Hello, Combobox!'
|
1143
1420
|
|
1144
|
-
combobox {
|
1145
|
-
|
1421
|
+
combobox {
|
1422
|
+
readonly true # this applies to text editing only (item selection still triggers a write to model)
|
1146
1423
|
text <=> [person, :country]
|
1147
1424
|
}
|
1148
1425
|
|
1149
|
-
button {
|
1426
|
+
button {
|
1150
1427
|
text "Reset Selection"
|
1151
1428
|
command {
|
1152
1429
|
person.reset_country
|
@@ -1165,7 +1442,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_combobox'"
|
|
1165
1442
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1166
1443
|
|
1167
1444
|
```
|
1168
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1445
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_combobox.rb
|
1169
1446
|
```
|
1170
1447
|
|
1171
1448
|
Glimmer app:
|
@@ -1205,7 +1482,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_list_single_selection'"
|
|
1205
1482
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1206
1483
|
|
1207
1484
|
```
|
1208
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1485
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_list_single_selection.rb
|
1209
1486
|
```
|
1210
1487
|
|
1211
1488
|
Glimmer app:
|
@@ -1243,13 +1520,302 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_list_multi_selection'"
|
|
1243
1520
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1244
1521
|
|
1245
1522
|
```
|
1246
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1523
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_list_multi_selection.rb
|
1247
1524
|
```
|
1248
1525
|
|
1249
1526
|
Glimmer app:
|
1250
1527
|
|
1251
1528
|
![glimmer dsl tk screenshot sample hello list multi selection](images/glimmer-dsl-tk-screenshot-sample-hello-list-multi-selection.png)
|
1252
1529
|
|
1530
|
+
### Hello, Entry!
|
1531
|
+
|
1532
|
+
Glimmer code (from [samples/hello/hello_entry.rb](samples/hello/hello_entry.rb)):
|
1533
|
+
|
1534
|
+
```ruby
|
1535
|
+
require 'glimmer-dsl-tk'
|
1536
|
+
|
1537
|
+
class HelloEntry
|
1538
|
+
include Glimmer
|
1539
|
+
|
1540
|
+
attr_accessor :default, :password, :telephone, :read_only
|
1541
|
+
|
1542
|
+
def initialize
|
1543
|
+
self.default = 'default'
|
1544
|
+
self.password = 'password'
|
1545
|
+
self.telephone = '555-555-5555'
|
1546
|
+
self.read_only = 'Telephone area code is 555'
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
def launch
|
1550
|
+
root {
|
1551
|
+
title 'Hello, Entry!'
|
1552
|
+
|
1553
|
+
label {
|
1554
|
+
grid sticky: 'ew'
|
1555
|
+
text 'default entry'
|
1556
|
+
}
|
1557
|
+
entry {
|
1558
|
+
grid sticky: 'ew'
|
1559
|
+
text <=> [self, :default]
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
label {
|
1563
|
+
grid sticky: 'ew'
|
1564
|
+
text 'password entry'
|
1565
|
+
}
|
1566
|
+
entry {
|
1567
|
+
grid sticky: 'ew'
|
1568
|
+
show '*'
|
1569
|
+
text <=> [self, :password]
|
1570
|
+
}
|
1571
|
+
|
1572
|
+
@validated_entry_label = label {
|
1573
|
+
grid sticky: 'ew'
|
1574
|
+
text 'entry with event handlers'
|
1575
|
+
}
|
1576
|
+
entry {
|
1577
|
+
grid sticky: 'ew'
|
1578
|
+
text <=> [self, :telephone]
|
1579
|
+
validate 'key'
|
1580
|
+
|
1581
|
+
## this event kicks in just after the user typed and before modifying the text variable
|
1582
|
+
on('validate') do |new_text_variable|
|
1583
|
+
telephone?(new_text_variable.value)
|
1584
|
+
end
|
1585
|
+
|
1586
|
+
## this event kicks in just after the text variable is validated and before it is modified
|
1587
|
+
on('invalid') do |validate_args|
|
1588
|
+
@validated_entry_label.text = "#{validate_args.string} is not valid!"
|
1589
|
+
@validated_entry_label.foreground = 'red'
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
## this event kicks in just after the text variable is validated and modified
|
1593
|
+
on('change') do |new_text_variable|
|
1594
|
+
self.read_only = "Telephone area code is #{new_text_variable.value.gsub(/[^0-9]/, '')[0...3]}"
|
1595
|
+
@validated_entry_label.text = 'entry with event handlers'
|
1596
|
+
@validated_entry_label.foreground = nil
|
1597
|
+
end
|
1598
|
+
}
|
1599
|
+
|
1600
|
+
label {
|
1601
|
+
grid sticky: 'ew'
|
1602
|
+
text 'read-only entry'
|
1603
|
+
}
|
1604
|
+
entry {
|
1605
|
+
grid sticky: 'ew'
|
1606
|
+
text <=> [self, :read_only]
|
1607
|
+
readonly true
|
1608
|
+
}
|
1609
|
+
}.open
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
def telephone?(text)
|
1613
|
+
!!text.match(/^\d{0,3}[-.\/]?\d{0,3}[-.\/]?\d{0,4}$/)
|
1614
|
+
end
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
HelloEntry.new.launch
|
1618
|
+
```
|
1619
|
+
|
1620
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1621
|
+
|
1622
|
+
```
|
1623
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_entry'"
|
1624
|
+
```
|
1625
|
+
|
1626
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1627
|
+
|
1628
|
+
```
|
1629
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_entry.rb
|
1630
|
+
```
|
1631
|
+
|
1632
|
+
Glimmer app:
|
1633
|
+
|
1634
|
+
![glimmer dsl tk screenshot sample hello entry](images/glimmer-dsl-tk-screenshot-sample-hello-entry.png)
|
1635
|
+
![glimmer dsl tk screenshot sample hello entry validated](images/glimmer-dsl-tk-screenshot-sample-hello-entry-validated.png)
|
1636
|
+
|
1637
|
+
### Hello, Text!
|
1638
|
+
|
1639
|
+
[Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) automatically provides a `text` attribute for the `text` widget that enables updating its content simply without worrying about whether to manually insert by index, delete, or append.
|
1640
|
+
|
1641
|
+
Glimmer code (from [samples/hello/hello_text.rb](samples/hello/hello_text.rb)):
|
1642
|
+
|
1643
|
+
```ruby
|
1644
|
+
require 'glimmer-dsl-tk'
|
1645
|
+
|
1646
|
+
class HelloText
|
1647
|
+
include Glimmer
|
1648
|
+
|
1649
|
+
COLOR_OPTIONS = %w[black purple blue green orange yellow red white].map(&:capitalize)
|
1650
|
+
FOREGROUND_PROMPT = '<select foreground>'
|
1651
|
+
BACKGROUND_PROMPT = '<select background>'
|
1652
|
+
|
1653
|
+
def initialize
|
1654
|
+
@foreground = FOREGROUND_PROMPT
|
1655
|
+
@background = BACKGROUND_PROMPT
|
1656
|
+
end
|
1657
|
+
|
1658
|
+
attr_accessor :foreground
|
1659
|
+
|
1660
|
+
def foreground_options
|
1661
|
+
[FOREGROUND_PROMPT] + COLOR_OPTIONS
|
1662
|
+
end
|
1663
|
+
|
1664
|
+
attr_accessor :background
|
1665
|
+
|
1666
|
+
def background_options
|
1667
|
+
[BACKGROUND_PROMPT] + COLOR_OPTIONS
|
1668
|
+
end
|
1669
|
+
|
1670
|
+
def launch
|
1671
|
+
root {
|
1672
|
+
title 'Hello, Text!'
|
1673
|
+
|
1674
|
+
frame {
|
1675
|
+
grid row: 0, column: 0
|
1676
|
+
|
1677
|
+
combobox {
|
1678
|
+
grid row: 0, column: 0, column_weight: 1
|
1679
|
+
readonly true
|
1680
|
+
text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }]
|
1681
|
+
}
|
1682
|
+
|
1683
|
+
combobox {
|
1684
|
+
grid row: 0, column: 1, column_weight: 1
|
1685
|
+
readonly true
|
1686
|
+
text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'black' : value) }]
|
1687
|
+
}
|
1688
|
+
}
|
1689
|
+
|
1690
|
+
@text = text {
|
1691
|
+
grid row: 1, column: 0, row_weight: 1
|
1692
|
+
text <<~MULTI_LINE_STRING
|
1693
|
+
According to the National Post, a heavy metal-loving high school principal in Canada will be allowed to keep her job, days after a public campaign to oust her made headlines around the globe.
|
1694
|
+
|
1695
|
+
Parents at Eden High School in St. Catharines, Ontario launched a petition to remove principal Sharon Burns after discovering she's an IRON MAIDEN fan.
|
1696
|
+
|
1697
|
+
The petition, titled "Eden High School Principal, Sharon Burns, Needs to Be Transferred Immediately!" read, "We are deeply disturbed that the principal assigned to the school blatantly showed Satanic symbols and her allegiance to Satanic practices on her public social media platforms where all the students can see them under @edenprincipal (not her personal account)."
|
1698
|
+
|
1699
|
+
More than 500 people signed the petition to transfer Burns after she posted a picture of herself flashing the "devil horns" hand sign with a doll of the MAIDEN zombie mascot Eddie behind her as well as a personalized license plate reading "IRNMADEN" and a handwritten note that reads "Eddie 666" on a car's dashboard.
|
1700
|
+
|
1701
|
+
|
1702
|
+
The number 666 is used to represent the devil, and is featured prominently in MAIDEN's artwork by the band, whose classic third album is titled "The Number Of The Beast".
|
1703
|
+
|
1704
|
+
The petition was later updated to state that the demand for her transfer is not because of her love for metal, but for "openly displaying her own handmade sign with the 666 clearly displayed on it".
|
1705
|
+
|
1706
|
+
The creator of the original petition wrote: "Sharon knows full well what she did was simply inappropriate, unnecessary and not professional but has yet to publicly admit so and is willing to allow people to believe a completely different story, making very real concerns seem petty."
|
1707
|
+
|
1708
|
+
Meanwhile, a counter-petition supporting Burns garnered over 20,000 signatures.
|
1709
|
+
|
1710
|
+
"It is ridiculous that a couple of parents judge her role as a principal only based on an Instagram post. (About liking the band IRON MAIDEN. That's it.) Eden High School is a public school. Not a Christian school," the petition titled "We need Mrs Burns" stated. "She has made Eden a safe space for so many people. She spreads nothing but love and kindness."
|
1711
|
+
|
1712
|
+
After the complaints were aired, the District School Board of Niagara spoke with Burns and the parents who launched the petition, and the issue is over as far as the board is concerned, Kim Sweeney, the board's chief communications officer, told the National Post. No disciplinary action or policy changes were needed.
|
1713
|
+
|
1714
|
+
"Our belief is that taste in music is subjective and we support that both students and staff enjoy a wide variety of genres," Sweeney said.
|
1715
|
+
|
1716
|
+
The original petition has since been removed.
|
1717
|
+
MULTI_LINE_STRING
|
1718
|
+
}
|
1719
|
+
}.open
|
1720
|
+
end
|
1721
|
+
end
|
1722
|
+
|
1723
|
+
HelloText.new.launch
|
1724
|
+
```
|
1725
|
+
|
1726
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1727
|
+
|
1728
|
+
```
|
1729
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_text'"
|
1730
|
+
```
|
1731
|
+
|
1732
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1733
|
+
|
1734
|
+
```
|
1735
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_text.rb
|
1736
|
+
```
|
1737
|
+
|
1738
|
+
Glimmer app:
|
1739
|
+
|
1740
|
+
![glimmer dsl tk screenshot sample hello text](images/glimmer-dsl-tk-screenshot-sample-hello-text.png)
|
1741
|
+
|
1742
|
+
### Hello, Spinbox!
|
1743
|
+
|
1744
|
+
Glimmer code (from [samples/hello/hello_spinbox.rb](samples/hello/hello_spinbox.rb)):
|
1745
|
+
|
1746
|
+
```ruby
|
1747
|
+
require 'glimmer-dsl-tk'
|
1748
|
+
|
1749
|
+
class HelloSpinbox
|
1750
|
+
class Person
|
1751
|
+
attr_accessor :donation
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
include Glimmer
|
1755
|
+
|
1756
|
+
def initialize
|
1757
|
+
@person = Person.new
|
1758
|
+
@person.donation = 5.0 # in dollars
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
def launch
|
1762
|
+
root {
|
1763
|
+
title 'Hello, Spinbox!'
|
1764
|
+
|
1765
|
+
label {
|
1766
|
+
text 'Please select the amount you would like to donate to the poor:'
|
1767
|
+
}
|
1768
|
+
|
1769
|
+
frame {
|
1770
|
+
label {
|
1771
|
+
grid row: 0, column: 0
|
1772
|
+
text 'Amount:'
|
1773
|
+
font 'caption'
|
1774
|
+
}
|
1775
|
+
|
1776
|
+
label {
|
1777
|
+
grid row: 0, column: 1
|
1778
|
+
text '$'
|
1779
|
+
}
|
1780
|
+
|
1781
|
+
spinbox { |sb|
|
1782
|
+
grid row: 0, column: 2
|
1783
|
+
from 1.0 # minimum value
|
1784
|
+
to 150.0 # maximum value
|
1785
|
+
increment 5.0 # increment on up and down
|
1786
|
+
format '%0.2f'
|
1787
|
+
text <=> [@person, :donation]
|
1788
|
+
}
|
1789
|
+
|
1790
|
+
label {
|
1791
|
+
grid row: 1, column: 0, columnspan: 3
|
1792
|
+
text <=> [@person, :donation, on_read: ->(value) { "Thank you for your donation of $#{"%.2f" % value.to_f}"}]
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
}
|
1796
|
+
}.open
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
HelloSpinbox.new.launch
|
1801
|
+
```
|
1802
|
+
|
1803
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1804
|
+
|
1805
|
+
```
|
1806
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_spinbox'"
|
1807
|
+
```
|
1808
|
+
|
1809
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1810
|
+
|
1811
|
+
```
|
1812
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_spinbox.rb
|
1813
|
+
```
|
1814
|
+
|
1815
|
+
Glimmer app:
|
1816
|
+
|
1817
|
+
![glimmer dsl tk screenshot sample hello spinbox](images/glimmer-dsl-tk-screenshot-sample-hello-spinbox.png)
|
1818
|
+
|
1253
1819
|
### Hello, Computed!
|
1254
1820
|
|
1255
1821
|
Glimmer code (from [samples/hello/hello_computed.rb](samples/hello/hello_computed.rb)):
|
@@ -1323,7 +1889,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_computed'"
|
|
1323
1889
|
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1324
1890
|
|
1325
1891
|
```
|
1326
|
-
ruby -r ./lib/glimmer-dsl-tk.rb
|
1892
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_computed.rb
|
1327
1893
|
```
|
1328
1894
|
|
1329
1895
|
Glimmer app:
|