glimmer-dsl-opal 0.10.2 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +252 -0
- data/README.md +187 -1301
- data/VERSION +1 -1
- data/lib/display.rb +3 -0
- data/lib/glimmer-dsl-opal.rb +2 -1
- data/lib/glimmer-dsl-opal/ext/glimmer/dsl/engine.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +15 -13
- data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +55 -28
- data/lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb +2 -2
- data/lib/glimmer-dsl-opal/samples/elaborate/weather.rb +157 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +8 -8
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox.rb +16 -14
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox_group.rb +14 -9
- data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +24 -22
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +32 -14
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +16 -12
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_date_time.rb +4 -4
- data/lib/glimmer-dsl-opal/samples/hello/hello_group.rb +6 -6
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio.rb +18 -16
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio_group.rb +17 -12
- data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +4 -4
- data/lib/glimmer/data_binding/table_items_binding.rb +3 -2
- data/lib/glimmer/dsl/opal/bind_expression.rb +24 -25
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +8 -8
- data/lib/glimmer/dsl/opal/dsl.rb +4 -0
- data/lib/glimmer/dsl/opal/menu_expression.rb +1 -1
- data/lib/glimmer/dsl/opal/property_expression.rb +2 -1
- data/lib/glimmer/dsl/opal/shape_expression.rb +26 -0
- data/lib/glimmer/dsl/opal/shell_expression.rb +1 -1
- data/lib/{glimmer-dsl-opal/samples/hello/hello_computed/contact.rb → glimmer/dsl/opal/shine_data_binding_expression.rb} +24 -17
- data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +2 -2
- data/lib/glimmer/dsl/opal/widget_expression.rb +1 -1
- data/lib/glimmer/swt/combo_proxy.rb +1 -0
- data/lib/glimmer/swt/composite_proxy.rb +2 -0
- data/lib/glimmer/swt/dialog_proxy.rb +1 -1
- data/lib/glimmer/swt/display_proxy.rb +63 -1
- data/lib/glimmer/swt/grid_layout_proxy.rb +17 -17
- data/lib/glimmer/swt/layout_proxy.rb +23 -3
- data/lib/glimmer/swt/message_box_proxy.rb +1 -1
- data/lib/glimmer/swt/row_layout_proxy.rb +12 -3
- data/lib/glimmer/swt/table_proxy.rb +19 -3
- data/lib/glimmer/swt/widget_proxy.rb +3 -4
- data/lib/glimmer/ui/custom_shell.rb +22 -5
- data/lib/glimmer/ui/custom_widget.rb +11 -2
- data/lib/net/http.rb +14 -6
- metadata +14 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '009ae1a27f92b9fe4ae8d28374761c84a8a46add536c37b49c67aba167a121b7'
|
4
|
+
data.tar.gz: baf143fe8365b8a3164eaf74adc4a3df720521557003d0507f09580f0da9b6b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81014168a1822232725770564b6f8a4522f08a4e93db72c4986966deaeac28eaffe7674f9446d7abf2d5a3a6056eec38a7f12508c72f751734bd8dc6356fdc2c
|
7
|
+
data.tar.gz: 800d13580d55f8c1255a68b7c07f6c4e7bdfb9308d3a41b14e44e94b50dd66056c9e437df38f73f2d04643633937cd0a99edba8a1ed174194cf8ce0be25328bf
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,252 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## 0.14.0
|
4
|
+
|
5
|
+
- Initial Net::HTTP support for get and post_form
|
6
|
+
- Added "Weather" elaborate sample (minus multi-threaded refetches)
|
7
|
+
- Updated Hello, Button!, Hello, Combo!, and Hello, Computed! from Glimmer DSL for SWT
|
8
|
+
|
9
|
+
## 0.13.0
|
10
|
+
|
11
|
+
- Support Shine data-binding syntax in custom widgets
|
12
|
+
- Update Hello, Checkbox!, Hello, Checkbox Group!, Hello, Radio! and Hello, Radio Group! to utilize Shine data-binding syntax from latest glimmer-dsl-swt
|
13
|
+
|
14
|
+
## 0.12.0
|
15
|
+
|
16
|
+
- Support CustomShell.launch opening in the same window if no other shell is open or DisplayProxy.open_custom_shells_in_current_window = true is set
|
17
|
+
- Support CustomShell.launch opening a new window if a shell is already open
|
18
|
+
- Support passing `table` data-binding column properties as `column_properties` or `column_attributes` an extra hash option to `bind` method call
|
19
|
+
- Support Shine data-binding syntax in `table`
|
20
|
+
- Update Hello, Custom Shell!, Hello, Table!, Contact Manager, and Login samples to use Shine data-binding syntax
|
21
|
+
|
22
|
+
## 0.11.0
|
23
|
+
|
24
|
+
- Upgrade to glimmer 2.0.0
|
25
|
+
- Support Shine syntax for basic widgets (no support for table, tree, shapes, custom widgets, or custom shells)
|
26
|
+
- Update samples to use Shine syntax
|
27
|
+
|
28
|
+
## 0.10.3
|
29
|
+
|
30
|
+
- Upgrade to glimmer 1.0.10
|
31
|
+
- Improvements to row_layout and grid_layout
|
32
|
+
- Adding launch/shutdown class methods to Custom Shells
|
33
|
+
|
34
|
+
## 0.10.2
|
35
|
+
|
36
|
+
- Support multiple dialogs/message_box'es opened from a listener, handling correct ordering of display with a queue scheduler
|
37
|
+
|
38
|
+
## 0.10.1
|
39
|
+
|
40
|
+
- Delaying shell rendering till `#open` method is called as per the right expectation
|
41
|
+
- When nesting dialogs on top of each other, disable all previously opened ones leaving only the top-most dialog active
|
42
|
+
|
43
|
+
## 0.10.0
|
44
|
+
|
45
|
+
- Hello, Dialog! Sample
|
46
|
+
- Support `dialog` widget
|
47
|
+
- Support `width` and `height` on `layout_data` for `row_layout`
|
48
|
+
- Support `center` for `row_layout`
|
49
|
+
|
50
|
+
## 0.9.3
|
51
|
+
|
52
|
+
- Extracted pure Ruby Struct to pure-struct gem (since it's also used by YASL)
|
53
|
+
- Alpha experimental incomplete implementation of Net::HTTP.post_form
|
54
|
+
- Fixed issue with not being able to interact with a shell proxy (LatestShellProxy) after opening (made class autoupgradable to attached ShellProxy after document ready)
|
55
|
+
|
56
|
+
## 0.9.2
|
57
|
+
|
58
|
+
- Fixed issue with opening message_box after internalizing the Document.ready? block
|
59
|
+
- Fixed issue with replacing newlines with HTML newlines in `label` and `message_box` text
|
60
|
+
|
61
|
+
## 0.9.1
|
62
|
+
|
63
|
+
- Log errors to error stream ($stderr) instead of standard out (STDOUT)
|
64
|
+
- Fixed issue with opening shell caused by internalizing the Document.ready? block
|
65
|
+
|
66
|
+
## 0.9.0
|
67
|
+
|
68
|
+
- Support `menu_bar`
|
69
|
+
- Hello, Menu Bar! Sample
|
70
|
+
- Remove the need to call Document.ready? before opening a Glimmer shell
|
71
|
+
- Support opening a message_box before creating a shell
|
72
|
+
|
73
|
+
## 0.8.0
|
74
|
+
|
75
|
+
- Hello, Pop Up Context Menu! Sample
|
76
|
+
- Hello Message Box!
|
77
|
+
- Update hello list samples
|
78
|
+
- Support context menus `menu`/`menu_item` directly under a widget (using jQuery UI)
|
79
|
+
- Support generating new lines when entering `label` `text` with \n (auto-converting to <br />)
|
80
|
+
- Support generating new lines when entering `message_box` `message` with \n (auto-converting to <br />)
|
81
|
+
- Support having any widget contribute static CSS to ShellProxy
|
82
|
+
- Add Kernel#include_package shim to allow running JRuby include_package from Glimmer DSL for SWT without failing
|
83
|
+
- Add WidgetProxy#swt_widget to allow running include_package from Glimmer DSL for SWT without failing
|
84
|
+
|
85
|
+
## 0.7.5
|
86
|
+
|
87
|
+
- Update login sample from Glimmer DSL for SWT's latest changes
|
88
|
+
- Update contact_manager sample from Glimmer DSL for SWT's latest changes
|
89
|
+
- Fixed issue regarding unavailable localStorage data when accessed by custom_widget_expression in hello_checkbox_group, hello_radio_group, and hello_custom_widget
|
90
|
+
|
91
|
+
## 0.7.4
|
92
|
+
|
93
|
+
- Hello, Button! Sample
|
94
|
+
- Fix issue with aligning label as :left, :center, or :right via style style when fill_layout is used
|
95
|
+
- Fix Hello, Browser sample by accessing https ssl website
|
96
|
+
- Fix issue with filling space horizontally when using grid layout
|
97
|
+
- Fix broken embedded `calendar` widget data-binding for hello_date_time.rb sample
|
98
|
+
- Fix broken message_box after opening multiple shells
|
99
|
+
- Fix issue with opening custom shells in new tabs/windows when CustomShell subclass is required conditionally
|
100
|
+
|
101
|
+
## 0.7.3
|
102
|
+
|
103
|
+
- Refactor to use to_collection gem
|
104
|
+
- Fix issue with breaking `date`/`date_drop_down` data-binding as table editor on focus lost
|
105
|
+
- Fix issue with requiring OS, File, and Display class after they've been extracted out
|
106
|
+
|
107
|
+
## 0.7.2
|
108
|
+
|
109
|
+
- `date_drop_down` `table_column` `editor`
|
110
|
+
- `date` `table_column` `editor`
|
111
|
+
- `time` `table_column` `editor`
|
112
|
+
- Implement `on_focus_gained`, `on_focus_lost` universally on all widgets
|
113
|
+
- Add support for Struct keyword_init to Opal
|
114
|
+
- Fix issue with hello_table button/combo not being centered (yet stretched)
|
115
|
+
- Fix issue with table item selection for booking not working after editing has been added
|
116
|
+
- Fix escape keyboard event handling for combo table editor
|
117
|
+
|
118
|
+
## 0.7.1
|
119
|
+
|
120
|
+
- Combo table editor (enabled in Hello, Table! sample)
|
121
|
+
- Fix issue with table cell selection for editing not working
|
122
|
+
- Remove widget from parent upon dispose
|
123
|
+
- Remove listeners upon widget dispose
|
124
|
+
|
125
|
+
## 0.7.0
|
126
|
+
|
127
|
+
- Hello, Table! Sample
|
128
|
+
- `table` :editable style to enable auto-editing
|
129
|
+
- `table` `header_visible` property to hide header when false
|
130
|
+
- `table` `item_count` property to set minimum item count (fill empty rows when below in table items)
|
131
|
+
- `table` selection data-binding
|
132
|
+
- `table` built-in sorting support
|
133
|
+
- `table_column` left text alignment and padding of 5px by default
|
134
|
+
- `table` sort property and direction in GUI
|
135
|
+
- `table_column` sort_property
|
136
|
+
- `table_column` sort_by block
|
137
|
+
- `table_column` sort block
|
138
|
+
- `table` default sort via property, compare block, and property block
|
139
|
+
- `table` additional sort properties
|
140
|
+
- Prevent `table` unnecessary updates by comparing data to previous data and not updating when it's the same
|
141
|
+
- Contact Manager sample support for on_key_pressed in text widgets upon hitting ENTER
|
142
|
+
- Fix issue with edit table item error on sorting table
|
143
|
+
|
144
|
+
## 0.6.1
|
145
|
+
|
146
|
+
- Fix issue with rendering date_time without a block
|
147
|
+
- Made listener event handling async to improve performance when triggering multiple events
|
148
|
+
- Brought Tic Tac Toe sample up-to-date with changes in Glimmer DSL for SWT
|
149
|
+
- Fixed silent error encountered in rendering custom widgets
|
150
|
+
|
151
|
+
## 0.6.0
|
152
|
+
|
153
|
+
- Hello, Date Time! Sample
|
154
|
+
- Support `date_time`, `date`, `date_drop_down`, `time`, `calendar` keywords
|
155
|
+
- Format Date/Time correctly as per SWT implementation by default
|
156
|
+
- Make glimmer-dsl-opal gem into a Rails engine to support importing default static assets like CSS styles and images
|
157
|
+
- Show drop down icon next to `date_drop_down` and `time`
|
158
|
+
|
159
|
+
## 0.5.1
|
160
|
+
|
161
|
+
- Fixed issue with Hello, Combo!, Hello, List...! samples
|
162
|
+
|
163
|
+
## 0.5.0
|
164
|
+
|
165
|
+
- Add `margin_top`, `margin_right`, `margin_bottom`, and `margin_left` to RowLayoutProxy
|
166
|
+
- `radio`
|
167
|
+
- Hello, Radio! Sample
|
168
|
+
- `radio_group`
|
169
|
+
- Hello, Radio Group! Sample
|
170
|
+
- `checkbox`
|
171
|
+
- Hello, Checkbox! Sample
|
172
|
+
- `checkbox_group`
|
173
|
+
- Fix issue with `label` `alignment` property
|
174
|
+
- Fix issues with default `composite` `grid_layout` not getting its styles removed when setting `row_layout`
|
175
|
+
- `button(:radio)` alias for `radio`
|
176
|
+
- `check` alias for `checkbox`
|
177
|
+
- `button(:check)` alias for `checkbox`
|
178
|
+
- Hello, Group! Sample
|
179
|
+
- Group widget
|
180
|
+
|
181
|
+
## 0.4.0
|
182
|
+
|
183
|
+
- Support `display` keyword representing an SWT Display
|
184
|
+
- Support display `on_swt_keydown` event listener (display-wide widget observer)
|
185
|
+
- Support `DisplayProxy#shells` method keeping track of open shell
|
186
|
+
- Make a custom shell open in the same window if there is no shell open already
|
187
|
+
- Support `sync_exec` keyword as just an alias to `async_exec`
|
188
|
+
- Provide a makeshift require for 'glimmer-dsl-swt' that requires 'glimmer-dsl-opal' instead
|
189
|
+
- Fake APIs on the web for OS.os?, File.read, Display.setAppName, Display.setAppVersion
|
190
|
+
- Provide a minimal URI class that supports URI::encode_www_form_component and URI::decode_www_form_component from Ruby
|
191
|
+
|
192
|
+
## 0.3.0
|
193
|
+
|
194
|
+
- Support opening a custom shell in a browser tab/window by passing in query parameters to URL (e.g. ?custom_shell=keyword+option1=value1 etc...)
|
195
|
+
- Make custom shells automatically open in a new tab/window (while standard shells continue to open in the same window by replacing its content)
|
196
|
+
- Hello, Custom Shell! Sample
|
197
|
+
|
198
|
+
## 0.2.0
|
199
|
+
|
200
|
+
- Color support
|
201
|
+
- Font support
|
202
|
+
- Custom Widget Support
|
203
|
+
- Hello, Custom Widget! sample
|
204
|
+
- Updated Hello, Combo! sample to match the latest changes in Glimmer DSL for SWT
|
205
|
+
- `SWT` full re-implementation in Opal as `Glimmer::SWT` with all the `SWT` style constants
|
206
|
+
|
207
|
+
## 0.1.0
|
208
|
+
|
209
|
+
- Code redesign to better match the glimmer-dsl-swt APIs
|
210
|
+
- opal-jquery refactoring
|
211
|
+
- opal-rspec test coverage
|
212
|
+
|
213
|
+
## 0.0.9
|
214
|
+
|
215
|
+
- Upgraded to glimmer gem v0.9.3
|
216
|
+
- Fixed issue with missing Glimmer::Opal::ElementProxy#id=(value) method breaking Contact Manager sample Find feature
|
217
|
+
|
218
|
+
## 0.0.8
|
219
|
+
|
220
|
+
- Contact Manager sample support
|
221
|
+
|
222
|
+
## 0.0.7
|
223
|
+
|
224
|
+
- Tic Tac Toe sample support
|
225
|
+
- Login sample support
|
226
|
+
|
227
|
+
## 0.0.6
|
228
|
+
|
229
|
+
- Hello, Tab! sample support
|
230
|
+
|
231
|
+
## 0.0.5
|
232
|
+
|
233
|
+
- Hello, Browser! sample support
|
234
|
+
|
235
|
+
## 0.0.4
|
236
|
+
|
237
|
+
- Hello, List Single Selection! sample support
|
238
|
+
- Hello, List Multi Selection! sample support
|
239
|
+
|
240
|
+
## 0.0.3
|
241
|
+
|
242
|
+
- Hello, Computed! sample support
|
243
|
+
|
244
|
+
## 0.0.2
|
245
|
+
|
246
|
+
- Hello, Combo! sample support
|
247
|
+
|
248
|
+
## 0.0.1
|
249
|
+
|
250
|
+
- Initial support for webifying Glimmer SWT apps
|
251
|
+
- Support for Shell and Label widgets (text property only).
|
252
|
+
- Hello, World! sample support
|
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
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 Opal 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 Opal 0.14.0 (Pure Ruby Web GUI)
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
|
3
3
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
4
|
|
5
|
-
### You can finally live in pure
|
5
|
+
### You can finally live in pure Rubyland on the web!
|
6
6
|
|
7
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Opal](https://opalrb.com/) is an **alpha** [gem](https://rubygems.org/gems/glimmer-dsl-opal) that enables building web GUI in pure Ruby via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/)
|
7
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Opal](https://opalrb.com/) is an **alpha** [gem](https://rubygems.org/gems/glimmer-dsl-opal) that enables building web GUI in pure Ruby via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) **(now comes with the new Shine data-binding syntax)**.
|
8
8
|
|
9
9
|
Use in one of two ways:
|
10
10
|
- **Direct:** build the GUI of web apps with the same friendly desktop GUI Ruby syntax as [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), thus requiring a lot less code than web technologies that is in pure Ruby and avoiding opaque web concepts like 'render' and 'reactive'. No HTML/JS/CSS skills are even required. Web designers may be involved with CSS styling only if needed.
|
11
|
-
- **Adapter:** auto-webify [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)) via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) without changing a line of code. Just insert them as a single require statement in a Rails app, and BOOM! They're running on the web! Apps may then optionally be custom-styled for the web by web designers with standard CSS if needed.
|
11
|
+
- **Adapter:** auto-webify [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)) via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) without changing a line of GUI code. Just insert them as a single require statement in a Rails app, and BOOM! They're running on the web! Apps may then optionally be custom-styled for the web by web designers with standard CSS if needed.
|
12
12
|
|
13
|
-
Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of
|
13
|
+
Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web (including Shine syntax using `<=>` and `<=` for bidirectional [two-way] and unidirectional [one-way] data-binding respectively).
|
14
14
|
|
15
15
|
#### Hello, Table! Sample
|
16
16
|
|
@@ -103,7 +103,7 @@ shell {
|
|
103
103
|
|
104
104
|
![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
|
105
105
|
|
106
|
-
**Hello, Table! (same code) running on the web via Opal on Rails (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):**
|
106
|
+
**Hello, Table! (same GUI code) running on the web via Opal on Rails (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):**
|
107
107
|
|
108
108
|
![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table.png)
|
109
109
|
|
@@ -141,17 +141,17 @@ Hello, Table! Game Booked
|
|
141
141
|
|
142
142
|
NOTE: Glimmer DSL for Opal is an alpha project. Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
|
143
143
|
|
144
|
-
**Alpha Version** 0.
|
144
|
+
**Alpha Version** 0.14.0 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
|
145
145
|
|
146
146
|
Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
147
147
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
148
148
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
149
149
|
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
150
|
-
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
|
150
|
+
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
|
151
151
|
|
152
152
|
## Table of Contents
|
153
153
|
|
154
|
-
- [Glimmer DSL for Opal 0.
|
154
|
+
- [Glimmer DSL for Opal 0.14.0 (Pure Ruby Web GUI)](#-glimmer-dsl-for-opal-0140-pure-ruby-web-gui)
|
155
155
|
- [Principles](#principles)
|
156
156
|
- [Background](#background)
|
157
157
|
- [Pre-requisites](#pre-requisites)
|
@@ -184,6 +184,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
184
184
|
- [Login](#login)
|
185
185
|
- [Tic Tac Toe](#tic-tac-toe)
|
186
186
|
- [Contact Manager](#contact-manager)
|
187
|
+
- [Weather](#weather)
|
187
188
|
- [External Samples](#external-samples)
|
188
189
|
- [Glimmer Calculator](#glimmer-calculator)
|
189
190
|
- [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
|
@@ -199,15 +200,17 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
199
200
|
|
200
201
|
## Principles
|
201
202
|
|
203
|
+
Please keep in mind this is a live list of innovative ideas, some of which have not been implemented yet. Watch the project on GitHub to stay up to date with its development.
|
204
|
+
|
202
205
|
- **Live purely in Rubyland via the Glimmer GUI DSL**, completely oblivious to web browser technologies, thanks to [Opal](https://opalrb.com/).
|
203
|
-
- **
|
204
|
-
- **HTML is strictly made for creating documents not interactive applications**. As such, software engineers can avoid it and focus on creating web applications more productively with Glimmer DSL for Opal in pure Ruby instead (just like they do in desktop development) while content creators and web designers can be the ones responsible for creating HTML documents for web content purposes only as HTML was originally intended. That way, Glimmer web GUI is used and embedded in web pages when providing users with applications while the rest of the web pages are maintained by non-engineers as pure HTML. This achieves a correct separation of responsibilities and better productivity and maintainability.
|
206
|
+
- **HTML is for creating documents not interactive applications**. As such, software engineers can avoid it and focus on creating web applications more productively with Glimmer DSL for Opal in pure Ruby instead (just like they do in desktop development) while content creators and web designers can be the ones responsible for creating HTML documents for web content purposes only as HTML was originally intended. That way, Glimmer web GUI is used and embedded in web pages when providing users with applications while the rest of the web pages are maintained by non-engineers as pure HTML. This achieves a correct separation of responsibilities and better productivity and maintainability.
|
205
207
|
- **Approximate styles by developers via the Glimmer GUI DSL. Perfect styles by designers via pure CSS**. Developers can simply build GUI with approximate styling similar to desktop GUI and mockups without worrying about pixel-perfect aesthetics. Web designers can take styling further with pure CSS since every HTML element auto-generated by Glimmer DSL for Opal has a predictable ID and CSS class. This achieves a proper separation of responsibilities between developers and designers.
|
206
208
|
- **Web servers are used just like servers in traditional client/server architecture**, meaning they simply provide RMI services to enable centralizing some of the application logic and data in the cloud to make available everywhere and enable data-sharing with others.
|
209
|
+
- **Forget Routers!** Glimmer DSL for Opal supports auto-routing of custom shells (windows), which are opened as separate tabs in a web browser with automatically generated routes and bookmarkable URLs.
|
207
210
|
|
208
211
|
## Background
|
209
212
|
|
210
|
-
The original idea behind Glimmer DSL for Opal (which later evolved) was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The pure Ruby [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is very simple, so it is more productive to build GUI in it since it does not go through a server/client request/response cycle and can be iterated on locally with a much shorter feedback cycle. Once the GUI and the rest of the app is built. You simply embed it in a Rails app as a one line require statement, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser. Until then, just use [Opal-jQuery](https://github.com/opal/opal-jquery) http support). That way, you get two apps for one: desktop and web.
|
213
|
+
The original idea behind Glimmer DSL for Opal (which [later evolved](#principles)) was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The pure Ruby [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is very simple, so it is more productive to build GUI in it since it does not go through a server/client request/response cycle and can be iterated on locally with a much shorter feedback cycle. Once the GUI and the rest of the app is built. You simply embed it in a Rails app as a one line require statement, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser. Until then, just use [Opal-jQuery](https://github.com/opal/opal-jquery) http support). That way, you get two apps for one: desktop and web.
|
211
214
|
|
212
215
|
Part of the idea is that web browsers just render GUI widgets similar to those of a desktop app (after all a web browser is a desktop app), so whether you run your GUI on the desktop or on the web should just be a low-level concern, hopefully automated completely with Glimmer DSL for Opal.
|
213
216
|
|
@@ -249,9 +252,9 @@ Add the following to `Gemfile`:
|
|
249
252
|
gem 'opal-rails', '~> 1.1.2'
|
250
253
|
gem 'opal-async', '~> 1.2.0'
|
251
254
|
gem 'opal-jquery', '~> 0.4.4'
|
252
|
-
gem 'glimmer-dsl-opal', '~> 0.
|
253
|
-
gem 'glimmer-dsl-xml', '~> 1.
|
254
|
-
gem 'glimmer-dsl-css', '~> 1.
|
255
|
+
gem 'glimmer-dsl-opal', '~> 0.14.0'
|
256
|
+
gem 'glimmer-dsl-xml', '~> 1.2.0', require: false
|
257
|
+
gem 'glimmer-dsl-css', '~> 1.2.0', require: false
|
255
258
|
|
256
259
|
```
|
257
260
|
|
@@ -310,7 +313,7 @@ shell {
|
|
310
313
|
|
311
314
|
## Supported Glimmer DSL Keywords
|
312
315
|
|
313
|
-
The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have partial support in Opal:
|
316
|
+
The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have fully functional partial support in Opal:
|
314
317
|
|
315
318
|
Widgets:
|
316
319
|
- `button`: featured in [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Message Box!](#hello-message-box) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login)
|
@@ -438,48 +441,50 @@ require 'glimmer-dsl-opal/samples/hello/hello_combo'
|
|
438
441
|
Or add the Glimmer code directly if you prefer to play around with it:
|
439
442
|
|
440
443
|
```ruby
|
441
|
-
class
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
444
|
+
class HelloCombo
|
445
|
+
class Person
|
446
|
+
attr_accessor :country, :country_options
|
447
|
+
|
448
|
+
def initialize
|
449
|
+
self.country_options = ['', 'Canada', 'US', 'Mexico']
|
450
|
+
reset_country!
|
451
|
+
end
|
452
|
+
|
453
|
+
def reset_country!
|
454
|
+
self.country = 'Canada'
|
455
|
+
end
|
451
456
|
end
|
452
|
-
end
|
453
457
|
|
454
|
-
|
455
|
-
include Glimmer
|
458
|
+
include Glimmer::UI::CustomShell
|
456
459
|
|
457
|
-
|
458
|
-
person = Person.new
|
459
|
-
|
460
|
+
before_body {
|
461
|
+
@person = Person.new
|
462
|
+
}
|
463
|
+
|
464
|
+
body {
|
460
465
|
shell {
|
461
466
|
row_layout(:vertical) {
|
462
|
-
|
467
|
+
fill true
|
463
468
|
}
|
464
469
|
|
465
470
|
text 'Hello, Combo!'
|
466
471
|
|
467
472
|
combo(:read_only) {
|
468
|
-
selection
|
473
|
+
selection <=> [@person, :country] # also binds to country_options by convention
|
469
474
|
}
|
470
475
|
|
471
476
|
button {
|
472
477
|
text 'Reset Selection'
|
473
478
|
|
474
479
|
on_widget_selected do
|
475
|
-
person.reset_country
|
480
|
+
@person.reset_country!
|
476
481
|
end
|
477
482
|
}
|
478
|
-
}
|
479
|
-
|
483
|
+
}
|
484
|
+
}
|
480
485
|
end
|
481
486
|
|
482
|
-
HelloCombo.
|
487
|
+
HelloCombo.launch
|
483
488
|
```
|
484
489
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
485
490
|
|
@@ -530,22 +535,21 @@ class HelloComputed
|
|
530
535
|
0
|
531
536
|
end
|
532
537
|
end
|
533
|
-
end
|
534
538
|
|
535
|
-
|
536
|
-
include Glimmer
|
539
|
+
include Glimmer::UI::CustomShell
|
537
540
|
|
538
|
-
|
541
|
+
before_body {
|
539
542
|
@contact = Contact.new(
|
540
543
|
first_name: 'Barry',
|
541
544
|
last_name: 'McKibbin',
|
542
545
|
year_of_birth: 1985
|
543
546
|
)
|
544
|
-
|
547
|
+
}
|
545
548
|
|
546
|
-
|
549
|
+
body {
|
547
550
|
shell {
|
548
551
|
text 'Hello, Computed!'
|
552
|
+
|
549
553
|
composite {
|
550
554
|
grid_layout {
|
551
555
|
num_columns 2
|
@@ -553,52 +557,57 @@ class HelloComputed
|
|
553
557
|
horizontal_spacing 20
|
554
558
|
vertical_spacing 10
|
555
559
|
}
|
560
|
+
|
556
561
|
label {text 'First &Name: '}
|
557
562
|
text {
|
558
|
-
text
|
563
|
+
text <=> [@contact, :first_name]
|
559
564
|
layout_data {
|
560
565
|
horizontal_alignment :fill
|
561
566
|
grab_excess_horizontal_space true
|
562
567
|
}
|
563
568
|
}
|
569
|
+
|
564
570
|
label {text '&Last Name: '}
|
565
571
|
text {
|
566
|
-
text
|
572
|
+
text <=> [@contact, :last_name]
|
567
573
|
layout_data {
|
568
574
|
horizontal_alignment :fill
|
569
575
|
grab_excess_horizontal_space true
|
570
576
|
}
|
571
577
|
}
|
578
|
+
|
572
579
|
label {text '&Year of Birth: '}
|
573
580
|
text {
|
574
|
-
text
|
581
|
+
text <=> [@contact, :year_of_birth]
|
575
582
|
layout_data {
|
576
583
|
horizontal_alignment :fill
|
577
584
|
grab_excess_horizontal_space true
|
578
585
|
}
|
579
586
|
}
|
587
|
+
|
580
588
|
label {text 'Name: '}
|
581
589
|
label {
|
582
|
-
text
|
590
|
+
text <= [@contact, :name, computed_by: [:first_name, :last_name]]
|
583
591
|
layout_data {
|
584
592
|
horizontal_alignment :fill
|
585
593
|
grab_excess_horizontal_space true
|
586
594
|
}
|
587
595
|
}
|
596
|
+
|
588
597
|
label {text 'Age: '}
|
589
598
|
label {
|
590
|
-
text
|
599
|
+
text <= [@contact, :age, on_write: :to_i, computed_by: [:year_of_birth]]
|
591
600
|
layout_data {
|
592
601
|
horizontal_alignment :fill
|
593
602
|
grab_excess_horizontal_space true
|
594
603
|
}
|
595
604
|
}
|
596
605
|
}
|
597
|
-
}
|
598
|
-
|
606
|
+
}
|
607
|
+
}
|
599
608
|
end
|
600
609
|
|
601
|
-
HelloComputed.
|
610
|
+
HelloComputed.launch
|
602
611
|
```
|
603
612
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
604
613
|
|
@@ -626,44 +635,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
626
635
|
require 'glimmer-dsl-opal/samples/hello/hello_list_single_selection'
|
627
636
|
```
|
628
637
|
|
629
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
630
|
-
|
631
|
-
```ruby
|
632
|
-
class Person
|
633
|
-
attr_accessor :country, :country_options
|
634
|
-
|
635
|
-
def initialize
|
636
|
-
self.country_options=["", "Canada", "US", "Mexico"]
|
637
|
-
self.country = "Canada"
|
638
|
-
end
|
639
|
-
|
640
|
-
def reset_country
|
641
|
-
self.country = "Canada"
|
642
|
-
end
|
643
|
-
end
|
644
|
-
|
645
|
-
class HelloListSingleSelection
|
646
|
-
include Glimmer
|
647
|
-
def launch
|
648
|
-
person = Person.new
|
649
|
-
shell {
|
650
|
-
composite {
|
651
|
-
list {
|
652
|
-
selection bind(person, :country)
|
653
|
-
}
|
654
|
-
button {
|
655
|
-
text "Reset"
|
656
|
-
on_widget_selected do
|
657
|
-
person.reset_country
|
658
|
-
end
|
659
|
-
}
|
660
|
-
}
|
661
|
-
}.open
|
662
|
-
end
|
663
|
-
end
|
664
|
-
|
665
|
-
HelloListSingleSelection.new.launch
|
666
|
-
```
|
667
638
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
668
639
|
|
669
640
|
![Glimmer DSL for SWT Hello List Single Selection](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-list-single-selection.png)
|
@@ -689,63 +660,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
689
660
|
require 'glimmer-dsl-opal/samples/hello/hello_list_multi_selection'
|
690
661
|
```
|
691
662
|
|
692
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
693
|
-
|
694
|
-
```ruby
|
695
|
-
class HelloListMultiSelection
|
696
|
-
class Person
|
697
|
-
attr_accessor :provinces, :provinces_options
|
698
|
-
|
699
|
-
def initialize
|
700
|
-
self.provinces_options = [
|
701
|
-
'',
|
702
|
-
'Alberta',
|
703
|
-
'British Columbia',
|
704
|
-
'Manitoba',
|
705
|
-
'New Brunswick',
|
706
|
-
'Newfoundland and Labrador',
|
707
|
-
'Northwest Territories',
|
708
|
-
'Nova Scotia',
|
709
|
-
'Nunavut',
|
710
|
-
'Ontario',
|
711
|
-
'Prince Edward Island',
|
712
|
-
'Quebec',
|
713
|
-
'Saskatchewan',
|
714
|
-
'Yukon'
|
715
|
-
]
|
716
|
-
reset_provinces
|
717
|
-
end
|
718
|
-
|
719
|
-
def reset_provinces
|
720
|
-
self.provinces = ['Quebec', 'Manitoba', 'Alberta']
|
721
|
-
end
|
722
|
-
end
|
723
|
-
|
724
|
-
include Glimmer
|
725
|
-
|
726
|
-
def launch
|
727
|
-
person = Person.new
|
728
|
-
|
729
|
-
shell {
|
730
|
-
grid_layout
|
731
|
-
|
732
|
-
text 'Hello, List Multi Selection!'
|
733
|
-
|
734
|
-
list(:multi) {
|
735
|
-
selection bind(person, :provinces)
|
736
|
-
}
|
737
|
-
|
738
|
-
button {
|
739
|
-
text 'Reset Selections To Default Values'
|
740
|
-
|
741
|
-
on_widget_selected { person.reset_provinces }
|
742
|
-
}
|
743
|
-
}.open
|
744
|
-
end
|
745
|
-
end
|
746
|
-
|
747
|
-
HelloListMultiSelection.new.launch
|
748
|
-
```
|
749
663
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
750
664
|
|
751
665
|
![Glimmer DSL for SWT Hello List Multi Selection](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-list-multi-selection.png)
|
@@ -771,18 +685,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
771
685
|
require 'glimmer-dsl-opal/samples/hello/hello_browser'
|
772
686
|
```
|
773
687
|
|
774
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
775
|
-
|
776
|
-
```ruby
|
777
|
-
include Glimmer
|
778
|
-
|
779
|
-
shell {
|
780
|
-
minimum_size 1024, 860
|
781
|
-
browser {
|
782
|
-
url 'http://brightonresort.com/about'
|
783
|
-
}
|
784
|
-
}.open
|
785
|
-
```
|
786
688
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
787
689
|
|
788
690
|
![Glimmer DSL for SWT Hello Browser](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-browser.png)
|
@@ -887,7 +789,7 @@ class GreetingLabel
|
|
887
789
|
after_body {
|
888
790
|
return if colors.nil?
|
889
791
|
|
890
|
-
Thread.new {
|
792
|
+
Thread.new { # imported from Glimmer DSL for SWT. In Opal, avoid Threads and sleep to avoid blocking GUI.
|
891
793
|
colors.cycle { |color|
|
892
794
|
async_exec {
|
893
795
|
self.color = color
|
@@ -902,7 +804,7 @@ class GreetingLabel
|
|
902
804
|
label(swt_style) {
|
903
805
|
text "#{greeting}, #{name}!"
|
904
806
|
font @font
|
905
|
-
foreground
|
807
|
+
foreground <=> [self, :color]
|
906
808
|
}
|
907
809
|
}
|
908
810
|
|
@@ -1124,103 +1026,14 @@ You should see "Hello, Custom Widget!"
|
|
1124
1026
|
|
1125
1027
|
#### Hello, Radio!
|
1126
1028
|
|
1029
|
+
This is the low level way of using `radio`
|
1030
|
+
|
1127
1031
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1128
1032
|
|
1129
1033
|
```ruby
|
1130
1034
|
require 'glimmer-dsl-opal/samples/hello/hello_radio'
|
1131
1035
|
```
|
1132
1036
|
|
1133
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1134
|
-
|
1135
|
-
```ruby
|
1136
|
-
class HelloRadio
|
1137
|
-
class Person
|
1138
|
-
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
1139
|
-
|
1140
|
-
def initialize
|
1141
|
-
reset
|
1142
|
-
end
|
1143
|
-
|
1144
|
-
def reset
|
1145
|
-
self.male = nil
|
1146
|
-
self.female = nil
|
1147
|
-
self.child = nil
|
1148
|
-
self.teen = nil
|
1149
|
-
self.adult = true
|
1150
|
-
self.senior = nil
|
1151
|
-
end
|
1152
|
-
end
|
1153
|
-
|
1154
|
-
include Glimmer
|
1155
|
-
|
1156
|
-
def launch
|
1157
|
-
person = Person.new
|
1158
|
-
|
1159
|
-
shell {
|
1160
|
-
text 'Hello, Radio!'
|
1161
|
-
row_layout :vertical
|
1162
|
-
|
1163
|
-
label {
|
1164
|
-
text 'Gender:'
|
1165
|
-
font style: :bold
|
1166
|
-
}
|
1167
|
-
|
1168
|
-
composite {
|
1169
|
-
row_layout
|
1170
|
-
|
1171
|
-
radio {
|
1172
|
-
text 'Male'
|
1173
|
-
selection bind(person, :male)
|
1174
|
-
}
|
1175
|
-
|
1176
|
-
radio {
|
1177
|
-
text 'Female'
|
1178
|
-
selection bind(person, :female)
|
1179
|
-
}
|
1180
|
-
}
|
1181
|
-
|
1182
|
-
label {
|
1183
|
-
text 'Age Group:'
|
1184
|
-
font style: :bold
|
1185
|
-
}
|
1186
|
-
|
1187
|
-
composite {
|
1188
|
-
row_layout
|
1189
|
-
|
1190
|
-
radio {
|
1191
|
-
text 'Child'
|
1192
|
-
selection bind(person, :child)
|
1193
|
-
}
|
1194
|
-
|
1195
|
-
radio {
|
1196
|
-
text 'Teen'
|
1197
|
-
selection bind(person, :teen)
|
1198
|
-
}
|
1199
|
-
|
1200
|
-
radio {
|
1201
|
-
text 'Adult'
|
1202
|
-
selection bind(person, :adult)
|
1203
|
-
}
|
1204
|
-
|
1205
|
-
radio {
|
1206
|
-
text 'Senior'
|
1207
|
-
selection bind(person, :senior)
|
1208
|
-
}
|
1209
|
-
}
|
1210
|
-
|
1211
|
-
button {
|
1212
|
-
text 'Reset'
|
1213
|
-
|
1214
|
-
on_widget_selected do
|
1215
|
-
person.reset
|
1216
|
-
end
|
1217
|
-
}
|
1218
|
-
}.open
|
1219
|
-
end
|
1220
|
-
end
|
1221
|
-
|
1222
|
-
HelloRadio.new.launch
|
1223
|
-
```
|
1224
1037
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1225
1038
|
|
1226
1039
|
![Glimmer DSL for SWT Hello Radio](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-radio.png)
|
@@ -1240,6 +1053,8 @@ You should see "Hello, Radio!"
|
|
1240
1053
|
|
1241
1054
|
#### Hello, Radio Group!
|
1242
1055
|
|
1056
|
+
`radio_group` is a level higher than `radio` in abstraction. It generates a group of radio widgets based on available options in model `attribute_options` methods.
|
1057
|
+
|
1243
1058
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1244
1059
|
|
1245
1060
|
```ruby
|
@@ -1254,7 +1069,7 @@ class HelloRadioGroup
|
|
1254
1069
|
attr_accessor :gender, :age_group
|
1255
1070
|
|
1256
1071
|
def initialize
|
1257
|
-
reset
|
1072
|
+
reset!
|
1258
1073
|
end
|
1259
1074
|
|
1260
1075
|
def gender_options
|
@@ -1265,17 +1080,19 @@ class HelloRadioGroup
|
|
1265
1080
|
['Child', 'Teen', 'Adult', 'Senior']
|
1266
1081
|
end
|
1267
1082
|
|
1268
|
-
def reset
|
1083
|
+
def reset!
|
1269
1084
|
self.gender = nil
|
1270
1085
|
self.age_group = 'Adult'
|
1271
1086
|
end
|
1272
1087
|
end
|
1273
1088
|
|
1274
|
-
include Glimmer
|
1089
|
+
include Glimmer::UI::CustomShell
|
1275
1090
|
|
1276
|
-
|
1277
|
-
person = Person.new
|
1278
|
-
|
1091
|
+
before_body {
|
1092
|
+
@person = Person.new
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
body {
|
1279
1096
|
shell {
|
1280
1097
|
text 'Hello, Radio Group!'
|
1281
1098
|
row_layout :vertical
|
@@ -1287,7 +1104,7 @@ class HelloRadioGroup
|
|
1287
1104
|
|
1288
1105
|
radio_group {
|
1289
1106
|
row_layout :horizontal
|
1290
|
-
selection
|
1107
|
+
selection <=> [@person, :gender]
|
1291
1108
|
}
|
1292
1109
|
|
1293
1110
|
label {
|
@@ -1297,21 +1114,21 @@ class HelloRadioGroup
|
|
1297
1114
|
|
1298
1115
|
radio_group {
|
1299
1116
|
row_layout :horizontal
|
1300
|
-
selection
|
1117
|
+
selection <=> [@person, :age_group]
|
1301
1118
|
}
|
1302
1119
|
|
1303
1120
|
button {
|
1304
1121
|
text 'Reset'
|
1305
1122
|
|
1306
1123
|
on_widget_selected do
|
1307
|
-
person.reset
|
1124
|
+
@person.reset!
|
1308
1125
|
end
|
1309
1126
|
}
|
1310
|
-
}
|
1311
|
-
|
1127
|
+
}
|
1128
|
+
}
|
1312
1129
|
end
|
1313
1130
|
|
1314
|
-
HelloRadioGroup.
|
1131
|
+
HelloRadioGroup.launch
|
1315
1132
|
```
|
1316
1133
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1317
1134
|
|
@@ -1332,99 +1149,14 @@ You should see "Hello, Radio Group!"
|
|
1332
1149
|
|
1333
1150
|
#### Hello, Group!
|
1334
1151
|
|
1152
|
+
Not to be confused with `radio_group` or `checkbox_group`, `group` simply groups arbitrary widgets together and adds a title header above them.
|
1153
|
+
|
1335
1154
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1336
1155
|
|
1337
1156
|
```ruby
|
1338
1157
|
require 'glimmer-dsl-opal/samples/hello/hello_group'
|
1339
1158
|
```
|
1340
1159
|
|
1341
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1342
|
-
|
1343
|
-
```ruby
|
1344
|
-
class HelloGroup
|
1345
|
-
class Person
|
1346
|
-
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
1347
|
-
|
1348
|
-
def initialize
|
1349
|
-
reset
|
1350
|
-
end
|
1351
|
-
|
1352
|
-
def reset
|
1353
|
-
self.male = nil
|
1354
|
-
self.female = nil
|
1355
|
-
self.child = nil
|
1356
|
-
self.teen = nil
|
1357
|
-
self.adult = true
|
1358
|
-
self.senior = nil
|
1359
|
-
end
|
1360
|
-
end
|
1361
|
-
|
1362
|
-
include Glimmer
|
1363
|
-
|
1364
|
-
def launch
|
1365
|
-
person = Person.new
|
1366
|
-
|
1367
|
-
shell {
|
1368
|
-
text 'Hello, Group!'
|
1369
|
-
row_layout :vertical
|
1370
|
-
|
1371
|
-
group {
|
1372
|
-
row_layout
|
1373
|
-
|
1374
|
-
text 'Gender'
|
1375
|
-
font style: :bold
|
1376
|
-
|
1377
|
-
radio {
|
1378
|
-
text 'Male'
|
1379
|
-
selection bind(person, :male)
|
1380
|
-
}
|
1381
|
-
|
1382
|
-
radio {
|
1383
|
-
text 'Female'
|
1384
|
-
selection bind(person, :female)
|
1385
|
-
}
|
1386
|
-
}
|
1387
|
-
|
1388
|
-
group {
|
1389
|
-
row_layout
|
1390
|
-
|
1391
|
-
text 'Age Group'
|
1392
|
-
font style: :bold
|
1393
|
-
|
1394
|
-
radio {
|
1395
|
-
text 'Child'
|
1396
|
-
selection bind(person, :child)
|
1397
|
-
}
|
1398
|
-
|
1399
|
-
radio {
|
1400
|
-
text 'Teen'
|
1401
|
-
selection bind(person, :teen)
|
1402
|
-
}
|
1403
|
-
|
1404
|
-
radio {
|
1405
|
-
text 'Adult'
|
1406
|
-
selection bind(person, :adult)
|
1407
|
-
}
|
1408
|
-
|
1409
|
-
radio {
|
1410
|
-
text 'Senior'
|
1411
|
-
selection bind(person, :senior)
|
1412
|
-
}
|
1413
|
-
}
|
1414
|
-
|
1415
|
-
button {
|
1416
|
-
text 'Reset'
|
1417
|
-
|
1418
|
-
on_widget_selected do
|
1419
|
-
person.reset
|
1420
|
-
end
|
1421
|
-
}
|
1422
|
-
}.open
|
1423
|
-
end
|
1424
|
-
end
|
1425
|
-
|
1426
|
-
HelloGroup.new.launch
|
1427
|
-
```
|
1428
1160
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1429
1161
|
|
1430
1162
|
![Glimmer DSL for SWT Hello Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-group.png)
|
@@ -1444,100 +1176,36 @@ You should see "Hello, Group!"
|
|
1444
1176
|
|
1445
1177
|
#### Hello, Checkbox!
|
1446
1178
|
|
1179
|
+
This is the low level way of using `checkbox`
|
1180
|
+
|
1447
1181
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1448
1182
|
|
1449
1183
|
```ruby
|
1450
1184
|
require 'glimmer-dsl-opal/samples/hello/hello_checkbox'
|
1451
1185
|
```
|
1452
1186
|
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
person = Person.new
|
1476
|
-
|
1477
|
-
shell {
|
1478
|
-
text 'Hello, Checkbox!'
|
1479
|
-
row_layout :vertical
|
1480
|
-
|
1481
|
-
label {
|
1482
|
-
text 'Check all snow activities you are interested in:'
|
1483
|
-
font style: :bold
|
1484
|
-
}
|
1485
|
-
|
1486
|
-
composite {
|
1487
|
-
checkbox {
|
1488
|
-
text 'Skiing'
|
1489
|
-
selection bind(person, :skiing)
|
1490
|
-
}
|
1491
|
-
|
1492
|
-
checkbox {
|
1493
|
-
text 'Snowboarding'
|
1494
|
-
selection bind(person, :snowboarding)
|
1495
|
-
}
|
1496
|
-
|
1497
|
-
checkbox {
|
1498
|
-
text 'Snowmobiling'
|
1499
|
-
selection bind(person, :snowmobiling)
|
1500
|
-
}
|
1501
|
-
|
1502
|
-
checkbox {
|
1503
|
-
text 'Snowshoeing'
|
1504
|
-
selection bind(person, :snowshoeing)
|
1505
|
-
}
|
1506
|
-
}
|
1507
|
-
|
1508
|
-
button {
|
1509
|
-
text 'Reset Activities'
|
1510
|
-
|
1511
|
-
on_widget_selected do
|
1512
|
-
person.reset_activities
|
1513
|
-
end
|
1514
|
-
}
|
1515
|
-
}.open
|
1516
|
-
end
|
1517
|
-
end
|
1518
|
-
|
1519
|
-
HelloCheckbox.new.launch
|
1520
|
-
```
|
1521
|
-
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1522
|
-
|
1523
|
-
![Glimmer DSL for SWT Hello Checkbox](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-checkbox.png)
|
1524
|
-
|
1525
|
-
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1526
|
-
|
1527
|
-
Start the Rails server:
|
1528
|
-
```
|
1529
|
-
rails s
|
1530
|
-
```
|
1531
|
-
|
1532
|
-
Visit `http://localhost:3000`
|
1533
|
-
|
1534
|
-
You should see "Hello, Checkbox!"
|
1535
|
-
|
1536
|
-
![Glimmer DSL for Opal Hello Checkbox](images/glimmer-dsl-opal-hello-checkbox.png)
|
1537
|
-
|
1538
|
-
#### Hello, Checkbox Group!
|
1539
|
-
|
1540
|
-
Add the following require statement to `app/assets/javascripts/application.rb`
|
1187
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1188
|
+
|
1189
|
+
![Glimmer DSL for SWT Hello Checkbox](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-checkbox.png)
|
1190
|
+
|
1191
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1192
|
+
|
1193
|
+
Start the Rails server:
|
1194
|
+
```
|
1195
|
+
rails s
|
1196
|
+
```
|
1197
|
+
|
1198
|
+
Visit `http://localhost:3000`
|
1199
|
+
|
1200
|
+
You should see "Hello, Checkbox!"
|
1201
|
+
|
1202
|
+
![Glimmer DSL for Opal Hello Checkbox](images/glimmer-dsl-opal-hello-checkbox.png)
|
1203
|
+
|
1204
|
+
#### Hello, Checkbox Group!
|
1205
|
+
|
1206
|
+
`checkbox_group` is a level higher than `checkbox` in abstraction. It generates a group of checkbox widgets based on available options in model `attribute_options` methods.
|
1207
|
+
|
1208
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
1541
1209
|
|
1542
1210
|
```ruby
|
1543
1211
|
require 'glimmer-dsl-opal/samples/hello/hello_checkbox_group'
|
@@ -1563,11 +1231,13 @@ class HelloCheckboxGroup
|
|
1563
1231
|
end
|
1564
1232
|
end
|
1565
1233
|
|
1566
|
-
include Glimmer
|
1234
|
+
include Glimmer::UI::CustomShell
|
1567
1235
|
|
1568
|
-
|
1569
|
-
person = Person.new
|
1570
|
-
|
1236
|
+
before_body {
|
1237
|
+
@person = Person.new
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
body {
|
1571
1241
|
shell {
|
1572
1242
|
text 'Hello, Checkbox Group!'
|
1573
1243
|
row_layout :vertical
|
@@ -1578,21 +1248,21 @@ class HelloCheckboxGroup
|
|
1578
1248
|
}
|
1579
1249
|
|
1580
1250
|
checkbox_group {
|
1581
|
-
selection
|
1251
|
+
selection <=> [@person, :activities]
|
1582
1252
|
}
|
1583
1253
|
|
1584
1254
|
button {
|
1585
1255
|
text 'Reset Activities'
|
1586
1256
|
|
1587
1257
|
on_widget_selected do
|
1588
|
-
person.reset_activities
|
1258
|
+
@person.reset_activities
|
1589
1259
|
end
|
1590
1260
|
}
|
1591
|
-
}
|
1592
|
-
|
1261
|
+
}
|
1262
|
+
}
|
1593
1263
|
end
|
1594
1264
|
|
1595
|
-
HelloCheckboxGroup.
|
1265
|
+
HelloCheckboxGroup.launch
|
1596
1266
|
```
|
1597
1267
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1598
1268
|
|
@@ -1619,53 +1289,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
1619
1289
|
require 'glimmer-dsl-opal/samples/hello/hello_date_time'
|
1620
1290
|
```
|
1621
1291
|
|
1622
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1623
|
-
|
1624
|
-
```ruby
|
1625
|
-
class HelloDateTime
|
1626
|
-
class Person
|
1627
|
-
attr_accessor :date_of_birth
|
1628
|
-
end
|
1629
|
-
|
1630
|
-
include Glimmer
|
1631
|
-
|
1632
|
-
def launch
|
1633
|
-
person = Person.new
|
1634
|
-
person.date_of_birth = DateTime.new(2013, 7, 12, 18, 37, 23)
|
1635
|
-
|
1636
|
-
shell {
|
1637
|
-
row_layout :vertical
|
1638
|
-
|
1639
|
-
text 'Hello, Date Time!'
|
1640
|
-
minimum_size 180, 180
|
1641
|
-
|
1642
|
-
label {
|
1643
|
-
text 'Date of Birth'
|
1644
|
-
font height: 16, style: :bold
|
1645
|
-
}
|
1646
|
-
|
1647
|
-
date { # alias for date_time(:date)
|
1648
|
-
date_time bind(person, :date_of_birth)
|
1649
|
-
}
|
1650
|
-
|
1651
|
-
date_drop_down { # alias for date_time(:date, :drop_down)
|
1652
|
-
date_time bind(person, :date_of_birth)
|
1653
|
-
}
|
1654
|
-
|
1655
|
-
time { # alias for date_time(:time)
|
1656
|
-
date_time bind(person, :date_of_birth)
|
1657
|
-
}
|
1658
|
-
|
1659
|
-
calendar { # alias for date_time(:calendar)
|
1660
|
-
date_time bind(person, :date_of_birth)
|
1661
|
-
}
|
1662
|
-
}.open
|
1663
|
-
end
|
1664
|
-
end
|
1665
|
-
|
1666
|
-
HelloDateTime.new.launch
|
1667
|
-
```
|
1668
|
-
|
1669
1292
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1670
1293
|
|
1671
1294
|
![Glimmer DSL for SWT Hello Checkbox Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-date-time.png)
|
@@ -1693,263 +1316,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
1693
1316
|
require 'glimmer-dsl-opal/samples/hello/hello_table'
|
1694
1317
|
```
|
1695
1318
|
|
1696
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1697
|
-
|
1698
|
-
```ruby
|
1699
|
-
class HelloTable
|
1700
|
-
class BaseballGame
|
1701
|
-
class << self
|
1702
|
-
attr_accessor :selected_game
|
1703
|
-
|
1704
|
-
def all_playoff_games
|
1705
|
-
@all_playoff_games ||= {
|
1706
|
-
'NLDS' => [
|
1707
|
-
new(Time.new(2037, 10, 6, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers', 'Free Bobblehead'),
|
1708
|
-
new(Time.new(2037, 10, 7, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers'),
|
1709
|
-
new(Time.new(2037, 10, 8, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
|
1710
|
-
new(Time.new(2037, 10, 9, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
|
1711
|
-
new(Time.new(2037, 10, 10, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs', 'Free Umbrella'),
|
1712
|
-
new(Time.new(2037, 10, 6, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals', 'Free Bobblehead'),
|
1713
|
-
new(Time.new(2037, 10, 7, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals'),
|
1714
|
-
new(Time.new(2037, 10, 8, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
|
1715
|
-
new(Time.new(2037, 10, 9, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
|
1716
|
-
new(Time.new(2037, 10, 10, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds', 'Free Umbrella'),
|
1717
|
-
],
|
1718
|
-
'ALDS' => [
|
1719
|
-
new(Time.new(2037, 10, 6, 12, 0), 'New York Yankees', 'Boston Red Sox', 'Free Bobblehead'),
|
1720
|
-
new(Time.new(2037, 10, 7, 12, 0), 'New York Yankees', 'Boston Red Sox'),
|
1721
|
-
new(Time.new(2037, 10, 8, 12, 0), 'Boston Red Sox', 'New York Yankees'),
|
1722
|
-
new(Time.new(2037, 10, 9, 12, 0), 'Boston Red Sox', 'New York Yankees'),
|
1723
|
-
new(Time.new(2037, 10, 10, 12, 0), 'Boston Red Sox', 'New York Yankees', 'Free Umbrella'),
|
1724
|
-
new(Time.new(2037, 10, 6, 18, 0), 'Houston Astros', 'Cleveland Indians', 'Free Bobblehead'),
|
1725
|
-
new(Time.new(2037, 10, 7, 18, 0), 'Houston Astros', 'Cleveland Indians'),
|
1726
|
-
new(Time.new(2037, 10, 8, 18, 0), 'Cleveland Indians', 'Houston Astros'),
|
1727
|
-
new(Time.new(2037, 10, 9, 18, 0), 'Cleveland Indians', 'Houston Astros'),
|
1728
|
-
new(Time.new(2037, 10, 10, 18, 0), 'Cleveland Indians', 'Houston Astros', 'Free Umbrella'),
|
1729
|
-
],
|
1730
|
-
'NLCS' => [
|
1731
|
-
new(Time.new(2037, 10, 12, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Towel'),
|
1732
|
-
new(Time.new(2037, 10, 13, 12, 0), 'Chicago Cubs', 'Cincinnati Reds'),
|
1733
|
-
new(Time.new(2037, 10, 14, 12, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1734
|
-
new(Time.new(2037, 10, 15, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1735
|
-
new(Time.new(2037, 10, 16, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1736
|
-
new(Time.new(2037, 10, 17, 18, 0), 'Chicago Cubs', 'Cincinnati Reds'),
|
1737
|
-
new(Time.new(2037, 10, 18, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Poncho'),
|
1738
|
-
],
|
1739
|
-
'ALCS' => [
|
1740
|
-
new(Time.new(2037, 10, 12, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Towel'),
|
1741
|
-
new(Time.new(2037, 10, 13, 12, 0), 'Houston Astros', 'Boston Red Sox'),
|
1742
|
-
new(Time.new(2037, 10, 14, 12, 0), 'Boston Red Sox', 'Houston Astros'),
|
1743
|
-
new(Time.new(2037, 10, 15, 18, 0), 'Boston Red Sox', 'Houston Astros'),
|
1744
|
-
new(Time.new(2037, 10, 16, 18, 0), 'Boston Red Sox', 'Houston Astros'),
|
1745
|
-
new(Time.new(2037, 10, 17, 18, 0), 'Houston Astros', 'Boston Red Sox'),
|
1746
|
-
new(Time.new(2037, 10, 18, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Poncho'),
|
1747
|
-
],
|
1748
|
-
'World Series' => [
|
1749
|
-
new(Time.new(2037, 10, 20, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free Baseball Cap'),
|
1750
|
-
new(Time.new(2037, 10, 21, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
|
1751
|
-
new(Time.new(2037, 10, 22, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1752
|
-
new(Time.new(2037, 10, 23, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1753
|
-
new(Time.new(2037, 10, 24, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1754
|
-
new(Time.new(2037, 10, 25, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
|
1755
|
-
new(Time.new(2037, 10, 26, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free World Series Polo'),
|
1756
|
-
]
|
1757
|
-
}
|
1758
|
-
end
|
1759
|
-
|
1760
|
-
def playoff_type
|
1761
|
-
@playoff_type ||= 'World Series'
|
1762
|
-
end
|
1763
|
-
|
1764
|
-
def playoff_type=(new_playoff_type)
|
1765
|
-
@playoff_type = new_playoff_type
|
1766
|
-
self.schedule=(all_playoff_games[@playoff_type])
|
1767
|
-
end
|
1768
|
-
|
1769
|
-
def playoff_type_options
|
1770
|
-
all_playoff_games.keys
|
1771
|
-
end
|
1772
|
-
|
1773
|
-
def schedule
|
1774
|
-
@schedule ||= all_playoff_games[playoff_type]
|
1775
|
-
end
|
1776
|
-
|
1777
|
-
def schedule=(new_schedule)
|
1778
|
-
@schedule = new_schedule
|
1779
|
-
end
|
1780
|
-
end
|
1781
|
-
|
1782
|
-
include Glimmer
|
1783
|
-
include Glimmer::DataBinding::ObservableModel
|
1784
|
-
|
1785
|
-
TEAM_BALLPARKS = {
|
1786
|
-
'Boston Red Sox' => 'Fenway Park',
|
1787
|
-
'Chicago Cubs' => 'Wrigley Field',
|
1788
|
-
'Cincinnati Reds' => 'Great American Ball Park',
|
1789
|
-
'Cleveland Indians' => 'Progressive Field',
|
1790
|
-
'Houston Astros' => 'Minute Maid Park',
|
1791
|
-
'Milwaukee Brewers' => 'Miller Park',
|
1792
|
-
'New York Yankees' => 'Yankee Stadium',
|
1793
|
-
'St Louis Cardinals' => 'Busch Stadium',
|
1794
|
-
}
|
1795
|
-
|
1796
|
-
attr_accessor :date_time, :home_team, :away_team, :ballpark, :promotion
|
1797
|
-
|
1798
|
-
def initialize(date_time, home_team, away_team, promotion = 'N/A')
|
1799
|
-
self.date_time = date_time
|
1800
|
-
self.home_team = home_team
|
1801
|
-
self.away_team = away_team
|
1802
|
-
self.promotion = promotion
|
1803
|
-
observe(self, :date_time) do |new_value|
|
1804
|
-
notify_observers(:game_date)
|
1805
|
-
notify_observers(:game_time)
|
1806
|
-
end
|
1807
|
-
end
|
1808
|
-
|
1809
|
-
def home_team=(home_team_value)
|
1810
|
-
if home_team_value != away_team
|
1811
|
-
@home_team = home_team_value
|
1812
|
-
self.ballpark = TEAM_BALLPARKS[@home_team]
|
1813
|
-
end
|
1814
|
-
end
|
1815
|
-
|
1816
|
-
def away_team=(away_team_value)
|
1817
|
-
if away_team_value != home_team
|
1818
|
-
@away_team = away_team_value
|
1819
|
-
end
|
1820
|
-
end
|
1821
|
-
|
1822
|
-
def date
|
1823
|
-
Date.new(date_time.year, date_time.month, date_time.day)
|
1824
|
-
end
|
1825
|
-
|
1826
|
-
def time
|
1827
|
-
Time.new(0, 1, 1, date_time.hour, date_time.min, date_time.sec, '+00:00')
|
1828
|
-
end
|
1829
|
-
|
1830
|
-
def game_date
|
1831
|
-
date_time.strftime("%m/%d/%Y")
|
1832
|
-
end
|
1833
|
-
|
1834
|
-
def game_time
|
1835
|
-
date_time.strftime("%I:%M %p")
|
1836
|
-
end
|
1837
|
-
|
1838
|
-
def home_team_options
|
1839
|
-
TEAM_BALLPARKS.keys
|
1840
|
-
end
|
1841
|
-
|
1842
|
-
def away_team_options
|
1843
|
-
TEAM_BALLPARKS.keys
|
1844
|
-
end
|
1845
|
-
|
1846
|
-
def ballpark_options
|
1847
|
-
[TEAM_BALLPARKS[@home_team], TEAM_BALLPARKS[@away_team]]
|
1848
|
-
end
|
1849
|
-
|
1850
|
-
def to_s
|
1851
|
-
"#{home_team} vs #{away_team} at #{ballpark} on #{game_date} #{game_time}"
|
1852
|
-
end
|
1853
|
-
|
1854
|
-
def book!
|
1855
|
-
"Thank you for booking #{to_s}"
|
1856
|
-
end
|
1857
|
-
end
|
1858
|
-
|
1859
|
-
include Glimmer
|
1860
|
-
|
1861
|
-
def launch
|
1862
|
-
shell {
|
1863
|
-
grid_layout
|
1864
|
-
|
1865
|
-
text 'Hello, Table!'
|
1866
|
-
|
1867
|
-
label {
|
1868
|
-
layout_data :center, :center, true, false
|
1869
|
-
|
1870
|
-
text 'Baseball Playoff Schedule'
|
1871
|
-
font height: 30, style: :bold
|
1872
|
-
}
|
1873
|
-
|
1874
|
-
combo(:read_only) {
|
1875
|
-
layout_data :center, :center, true, false
|
1876
|
-
selection bind(BaseballGame, :playoff_type)
|
1877
|
-
font height: 16
|
1878
|
-
}
|
1879
|
-
|
1880
|
-
table(:editable) { |table_proxy|
|
1881
|
-
layout_data :fill, :fill, true, true
|
1882
|
-
|
1883
|
-
table_column {
|
1884
|
-
text 'Game Date'
|
1885
|
-
width 150
|
1886
|
-
sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
|
1887
|
-
editor :date_drop_down, property: :date_time
|
1888
|
-
}
|
1889
|
-
table_column {
|
1890
|
-
text 'Game Time'
|
1891
|
-
width 150
|
1892
|
-
sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
|
1893
|
-
editor :time, property: :date_time
|
1894
|
-
}
|
1895
|
-
table_column {
|
1896
|
-
text 'Ballpark'
|
1897
|
-
width 180
|
1898
|
-
editor :none
|
1899
|
-
}
|
1900
|
-
table_column {
|
1901
|
-
text 'Home Team'
|
1902
|
-
width 150
|
1903
|
-
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
1904
|
-
}
|
1905
|
-
table_column {
|
1906
|
-
text 'Away Team'
|
1907
|
-
width 150
|
1908
|
-
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
1909
|
-
}
|
1910
|
-
table_column {
|
1911
|
-
text 'Promotion'
|
1912
|
-
width 150
|
1913
|
-
# default text editor is used here
|
1914
|
-
}
|
1915
|
-
|
1916
|
-
# Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
|
1917
|
-
items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
|
1918
|
-
|
1919
|
-
# Data-bind table selection
|
1920
|
-
selection bind(BaseballGame, :selected_game)
|
1921
|
-
|
1922
|
-
# Default initial sort property
|
1923
|
-
sort_property :date
|
1924
|
-
|
1925
|
-
# Sort by these additional properties after handling sort by the column the user clicked
|
1926
|
-
additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
|
1927
|
-
}
|
1928
|
-
|
1929
|
-
button {
|
1930
|
-
text 'Book Selected Game'
|
1931
|
-
layout_data :center, :center, true, false
|
1932
|
-
font height: 16
|
1933
|
-
enabled bind(BaseballGame, :selected_game)
|
1934
|
-
|
1935
|
-
on_widget_selected {
|
1936
|
-
book_selected_game
|
1937
|
-
}
|
1938
|
-
}
|
1939
|
-
}.open
|
1940
|
-
end
|
1941
|
-
|
1942
|
-
def book_selected_game
|
1943
|
-
message_box {
|
1944
|
-
text 'Baseball Game Booked!'
|
1945
|
-
message BaseballGame.selected_game.book!
|
1946
|
-
}.open
|
1947
|
-
end
|
1948
|
-
end
|
1949
|
-
|
1950
|
-
HelloTable.new.launch
|
1951
|
-
```
|
1952
|
-
|
1953
1319
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1954
1320
|
|
1955
1321
|
![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
|
@@ -2044,30 +1410,30 @@ Or add the Glimmer code directly if you prefer to play around with it:
|
|
2044
1410
|
|
2045
1411
|
```ruby
|
2046
1412
|
class HelloButton
|
2047
|
-
include Glimmer
|
1413
|
+
include Glimmer::UI::CustomShell
|
2048
1414
|
|
2049
1415
|
attr_accessor :count
|
2050
1416
|
|
2051
|
-
|
1417
|
+
before_body {
|
2052
1418
|
@count = 0
|
2053
|
-
|
1419
|
+
}
|
2054
1420
|
|
2055
|
-
|
1421
|
+
body {
|
2056
1422
|
shell {
|
2057
1423
|
text 'Hello, Button!'
|
2058
1424
|
|
2059
1425
|
button {
|
2060
|
-
text
|
1426
|
+
text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
|
2061
1427
|
|
2062
1428
|
on_widget_selected {
|
2063
1429
|
self.count += 1
|
2064
1430
|
}
|
2065
1431
|
}
|
2066
|
-
}
|
2067
|
-
|
1432
|
+
}
|
1433
|
+
}
|
2068
1434
|
end
|
2069
1435
|
|
2070
|
-
HelloButton.
|
1436
|
+
HelloButton.launch
|
2071
1437
|
```
|
2072
1438
|
|
2073
1439
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
@@ -2687,19 +2053,24 @@ class LoginPresenter
|
|
2687
2053
|
end
|
2688
2054
|
|
2689
2055
|
class Login
|
2690
|
-
include Glimmer
|
2056
|
+
include Glimmer::UI::CustomShell
|
2057
|
+
|
2058
|
+
before_body {
|
2059
|
+
@presenter = LoginPresenter.new
|
2060
|
+
}
|
2691
2061
|
|
2692
|
-
|
2693
|
-
|
2694
|
-
@shell = shell {
|
2062
|
+
body {
|
2063
|
+
shell {
|
2695
2064
|
text "Login"
|
2065
|
+
|
2696
2066
|
composite {
|
2697
2067
|
grid_layout 2, false #two columns with differing widths
|
2698
2068
|
|
2699
2069
|
label { text "Username:" } # goes in column 1
|
2700
2070
|
@user_name_text = text { # goes in column 2
|
2701
|
-
text
|
2702
|
-
enabled
|
2071
|
+
text <=> [@presenter, :user_name]
|
2072
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2073
|
+
|
2703
2074
|
on_key_pressed { |event|
|
2704
2075
|
@password_text.set_focus if event.keyCode == swt(:cr)
|
2705
2076
|
}
|
@@ -2707,43 +2078,47 @@ class Login
|
|
2707
2078
|
|
2708
2079
|
label { text "Password:" }
|
2709
2080
|
@password_text = text(:password, :border) {
|
2710
|
-
text
|
2711
|
-
enabled
|
2081
|
+
text <=> [@presenter, :password]
|
2082
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2083
|
+
|
2712
2084
|
on_key_pressed { |event|
|
2713
|
-
presenter.login if event.keyCode == swt(:cr)
|
2085
|
+
@presenter.login! if event.keyCode == swt(:cr)
|
2714
2086
|
}
|
2715
2087
|
}
|
2716
2088
|
|
2717
2089
|
label { text "Status:" }
|
2718
|
-
label { text
|
2090
|
+
label { text <= [@presenter, :status] }
|
2719
2091
|
|
2720
2092
|
button {
|
2721
2093
|
text "Login"
|
2722
|
-
enabled
|
2723
|
-
|
2094
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2095
|
+
|
2096
|
+
on_widget_selected { @presenter.login! }
|
2724
2097
|
on_key_pressed { |event|
|
2725
|
-
|
2098
|
+
if event.keyCode == swt(:cr)
|
2099
|
+
@presenter.login!
|
2100
|
+
end
|
2726
2101
|
}
|
2727
2102
|
}
|
2728
2103
|
|
2729
2104
|
button {
|
2730
2105
|
text "Logout"
|
2731
|
-
enabled
|
2732
|
-
|
2106
|
+
enabled <= [@presenter, :logged_in?, computed_by: :status]
|
2107
|
+
|
2108
|
+
on_widget_selected { @presenter.logout! }
|
2733
2109
|
on_key_pressed { |event|
|
2734
2110
|
if event.keyCode == swt(:cr)
|
2735
|
-
presenter.logout
|
2111
|
+
@presenter.logout!
|
2736
2112
|
@user_name_text.set_focus
|
2737
2113
|
end
|
2738
2114
|
}
|
2739
2115
|
}
|
2740
2116
|
}
|
2741
2117
|
}
|
2742
|
-
|
2743
|
-
end
|
2118
|
+
}
|
2744
2119
|
end
|
2745
2120
|
|
2746
|
-
Login.
|
2121
|
+
Login.launch
|
2747
2122
|
```
|
2748
2123
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2749
2124
|
|
@@ -2774,214 +2149,7 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
2774
2149
|
require 'glimmer-dsl-opal/samples/elaborate/tic_tac_toe'
|
2775
2150
|
```
|
2776
2151
|
|
2777
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
2778
|
-
|
2779
2152
|
```ruby
|
2780
|
-
class TicTacToe
|
2781
|
-
class Cell
|
2782
|
-
EMPTY = ""
|
2783
|
-
attr_accessor :sign, :empty
|
2784
|
-
|
2785
|
-
def initialize
|
2786
|
-
reset
|
2787
|
-
end
|
2788
|
-
|
2789
|
-
def mark(sign)
|
2790
|
-
self.sign = sign
|
2791
|
-
end
|
2792
|
-
|
2793
|
-
def reset
|
2794
|
-
self.sign = EMPTY
|
2795
|
-
end
|
2796
|
-
|
2797
|
-
def sign=(sign_symbol)
|
2798
|
-
@sign = sign_symbol
|
2799
|
-
self.empty = sign == EMPTY
|
2800
|
-
end
|
2801
|
-
|
2802
|
-
def marked
|
2803
|
-
!empty
|
2804
|
-
end
|
2805
|
-
end
|
2806
|
-
end
|
2807
|
-
|
2808
|
-
class TicTacToe
|
2809
|
-
class Board
|
2810
|
-
DRAW = :draw
|
2811
|
-
IN_PROGRESS = :in_progress
|
2812
|
-
WIN = :win
|
2813
|
-
attr :winning_sign
|
2814
|
-
attr_accessor :game_status
|
2815
|
-
|
2816
|
-
def initialize
|
2817
|
-
@sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
|
2818
|
-
build_grid
|
2819
|
-
@winning_sign = Cell::EMPTY
|
2820
|
-
@game_status = IN_PROGRESS
|
2821
|
-
end
|
2822
|
-
|
2823
|
-
#row and column numbers are 1-based
|
2824
|
-
def mark(row, column)
|
2825
|
-
self[row, column].mark(current_sign)
|
2826
|
-
game_over? #updates winning sign
|
2827
|
-
end
|
2828
|
-
|
2829
|
-
def current_sign
|
2830
|
-
@current_sign = @sign_state_machine[@current_sign]
|
2831
|
-
end
|
2832
|
-
|
2833
|
-
def [](row, column)
|
2834
|
-
@grid[row-1][column-1]
|
2835
|
-
end
|
2836
|
-
|
2837
|
-
def game_over?
|
2838
|
-
win? or draw?
|
2839
|
-
end
|
2840
|
-
|
2841
|
-
def win?
|
2842
|
-
win = (row_win? or column_win? or diagonal_win?)
|
2843
|
-
self.game_status=WIN if win
|
2844
|
-
win
|
2845
|
-
end
|
2846
|
-
|
2847
|
-
def reset
|
2848
|
-
(1..3).each do |row|
|
2849
|
-
(1..3).each do |column|
|
2850
|
-
self[row, column].reset
|
2851
|
-
end
|
2852
|
-
end
|
2853
|
-
@winning_sign = Cell::EMPTY
|
2854
|
-
@current_sign = nil
|
2855
|
-
self.game_status=IN_PROGRESS
|
2856
|
-
end
|
2857
|
-
|
2858
|
-
private
|
2859
|
-
|
2860
|
-
def build_grid
|
2861
|
-
@grid = []
|
2862
|
-
3.times do |row_index| #0-based
|
2863
|
-
@grid << []
|
2864
|
-
3.times { @grid[row_index] << Cell.new }
|
2865
|
-
end
|
2866
|
-
end
|
2867
|
-
|
2868
|
-
def row_win?
|
2869
|
-
(1..3).each do |row|
|
2870
|
-
if row_has_same_sign(row)
|
2871
|
-
@winning_sign = self[row, 1].sign
|
2872
|
-
return true
|
2873
|
-
end
|
2874
|
-
end
|
2875
|
-
false
|
2876
|
-
end
|
2877
|
-
|
2878
|
-
def column_win?
|
2879
|
-
(1..3).each do |column|
|
2880
|
-
if column_has_same_sign(column)
|
2881
|
-
@winning_sign = self[1, column].sign
|
2882
|
-
return true
|
2883
|
-
end
|
2884
|
-
end
|
2885
|
-
false
|
2886
|
-
end
|
2887
|
-
|
2888
|
-
#needs refactoring if we ever decide to make the board size dynamic
|
2889
|
-
def diagonal_win?
|
2890
|
-
if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
|
2891
|
-
@winning_sign = self[1, 1].sign
|
2892
|
-
return true
|
2893
|
-
end
|
2894
|
-
if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
|
2895
|
-
@winning_sign = self[3, 1].sign
|
2896
|
-
return true
|
2897
|
-
end
|
2898
|
-
false
|
2899
|
-
end
|
2900
|
-
|
2901
|
-
def draw?
|
2902
|
-
@board_full = true
|
2903
|
-
3.times do |x|
|
2904
|
-
3.times do |y|
|
2905
|
-
@board_full = false if self[x, y].empty
|
2906
|
-
end
|
2907
|
-
end
|
2908
|
-
self.game_status = DRAW if @board_full
|
2909
|
-
@board_full
|
2910
|
-
end
|
2911
|
-
|
2912
|
-
def row_has_same_sign(number)
|
2913
|
-
row_sign = self[number, 1].sign
|
2914
|
-
[2, 3].each do |column|
|
2915
|
-
return false unless row_sign == (self[number, column].sign)
|
2916
|
-
end
|
2917
|
-
true if self[number, 1].marked
|
2918
|
-
end
|
2919
|
-
|
2920
|
-
def column_has_same_sign(number)
|
2921
|
-
column_sign = self[1, number].sign
|
2922
|
-
[2, 3].each do |row|
|
2923
|
-
return false unless column_sign == (self[row, number].sign)
|
2924
|
-
end
|
2925
|
-
true if self[1, number].marked
|
2926
|
-
end
|
2927
|
-
|
2928
|
-
end
|
2929
|
-
end
|
2930
|
-
|
2931
|
-
class TicTacToe
|
2932
|
-
include Glimmer
|
2933
|
-
|
2934
|
-
def initialize
|
2935
|
-
@tic_tac_toe_board = Board.new
|
2936
|
-
@shell = shell {
|
2937
|
-
text "Tic-Tac-Toe"
|
2938
|
-
minimum_size 150, 178
|
2939
|
-
composite {
|
2940
|
-
grid_layout 3, true
|
2941
|
-
(1..3).each { |row|
|
2942
|
-
(1..3).each { |column|
|
2943
|
-
button {
|
2944
|
-
layout_data :fill, :fill, true, true
|
2945
|
-
text bind(@tic_tac_toe_board[row, column], :sign)
|
2946
|
-
enabled bind(@tic_tac_toe_board[row, column], :empty)
|
2947
|
-
font style: :bold, height: 20
|
2948
|
-
on_widget_selected {
|
2949
|
-
@tic_tac_toe_board.mark(row, column)
|
2950
|
-
}
|
2951
|
-
}
|
2952
|
-
}
|
2953
|
-
}
|
2954
|
-
}
|
2955
|
-
}
|
2956
|
-
observe(@tic_tac_toe_board, :game_status) { |game_status|
|
2957
|
-
display_win_message if game_status == Board::WIN
|
2958
|
-
display_draw_message if game_status == Board::DRAW
|
2959
|
-
}
|
2960
|
-
end
|
2961
|
-
|
2962
|
-
def display_win_message
|
2963
|
-
display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
|
2964
|
-
end
|
2965
|
-
|
2966
|
-
def display_draw_message
|
2967
|
-
display_game_over_message("Draw!")
|
2968
|
-
end
|
2969
|
-
|
2970
|
-
def display_game_over_message(message_text)
|
2971
|
-
message_box(@shell) {
|
2972
|
-
text 'Game Over'
|
2973
|
-
message message_text
|
2974
|
-
}.open
|
2975
|
-
@tic_tac_toe_board.reset
|
2976
|
-
end
|
2977
|
-
|
2978
|
-
def open
|
2979
|
-
@shell.open
|
2980
|
-
end
|
2981
|
-
end
|
2982
|
-
|
2983
|
-
TicTacToe.new.open
|
2984
|
-
```
|
2985
2153
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2986
2154
|
|
2987
2155
|
![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
|
@@ -3011,321 +2179,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
3011
2179
|
require 'glimmer-dsl-opal/samples/elaborate/contact_manager'
|
3012
2180
|
```
|
3013
2181
|
|
3014
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
3015
|
-
|
3016
|
-
```ruby
|
3017
|
-
class ContactManager
|
3018
|
-
class Contact
|
3019
|
-
attr_accessor :first_name, :last_name, :email
|
3020
|
-
|
3021
|
-
def initialize(attribute_map)
|
3022
|
-
@first_name = attribute_map[:first_name]
|
3023
|
-
@last_name = attribute_map[:last_name]
|
3024
|
-
@email = attribute_map[:email]
|
3025
|
-
end
|
3026
|
-
end
|
3027
|
-
end
|
3028
|
-
|
3029
|
-
class ContactManager
|
3030
|
-
class ContactRepository
|
3031
|
-
NAMES_FIRST = %w[
|
3032
|
-
Liam
|
3033
|
-
Noah
|
3034
|
-
William
|
3035
|
-
James
|
3036
|
-
Oliver
|
3037
|
-
Benjamin
|
3038
|
-
Elijah
|
3039
|
-
Lucas
|
3040
|
-
Mason
|
3041
|
-
Logan
|
3042
|
-
Alexander
|
3043
|
-
Ethan
|
3044
|
-
Jacob
|
3045
|
-
Michael
|
3046
|
-
Daniel
|
3047
|
-
Henry
|
3048
|
-
Jackson
|
3049
|
-
Sebastian
|
3050
|
-
Aiden
|
3051
|
-
Matthew
|
3052
|
-
Samuel
|
3053
|
-
David
|
3054
|
-
Joseph
|
3055
|
-
Carter
|
3056
|
-
Owen
|
3057
|
-
Wyatt
|
3058
|
-
John
|
3059
|
-
Jack
|
3060
|
-
Luke
|
3061
|
-
Jayden
|
3062
|
-
Dylan
|
3063
|
-
Grayson
|
3064
|
-
Levi
|
3065
|
-
Isaac
|
3066
|
-
Gabriel
|
3067
|
-
Julian
|
3068
|
-
Mateo
|
3069
|
-
Anthony
|
3070
|
-
Jaxon
|
3071
|
-
Lincoln
|
3072
|
-
Joshua
|
3073
|
-
Christopher
|
3074
|
-
Andrew
|
3075
|
-
Theodore
|
3076
|
-
Caleb
|
3077
|
-
Ryan
|
3078
|
-
Asher
|
3079
|
-
Nathan
|
3080
|
-
Thomas
|
3081
|
-
Leo
|
3082
|
-
Isaiah
|
3083
|
-
Charles
|
3084
|
-
Josiah
|
3085
|
-
Hudson
|
3086
|
-
Christian
|
3087
|
-
Hunter
|
3088
|
-
Connor
|
3089
|
-
Eli
|
3090
|
-
Ezra
|
3091
|
-
Aaron
|
3092
|
-
Landon
|
3093
|
-
Adrian
|
3094
|
-
Jonathan
|
3095
|
-
Nolan
|
3096
|
-
Jeremiah
|
3097
|
-
Easton
|
3098
|
-
Elias
|
3099
|
-
Colton
|
3100
|
-
Cameron
|
3101
|
-
Carson
|
3102
|
-
Robert
|
3103
|
-
Angel
|
3104
|
-
Maverick
|
3105
|
-
Nicholas
|
3106
|
-
Dominic
|
3107
|
-
Jaxson
|
3108
|
-
Greyson
|
3109
|
-
Adam
|
3110
|
-
Ian
|
3111
|
-
Austin
|
3112
|
-
Santiago
|
3113
|
-
Jordan
|
3114
|
-
Cooper
|
3115
|
-
Brayden
|
3116
|
-
Roman
|
3117
|
-
Evan
|
3118
|
-
Ezekiel
|
3119
|
-
Xaviar
|
3120
|
-
Jose
|
3121
|
-
Jace
|
3122
|
-
Jameson
|
3123
|
-
Leonardo
|
3124
|
-
Axel
|
3125
|
-
Everett
|
3126
|
-
Kayden
|
3127
|
-
Miles
|
3128
|
-
Sawyer
|
3129
|
-
Jason
|
3130
|
-
Emma
|
3131
|
-
Olivia
|
3132
|
-
]
|
3133
|
-
NAMES_LAST = %w[
|
3134
|
-
Smith
|
3135
|
-
Johnson
|
3136
|
-
Williams
|
3137
|
-
Brown
|
3138
|
-
Jones
|
3139
|
-
Miller
|
3140
|
-
Davis
|
3141
|
-
Wilson
|
3142
|
-
Anderson
|
3143
|
-
Taylor
|
3144
|
-
]
|
3145
|
-
def initialize(contacts = nil)
|
3146
|
-
@contacts = contacts || 100.times.map do |n|
|
3147
|
-
random_first_name_index = (rand*NAMES_FIRST.size).to_i
|
3148
|
-
random_last_name_index = (rand*NAMES_LAST.size).to_i
|
3149
|
-
first_name = NAMES_FIRST[random_first_name_index]
|
3150
|
-
last_name = NAMES_LAST[random_last_name_index]
|
3151
|
-
email = "#{first_name}@#{last_name}.com".downcase
|
3152
|
-
Contact.new(
|
3153
|
-
first_name: first_name,
|
3154
|
-
last_name: last_name,
|
3155
|
-
email: email
|
3156
|
-
)
|
3157
|
-
end
|
3158
|
-
end
|
3159
|
-
|
3160
|
-
def find(attribute_filter_map)
|
3161
|
-
@contacts.find_all do |contact|
|
3162
|
-
match = true
|
3163
|
-
attribute_filter_map.keys.each do |attribute_name|
|
3164
|
-
contact_value = contact.send(attribute_name).downcase
|
3165
|
-
filter_value = attribute_filter_map[attribute_name].downcase
|
3166
|
-
match = false unless contact_value.match(filter_value)
|
3167
|
-
end
|
3168
|
-
match
|
3169
|
-
end
|
3170
|
-
end
|
3171
|
-
end
|
3172
|
-
end
|
3173
|
-
|
3174
|
-
class ContactManager
|
3175
|
-
class ContactManagerPresenter
|
3176
|
-
attr_accessor :results
|
3177
|
-
@@contact_attributes = [:first_name, :last_name, :email]
|
3178
|
-
@@contact_attributes.each {|attribute_name| attr_accessor attribute_name}
|
3179
|
-
|
3180
|
-
def initialize(contact_repository = nil)
|
3181
|
-
@contact_repository = contact_repository || ContactRepository.new
|
3182
|
-
@results = []
|
3183
|
-
end
|
3184
|
-
|
3185
|
-
def list
|
3186
|
-
self.results = @contact_repository.find({})
|
3187
|
-
end
|
3188
|
-
|
3189
|
-
def find
|
3190
|
-
filter_map = {}
|
3191
|
-
@@contact_attributes.each do |attribute_name|
|
3192
|
-
filter_map[attribute_name] = self.send(attribute_name) if self.send(attribute_name)
|
3193
|
-
end
|
3194
|
-
self.results = @contact_repository.find(filter_map)
|
3195
|
-
@sort_attribute_name = nil
|
3196
|
-
@sort_direction_ascending = nil
|
3197
|
-
end
|
3198
|
-
|
3199
|
-
def toggle_sort(attribute_name)
|
3200
|
-
@sort_attribute_name = attribute_name
|
3201
|
-
@sort_direction_ascending = !@sort_direction_ascending
|
3202
|
-
sorted_results = self.results.sort_by {|contact| contact.send(attribute_name).downcase}
|
3203
|
-
sorted_results = sorted_results.reverse unless @sort_direction_ascending
|
3204
|
-
self.results = sorted_results
|
3205
|
-
end
|
3206
|
-
end
|
3207
|
-
end
|
3208
|
-
|
3209
|
-
class ContactManager
|
3210
|
-
include Glimmer
|
3211
|
-
|
3212
|
-
def initialize
|
3213
|
-
@contact_manager_presenter = ContactManagerPresenter.new
|
3214
|
-
@contact_manager_presenter.list
|
3215
|
-
end
|
3216
|
-
|
3217
|
-
def launch
|
3218
|
-
shell {
|
3219
|
-
text "Contact Manager"
|
3220
|
-
composite {
|
3221
|
-
group {
|
3222
|
-
grid_layout(2, false) {
|
3223
|
-
margin_width 0
|
3224
|
-
margin_height 0
|
3225
|
-
}
|
3226
|
-
layout_data :fill, :center, true, false
|
3227
|
-
text 'Lookup Contacts'
|
3228
|
-
font height: 24
|
3229
|
-
|
3230
|
-
label {
|
3231
|
-
layout_data :right, :center, false, false
|
3232
|
-
text "First &Name: "
|
3233
|
-
font height: 16
|
3234
|
-
}
|
3235
|
-
text {
|
3236
|
-
layout_data :fill, :center, true, false
|
3237
|
-
text bind(@contact_manager_presenter, :first_name)
|
3238
|
-
on_key_pressed {|key_event|
|
3239
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3240
|
-
}
|
3241
|
-
}
|
3242
|
-
|
3243
|
-
label {
|
3244
|
-
layout_data :right, :center, false, false
|
3245
|
-
text "&Last Name: "
|
3246
|
-
font height: 16
|
3247
|
-
}
|
3248
|
-
text {
|
3249
|
-
layout_data :fill, :center, true, false
|
3250
|
-
text bind(@contact_manager_presenter, :last_name)
|
3251
|
-
on_key_pressed {|key_event|
|
3252
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3253
|
-
}
|
3254
|
-
}
|
3255
|
-
|
3256
|
-
label {
|
3257
|
-
layout_data :right, :center, false, false
|
3258
|
-
text "&Email: "
|
3259
|
-
font height: 16
|
3260
|
-
}
|
3261
|
-
text {
|
3262
|
-
layout_data :fill, :center, true, false
|
3263
|
-
text bind(@contact_manager_presenter, :email)
|
3264
|
-
on_key_pressed {|key_event|
|
3265
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3266
|
-
}
|
3267
|
-
}
|
3268
|
-
|
3269
|
-
composite {
|
3270
|
-
row_layout {
|
3271
|
-
margin_width 0
|
3272
|
-
margin_height 0
|
3273
|
-
}
|
3274
|
-
layout_data(:right, :center, false, false) {
|
3275
|
-
horizontal_span 2
|
3276
|
-
}
|
3277
|
-
|
3278
|
-
button {
|
3279
|
-
text "&Find"
|
3280
|
-
on_widget_selected { @contact_manager_presenter.find }
|
3281
|
-
on_key_pressed {|key_event|
|
3282
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3283
|
-
}
|
3284
|
-
}
|
3285
|
-
|
3286
|
-
button {
|
3287
|
-
text "&List All"
|
3288
|
-
on_widget_selected { @contact_manager_presenter.list }
|
3289
|
-
on_key_pressed {|key_event|
|
3290
|
-
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
3291
|
-
}
|
3292
|
-
}
|
3293
|
-
}
|
3294
|
-
}
|
3295
|
-
|
3296
|
-
table(:multi) { |table_proxy|
|
3297
|
-
layout_data {
|
3298
|
-
horizontal_alignment :fill
|
3299
|
-
vertical_alignment :fill
|
3300
|
-
grab_excess_horizontal_space true
|
3301
|
-
grab_excess_vertical_space true
|
3302
|
-
height_hint 200
|
3303
|
-
}
|
3304
|
-
table_column {
|
3305
|
-
text "First Name"
|
3306
|
-
width 80
|
3307
|
-
}
|
3308
|
-
table_column {
|
3309
|
-
text "Last Name"
|
3310
|
-
width 80
|
3311
|
-
}
|
3312
|
-
table_column {
|
3313
|
-
text "Email"
|
3314
|
-
width 200
|
3315
|
-
}
|
3316
|
-
items bind(@contact_manager_presenter, :results),
|
3317
|
-
column_properties(:first_name, :last_name, :email)
|
3318
|
-
on_mouse_up { |event|
|
3319
|
-
table_proxy.edit_table_item(event.table_item, event.column_index)
|
3320
|
-
}
|
3321
|
-
}
|
3322
|
-
}
|
3323
|
-
}.open
|
3324
|
-
end
|
3325
|
-
end
|
3326
|
-
|
3327
|
-
ContactManager.new.launch
|
3328
|
-
```
|
3329
2182
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
3330
2183
|
|
3331
2184
|
Glimmer DSL for SWT Contact Manager
|
@@ -3379,6 +2232,39 @@ Glimmer DSL for Opal Contact Manager Edit Done
|
|
3379
2232
|
|
3380
2233
|
![Glimmer DSL for Opal Contact Manager Edit Done](images/glimmer-dsl-opal-contact-manager-edit-done.png)
|
3381
2234
|
|
2235
|
+
#### Weather
|
2236
|
+
|
2237
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
2238
|
+
|
2239
|
+
```ruby
|
2240
|
+
require 'glimmer-dsl-opal/samples/elaborate/weather'
|
2241
|
+
```
|
2242
|
+
|
2243
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2244
|
+
|
2245
|
+
![Weather Montreal C](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-celsius.png)
|
2246
|
+
|
2247
|
+
![Weather Montreal F](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-fahrenheit.png)
|
2248
|
+
|
2249
|
+
![Weather Atlanta F](https://github.com/AMaleh /glimmer-dsl-swt/raw/master/images/glimmer-weather-atlanta-fahrenheit.png)
|
2250
|
+
|
2251
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
2252
|
+
|
2253
|
+
Start the Rails server:
|
2254
|
+
```
|
2255
|
+
rails s
|
2256
|
+
```
|
2257
|
+
|
2258
|
+
Visit `http://localhost:3000`
|
2259
|
+
|
2260
|
+
You should see "Weather"
|
2261
|
+
|
2262
|
+
![Opal Weather Montreal C](/images/glimmer-dsl-opal-weather-montreal-celsius.png)
|
2263
|
+
|
2264
|
+
![Opal Weather Montreal F](/images/glimmer-dsl-opal-weather-montreal-fahrenheit.png)
|
2265
|
+
|
2266
|
+
![Opal Weather Atlanta F](/images/glimmer-dsl-opal-weather-atlanta-fahrenheit.png)
|
2267
|
+
|
3382
2268
|
### External Samples
|
3383
2269
|
|
3384
2270
|
#### Glimmer Calculator
|