glimmer-dsl-tk 0.0.18 → 0.0.23
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 +36 -0
- data/README.md +429 -21
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/message_box_expression.rb +4 -1
- data/lib/glimmer/dsl/tk/on_expression.rb +35 -0
- data/lib/glimmer/dsl/tk/widget_expression.rb +0 -7
- data/lib/glimmer/tk/button_proxy.rb +2 -3
- data/lib/glimmer/tk/checkbutton_proxy.rb +36 -0
- data/lib/glimmer/tk/combobox_proxy.rb +34 -0
- data/lib/glimmer/tk/commandable.rb +42 -0
- data/lib/glimmer/tk/entry_proxy.rb +3 -0
- data/lib/glimmer/tk/frame_proxy.rb +1 -0
- data/lib/glimmer/tk/label_proxy.rb +3 -0
- 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 +122 -2
- 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 +102 -23
- data/lib/glimmer-dsl-tk.rb +1 -0
- data/samples/hello/hello_checkbutton.rb +131 -0
- data/samples/hello/hello_notebook.rb +1 -1
- data/samples/hello/hello_radiobutton.rb +87 -0
- data/samples/hello/hello_root.rb +48 -0
- metadata +45 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d722c9396a9adb7252e4fc65c283fbf923dbe0cb93e17a9d34649ea887f5e56
|
4
|
+
data.tar.gz: 20682a6aa497800f683b87fc180754a58a96362a5a286fab3754bc38edd5d084
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77c488d614a997861369fd032fc1ebc578bee01aa8367c0fd267b99442ec462769f0218c11e236533b3443558294c2ca0940c773777698f4216df85cd1179243
|
7
|
+
data.tar.gz: 521a5c5e3db695b7938fc225619779114e32c06fa2bce870de16f233597d212b3662218a101e95921733c58f4ea02764598167eaa507835bbb25855187566b6a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,41 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.23
|
4
|
+
|
5
|
+
- Hello, Radiobutton!
|
6
|
+
- Support `radiobutton` ensuring that sibling radio buttons share the same variable to achieve mutually exclusive selection
|
7
|
+
- Improved Hello, Checkbutton! sample to demonstrate alternate checkbutton value (half-checked state)
|
8
|
+
- Support `checkbutton` with specified `onvalue` and `offvalue` (when they do not have values 1 and 0)
|
9
|
+
- Alias `root` `title` attribute as `text` & add children attribute to widgets
|
10
|
+
- Alias `notebook` `frame` `:title` as `:text`
|
11
|
+
- Alias message_box `:title` as `:text`
|
12
|
+
- Fix reference to `Glimmer::Tk::CheckbuttonProxy` (was `Glimmer::Tk::ChecktbuttonProxy`)
|
13
|
+
|
14
|
+
## 0.0.22
|
15
|
+
|
16
|
+
- Hello, Checkbutton!
|
17
|
+
- Support checkbutton data-binding
|
18
|
+
|
19
|
+
## 0.0.21
|
20
|
+
|
21
|
+
- Support event bindings via `on(event) {}` syntax nestable under any widget
|
22
|
+
- Support `root` event binding: `'WM_DELETE_WINDOW'` and alias `'DELETE_WINDOW'`
|
23
|
+
- Support `root` event binding: `'OPEN_WINDOW'`
|
24
|
+
- Support `root` attribute: `background` (any color including `systemTransparent`)
|
25
|
+
- Support `root` boolean attribute: `alpha`
|
26
|
+
- Support `root` boolean attributes: `fullscreen`, `topmost`, `transparent`
|
27
|
+
- Support `root` attributes: `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`
|
28
|
+
- Support `root` attribute: `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`)
|
29
|
+
|
30
|
+
## 0.0.20
|
31
|
+
|
32
|
+
- Hello, Root! sample
|
33
|
+
- Support `root` `width`, `height`, `x`, `y` attributes
|
34
|
+
- Support `root` attribute: `resizable`
|
35
|
+
- Support `root` attribute: `minsize`
|
36
|
+
- Support `root` attribute: `maxsize`
|
37
|
+
- Set minimum width/height on `root` (190 pixels)
|
38
|
+
|
3
39
|
## 0.0.18
|
4
40
|
|
5
41
|
- Hello, Frame! sample
|
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.23
|
2
2
|
## MRI Ruby Desktop Development GUI Library
|
3
3
|
[](http://badge.fury.io/rb/glimmer-dsl-tk)
|
4
4
|
[](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
|
@@ -83,17 +83,22 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
83
83
|
- [Icon Photo](#icon-photo)
|
84
84
|
- [The Grid Geometry Manager](#the-grid-geometry-manager)
|
85
85
|
- [Bidirectional Data-Binding](#bidirectional-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
|
+
- [Checkbutton Data-Binding](#checkbutton-data-binding)
|
92
|
+
- [Radiobutton Data-Binding](#radiobutton-data-binding)
|
93
|
+
- [Command Callback](#command-callback)
|
92
94
|
- [Gotchas](#gotchas)
|
93
95
|
- [Samples](#samples)
|
94
96
|
- [Hello, World!](#hello-world)
|
95
97
|
- [Hello, Button!](#hello-button)
|
98
|
+
- [Hello, Checkbutton!](#hello-checkbutton)
|
99
|
+
- [Hello, Radiobutton!](#hello-radiobutton)
|
96
100
|
- [Hello, Frame!](#hello-frame)
|
101
|
+
- [Hello, Root!](#hello-root)
|
97
102
|
- [Hello, Notebook!](#hello-notebook)
|
98
103
|
- [Hello, Label!](#hello-label)
|
99
104
|
- [Hello, Message Box!](#hello-message-box)
|
@@ -119,7 +124,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
119
124
|
For example, on the Mac, you can:
|
120
125
|
- Install the ActiveTcl Mac package from [ActiveState.com](https://activestate.com)
|
121
126
|
- Install [RVM](https://rvm.io/) by running `\curl -sSL https://get.rvm.io | bash -s stable` (and run `curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -` if needed for mentioned security reasons)
|
122
|
-
- Run: `rvm install
|
127
|
+
- Run: `rvm install 3.0.2 --enable-shared --enable-pthread --with-tk --with-tcl`
|
123
128
|
- Run: `gem install tk -v0.4.0`
|
124
129
|
|
125
130
|
Afterwards, if you open `irb`, you should be able to run `require 'tk'` successfully.
|
@@ -137,7 +142,7 @@ gem install glimmer-dsl-tk
|
|
137
142
|
|
138
143
|
Add the following to `Gemfile`:
|
139
144
|
```
|
140
|
-
gem 'glimmer-dsl-tk', '~> 0.0.
|
145
|
+
gem 'glimmer-dsl-tk', '~> 0.0.23'
|
141
146
|
```
|
142
147
|
|
143
148
|
And, then run:
|
@@ -179,6 +184,7 @@ The Glimmer GUI DSL follows these simple concepts in mapping from Tk syntax:
|
|
179
184
|
- **Widget Keyword**: Any Tk widget (e.g. `Tk::Tile::Label`) or toplevel window (e.g. `TkRoot`) may be declared by its lower-case underscored name without the namespace (e.g. `label` or `root`). This is called a keyword and is represented in the Glimmer GUI DSL by a Ruby method behind the scenes.
|
180
185
|
- **Args**: Any keyword method may optionally take arguments surrounded by parentheses (e.g. a `frame` nested under a `notebook` may receive tab options like `frame(text: 'Users')`, which gets used behind the scenes by Tk code such as `notebook.add tab, text: 'Users'`)
|
181
186
|
- **Content/Options Block**: Any keyword may optionally be followed by a Ruby curly-brace block containing nested widgets (content) and attributes (options). Attributes are simply Tk option keywords followed by arguments and no block (e.g. `title 'Hello, World!'` under a `root`)
|
187
|
+
- **Event Binding Block**: `on(event) {}` keyword receiving a Tk binding event name (e.g. `KeyPress` or `ComboboxSelected`). No need to surround event by `<>` as [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) takes care of that automatically.
|
182
188
|
|
183
189
|
Example of an app written in [Tk](https://www.tcl.tk/) imperative syntax:
|
184
190
|
|
@@ -198,6 +204,15 @@ notebook.add tab2, text: 'French'
|
|
198
204
|
label2 = ::Tk::Tile::Label.new(tab2).grid
|
199
205
|
label2.text = 'Bonjour, Univers!'
|
200
206
|
|
207
|
+
root.bind('KeyPress') do |event|
|
208
|
+
case event.keysym
|
209
|
+
when 'e', 'E'
|
210
|
+
notebook.select(0)
|
211
|
+
when 'f', 'F'
|
212
|
+
notebook.select(1)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
201
216
|
root.mainloop
|
202
217
|
```
|
203
218
|
|
@@ -207,7 +222,7 @@ Example of the same app written in [Glimmer](https://github.com/AndyObtiva/glimm
|
|
207
222
|
root {
|
208
223
|
title 'Hello, Notebook!'
|
209
224
|
|
210
|
-
notebook {
|
225
|
+
@notebook = notebook {
|
211
226
|
frame(text: 'English') {
|
212
227
|
label {
|
213
228
|
text 'Hello, World!'
|
@@ -220,6 +235,15 @@ root {
|
|
220
235
|
}
|
221
236
|
}
|
222
237
|
}
|
238
|
+
|
239
|
+
on('KeyPress') do |event|
|
240
|
+
case event.keysym
|
241
|
+
when 'e', 'E'
|
242
|
+
@notebook.select(0)
|
243
|
+
when 'f', 'F'
|
244
|
+
@notebook.select(1)
|
245
|
+
end
|
246
|
+
end
|
223
247
|
}.open
|
224
248
|
```
|
225
249
|
|
@@ -227,19 +251,53 @@ root {
|
|
227
251
|
|
228
252
|
keyword(args) | attributes | event bindings & callbacks
|
229
253
|
------------- | ---------- | ---------
|
230
|
-
`button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command`
|
254
|
+
`button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
|
255
|
+
`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 {}`
|
256
|
+
`combobox` | `state`, `text` | `'ComboboxSelected'`
|
231
257
|
`entry` | `width`, `text` | None
|
232
258
|
`frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
|
233
259
|
`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
|
234
260
|
`list` | `selectmode`, `selection` | None
|
235
261
|
`message_box(type: , message: , detail: , title: , icon: , default: , parent: )` | None | None
|
236
262
|
`notebook` | None | None
|
237
|
-
`
|
263
|
+
`radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
|
264
|
+
`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'`
|
238
265
|
|
239
266
|
#### Common Attributes
|
240
267
|
|
241
268
|
- `grid`: `Hash` of `:row`, `:column`, `:padx`, `:pady`, `:sticky` (`'e', 'w', 'n', 's'` or any combination of direction letters)
|
242
269
|
|
270
|
+
#### Common Event Bindings
|
271
|
+
|
272
|
+
- `Activate`
|
273
|
+
- `Deactivate`
|
274
|
+
- `MouseWheel`
|
275
|
+
- `KeyPress`
|
276
|
+
- `KeyRelease`
|
277
|
+
- `ButtonPress`
|
278
|
+
- `ButtonRelease`
|
279
|
+
- `Motion`
|
280
|
+
- `Configure`
|
281
|
+
- `Map`
|
282
|
+
- `Unmap`
|
283
|
+
- `Visibility`
|
284
|
+
- `Expose`
|
285
|
+
- `Destroy`
|
286
|
+
- `FocusIn`
|
287
|
+
- `FocusOut`
|
288
|
+
- `Enter`
|
289
|
+
- `Leave`
|
290
|
+
- `Property`
|
291
|
+
- `Colormap`
|
292
|
+
- `MapRequest`
|
293
|
+
- `CirculateRequest`
|
294
|
+
- `ResizeRequest`
|
295
|
+
- `ConfigureRequest`
|
296
|
+
- `Create`
|
297
|
+
- `Gravity`
|
298
|
+
- `Reparent`
|
299
|
+
- `Circulate`
|
300
|
+
|
243
301
|
#### Common Themed Widget States
|
244
302
|
|
245
303
|
- `active?`
|
@@ -255,6 +313,10 @@ keyword(args) | attributes | event bindings & callbacks
|
|
255
313
|
|
256
314
|
### Smart Defaults and Convensions
|
257
315
|
|
316
|
+
#### Event Bindings
|
317
|
+
|
318
|
+
Any events that normally can be accepted by the Tk `bind` or `protocol` methods can be accepted by the `on(event) {}` listener syntax. 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.
|
319
|
+
|
258
320
|
#### Grid Layout
|
259
321
|
|
260
322
|
`grid` layout is the default on most widgets (which support it).
|
@@ -315,7 +377,7 @@ More details can be found in the [Hello, Computed!](#hello-computed) sample belo
|
|
315
377
|
|
316
378
|
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).
|
317
379
|
|
318
|
-
###
|
380
|
+
### Label Data-Binding
|
319
381
|
|
320
382
|
Example:
|
321
383
|
|
@@ -323,11 +385,11 @@ This assumes a `Person` model with a `country` attribute.
|
|
323
385
|
|
324
386
|
```ruby
|
325
387
|
label {
|
326
|
-
text
|
388
|
+
text <= [person, :country]
|
327
389
|
}
|
328
390
|
```
|
329
391
|
|
330
|
-
That code binds the `textvariable` value of the `label` to the `country` property on the `person` model.
|
392
|
+
That code binds the `textvariable` value of the `label` unidirectionally (read-only) to the `country` property on the `person` model.
|
331
393
|
|
332
394
|
It automatically handles all the Tk plumbing behind the scenes.
|
333
395
|
|
@@ -368,8 +430,8 @@ This assumes a `Person` model with a `country` attribute representing their curr
|
|
368
430
|
}
|
369
431
|
```
|
370
432
|
|
371
|
-
That code binds the `items` text of the `list` to the `country_options`
|
372
|
-
It also binds the `selection` text of the `list` to the `country`
|
433
|
+
That code binds the `items` text of the `list` to the `country_options` attribute on the `person` model (data-binding attribute + "_options" by convention).
|
434
|
+
It also binds the `selection` text of the `list` to the `country` attribute on the `person` model.
|
373
435
|
|
374
436
|
It automatically handles all the Tk plumbing behind the scenes.
|
375
437
|
|
@@ -389,8 +451,8 @@ This assumes a `Person` model with a `provinces` attribute representing their cu
|
|
389
451
|
}
|
390
452
|
```
|
391
453
|
|
392
|
-
That code binds the `items` text of the `list` to the `provinces_options`
|
393
|
-
It also binds the `selection` text of the `list` to the `provinces`
|
454
|
+
That code binds the `items` text of the `list` to the `provinces_options` attribute on the `person` model (data-binding attribute + "_options" by convention).
|
455
|
+
It also binds the `selection` text of the `list` to the `provinces` attribute on the `person` model.
|
394
456
|
|
395
457
|
It automatically handles all the Tk plumbing behind the scenes.
|
396
458
|
|
@@ -408,30 +470,75 @@ This assumes a `Person` model with a `country` attribute.
|
|
408
470
|
}
|
409
471
|
```
|
410
472
|
|
411
|
-
That code binds the `textvariable` value of the `entry` to the `country`
|
473
|
+
That code binds the `textvariable` value of the `entry` to the `country` attribute on the `person` model.
|
412
474
|
|
413
475
|
It automatically handles all the Tk plumbing behind the scenes.
|
414
476
|
|
415
477
|
More details can be found in the [Hello, Computed!](#hello-computed) sample below.
|
416
478
|
|
417
|
-
|
479
|
+
### Checkbutton Data-Binding
|
480
|
+
|
481
|
+
Example:
|
482
|
+
|
483
|
+
This assumes a `Person` model with a boolean `adult` attribute.
|
484
|
+
|
485
|
+
```ruby
|
486
|
+
checkbutton {
|
487
|
+
variable <=> [person, :adult]
|
488
|
+
}
|
489
|
+
```
|
490
|
+
|
491
|
+
That code binds the `variable` value of the `checkbutton` to the boolean `adult` attribute on the `person` model.
|
492
|
+
|
493
|
+
It automatically handles all the Tk plumbing behind the scenes.
|
494
|
+
|
495
|
+
If you need to display a half-checked `checkbutton`, bind to `alternate` attribute.
|
496
|
+
|
497
|
+
More details can be found in the [Hello, Checkbutton!](#hello-checkbutton) sample below.
|
498
|
+
|
499
|
+
### Radiobutton Data-Binding
|
500
|
+
|
501
|
+
Example:
|
502
|
+
|
503
|
+
This assumes a `Person` model with boolean `male` and `female` attributes.
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
radiobutton {
|
507
|
+
text 'Male'
|
508
|
+
variable <=> [@person, :male]
|
509
|
+
}
|
510
|
+
|
511
|
+
radiobutton {
|
512
|
+
text 'Female'
|
513
|
+
variable <=> [@person, :female]
|
514
|
+
}
|
515
|
+
```
|
516
|
+
|
517
|
+
That code binds the `variable` value of the `radiobutton` to the boolean `male` and `female` attributes on the `person` model.
|
518
|
+
|
519
|
+
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`.
|
520
|
+
|
521
|
+
For very rare cases, if you need to display a half-selected `radiobutton`, set `alternate` attribute as `true` when the `variable` value is `false`.
|
522
|
+
|
523
|
+
More details can be found in the [Hello, Radiobutton!](#hello-radiobutton) sample below.
|
524
|
+
|
525
|
+
## Command Callback
|
418
526
|
|
419
|
-
|
527
|
+
`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.
|
420
528
|
|
421
529
|
Example:
|
422
530
|
|
423
531
|
```ruby
|
424
532
|
button {
|
425
533
|
text "Reset Selection"
|
534
|
+
|
426
535
|
command {
|
427
536
|
person.reset_country
|
428
537
|
}
|
429
538
|
}
|
430
539
|
```
|
431
540
|
|
432
|
-
|
433
|
-
|
434
|
-
More details can be found in the [Hello, Combobox!](#hello-combobox) sample below.
|
541
|
+
More details can be found in the [Hello, Button!](#hello-button) sample below.
|
435
542
|
|
436
543
|
## Gotchas
|
437
544
|
|
@@ -572,6 +679,253 @@ Glimmer app:
|
|
572
679
|
|
573
680
|

|
574
681
|
|
682
|
+
### Hello, Checkbutton!
|
683
|
+
|
684
|
+
Glimmer code (from [samples/hello/hello_checkbutton.rb](samples/hello/hello_checkbutton.rb)):
|
685
|
+
|
686
|
+
```ruby
|
687
|
+
require 'glimmer-dsl-tk'
|
688
|
+
|
689
|
+
class HelloCheckbutton
|
690
|
+
class Person
|
691
|
+
attr_accessor :skiing, :snowboarding, :snowmobiling, :snowshoeing, :snow_activities, :snow_activities_alternate
|
692
|
+
|
693
|
+
def initialize
|
694
|
+
reset_activities!
|
695
|
+
individual_observer = Glimmer::DataBinding::Observer.proc do
|
696
|
+
unless @updating_group
|
697
|
+
@updating_individual = true
|
698
|
+
if skiing && snowboarding && snowmobiling && snowshoeing
|
699
|
+
self.snow_activities = true
|
700
|
+
self.snow_activities_alternate = false
|
701
|
+
elsif skiing || snowboarding || snowmobiling || snowshoeing
|
702
|
+
self.snow_activities = true
|
703
|
+
self.snow_activities_alternate = true
|
704
|
+
else
|
705
|
+
self.snow_activities = false
|
706
|
+
self.snow_activities_alternate = false
|
707
|
+
end
|
708
|
+
@updating_individual = false
|
709
|
+
end
|
710
|
+
end
|
711
|
+
individual_observer.observe(self, :skiing)
|
712
|
+
individual_observer.observe(self, :snowboarding)
|
713
|
+
individual_observer.observe(self, :snowmobiling)
|
714
|
+
individual_observer.observe(self, :snowshoeing)
|
715
|
+
|
716
|
+
group_observer = Glimmer::DataBinding::Observer.proc do
|
717
|
+
unless @updating_individual
|
718
|
+
@updating_group = true
|
719
|
+
self.skiing = self.snow_activities
|
720
|
+
self.snowboarding = self.snow_activities
|
721
|
+
self.snowmobiling = self.snow_activities
|
722
|
+
self.snowshoeing = self.snow_activities
|
723
|
+
@updating_group = false
|
724
|
+
end
|
725
|
+
end
|
726
|
+
group_observer.observe(self, :snow_activities)
|
727
|
+
end
|
728
|
+
|
729
|
+
def reset_activities!
|
730
|
+
self.snow_activities = true
|
731
|
+
self.snow_activities_alternate = true
|
732
|
+
self.skiing = false
|
733
|
+
self.snowboarding = true
|
734
|
+
self.snowmobiling = false
|
735
|
+
self.snowshoeing = false
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
include Glimmer
|
740
|
+
|
741
|
+
def initialize
|
742
|
+
@person = Person.new
|
743
|
+
end
|
744
|
+
|
745
|
+
def launch
|
746
|
+
root {
|
747
|
+
title 'Hello, Checkbutton!'
|
748
|
+
background '#ececec' if OS.mac?
|
749
|
+
|
750
|
+
label {
|
751
|
+
text 'Check all snow activities you are interested in:'
|
752
|
+
font 'caption'
|
753
|
+
}
|
754
|
+
|
755
|
+
frame {
|
756
|
+
checkbutton {
|
757
|
+
text 'Snow Activities'
|
758
|
+
variable <=> [@person, :snow_activities]
|
759
|
+
alternate <=> [@person, :snow_activities_alternate] # binds half-checked state
|
760
|
+
}
|
761
|
+
|
762
|
+
frame {
|
763
|
+
checkbutton {
|
764
|
+
text 'Skiing'
|
765
|
+
variable <=> [@person, :skiing]
|
766
|
+
}
|
767
|
+
|
768
|
+
checkbutton {
|
769
|
+
text 'Snowboarding'
|
770
|
+
variable <=> [@person, :snowboarding]
|
771
|
+
}
|
772
|
+
|
773
|
+
checkbutton {
|
774
|
+
text 'Snowmobiling'
|
775
|
+
variable <=> [@person, :snowmobiling]
|
776
|
+
}
|
777
|
+
|
778
|
+
checkbutton {
|
779
|
+
text 'Snowshoeing'
|
780
|
+
variable <=> [@person, :snowshoeing]
|
781
|
+
}
|
782
|
+
}
|
783
|
+
}
|
784
|
+
|
785
|
+
button {
|
786
|
+
text 'Reset Activities'
|
787
|
+
|
788
|
+
command do
|
789
|
+
@person.reset_activities!
|
790
|
+
end
|
791
|
+
}
|
792
|
+
}.open
|
793
|
+
end
|
794
|
+
end
|
795
|
+
|
796
|
+
HelloCheckbutton.new.launch
|
797
|
+
```
|
798
|
+
|
799
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
800
|
+
|
801
|
+
```
|
802
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_checkbutton'"
|
803
|
+
```
|
804
|
+
|
805
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
806
|
+
|
807
|
+
```
|
808
|
+
ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_checkbutton.rb
|
809
|
+
```
|
810
|
+
|
811
|
+
Glimmer app:
|
812
|
+
|
813
|
+

|
814
|
+
|
815
|
+

|
816
|
+
|
817
|
+

|
818
|
+
|
819
|
+
### Hello, Radiobutton!
|
820
|
+
|
821
|
+
Glimmer code (from [samples/hello/hello_radiobutton.rb](samples/hello/hello_radiobutton.rb)):
|
822
|
+
|
823
|
+
```ruby
|
824
|
+
require 'glimmer-dsl-tk'
|
825
|
+
|
826
|
+
class HelloRadiobutton
|
827
|
+
class Person
|
828
|
+
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
829
|
+
|
830
|
+
def initialize
|
831
|
+
reset!
|
832
|
+
end
|
833
|
+
|
834
|
+
def reset!
|
835
|
+
self.male = true
|
836
|
+
self.female = nil
|
837
|
+
self.child = nil
|
838
|
+
self.teen = nil
|
839
|
+
self.adult = true
|
840
|
+
self.senior = nil
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
include Glimmer
|
845
|
+
|
846
|
+
def initialize
|
847
|
+
@person = Person.new
|
848
|
+
end
|
849
|
+
|
850
|
+
def launch
|
851
|
+
root {
|
852
|
+
title 'Hello, Radio!'
|
853
|
+
background '#ececec' if OS.mac?
|
854
|
+
|
855
|
+
label {
|
856
|
+
text 'Gender:'
|
857
|
+
font 'caption'
|
858
|
+
}
|
859
|
+
|
860
|
+
frame {
|
861
|
+
radiobutton {
|
862
|
+
text 'Male'
|
863
|
+
variable <=> [@person, :male]
|
864
|
+
}
|
865
|
+
|
866
|
+
radiobutton {
|
867
|
+
text 'Female'
|
868
|
+
variable <=> [@person, :female]
|
869
|
+
}
|
870
|
+
}
|
871
|
+
|
872
|
+
label {
|
873
|
+
text 'Age Group:'
|
874
|
+
font 'caption'
|
875
|
+
}
|
876
|
+
|
877
|
+
frame {
|
878
|
+
radiobutton {
|
879
|
+
text 'Child'
|
880
|
+
variable <=> [@person, :child]
|
881
|
+
}
|
882
|
+
|
883
|
+
radiobutton {
|
884
|
+
text 'Teen'
|
885
|
+
variable <=> [@person, :teen]
|
886
|
+
}
|
887
|
+
|
888
|
+
radiobutton {
|
889
|
+
text 'Adult'
|
890
|
+
variable <=> [@person, :adult]
|
891
|
+
}
|
892
|
+
|
893
|
+
radiobutton {
|
894
|
+
text 'Senior'
|
895
|
+
variable <=> [@person, :senior]
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
button {
|
900
|
+
text 'Reset'
|
901
|
+
|
902
|
+
command do
|
903
|
+
@person.reset!
|
904
|
+
end
|
905
|
+
}
|
906
|
+
}.open
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
HelloRadiobutton.new.launch
|
911
|
+
```
|
912
|
+
|
913
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
914
|
+
|
915
|
+
```
|
916
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_radiobutton'"
|
917
|
+
```
|
918
|
+
|
919
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
920
|
+
|
921
|
+
```
|
922
|
+
ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_radiobutton.rb
|
923
|
+
```
|
924
|
+
|
925
|
+
Glimmer app:
|
926
|
+
|
927
|
+

|
928
|
+
|
575
929
|
### Hello, Frame!
|
576
930
|
|
577
931
|
Glimmer code (from [samples/hello/hello_frame.rb](samples/hello/hello_frame.rb)):
|
@@ -645,6 +999,60 @@ Glimmer app:
|
|
645
999
|
|
646
1000
|

|
647
1001
|
|
1002
|
+
### Hello, Root!
|
1003
|
+
|
1004
|
+
Glimmer code (from [samples/hello/hello_frame.rb](samples/hello/hello_frame.rb)):
|
1005
|
+
|
1006
|
+
```ruby
|
1007
|
+
require 'glimmer-dsl-tk'
|
1008
|
+
|
1009
|
+
include Glimmer
|
1010
|
+
|
1011
|
+
root { |r|
|
1012
|
+
title 'Hello, Root!'
|
1013
|
+
iconphoto File.expand_path('../../icons/glimmer.png', __dir__)
|
1014
|
+
width 400
|
1015
|
+
height 200
|
1016
|
+
x -150
|
1017
|
+
y 300
|
1018
|
+
resizable true # same as `resizable true, true`, meaning cannot resize horizontally and vertically
|
1019
|
+
minsize 200, 100
|
1020
|
+
maxsize 600, 400
|
1021
|
+
background 'lightgrey'
|
1022
|
+
alpha 0.85 # on the mac, you can set `transparent true` as well
|
1023
|
+
topmost true
|
1024
|
+
|
1025
|
+
on('OPEN_WINDOW') do # custom event that runs right after Tk.mainloop
|
1026
|
+
message_box(parent: r, title: 'Hi', message: 'Hi')
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
on('DELETE_WINDOW') do |event| # alias for WM_DELETE_WINDOW protocol event
|
1030
|
+
message_box(parent: r, title: 'Bye', message: 'Bye')
|
1031
|
+
exit(0)
|
1032
|
+
end
|
1033
|
+
}.open
|
1034
|
+
```
|
1035
|
+
|
1036
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1037
|
+
|
1038
|
+
```
|
1039
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_root'"
|
1040
|
+
```
|
1041
|
+
|
1042
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1043
|
+
|
1044
|
+
```
|
1045
|
+
ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_root.rb
|
1046
|
+
```
|
1047
|
+
|
1048
|
+
Glimmer app:
|
1049
|
+
|
1050
|
+

|
1051
|
+
|
1052
|
+

|
1053
|
+
|
1054
|
+

|
1055
|
+
|
648
1056
|
### Hello, Notebook!
|
649
1057
|
|
650
1058
|
Glimmer code (from [samples/hello/hello_notebook.rb](samples/hello/hello_notebook.rb)):
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.23
|
data/glimmer-dsl-tk.gemspec
CHANGED
Binary file
|
@@ -27,7 +27,10 @@ module Glimmer
|
|
27
27
|
module Tk
|
28
28
|
class MessageBoxExpression < StaticExpression
|
29
29
|
def interpret(parent, keyword, *args, &block)
|
30
|
-
|
30
|
+
if args.first.is_a?(Hash)
|
31
|
+
args.first[:parent] = args.first[:parent].tk if args.first[:parent].is_a?(Glimmer::Tk::RootProxy)
|
32
|
+
args.first[:title] = args.first.delete(:text) if args.first.keys.include?(:text)
|
33
|
+
end
|
31
34
|
::Tk::messageBox(*args)
|
32
35
|
end
|
33
36
|
end
|