glimmer-dsl-opal 0.7.3 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +847 -158
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +15 -3
  6. data/lib/glimmer-dsl-opal/ext/class.rb +10 -0
  7. data/lib/{file.rb → glimmer-dsl-opal/ext/file.rb} +0 -0
  8. data/lib/glimmer-dsl-opal/ext/glimmer/dsl/engine.rb +25 -0
  9. data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
  10. data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
  11. data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +24 -1
  12. data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
  13. data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -0
  14. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
  15. data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +62 -32
  16. data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +47 -22
  17. data/lib/glimmer-dsl-opal/samples/hello/hello_menu_bar.rb +241 -0
  18. data/lib/glimmer-dsl-opal/samples/hello/hello_message_box.rb +37 -0
  19. data/lib/glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu.rb +84 -0
  20. data/lib/glimmer-dsl-opal/samples/hello/hello_world.rb +3 -3
  21. data/lib/glimmer/config/opal_logger.rb +16 -0
  22. data/lib/glimmer/data_binding/observable_element.rb +1 -1
  23. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +6 -0
  24. data/lib/glimmer/dsl/opal/dsl.rb +2 -0
  25. data/lib/glimmer/dsl/opal/menu_bar_expression.rb +54 -0
  26. data/lib/glimmer/dsl/opal/menu_expression.rb +61 -0
  27. data/lib/glimmer/dsl/opal/shell_expression.rb +0 -4
  28. data/lib/glimmer/dsl/opal/widget_expression.rb +3 -2
  29. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +2 -2
  30. data/lib/glimmer/swt/custom/checkbox_group.rb +2 -2
  31. data/lib/glimmer/swt/custom/radio_group.rb +2 -2
  32. data/lib/glimmer/swt/date_time_proxy.rb +1 -1
  33. data/lib/glimmer/swt/display_proxy.rb +5 -4
  34. data/lib/glimmer/swt/event_listener_proxy.rb +14 -4
  35. data/lib/glimmer/swt/grid_layout_proxy.rb +21 -12
  36. data/lib/glimmer/swt/label_proxy.rb +17 -6
  37. data/lib/glimmer/swt/latest_message_box_proxy.rb +20 -0
  38. data/lib/glimmer/swt/latest_shell_proxy.rb +20 -0
  39. data/lib/glimmer/swt/layout_data_proxy.rb +6 -6
  40. data/lib/glimmer/swt/list_proxy.rb +15 -0
  41. data/lib/glimmer/swt/menu_item_proxy.rb +174 -0
  42. data/lib/glimmer/swt/menu_proxy.rb +273 -0
  43. data/lib/glimmer/swt/message_box_proxy.rb +57 -72
  44. data/lib/glimmer/swt/property_owner.rb +2 -0
  45. data/lib/glimmer/swt/radio_proxy.rb +1 -1
  46. data/lib/glimmer/swt/shell_proxy.rb +34 -189
  47. data/lib/glimmer/swt/tab_folder_proxy.rb +43 -0
  48. data/lib/glimmer/swt/table_column_proxy.rb +3 -2
  49. data/lib/glimmer/swt/table_editor.rb +1 -1
  50. data/lib/glimmer/swt/table_item_proxy.rb +7 -5
  51. data/lib/glimmer/swt/table_proxy.rb +10 -0
  52. data/lib/glimmer/swt/widget_proxy.rb +325 -31
  53. data/lib/glimmer/ui/custom_shell.rb +9 -7
  54. data/lib/glimmer/ui/custom_widget.rb +3 -3
  55. metadata +26 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 267d755e70aa2465ba671e499fcdccb7059de89658f381dafee9480a095e9bf5
4
- data.tar.gz: 8b5a6ae6d22fef47f7623755810b47dad3b1b25d6ce76bdadde4f89ec8da976c
3
+ metadata.gz: 17d97486e2535b96ec91e1cf8779eb25d7bdf2c06555a1cc3ae13c54cf4bf185
4
+ data.tar.gz: 3c66f6ae88bc76892fd7c2f330715a7e4977b86be233d71c88fa0711d8f3cc77
5
5
  SHA512:
6
- metadata.gz: a3a5a6621c062459650d83f707cc76819ca9c8abfe50c59a1d5b657648453fa2187ee0faabad2090593192304eabd2454ef4ab3f8c27d5658bba4ae4b8f07c2d
7
- data.tar.gz: f49a05966c477fb1c38886dc772a50b1f8b9e6249741776a82a3ebc836ec879e8906df2e5c8528246e73b9b349401b3548c97db2af6e42545ece54d6fb334c28
6
+ metadata.gz: 551b4618800f75f3ace354647fc09e27a79846e02ec31756a4839759dd23db690de246c1064454056fa0039b809a7bb084b54df6785959e1b4173b251d3b9fda
7
+ data.tar.gz: 947bdeaf86464c004d0a1d0e20bff91781ee1282c207197f1fd77fb2a3435c6ecf589247324e887db1ce65ec156d8826009a94da9758ebd2f92d8c77d21fecee
@@ -1,5 +1,45 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.9.1
4
+
5
+ - Log errors to error stream ($stderr) instead of standard out (STDOUT)
6
+ - Fixed issue with opening shell caused by internalizing the Document.ready? block
7
+
8
+ ## 0.9.0
9
+
10
+ - Support `menu_bar`
11
+ - Hello, Menu Bar! Sample
12
+ - Remove the need to call Document.ready? before opening a Glimmer shell
13
+ - Support opening a message_box before creating a shell
14
+
15
+ ## 0.8.0
16
+
17
+ - Hello, Pop Up Context Menu! Sample
18
+ - Hello Message Box!
19
+ - Update hello list samples
20
+ - Support context menus `menu`/`menu_item` directly under a widget (using jQuery UI)
21
+ - Support generating new lines when entering `label` `text` with \n (auto-converting to <br />)
22
+ - Support generating new lines when entering `message_box` `message` with \n (auto-converting to <br />)
23
+ - Support having any widget contribute static CSS to ShellProxy
24
+ - Add Kernel#include_package shim to allow running JRuby include_package from Glimmer DSL for SWT without failing
25
+ - Add WidgetProxy#swt_widget to allow running include_package from Glimmer DSL for SWT without failing
26
+
27
+ ## 0.7.5
28
+
29
+ - Update login sample from Glimmer DSL for SWT's latest changes
30
+ - Update contact_manager sample from Glimmer DSL for SWT's latest changes
31
+ - Fixed issue regarding unavailable localStorage data when accessed by custom_widget_expression in hello_checkbox_group, hello_radio_group, and hello_custom_widget
32
+
33
+ ## 0.7.4
34
+
35
+ - Hello, Button! Sample
36
+ - Fix issue with aligning label as :left, :center, or :right via style style when fill_layout is used
37
+ - Fix Hello, Browser sample by accessing https ssl website
38
+ - Fix issue with filling space horizontally when using grid layout
39
+ - Fix broken embedded `calendar` widget data-binding for hello_date_time.rb sample
40
+ - Fix broken message_box after opening multiple shells
41
+ - Fix issue with opening custom shells in new tabs/windows when CustomShell subclass is required conditionally
42
+
3
43
  ## 0.7.3
4
44
 
5
45
  - Refactor to use to_collection gem
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.7.3 (Pure Ruby Web GUI)
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.9.1 (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
 
@@ -12,55 +12,138 @@ Use in one of two ways:
12
12
 
13
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 powerful Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web.
14
14
 
15
- #### Tic Tac Toe Sample
15
+ #### Hello, Table! Sample
16
16
 
17
- Add the following require statement to `app/assets/javascripts/application.rb` in a [Glimmer setup](#setup) Rails app:
18
-
19
- ```ruby
20
- require 'glimmer-dsl-opal/samples/elaborate/tic_tac_toe'
21
- ```
22
-
23
- Glimmer GUI code from [glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb](lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb):
17
+ Glimmer GUI code from [glimmer-dsl-opal/samples/hello/hello_table.rb](lib/glimmer-dsl-opal/samples/hello/hello_table.rb):
24
18
 
25
19
  ```ruby
26
20
  # ...
27
- @shell = shell {
28
- text "Tic-Tac-Toe"
29
- minimum_size 150, 178
30
- composite {
31
- grid_layout 3, true
32
- (1..3).each { |row|
33
- (1..3).each { |column|
34
- button {
35
- layout_data :fill, :fill, true, true
36
- text bind(@tic_tac_toe_board[row, column], :sign)
37
- enabled bind(@tic_tac_toe_board[row, column], :empty)
38
- font style: :bold, height: 20
39
- on_widget_selected {
40
- @tic_tac_toe_board.mark(row, column)
41
- }
42
- }
43
- }
44
- }
45
- }
21
+ shell {
22
+ grid_layout
23
+
24
+ text 'Hello, Table!'
25
+
26
+ label {
27
+ layout_data :center, :center, true, false
28
+
29
+ text 'Baseball Playoff Schedule'
30
+ font height: 30, style: :bold
31
+ }
32
+
33
+ combo(:read_only) {
34
+ layout_data :center, :center, true, false
35
+ selection bind(BaseballGame, :playoff_type)
36
+ font height: 16
37
+ }
38
+
39
+ table(:editable) { |table_proxy|
40
+ layout_data :fill, :fill, true, true
41
+
42
+ table_column {
43
+ text 'Game Date'
44
+ width 150
45
+ sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
46
+ editor :date_drop_down, property: :date_time
47
+ }
48
+ table_column {
49
+ text 'Game Time'
50
+ width 150
51
+ sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
52
+ editor :time, property: :date_time
53
+ }
54
+ table_column {
55
+ text 'Ballpark'
56
+ width 180
57
+ editor :none
58
+ }
59
+ table_column {
60
+ text 'Home Team'
61
+ width 150
62
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
63
+ }
64
+ table_column {
65
+ text 'Away Team'
66
+ width 150
67
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
68
+ }
69
+ table_column {
70
+ text 'Promotion'
71
+ width 150
72
+ # default text editor is used here
73
+ }
74
+
75
+ # Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
76
+ items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
77
+
78
+ # Data-bind table selection
79
+ selection bind(BaseballGame, :selected_game)
80
+
81
+ # Default initial sort property
82
+ sort_property :date
83
+
84
+ # Sort by these additional properties after handling sort by the column the user clicked
85
+ additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
86
+ }
87
+
88
+ button {
89
+ text 'Book Selected Game'
90
+ layout_data :center, :center, true, false
91
+ font height: 16
92
+ enabled bind(BaseballGame, :selected_game)
93
+
94
+ on_widget_selected {
95
+ book_selected_game
46
96
  }
97
+ }
98
+ }.open
47
99
  # ...
48
100
  ```
49
- Tic Tac Toe on the web (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):
50
101
 
51
- ![Glimmer DSL for Opal Tic Tac Toe](images/glimmer-dsl-opal-tic-tac-toe.png)
52
- ![Glimmer DSL for Opal Tic Tac Toe In Progress](images/glimmer-dsl-opal-tic-tac-toe-in-progress.png)
53
- ![Glimmer DSL for Opal Tic Tac Toe Game Over](images/glimmer-dsl-opal-tic-tac-toe-game-over.png)
102
+ **Hello, Table! originally running on the desktop (using the [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):**
54
103
 
55
- Tic Tac Toe on the desktop with the same exact code (using the [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
104
+ ![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
56
105
 
57
- ![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
58
- ![Glimmer DSL for SWT Tic Tac Toe In Progress](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-in-progress.png)
59
- ![Glimmer DSL for SWT Tic Tac Toe Game Over](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-game-over.png)
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):**
60
107
 
61
- NOTE: **Alpha Version** 0.7.3 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
108
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table.png)
62
109
 
63
- Hello:
110
+ Hello, Table! Editing Game Date
111
+
112
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-game-date.png)
113
+
114
+ Hello, Table! Editing Game Time
115
+
116
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-game-time.png)
117
+
118
+ Hello, Table! Editing Home Team
119
+
120
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-home-team.png)
121
+
122
+ Hello, Table! Sorted Game Date Ascending
123
+
124
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-sorted-game-date-ascending.png)
125
+
126
+ Hello, Table! Sorted Game Date Descending
127
+
128
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-sorted-game-date-descending.png)
129
+
130
+ Hello, Table! Playoff Type Combo
131
+
132
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-playoff-type-combo.png)
133
+
134
+ Hello, Table! Playoff Type Changed
135
+
136
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-playoff-type-changed.png)
137
+
138
+ Hello, Table! Game Booked
139
+
140
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-game-booked.png)
141
+
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
+
144
+ **Alpha Version** 0.9.1 only supports bare-minimum capabilities for the following [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)):
145
+
146
+ [Hello samples](#hello-samples):
64
147
 
65
148
  - [Hello, World!](#hello-world)
66
149
  - [Hello, Combo!](#hello-combo)
@@ -78,8 +161,12 @@ Hello:
78
161
  - [Hello, Checkbox Group!](#hello-checkbox-group)
79
162
  - [Hello, Date Time!](#hello-date-time)
80
163
  - [Hello, Table!](#hello-table)
164
+ - [Hello, Button!](#hello-button)
165
+ - [Hello, Message Box!](#hello-message-box)
166
+ - [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
167
+ - [Hello, Menu Bar!](#hello-menu-bar)
81
168
 
82
- Elaborate:
169
+ [Elaborate samples](#elaborate-samples):
83
170
 
84
171
  - [Login](#login)
85
172
  - [Tic Tac Toe](#tic-tac-toe)
@@ -100,40 +187,68 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
100
187
  The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have partial support in Opal:
101
188
 
102
189
  Widgets:
103
- - `shell`
104
- - `label`
105
- - `combo`
106
- - `button`
107
- - `text`
108
- - `composite`
109
- - `list` & `list(:multi)`
110
- - `tab_folder`
111
- - `tab_item`
112
- - `table`
113
- - `table_column`
114
- - `message_box`
115
- - Glimmer::UI::CustomWidget: ability to define any keyword as a custom widget
116
- - Glimmer::UI::CustomShell: ability to define any keyword as a custom shell (aka custom window) that opens in a new browser window (tab) automatically unless there is no shell open in the current browser window (tab)
190
+ - `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)
191
+ - `browser`: featured in [Hello, Browser!](#hello-browser)
192
+ - `calendar`: featured in [Hello, Date Time!](#hello-date-time)
193
+ - `checkbox`: featured in [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox)
194
+ - `checkbox_group`: featured in [Hello, Checkbox Group!](#hello-checkbox-group)
195
+ - `combo`: featured in [Hello, Table!](#hello-table) / [Hello, Combo!](#hello-combo)
196
+ - `composite`: featured in [Hello, Radio!](#hello-radio) / [Hello, Computed!](#hello-computed) / [Hello, Checkbox!](#hello-checkbox) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login) / [Contact Manager](#contact-manager)
197
+ - `date`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Shell!](#hello-custom-shell) / [Tic Tac Toe](#tic-tac-toe)
198
+ - `date_drop_down`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time)
199
+ - `group`: featured in [Hello, Group!](#hello-group) / [Contact Manager](#contact-manager)
200
+ - `label`: featured in [Hello, Computed!](#hello-computed) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, World!](#hello-world) / [Hello, Table!](#hello-table) / [Hello, Tab!](#hello-tab) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager) / [Login](#login)
201
+ - `list` (w/ optional `:multi` SWT style): featured in [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Contact Manager](#contact-manager)
202
+ - `menu`: featured in [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Table!](#hello-table)
203
+ - `menu_bar`: featured in [Hello, Menu Bar!](#hello-menu-bar)
204
+ - `menu_item`: featured in [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar)
205
+ - `message_box`: featured in [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Message Box!](#hello-message-box) / [Hello, Menu Bar!](#hello-menu-bar)
206
+ - `radio`: featured in [Hello, Radio!](#hello-radio) / [Hello, Group!](#hello-group)
207
+ - `radio_group`: featured in [Hello, Radio Group!](#hello-radio-group)
208
+ - `scrolled_composite`
209
+ - `shell`: featured in [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Tab!](#hello-tab) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login)
210
+ - `tab_folder`: featured in [Hello, Tab!](#hello-tab)
211
+ - `tab_item`: featured in [Hello, Tab!](#hello-tab)
212
+ - `table`: featured in [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Table!](#hello-table) / [Contact Manager](#contact-manager)
213
+ - `table_column`: featured in [Hello, Table!](#hello-table) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager)
214
+ - `text`: featured in [Hello, Computed!](#hello-computed) / [Login](#login) / [Contact Manager](#contact-manager)
215
+ - `time`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time)
216
+ - Glimmer::UI::CustomWidget: ability to define any keyword as a custom widget - featured in [Hello, Custom Widget!](#hello-custom-widget)
217
+ - Glimmer::UI::CustomShell: ability to define any keyword as a custom shell (aka custom window) that opens in a new browser window (tab) automatically unless there is no shell open in the current browser window (tab) - featured in [Hello, Custom Shell!](#hello-custom-shell)
117
218
 
118
219
  Layouts:
119
- - `grid_layout`
120
- - `row_layout`
121
- - `fill_layout`
122
- - `layout_data`
220
+ - `grid_layout`: featured in [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Contact Manager](#contact-manager) / [Login](#login) / [Tic Tac Toe](#tic-tac-toe)
221
+ - `row_layout`: featured in [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Contact Manager](#contact-manager)
222
+ - `fill_layout`: featured in [Hello, Custom Widget!](#hello-custom-widget)
223
+ - `layout_data`: featured in [Hello, Table!](#hello-table) / [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Tic Tac Toe](#tic-tac-toe) / [Contact Manager](#contact-manager)
123
224
 
124
- Graphics:
125
- - `color`
126
- - `font`
225
+ Graphics/Style:
226
+ - `color`: featured in [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Menu Bar!](#hello-menu-bar)
227
+ - `font`: featured in [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe)
228
+ - `Point` class used in setting location on widgets
229
+ - `swt` and `SWT` class to set SWT styles on widgets - featured in [Hello, Custom Shell!](#hello-custom-shell) / [Login](#login) / [Contact Manager](#contact-manager)
127
230
 
128
231
  Data-Binding/Observers:
129
- - `bind`
130
- - `observe`
131
- - `on_widget_selected`
232
+ - `bind`: featured in [Hello, Computed!](#hello-computed) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Login](#login) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe)
233
+ - `observe`: featured in [Hello, Table!](#hello-table) / [Tic Tac Toe](#tic-tac-toe)
234
+ - `on_widget_selected`: featured in [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Message Box!](#hello-message-box) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Contact Manager](#contact-manager) / [Login](#login) / [Tic Tac Toe](#tic-tac-toe)
132
235
  - `on_modify_text`
236
+ - `on_key_pressed` (and SWT alias `on_swt_keydown`) - featured in [Login](#login) / [Contact Manager](#contact-manager)
237
+ - `on_key_released` (and SWT alias `on_swt_keyup`)
238
+ - `on_mouse_down` (and SWT alias `on_swt_mousedown`)
239
+ - `on_mouse_up` (and SWT alias `on_swt_mouseup`) - featured in [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager)
133
240
 
134
241
  Event loop:
135
- - `display`
136
- - `async_exec`
242
+ - `display`: featured in [Tic Tac Toe](#tic-tac-toe)
243
+ - `async_exec`: featured in [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell)
244
+
245
+ ## Principles
246
+
247
+ - **Live purely in Rubyland via the Glimmer GUI DSL**, completely oblivious to web browser technologies.
248
+ - **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.
249
+ - **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.
250
+ - **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 without worrying about pixel-perfect aethetics. 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.
251
+ - **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.
137
252
 
138
253
  ## Background
139
254
 
@@ -155,7 +270,7 @@ Alternatively, web developers may directly use [Glimmer DSL for Opal](https://ru
155
270
 
156
271
  ## Setup
157
272
 
158
- (NOTE: if you run into issues, keep in mind this is a very early experimental and incomplete **alpha**. Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
273
+ (NOTE: Keep in mind this is a very early experimental and incomplete **alpha**. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-opal/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
159
274
 
160
275
  The [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem is a Rails Engine gem that includes assets.
161
276
 
@@ -179,7 +294,7 @@ Add the following to `Gemfile`:
179
294
  gem 'opal-rails', '~> 1.1.2'
180
295
  gem 'opal-async', '~> 1.2.0'
181
296
  gem 'opal-jquery', '~> 0.4.4'
182
- gem 'glimmer-dsl-opal', '~> 0.7.3'
297
+ gem 'glimmer-dsl-opal', '~> 0.9.1'
183
298
  gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
184
299
  gem 'glimmer-dsl-css', '~> 1.1.0', require: false
185
300
 
@@ -204,12 +319,6 @@ Modify `config/routes.rb`:
204
319
  root to: 'welcomes#index'
205
320
  ```
206
321
 
207
- Add the following line to the top of an empty `app/assets/javascripts/application.rb` (replacing `application.js`)
208
-
209
- ```ruby
210
- require 'glimmer-dsl-opal' # brings opal and other dependencies automatically
211
- ```
212
-
213
322
  Edit `app/views/layouts/application.html.erb` and add the following below other `stylesheet_link_tag` declarations:
214
323
 
215
324
  ```erb
@@ -218,41 +327,49 @@ Edit `app/views/layouts/application.html.erb` and add the following below other
218
327
 
219
328
  Clear the file `app/views/welcomes/index.html.erb` from any content.
220
329
 
221
- Open `app/assets/javascripts/application.rb`, add a `Document.ready?` block, and add inside it Glimmer GUI DSL code or a require statement for one of the samples below.
330
+ Add the following line to the top of an empty `app/assets/javascripts/application.rb` (replacing `application.js`), and add Glimmer GUI DSL code or a require statement for one of the samples below.
222
331
 
223
332
  ```ruby
224
- Document.ready? do
225
- # require-statement/code goes here.
226
- end
333
+ require 'glimmer-dsl-opal' # brings opal and other dependencies automatically
334
+
335
+ # require-statement/code goes here.
227
336
  ```
228
337
 
229
338
  Example to confirm setup is working:
230
339
 
231
340
  ```ruby
232
- Document.ready? do
233
- include Glimmer
234
-
235
- shell {
236
- fill_layout
237
- text 'Example to confirm setup is working'
238
- label {
239
- text "Welcome to Glimmer DSL for Opal!"
240
- foreground :red
241
- font height: 24
242
- }
243
- }.open
244
- end
341
+ require 'glimmer-dsl-opal'
342
+
343
+ include Glimmer
344
+
345
+ shell {
346
+ fill_layout
347
+ text 'Example to confirm setup is working'
348
+ label {
349
+ text "Welcome to Glimmer DSL for Opal!"
350
+ foreground :red
351
+ font height: 24
352
+ }
353
+ }.open
245
354
  ```
246
355
 
247
356
  ## Samples
248
357
 
249
358
  Follow the instructions below to try out [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) samples webified via [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal)
250
359
 
251
- Also, this external sample app contains all the samples mentioned below configured inside a Rails 5 [Opal](https://opalrb.com/) app with all the pre-requisites ready to go for convenience:
360
+ The [Hello samples](#hello-samples) demonstrate tiny building blocks (widgets) for building full fledged applications.
361
+
362
+ The [Elaborate samples](#elaborate-samples) demonstrate more advanced sample applications that assemble multiple building blocks.
252
363
 
253
- [https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails5-app](https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails5-app)
364
+ This external sample app contains all the samples mentioned below configured inside a Rails [Opal](https://opalrb.com/) app with all the pre-requisites ready to go for convenience:
254
365
 
255
- Some of the screenshots might be out of date with updates done to samples in both [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) and [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal).
366
+ [https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails-app](https://github.com/AndyObtiva/sample-glimmer-dsl-opal-rails-app)
367
+
368
+ You may visit a Heroku hosted version at:
369
+
370
+ https://sample-glimmer-dsl-opal-app.herokuapp.com/
371
+
372
+ Note: Some of the screenshots might be out of date with updates done to samples in both [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) and [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal).
256
373
 
257
374
  ### Hello Samples
258
375
 
@@ -559,44 +676,53 @@ require 'glimmer-dsl-opal/samples/hello/hello_list_multi_selection'
559
676
  Or add the Glimmer code directly if you prefer to play around with it:
560
677
 
561
678
  ```ruby
562
- class Person
563
- attr_accessor :provinces, :provinces_options
564
-
565
- def initialize
566
- self.provinces_options=[
567
- "",
568
- "Quebec",
569
- "Ontario",
570
- "Manitoba",
571
- "Saskatchewan",
572
- "Alberta",
573
- "British Columbia",
574
- "Nova Skotia",
575
- "Newfoundland"
576
- ]
577
- self.provinces = ["Quebec", "Manitoba", "Alberta"]
578
- end
579
-
580
- def reset_provinces
581
- self.provinces = ["Quebec", "Manitoba", "Alberta"]
582
- end
583
- end
584
-
585
679
  class HelloListMultiSelection
680
+ class Person
681
+ attr_accessor :provinces, :provinces_options
682
+
683
+ def initialize
684
+ self.provinces_options = [
685
+ '',
686
+ 'Alberta',
687
+ 'British Columbia',
688
+ 'Manitoba',
689
+ 'New Brunswick',
690
+ 'Newfoundland and Labrador',
691
+ 'Northwest Territories',
692
+ 'Nova Scotia',
693
+ 'Nunavut',
694
+ 'Ontario',
695
+ 'Prince Edward Island',
696
+ 'Quebec',
697
+ 'Saskatchewan',
698
+ 'Yukon'
699
+ ]
700
+ reset_provinces
701
+ end
702
+
703
+ def reset_provinces
704
+ self.provinces = ['Quebec', 'Manitoba', 'Alberta']
705
+ end
706
+ end
707
+
586
708
  include Glimmer
709
+
587
710
  def launch
588
711
  person = Person.new
712
+
589
713
  shell {
590
- composite {
591
- list(:multi) {
592
- selection bind(person, :provinces)
593
- }
594
- button {
595
- text "Reset"
596
- on_widget_selected do
597
- person.reset_provinces
598
- end
599
- }
714
+ grid_layout
715
+
716
+ text 'Hello, List Multi Selection!'
717
+
718
+ list(:multi) {
719
+ selection bind(person, :provinces)
720
+ }
721
+
722
+ button {
723
+ text 'Reset Selections To Default Values'
724
+
725
+ on_widget_selected { person.reset_provinces }
600
726
  }
601
727
  }.open
602
728
  end
@@ -809,6 +935,10 @@ You should see "Hello, Custom Widget!"
809
935
 
810
936
  #### Hello, Custom Shell!
811
937
 
938
+ This sample demonstrates Glimmer DSL for Opal's ability to open multiple shells (windows) as web browser tabs.
939
+
940
+ It automatically handles routing so that tab URLs are bookmarkable. Web developers do not have to do any routing configuration manually.
941
+
812
942
  Add the following require statement to `app/assets/javascripts/application.rb`
813
943
 
814
944
  ```ruby
@@ -1886,6 +2016,508 @@ Hello, Table! Game Booked
1886
2016
 
1887
2017
  ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-game-booked.png)
1888
2018
 
2019
+ #### Hello, Button!
2020
+
2021
+ Add the following require statement to `app/assets/javascripts/application.rb`
2022
+
2023
+ ```ruby
2024
+ require 'glimmer-dsl-opal/samples/hello/hello_button'
2025
+ ```
2026
+
2027
+ Or add the Glimmer code directly if you prefer to play around with it:
2028
+
2029
+ ```ruby
2030
+ class HelloButton
2031
+ include Glimmer
2032
+
2033
+ attr_accessor :count
2034
+
2035
+ def initialize
2036
+ @count = 0
2037
+ end
2038
+
2039
+ def launch
2040
+ shell {
2041
+ text 'Hello, Button!'
2042
+
2043
+ button {
2044
+ text bind(self, :count) {|value| "Click To Increment: #{value} "}
2045
+
2046
+ on_widget_selected {
2047
+ self.count += 1
2048
+ }
2049
+ }
2050
+ }.open
2051
+ end
2052
+ end
2053
+
2054
+ HelloButton.new.launch
2055
+ ```
2056
+
2057
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2058
+
2059
+ ![Glimmer DSL for SWT Hello Button](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-button.png)
2060
+ ![Glimmer DSL for SWT Hello Button](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-button-incremented.png)
2061
+
2062
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
2063
+
2064
+ Start the Rails server:
2065
+ ```
2066
+ rails s
2067
+ ```
2068
+
2069
+ Visit `http://localhost:3000`
2070
+
2071
+ You should see "Hello, Button!"
2072
+
2073
+ ![Glimmer DSL for Opal Hello Button](images/glimmer-dsl-opal-hello-button.png)
2074
+ ![Glimmer DSL for Opal Hello Button](images/glimmer-dsl-opal-hello-button-incremented.png)
2075
+
2076
+ #### Hello, Message Box!
2077
+
2078
+ Add the following require statement to `app/assets/javascripts/application.rb`
2079
+
2080
+ ```ruby
2081
+ require 'glimmer-dsl-opal/samples/hello/hello_message_box'
2082
+ ```
2083
+
2084
+ Or add the Glimmer code directly if you prefer to play around with it:
2085
+
2086
+ ```ruby
2087
+ include Glimmer
2088
+
2089
+ shell {
2090
+ text 'Hello, Message Box!'
2091
+
2092
+ button {
2093
+ text 'Please Click To Win a Surprise'
2094
+
2095
+ on_widget_selected {
2096
+ message_box {
2097
+ text 'Surprise'
2098
+ message "Congratulations!\n\nYou won $1,000,000!"
2099
+ }.open
2100
+ }
2101
+ }
2102
+ }.open
2103
+ ```
2104
+
2105
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2106
+
2107
+ ![Glimmer DSL for SWT Message Box](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-message-box.png)
2108
+ ![Glimmer DSL for SWT Message Box Dialog](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-message-box-dialog.png)
2109
+
2110
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
2111
+
2112
+ Start the Rails server:
2113
+ ```
2114
+ rails s
2115
+ ```
2116
+
2117
+ Visit `http://localhost:3000`
2118
+
2119
+ You should see "Hello, Message Box!"
2120
+
2121
+ ![Glimmer DSL for Opal Hello Message Box](images/glimmer-dsl-opal-hello-message-box.png)
2122
+ ![Glimmer DSL for Opal Hello Message Box Dialog](images/glimmer-dsl-opal-hello-message-box-dialog.png)
2123
+
2124
+ #### Hello, Pop Up Context Menu!
2125
+
2126
+ Add the following require statement to `app/assets/javascripts/application.rb`
2127
+
2128
+ ```ruby
2129
+ require 'glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu'
2130
+ ```
2131
+
2132
+ Or add the Glimmer code directly if you prefer to play around with it:
2133
+
2134
+ ```ruby
2135
+ include Glimmer
2136
+
2137
+ shell {
2138
+ grid_layout {
2139
+ margin_width 0
2140
+ margin_height 0
2141
+ }
2142
+
2143
+ text 'Hello, Pop Up Context Menu!'
2144
+
2145
+ label {
2146
+ text "Right-Click on the Text to\nPop Up a Context Menu"
2147
+ font height: 50
2148
+
2149
+ menu {
2150
+ menu {
2151
+ text '&History'
2152
+ menu {
2153
+ text '&Recent'
2154
+ menu_item {
2155
+ text 'File 1'
2156
+ on_widget_selected {
2157
+ message_box {
2158
+ text 'File 1'
2159
+ message 'File 1 Contents'
2160
+ }.open
2161
+ }
2162
+ }
2163
+ menu_item {
2164
+ text 'File 2'
2165
+ on_widget_selected {
2166
+ message_box {
2167
+ text 'File 2'
2168
+ message 'File 2 Contents'
2169
+ }.open
2170
+ }
2171
+ }
2172
+ }
2173
+ menu {
2174
+ text '&Archived'
2175
+ menu_item {
2176
+ text 'File 3'
2177
+ on_widget_selected {
2178
+ message_box {
2179
+ text 'File 3'
2180
+ message 'File 3 Contents'
2181
+ }.open
2182
+ }
2183
+ }
2184
+ menu_item {
2185
+ text 'File 4'
2186
+ on_widget_selected {
2187
+ message_box {
2188
+ text 'File 4'
2189
+ message 'File 4 Contents'
2190
+ }.open
2191
+ }
2192
+ }
2193
+ }
2194
+ }
2195
+ }
2196
+ }
2197
+ }.open
2198
+ ```
2199
+
2200
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2201
+
2202
+ ![Glimmer DSL for SWT Hello Pop Up Context Menu Popped Up](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-pop-up-context-menu.png)
2203
+ ![Glimmer DSL for SWT Hello Pop Up Context Menu](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-pop-up-context-menu-popped-up.png)
2204
+
2205
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
2206
+
2207
+ Start the Rails server:
2208
+ ```
2209
+ rails s
2210
+ ```
2211
+
2212
+ Visit `http://localhost:3000`
2213
+
2214
+ You should see "Hello, Pop Up Context Menu!"
2215
+
2216
+ ![Glimmer DSL for Opal Hello Pop Up Context Menu](images/glimmer-dsl-opal-hello-pop-up-context-menu.png)
2217
+ ![Glimmer DSL for Opal Hello Pop Up Context Menu Popped Up](images/glimmer-dsl-opal-hello-pop-up-context-menu-popped-up.png)
2218
+
2219
+ #### Hello, Menu Bar!
2220
+
2221
+ This sample demonstrates a menu bar similar to the File menu bar you see at the top of desktop applications.
2222
+
2223
+ In web applications, it is typically used to provide website information architecture by denoting things like Products, News, Careers, and About.
2224
+
2225
+ In web applications, it is also typically styled by CSS with margin/padding around every menu, distancing it from the top.
2226
+
2227
+ When auto-webifying a pre-existing desktop application, the menu bar can be hidden with CSS if not needed, or simply shown on hover only. Web designers could decide these things to their heart's content with pure CSS independently of the developers' code.
2228
+
2229
+ Add the following require statement to `app/assets/javascripts/application.rb`
2230
+
2231
+ ```ruby
2232
+ require 'glimmer-dsl-opal/samples/hello/hello_menu_bar'
2233
+ ```
2234
+
2235
+ Or add the Glimmer code directly if you prefer to play around with it:
2236
+
2237
+ ```ruby
2238
+ include Glimmer
2239
+
2240
+ COLORS = [:white, :red, :yellow, :green, :blue, :magenta, :gray, :black]
2241
+
2242
+ shell {
2243
+ grid_layout {
2244
+ margin_width 0
2245
+ margin_height 0
2246
+ }
2247
+
2248
+ text 'Hello, Menu Bar!'
2249
+
2250
+ @label = label(:center) {
2251
+ font height: 50
2252
+ text 'Check Out The Menu Bar Above!'
2253
+ }
2254
+
2255
+ menu_bar {
2256
+ menu {
2257
+ text '&File'
2258
+ menu_item {
2259
+ text '&New'
2260
+ accelerator :command, :N
2261
+
2262
+ on_widget_selected {
2263
+ message_box {
2264
+ text 'New'
2265
+ message 'New file created.'
2266
+ }.open
2267
+ }
2268
+ }
2269
+ menu_item {
2270
+ text '&Open...'
2271
+ accelerator :command, :O
2272
+
2273
+ on_widget_selected {
2274
+ message_box {
2275
+ text 'Open'
2276
+ message 'Opening File...'
2277
+ }.open
2278
+ }
2279
+ }
2280
+ menu {
2281
+ text 'Open &Recent'
2282
+ menu_item {
2283
+ text 'File 1'
2284
+ on_widget_selected {
2285
+ message_box {
2286
+ text 'File 1'
2287
+ message 'File 1 Contents'
2288
+ }.open
2289
+ }
2290
+ }
2291
+ menu_item {
2292
+ text 'File 2'
2293
+ on_widget_selected {
2294
+ message_box {
2295
+ text 'File 2'
2296
+ message 'File 2 Contents'
2297
+ }.open
2298
+ }
2299
+ }
2300
+ }
2301
+ menu_item(:separator)
2302
+ menu_item {
2303
+ text 'E&xit'
2304
+
2305
+ on_widget_selected {
2306
+ exit(0)
2307
+ }
2308
+ }
2309
+ }
2310
+ menu {
2311
+ text '&Edit'
2312
+ menu_item {
2313
+ text 'Cut'
2314
+ accelerator :command, :X
2315
+ }
2316
+ menu_item {
2317
+ text 'Copy'
2318
+ accelerator :command, :C
2319
+ }
2320
+ menu_item {
2321
+ text 'Paste'
2322
+ accelerator :command, :V
2323
+ }
2324
+ }
2325
+ menu {
2326
+ text '&Options'
2327
+
2328
+ menu_item(:radio) {
2329
+ text '&Enabled'
2330
+
2331
+ on_widget_selected {
2332
+ @select_one_menu.enabled = true
2333
+ @select_multiple_menu.enabled = true
2334
+ }
2335
+ }
2336
+ @select_one_menu = menu {
2337
+ text '&Select One'
2338
+ enabled false
2339
+
2340
+ menu_item(:radio) {
2341
+ text 'Option 1'
2342
+ }
2343
+ menu_item(:radio) {
2344
+ text 'Option 2'
2345
+ }
2346
+ menu_item(:radio) {
2347
+ text 'Option 3'
2348
+ }
2349
+ }
2350
+ @select_multiple_menu = menu {
2351
+ text '&Select Multiple'
2352
+ enabled false
2353
+
2354
+ menu_item(:check) {
2355
+ text 'Option 4'
2356
+ }
2357
+ menu_item(:check) {
2358
+ text 'Option 5'
2359
+ }
2360
+ menu_item(:check) {
2361
+ text 'Option 6'
2362
+ }
2363
+ }
2364
+ }
2365
+ menu {
2366
+ text '&Format'
2367
+ menu {
2368
+ text '&Background Color'
2369
+ COLORS.each { |color_style|
2370
+ menu_item(:radio) {
2371
+ text color_style.to_s.split('_').map(&:capitalize).join(' ')
2372
+
2373
+ on_widget_selected {
2374
+ @label.background = color_style
2375
+ }
2376
+ }
2377
+ }
2378
+ }
2379
+ menu {
2380
+ text 'Foreground &Color'
2381
+ COLORS.each { |color_style|
2382
+ menu_item(:radio) {
2383
+ text color_style.to_s.split('_').map(&:capitalize).join(' ')
2384
+
2385
+ on_widget_selected {
2386
+ @label.foreground = color_style
2387
+ }
2388
+ }
2389
+ }
2390
+ }
2391
+ }
2392
+ menu {
2393
+ text '&View'
2394
+ menu_item(:radio) {
2395
+ text 'Small'
2396
+
2397
+ on_widget_selected {
2398
+ @label.font = {height: 25}
2399
+ @label.parent.pack
2400
+ }
2401
+ }
2402
+ menu_item(:radio) {
2403
+ text 'Medium'
2404
+ selection true
2405
+
2406
+ on_widget_selected {
2407
+ @label.font = {height: 50}
2408
+ @label.parent.pack
2409
+ }
2410
+ }
2411
+ menu_item(:radio) {
2412
+ text 'Large'
2413
+
2414
+ on_widget_selected {
2415
+ @label.font = {height: 75}
2416
+ @label.parent.pack
2417
+ }
2418
+ }
2419
+ }
2420
+ menu {
2421
+ text '&Help'
2422
+ menu_item {
2423
+ text '&Manual'
2424
+ accelerator :command, :shift, :M
2425
+
2426
+ on_widget_selected {
2427
+ message_box {
2428
+ text 'Manual'
2429
+ message 'Manual Contents'
2430
+ }.open
2431
+ }
2432
+ }
2433
+ menu_item {
2434
+ text '&Tutorial'
2435
+ accelerator :command, :shift, :T
2436
+
2437
+ on_widget_selected {
2438
+ message_box {
2439
+ text 'Tutorial'
2440
+ message 'Tutorial Contents'
2441
+ }.open
2442
+ }
2443
+ }
2444
+ menu_item(:separator)
2445
+ menu_item {
2446
+ text '&Report an Issue...'
2447
+
2448
+ on_widget_selected {
2449
+ message_box {
2450
+ text 'Report an Issue'
2451
+ message 'Reporting an issue...'
2452
+ }.open
2453
+ }
2454
+ }
2455
+ }
2456
+ }
2457
+ }.open
2458
+ ```
2459
+
2460
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2461
+
2462
+ ![Hello Menu Bar](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar.png)
2463
+
2464
+ ![Hello Menu Bar File Menu](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-file-menu.png)
2465
+
2466
+ ![Hello Menu Bar Edit Menu](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-edit-menu.png)
2467
+
2468
+ ![Hello Menu Bar Options Menu Disabled](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-options-menu-disabled.png)
2469
+
2470
+ ![Hello Menu Bar Options Menu Select One](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-options-menu-select-one.png)
2471
+
2472
+ ![Hello Menu Bar Options Menu Select Multiple](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-options-menu-select-multiple.png)
2473
+
2474
+ ![Hello Menu Bar Format Menu Background Color](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-format-menu-background-color.png)
2475
+
2476
+ ![Hello Menu Bar Format Menu Foreground Color](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-format-menu-foreground-color.png)
2477
+
2478
+ ![Hello Menu Bar View Menu](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-view-menu.png)
2479
+
2480
+ ![Hello Menu Bar View Small](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-view-small.png)
2481
+
2482
+ ![Hello Menu Bar View Large](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-view-large.png)
2483
+
2484
+ ![Hello Menu Bar Help Menu](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-menu-bar-help-menu.png)
2485
+
2486
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
2487
+
2488
+ Start the Rails server:
2489
+ ```
2490
+ rails s
2491
+ ```
2492
+
2493
+ Visit `http://localhost:3000`
2494
+
2495
+ You should see "Hello, Menu Bar!"
2496
+
2497
+ ![Hello Menu Bar](images/glimmer-dsl-opal-hello-menu-bar.png)
2498
+
2499
+ ![Hello Menu Bar File Menu](images/glimmer-dsl-opal-hello-menu-bar-file-menu.png)
2500
+
2501
+ ![Hello Menu Bar Edit Menu](images/glimmer-dsl-opal-hello-menu-bar-edit-menu.png)
2502
+
2503
+ ![Hello Menu Bar Options Menu Disabled](images/glimmer-dsl-opal-hello-menu-bar-options-menu-disabled.png)
2504
+
2505
+ ![Hello Menu Bar Options Menu Select One](images/glimmer-dsl-opal-hello-menu-bar-options-menu-select-one.png)
2506
+
2507
+ ![Hello Menu Bar Options Menu Select Multiple](images/glimmer-dsl-opal-hello-menu-bar-options-menu-select-multiple.png)
2508
+
2509
+ ![Hello Menu Bar Format Menu Background Color](images/glimmer-dsl-opal-hello-menu-bar-format-menu-background-color.png)
2510
+
2511
+ ![Hello Menu Bar Format Menu Foreground Color](images/glimmer-dsl-opal-hello-menu-bar-format-menu-foreground-color.png)
2512
+
2513
+ ![Hello Menu Bar View Menu](images/glimmer-dsl-opal-hello-menu-bar-view-menu.png)
2514
+
2515
+ ![Hello Menu Bar View Small](images/glimmer-dsl-opal-hello-menu-bar-view-small.png)
2516
+
2517
+ ![Hello Menu Bar View Large](images/glimmer-dsl-opal-hello-menu-bar-view-large.png)
2518
+
2519
+ ![Hello Menu Bar Help Menu](images/glimmer-dsl-opal-hello-menu-bar-help-menu.png)
2520
+
1889
2521
  ### Elaborate Samples
1890
2522
 
1891
2523
  #### Login
@@ -1901,7 +2533,6 @@ Or add the Glimmer code directly if you prefer to play around with it:
1901
2533
  ```ruby
1902
2534
  require "observer"
1903
2535
 
1904
- #Presents login screen data
1905
2536
  class LoginPresenter
1906
2537
 
1907
2538
  attr_accessor :user_name
@@ -1917,10 +2548,13 @@ class LoginPresenter
1917
2548
  def status=(status)
1918
2549
  @status = status
1919
2550
 
1920
- #TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
1921
2551
  notify_observers("logged_in")
1922
2552
  notify_observers("logged_out")
1923
2553
  end
2554
+
2555
+ def valid?
2556
+ !@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
2557
+ end
1924
2558
 
1925
2559
  def logged_in
1926
2560
  self.status == "Logged In"
@@ -1931,6 +2565,7 @@ class LoginPresenter
1931
2565
  end
1932
2566
 
1933
2567
  def login
2568
+ return unless valid?
1934
2569
  self.status = "Logged In"
1935
2570
  end
1936
2571
 
@@ -1942,7 +2577,6 @@ class LoginPresenter
1942
2577
 
1943
2578
  end
1944
2579
 
1945
- #Login screen
1946
2580
  class Login
1947
2581
  include Glimmer
1948
2582
 
@@ -1954,15 +2588,21 @@ class Login
1954
2588
  grid_layout 2, false #two columns with differing widths
1955
2589
 
1956
2590
  label { text "Username:" } # goes in column 1
1957
- text { # goes in column 2
2591
+ @user_name_text = text { # goes in column 2
1958
2592
  text bind(presenter, :user_name)
1959
2593
  enabled bind(presenter, :logged_out)
2594
+ on_key_pressed { |event|
2595
+ @password_text.set_focus if event.keyCode == swt(:cr)
2596
+ }
1960
2597
  }
1961
2598
 
1962
2599
  label { text "Password:" }
1963
- text(:password, :border) {
2600
+ @password_text = text(:password, :border) {
1964
2601
  text bind(presenter, :password)
1965
2602
  enabled bind(presenter, :logged_out)
2603
+ on_key_pressed { |event|
2604
+ presenter.login if event.keyCode == swt(:cr)
2605
+ }
1966
2606
  }
1967
2607
 
1968
2608
  label { text "Status:" }
@@ -1972,12 +2612,21 @@ class Login
1972
2612
  text "Login"
1973
2613
  enabled bind(presenter, :logged_out)
1974
2614
  on_widget_selected { presenter.login }
2615
+ on_key_pressed { |event|
2616
+ presenter.login if event.keyCode == swt(:cr)
2617
+ }
1975
2618
  }
1976
2619
 
1977
2620
  button {
1978
2621
  text "Logout"
1979
2622
  enabled bind(presenter, :logged_in)
1980
2623
  on_widget_selected { presenter.logout }
2624
+ on_key_pressed { |event|
2625
+ if event.keyCode == swt(:cr)
2626
+ presenter.logout
2627
+ @user_name_text.set_focus
2628
+ end
2629
+ }
1981
2630
  }
1982
2631
  }
1983
2632
  }
@@ -2460,41 +3109,76 @@ class ContactManager
2460
3109
  shell {
2461
3110
  text "Contact Manager"
2462
3111
  composite {
2463
- composite {
2464
- grid_layout 2, false
2465
- label {text "First &Name: "}
3112
+ group {
3113
+ grid_layout(2, false) {
3114
+ margin_width 0
3115
+ margin_height 0
3116
+ }
3117
+ layout_data :fill, :center, true, false
3118
+ text 'Lookup Contacts'
3119
+ font height: 24
3120
+
3121
+ label {
3122
+ layout_data :right, :center, false, false
3123
+ text "First &Name: "
3124
+ font height: 16
3125
+ }
2466
3126
  text {
3127
+ layout_data :fill, :center, true, false
2467
3128
  text bind(@contact_manager_presenter, :first_name)
2468
3129
  on_key_pressed {|key_event|
2469
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
3130
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
2470
3131
  }
2471
3132
  }
2472
- label {text "&Last Name: "}
3133
+
3134
+ label {
3135
+ layout_data :right, :center, false, false
3136
+ text "&Last Name: "
3137
+ font height: 16
3138
+ }
2473
3139
  text {
3140
+ layout_data :fill, :center, true, false
2474
3141
  text bind(@contact_manager_presenter, :last_name)
2475
3142
  on_key_pressed {|key_event|
2476
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
3143
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
2477
3144
  }
2478
3145
  }
2479
- label {text "&Email: "}
3146
+
3147
+ label {
3148
+ layout_data :right, :center, false, false
3149
+ text "&Email: "
3150
+ font height: 16
3151
+ }
2480
3152
  text {
3153
+ layout_data :fill, :center, true, false
2481
3154
  text bind(@contact_manager_presenter, :email)
2482
3155
  on_key_pressed {|key_event|
2483
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
3156
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
2484
3157
  }
2485
3158
  }
3159
+
2486
3160
  composite {
2487
- grid_layout 2, false
3161
+ row_layout {
3162
+ margin_width 0
3163
+ margin_height 0
3164
+ }
3165
+ layout_data(:right, :center, false, false) {
3166
+ horizontal_span 2
3167
+ }
3168
+
2488
3169
  button {
2489
3170
  text "&Find"
2490
- on_widget_selected {
2491
- @contact_manager_presenter.find
3171
+ on_widget_selected { @contact_manager_presenter.find }
3172
+ on_key_pressed {|key_event|
3173
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
2492
3174
  }
2493
3175
  }
3176
+
2494
3177
  button {
2495
3178
  text "&List All"
2496
- on_widget_selected {
2497
- @contact_manager_presenter.list
3179
+ on_widget_selected { @contact_manager_presenter.list }
3180
+ on_key_pressed {|key_event|
3181
+ @contact_manager_presenter.list if key_event.keyCode == swt(:cr)
2498
3182
  }
2499
3183
  }
2500
3184
  }
@@ -2511,26 +3195,18 @@ class ContactManager
2511
3195
  table_column {
2512
3196
  text "First Name"
2513
3197
  width 80
2514
- on_widget_selected {
2515
- @contact_manager_presenter.toggle_sort(:first_name)
2516
- }
2517
3198
  }
2518
3199
  table_column {
2519
3200
  text "Last Name"
2520
3201
  width 80
2521
- on_widget_selected {
2522
- @contact_manager_presenter.toggle_sort(:last_name)
2523
- }
2524
3202
  }
2525
3203
  table_column {
2526
3204
  text "Email"
2527
3205
  width 200
2528
- on_widget_selected {
2529
- @contact_manager_presenter.toggle_sort(:email)
2530
- }
2531
3206
  }
2532
- items bind(@contact_manager_presenter, :results), column_properties(:first_name, :last_name, :email)
2533
- on_mouse_down { |event|
3207
+ items bind(@contact_manager_presenter, :results),
3208
+ column_properties(:first_name, :last_name, :email)
3209
+ on_mouse_up { |event|
2534
3210
  table_proxy.edit_table_item(event.table_item, event.column_index)
2535
3211
  }
2536
3212
  }
@@ -2540,7 +3216,6 @@ class ContactManager
2540
3216
  end
2541
3217
 
2542
3218
  ContactManager.new.launch
2543
-
2544
3219
  ```
2545
3220
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2546
3221
 
@@ -2637,13 +3312,27 @@ You should see "Apple Calculator Theme"
2637
3312
 
2638
3313
  [![Glimmer Calculator Opal Apple Calculator Theme](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal-apple.png)](http://glimmer-cs-calculator-server.herokuapp.com/welcomes/apple)
2639
3314
 
3315
+ ## Glimmer Supporting Libraries
3316
+
3317
+ Here is a list of notable 3rd party gems used by Glimmer DSL for Opal:
3318
+ - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML & HTML in pure Ruby.
3319
+ - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets) in pure Ruby.
3320
+ - [opal-async](https://github.com/AndyObtiva/opal-async): Non-blocking tasks and enumerators for Opal.
3321
+ - [to_collection](https://github.com/AndyObtiva/opal-async): Treat an array of objects and a singular object uniformly as a collection of objects.
3322
+
3323
+ ## Glimmer Process
3324
+
3325
+ [Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md) is the lightweight software development process used for building Glimmer libraries and Glimmer apps, which goes beyond Agile, rendering all Agile processes obsolete. [Glimmer Process](PROCESS.md) is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied.
3326
+
3327
+ Learn more by reading the [GPG](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md) (Glimmer Process Guidelines)
3328
+
2640
3329
  ## Help
2641
3330
 
2642
3331
  ### Issues
2643
3332
 
2644
- You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub](https://github.com/AndyObtiva/glimmer/issues).
3333
+ You may submit [issues](https://github.com/AndyObtiva/glimmer-dsl-opal/issues) on [GitHub](https://github.com/AndyObtiva/glimmer-dsl-opal/issues).
2645
3334
 
2646
- [Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
3335
+ [Click here to submit an issue.](https://github.com/AndyObtiva/glimmer-dsl-opal/issues)
2647
3336
 
2648
3337
  ### Chat
2649
3338