glimmer 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +331 -71
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53c846877535c288cc80b8c2972b14f5fd961b6e3e51f744278e8c6da47cfe6d
|
4
|
+
data.tar.gz: 4be53a6c16f2a9ae9c6101ca4726b576bec5e17dae05f55d64c0714ab13ab6fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f717afdd64e347b706a3d909474b579031c4a235d4881c490958d7c743892f363b64ae29f40bf8401506f327764163c4d08660cb6a29d8507b7077f11e06c29
|
7
|
+
data.tar.gz: c2b5de327710faa1e6dde42e5ef011af9b5375b87c030edeea40a0e672c7abd8a848dd1f8f48da9deeee903be27c9cc8e79e4a8a404a31cbf522be11dad35ee3
|
data/README.markdown
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Glimmer (
|
1
|
+
# Glimmer (JRuby Desktop UI DSL + Data-Binding)
|
2
2
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
3
3
|
|
4
4
|
Glimmer is a cross-platform Ruby desktop development library. Glimmer's main innovation is a JRuby DSL that enables easy and efficient authoring of desktop application user-interfaces while relying on the robust platform-independent Eclipse SWT library. Glimmer additionally innovates by having built-in desktop UI data-binding support to greatly facilitate synchronizing the UI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about UI concerns, or alternatively drive development UI-first, and then write clean business components test-first afterward.
|
@@ -83,10 +83,20 @@ Glimmer runs on the following platforms:
|
|
83
83
|
- Windows
|
84
84
|
- Linux
|
85
85
|
|
86
|
+
SWT uses Win32 on Windows, Cocoa on Mac, and GTK on Linux according to Eclipse WIKI:
|
87
|
+
|
88
|
+
https://wiki.eclipse.org/SWT/Devel/Gtk/Dev_guide#Win32.2FCocoa.2FGTK
|
89
|
+
|
90
|
+
The SWT FAQ has further details:
|
91
|
+
|
92
|
+
https://www.eclipse.org/swt/faq.php
|
93
|
+
|
94
|
+
|
86
95
|
## Pre-requisites
|
87
96
|
|
88
97
|
* Java SE Runtime Environment 7 or higher (find at https://www.oracle.com/java/technologies/javase-downloads.html)
|
89
98
|
* JRuby 9.2.10.0 (supporting Ruby 2.5.x syntax) (find at https://www.jruby.org/download)
|
99
|
+
* SWT 4.14 (comes included in Glimmer)
|
90
100
|
|
91
101
|
On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
|
92
102
|
|
@@ -102,14 +112,14 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
102
112
|
|
103
113
|
Run this command to install directly:
|
104
114
|
```
|
105
|
-
jgem install glimmer -v 0.4.
|
115
|
+
jgem install glimmer -v 0.4.6
|
106
116
|
```
|
107
117
|
|
108
118
|
### Option 2: Bundler
|
109
119
|
|
110
120
|
Add the following to `Gemfile`:
|
111
121
|
```
|
112
|
-
gem 'glimmer', '~> 0.4.
|
122
|
+
gem 'glimmer', '~> 0.4.6'
|
113
123
|
```
|
114
124
|
|
115
125
|
And, then run:
|
@@ -137,21 +147,99 @@ This runs the Glimmer application hello_world.rb
|
|
137
147
|
|
138
148
|
### Widgets
|
139
149
|
|
140
|
-
Glimmer UIs (user interfaces) are modeled with widgets
|
150
|
+
Glimmer UIs (user interfaces) are modeled with widgets, which are wrappers around the SWT library widgets found here:
|
151
|
+
|
152
|
+
https://www.eclipse.org/swt/widgets/
|
153
|
+
|
154
|
+
This screenshot taken from the link above should give a glimpse of how SWT widgets look and feel:
|
155
|
+
|
156
|
+
![SWT Widgets](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-swt-widgets.png)
|
141
157
|
|
142
|
-
In Glimmer DSL, widgets are declared with lowercase underscored
|
158
|
+
In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name:
|
143
159
|
|
144
|
-
|
160
|
+
- `shell` instantiates `org.eclipse.swt.widgets.Shell`
|
161
|
+
- `text` instantiates `org.eclipse.swt.widgets.Text`
|
162
|
+
- `button` instantiates `org.eclipse.swt.widgets.Button`
|
163
|
+
- `label` instantiates `org.eclipse.swt.widgets.Label`
|
164
|
+
- `composite` instantiates `org.eclipse.swt.widgets.Composite`
|
165
|
+
- `tab_folder` instantiates `org.eclipse.swt.widgets.TabFolder`
|
166
|
+
- `tab_item` instantiates `org.eclipse.swt.widgets.TabItem`
|
167
|
+
- `table` instantiates `org.eclipse.swt.widgets.Table`
|
168
|
+
- `table_column` instantiates `org.eclipse.swt.widgets.TableColumn`
|
169
|
+
- `tree` instantiates `org.eclipse.swt.widgets.Tree`
|
170
|
+
- `combo` instantiates `org.eclipse.swt.widgets.Combo`
|
171
|
+
- `list` instantiates `org.eclipse.swt.widgets.List`
|
145
172
|
|
146
|
-
|
147
|
-
- `button`: wrapper for `org.eclipse.swt.widgets.Button`
|
148
|
-
- `label`: wrapper for `org.eclipse.swt.widgets.Label`
|
149
|
-
- `tab_folder`: wrapper for `org.eclipse.swt.widgets.TabFolder`
|
150
|
-
- `tab_item`: wrapper for `org.eclipse.swt.widgets.TabItem`
|
151
|
-
- `table`: wrapper for `org.eclipse.swt.widgets.Table`
|
152
|
-
- `table_column`: wrapper for `org.eclipse.swt.widgets.TableColumn`
|
153
|
-
- `tree`: wrapper for `org.eclipse.swt.widgets.Tree`
|
173
|
+
A **widget** name is followed by a Ruby block that contains the widget **properties** and **content**. Optionally, an SWT **style** ***argument*** may also be passed (see [next section](#widget-styles) for details).
|
154
174
|
|
175
|
+
For example, if we were to revisit `hello_world.rb` above:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
include Glimmer
|
179
|
+
|
180
|
+
shell {
|
181
|
+
text "Glimmer"
|
182
|
+
label {
|
183
|
+
text "Hello World!"
|
184
|
+
}
|
185
|
+
}.open
|
186
|
+
```
|
187
|
+
|
188
|
+
Note that `shell` instantiates the outer shell **widget**, in other words, the window that houses all of the desktop graphical user interface.
|
189
|
+
|
190
|
+
`shell` is then followed by a ***block*** that contains
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
text "Glimmer" # text property of shell
|
194
|
+
label { # label widget declaration
|
195
|
+
text "Hello World!" # text property of label
|
196
|
+
}
|
197
|
+
```
|
198
|
+
|
199
|
+
The first line declares a **property** called `text`, which sets the title of the shell (window) to `"Glimmer"`. **Properties** always have ***arguments***, such as the text `"Glimmer"` in this case, and do **NOT** have a ***block***.
|
200
|
+
|
201
|
+
The second line declares the `label` **widget**, which is followed by a Ruby **content** ***block*** that contains its `text` **property** with value `"Hello World!"`
|
202
|
+
|
203
|
+
Note that The `shell` widget is always the outermost widget containing all others in a Glimmer desktop windowed application.
|
204
|
+
|
205
|
+
After it is declared, a `shell` must be opened with the `#open` method, which can be called on the block directly as in the example above, or by capturing `shell` in a `@shell` variable (shown in example below), and calling `#open` on it independently (recommended in actual apps)
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
@shell = shell {
|
209
|
+
# properties and content
|
210
|
+
}
|
211
|
+
@shell.open
|
212
|
+
```
|
213
|
+
|
214
|
+
It is centered upon initial display and has a minimum width of 130 (can be re-centered when needed with `@shell.center` method after capturing `shell` in a `@shell` variable as per samples)
|
215
|
+
|
216
|
+
Check out the [samples](https://github.com/AndyObtiva/glimmer/tree/master/samples) directory for more examples.
|
217
|
+
|
218
|
+
Example from [hello_tab.rb](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_tab.rb) sample:
|
219
|
+
|
220
|
+
![Hello Tab 1](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab1.png)
|
221
|
+
|
222
|
+
![Hello Tab 2](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab2.png)
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
shell {
|
226
|
+
text "SWT"
|
227
|
+
tab_folder {
|
228
|
+
tab_item {
|
229
|
+
text "Tab 1"
|
230
|
+
label {
|
231
|
+
text "Hello World!"
|
232
|
+
}
|
233
|
+
}
|
234
|
+
tab_item {
|
235
|
+
text "Tab 2"
|
236
|
+
label {
|
237
|
+
text "Bonjour Univers!"
|
238
|
+
}
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}.open
|
242
|
+
```
|
155
243
|
|
156
244
|
**Browser Widget**
|
157
245
|
|
@@ -281,6 +369,65 @@ button {
|
|
281
369
|
|
282
370
|
In the above example, the `text` widget `enabled` property was data-bound to `#empty` method on `@tic_tac_toe_board.box(row, column)` (learn more about data-binding below)
|
283
371
|
|
372
|
+
#### Colors
|
373
|
+
|
374
|
+
Colors make up a subset of widget properties. SWT accepts color objects created with RGB (Red Green Blue) or RGBA (Red Green Blue Alpha). Glimmer supports constructing color objects using the `rgb` and `rgba` DSL methods.
|
375
|
+
|
376
|
+
Example:
|
377
|
+
|
378
|
+
```ruby
|
379
|
+
label {
|
380
|
+
background rgb(144, 240, 244)
|
381
|
+
foreground rgba(38, 92, 232, 255)
|
382
|
+
}
|
383
|
+
```
|
384
|
+
|
385
|
+
SWT also supports standard colors available as constants under the `SWT` namespace with the `COLOR_` prefix (e.g. `SWT::COLOR_BLUE`, `SWT::COLOR_WHITE`, `SWT::COLOR_RED`)
|
386
|
+
|
387
|
+
Glimmer accepts these constants as lowercase Ruby symbols with or without `color_` prefix.
|
388
|
+
|
389
|
+
Example:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
label {
|
393
|
+
background :black
|
394
|
+
foreground :yellow
|
395
|
+
}
|
396
|
+
label {
|
397
|
+
background :color_white
|
398
|
+
foreground :color_red
|
399
|
+
}
|
400
|
+
```
|
401
|
+
|
402
|
+
You may check out all available standard colors in `SWT` over here (having `COLOR_` prefix):
|
403
|
+
|
404
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
405
|
+
|
406
|
+
#### Fonts
|
407
|
+
|
408
|
+
Fonts are represented in Glimmer as a hash of name, height, and style keys.
|
409
|
+
|
410
|
+
The style can be one (or more) of 3 values: `:normal`, `:bold`, and `:italic`
|
411
|
+
|
412
|
+
Example:
|
413
|
+
|
414
|
+
```ruby
|
415
|
+
label {
|
416
|
+
font name: 'Arial', height: 36, style: :normal
|
417
|
+
}
|
418
|
+
```
|
419
|
+
|
420
|
+
Keys are optional, so some of them may be left off.
|
421
|
+
When passing multiple styles, they are included in an array.
|
422
|
+
|
423
|
+
Example:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
label {
|
427
|
+
font style: [:bold, :italic]
|
428
|
+
}
|
429
|
+
```
|
430
|
+
|
284
431
|
### Layouts
|
285
432
|
|
286
433
|
Glimmer lays widgets out visually using SWT layouts, which can only be set on composite widget and subclasses.
|
@@ -452,97 +599,206 @@ Also, for a reference, check the SWT API:
|
|
452
599
|
|
453
600
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
|
454
601
|
|
455
|
-
###
|
602
|
+
### Data-Binding
|
456
603
|
|
457
|
-
|
604
|
+
Data-binding is done with `bind` command following widget property to bind and taking model and bindable attribute as arguments.
|
458
605
|
|
459
|
-
|
606
|
+
Data-binding examples:
|
607
|
+
- `text bind(contact, :first_name)`
|
608
|
+
- `text bind(contact, 'address.street')`
|
609
|
+
- `text bind(contact, 'addresses[1].street')`
|
610
|
+
- `text bind(contact, :age, computed_by: :date_of_birth)`
|
611
|
+
- `text bind(contact, :name, computed_by: [:first_name, :last_name])`
|
612
|
+
- `text bind(contact, 'profiles[0].name', computed_by: ['profiles[0].first_name', 'profiles[0].last_name'])`
|
460
613
|
|
461
|
-
|
462
|
-
label {
|
463
|
-
background rgb(144, 240, 244)
|
464
|
-
foreground rgba(38, 92, 232, 255)
|
465
|
-
}
|
466
|
-
```
|
614
|
+
The 1st example binds the text property of a widget like `label` to the first name of a contact model.
|
467
615
|
|
468
|
-
|
616
|
+
The 2nd example binds the text property of a widget like `label` to the nested street of
|
617
|
+
the address of a contact. This is called nested property data binding.
|
469
618
|
|
470
|
-
|
619
|
+
The 3rd example binds the text property of a widget like `label` to the nested indexed address street of a contact. This is called nested indexed property data binding.
|
471
620
|
|
472
|
-
|
621
|
+
The 4th example demonstrates computed value data binding whereby the value of `age` depends on changes to `date_of_birth`.
|
622
|
+
|
623
|
+
The 5th example demonstrates computed value data binding whereby the value of `name` depends on changes to both `first_name` and `last_name`.
|
624
|
+
|
625
|
+
The 6th example demonstrates nested indexed computed value data binding whereby the value of `profiles[0].name` depends on changes to both nested `profiles[0].first_name` and `profiles[0].last_name`.
|
626
|
+
|
627
|
+
Example from [hello_combo.rb](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_combo.rb) sample:
|
628
|
+
|
629
|
+
![Hello Combo](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-combo.png)
|
630
|
+
|
631
|
+
![Hello Combo](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-combo-expanded.png)
|
473
632
|
|
474
633
|
```ruby
|
475
|
-
|
476
|
-
|
477
|
-
foreground :yellow
|
478
|
-
}
|
479
|
-
label {
|
480
|
-
background :color_white
|
481
|
-
foreground :color_red
|
482
|
-
}
|
483
|
-
```
|
634
|
+
class Person
|
635
|
+
attr_accessor :country, :country_options
|
484
636
|
|
485
|
-
|
637
|
+
def initialize
|
638
|
+
self.country_options=["", "Canada", "US", "Mexico"]
|
639
|
+
self.country = "Canada"
|
640
|
+
end
|
486
641
|
|
487
|
-
|
642
|
+
def reset_country
|
643
|
+
self.country = "Canada"
|
644
|
+
end
|
645
|
+
end
|
488
646
|
|
489
|
-
|
647
|
+
class HelloCombo
|
648
|
+
include Glimmer
|
649
|
+
def launch
|
650
|
+
person = Person.new
|
651
|
+
shell {
|
652
|
+
composite {
|
653
|
+
combo(:read_only) {
|
654
|
+
selection bind(person, :country)
|
655
|
+
}
|
656
|
+
button {
|
657
|
+
text "Reset"
|
658
|
+
on_widget_selected do
|
659
|
+
person.reset_country
|
660
|
+
end
|
661
|
+
}
|
662
|
+
}
|
663
|
+
}.open
|
664
|
+
end
|
665
|
+
end
|
490
666
|
|
491
|
-
|
667
|
+
HelloCombo.new.launch
|
668
|
+
```
|
492
669
|
|
493
|
-
|
670
|
+
`combo` widget is data-bound to the country of a person. Note that it expects `person` object to have `:country` attribute and `:country_options` attribute containing all available countries.
|
494
671
|
|
495
|
-
Example:
|
672
|
+
Example from [hello_list_single_selection.rb](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_list_single_selection.rb) sample:
|
673
|
+
|
674
|
+
![Hello List Single Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-single-selection.png)
|
496
675
|
|
497
676
|
```ruby
|
498
|
-
|
499
|
-
|
500
|
-
|
677
|
+
shell {
|
678
|
+
composite {
|
679
|
+
list {
|
680
|
+
selection bind(person, :country)
|
681
|
+
}
|
682
|
+
button {
|
683
|
+
text "Reset"
|
684
|
+
on_widget_selected do
|
685
|
+
person.reset_country
|
686
|
+
end
|
687
|
+
}
|
688
|
+
}
|
689
|
+
}.open
|
501
690
|
```
|
502
691
|
|
503
|
-
|
504
|
-
When passing multiple styles, they are included in an array.
|
692
|
+
`list` widget is also data-bound to the country of a person similarly to the combo widget. Not much difference here (the rest of the code not shown is the same).
|
505
693
|
|
506
|
-
|
694
|
+
Nonetheless, in the next example, a multi-selection list is declared instead allowing data-binding of multiple selection values to the bindable attribute on the model.
|
695
|
+
|
696
|
+
![Hello List Multi Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-multi-selection.png)
|
507
697
|
|
508
698
|
```ruby
|
509
|
-
|
510
|
-
|
511
|
-
|
699
|
+
class Person
|
700
|
+
attr_accessor :provinces, :provinces_options
|
701
|
+
|
702
|
+
def initialize
|
703
|
+
self.provinces_options=[
|
704
|
+
"",
|
705
|
+
"Quebec",
|
706
|
+
"Ontario",
|
707
|
+
"Manitoba",
|
708
|
+
"Saskatchewan",
|
709
|
+
"Alberta",
|
710
|
+
"British Columbia",
|
711
|
+
"Nova Skotia",
|
712
|
+
"Newfoundland"
|
713
|
+
]
|
714
|
+
self.provinces = ["Quebec", "Manitoba", "Alberta"]
|
715
|
+
end
|
716
|
+
|
717
|
+
def reset_provinces
|
718
|
+
self.provinces = ["Quebec", "Manitoba", "Alberta"]
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
class HelloListMultiSelection
|
723
|
+
include Glimmer
|
724
|
+
def launch
|
725
|
+
person = Person.new
|
726
|
+
shell {
|
727
|
+
composite {
|
728
|
+
list(:multi) {
|
729
|
+
selection bind(person, :provinces)
|
730
|
+
}
|
731
|
+
button {
|
732
|
+
text "Reset"
|
733
|
+
on_widget_selected do
|
734
|
+
person.reset_provinces
|
735
|
+
end
|
736
|
+
}
|
737
|
+
}
|
738
|
+
}.open
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
HelloListMultiSelection.new.launch
|
512
743
|
```
|
513
744
|
|
514
|
-
|
745
|
+
The Glimmer code is not much different from above except for passing the `:multi` style to the `list` widget. However, the model code behind the scenes is quite different as it is a `provinces` array bindable to the selection of multiple values on a `list` widget. `provinces_options` contains all available province values just as expected by a single selection `list` and `combo`.
|
515
746
|
|
516
|
-
|
747
|
+
Note that in all the data-binding examples above, there was also an observer attached to the `button` widget to trigger an action on the model, which in turn triggers a data-binding update on the `list` or `combo`. Observers will be discussed in more details in the [next section](#observer).
|
517
748
|
|
518
|
-
|
519
|
-
- `text bind(contact, :first_name)`
|
520
|
-
- `text bind(contact, 'address.street')`
|
521
|
-
- `text bind(contact, 'addresses[1].street')`
|
522
|
-
- `text bind(contact, :age, computed_by: :date_of_birth)`
|
523
|
-
- `text bind(contact, :name, computed_by: [:first_name, :last_name])`
|
524
|
-
- `text bind(contact, 'profiles[0].name', computed_by: ['profiles[0].first_name', 'profiles[0].last_name'])`
|
749
|
+
You may learn more about Glimmer's data-binding syntax by reading the [Eclipse Zone Tutorial](http://eclipse.dzone.com/articles/an-introduction-glimmer) mentioned in resources and opening up the samples under the [samples](https://github.com/AndyObtiva/glimmer/tree/master/samples) directory.
|
525
750
|
|
526
|
-
|
751
|
+
### Observer
|
527
752
|
|
528
|
-
|
529
|
-
the address of a contact. This is called nested property data binding.
|
753
|
+
Glimmer comes with `Observer` module, which is used internally for data-binding, but can also be used externally for custom use of the Observer Pattern. It is hidden when observing widgets, and used explicitly when observing models.
|
530
754
|
|
531
|
-
|
755
|
+
#### Observing Widgets
|
532
756
|
|
533
|
-
|
757
|
+
Glimmer supports observing widgets with an `on_*event*` declaration where the '*event*' part is replaced with the lowercase underscored name of an SWT listener event method.
|
534
758
|
|
535
|
-
|
759
|
+
To figure out what the available events for an SWT widget are, check out all of its API methods starting with `add` and ending with `Listener`, and then open the listener class to check its "event methods".
|
536
760
|
|
537
|
-
|
761
|
+
For example, if you look at the `Button` SWT API:
|
762
|
+
https://help.eclipse.org/2019-12/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fbrowser%2FBrowser.html
|
538
763
|
|
539
|
-
|
764
|
+
It has `addSelectionListener`. Additionally, under its `Control` super class, it has `addControlListener`, `addDragDetectListener`, `addFocusListener`, `addGestureListener`, `addHelpListener`, `addKeyListener`, `addMenuDetectListener`, `addMouseListener`, `addMouseMoveListener`, `addMouseTrackListener`, `addMouseWheelListener`, `addPaintListener`, `addTouchListener`, and `addTraverseListener`
|
540
765
|
|
541
|
-
|
766
|
+
Suppose, we select `addSelectionListener`, which is responsible for what happens when a user selects a button (clicks it). Then, open its argument `SelectionListener` SWT API, and you find the event (instance) methods: `widgetDefaultSelected` and `widgetSelected`. Let's select the second one, which is what gets invoked when a button is clicked.
|
767
|
+
|
768
|
+
Now, Glimmer simplifies the process of hooking into that listener (observer) by neither requiring you to call the `addSelectionListener` method nor requiring you to implement/extend the `SelectionListener` API.
|
769
|
+
|
770
|
+
Instead, simply add a `on_widget_selected` followed by a Ruby block containing the logic to perform. Glimmer figures out the rest.
|
771
|
+
|
772
|
+
Let's revisit the Tic Tac Toe example shown near the beginning of the page:
|
773
|
+
|
774
|
+
```ruby
|
775
|
+
shell {
|
776
|
+
text "Tic-Tac-Toe"
|
777
|
+
composite {
|
778
|
+
grid_layout 3, true
|
779
|
+
(1..3).each { |row|
|
780
|
+
(1..3).each { |column|
|
781
|
+
button {
|
782
|
+
layout_data :fill, :fill, true, true
|
783
|
+
text bind(@tic_tac_toe_board[row, column], :sign)
|
784
|
+
enabled bind(@tic_tac_toe_board[row, column], :empty)
|
785
|
+
on_widget_selected {
|
786
|
+
@tic_tac_toe_board.mark_box(row, column)
|
787
|
+
}
|
788
|
+
}
|
789
|
+
}
|
790
|
+
}
|
791
|
+
}
|
792
|
+
}
|
793
|
+
```
|
794
|
+
|
795
|
+
Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties data-bound to the `sign` and `empty` attributes on the `TicTacToeBoard` model respectively.
|
542
796
|
|
543
|
-
|
797
|
+
Next however, each of these Tic Tac Toe grid cells, which are clickable buttons, have an `on_widget_selected` observer, which once triggered, marks the box (cell) on the `TicTacToeBoard` to make a move.
|
544
798
|
|
545
|
-
|
799
|
+
#### Observing Models
|
800
|
+
|
801
|
+
The class that needs to observe a model object must include (mix in) the `Observer` module and implement the `#call(new_value)` method. The class to be observed doesn't need to do anything. It will automatically be enhanced by Glimmer for observation.
|
546
802
|
|
547
803
|
To register observer, one has to call the `#observe` method and pass in the observable and the property(ies) to observe.
|
548
804
|
|
@@ -743,7 +999,11 @@ Here is the SWT API:
|
|
743
999
|
|
744
1000
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
|
745
1001
|
|
746
|
-
Here is a list of SWT widgets:
|
1002
|
+
Here is a visual list of SWT widgets:
|
1003
|
+
|
1004
|
+
https://www.eclipse.org/swt/widgets/
|
1005
|
+
|
1006
|
+
Here is a textual list of SWT widgets:
|
747
1007
|
|
748
1008
|
https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
|
749
1009
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|