glimmer-dsl-swt 4.18.3.5 → 4.18.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -0
  3. data/LICENSE.txt +20 -20
  4. data/README.md +782 -716
  5. data/RUBY_VERSION +1 -1
  6. data/VERSION +1 -1
  7. data/bin/girb +31 -31
  8. data/bin/girb_runner.rb +34 -34
  9. data/bin/glimmer +26 -26
  10. data/glimmer-dsl-swt.gemspec +10 -7
  11. data/lib/ext/glimmer.rb +41 -41
  12. data/lib/ext/glimmer/config.rb +167 -167
  13. data/lib/ext/rouge/themes/glimmer.rb +29 -29
  14. data/lib/glimmer-dsl-swt.rb +44 -44
  15. data/lib/glimmer/Rakefile +26 -26
  16. data/lib/glimmer/data_binding/list_selection_binding.rb +72 -72
  17. data/lib/glimmer/data_binding/observable_widget.rb +38 -38
  18. data/lib/glimmer/data_binding/shine.rb +44 -44
  19. data/lib/glimmer/data_binding/table_items_binding.rb +89 -89
  20. data/lib/glimmer/data_binding/tree_items_binding.rb +108 -108
  21. data/lib/glimmer/data_binding/widget_binding.rb +73 -73
  22. data/lib/glimmer/dsl/swt/animation_expression.rb +43 -43
  23. data/lib/glimmer/dsl/swt/async_exec_expression.rb +35 -35
  24. data/lib/glimmer/dsl/swt/bind_expression.rb +58 -58
  25. data/lib/glimmer/dsl/swt/block_property_expression.rb +41 -41
  26. data/lib/glimmer/dsl/swt/checkbox_group_selection_data_binding_expression.rb +61 -61
  27. data/lib/glimmer/dsl/swt/color_expression.rb +40 -40
  28. data/lib/glimmer/dsl/swt/column_properties_expression.rb +45 -45
  29. data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +67 -67
  30. data/lib/glimmer/dsl/swt/cursor_expression.rb +44 -44
  31. data/lib/glimmer/dsl/swt/custom_widget_expression.rb +63 -63
  32. data/lib/glimmer/dsl/swt/data_binding_expression.rb +55 -55
  33. data/lib/glimmer/dsl/swt/dialog_expression.rb +48 -48
  34. data/lib/glimmer/dsl/swt/directory_dialog_expression.rb +48 -48
  35. data/lib/glimmer/dsl/swt/display_expression.rb +40 -40
  36. data/lib/glimmer/dsl/swt/dnd_expression.rb +46 -46
  37. data/lib/glimmer/dsl/swt/dsl.rb +63 -63
  38. data/lib/glimmer/dsl/swt/exec_expression.rb +55 -55
  39. data/lib/glimmer/dsl/swt/expand_item_expression.rb +60 -60
  40. data/lib/glimmer/dsl/swt/file_dialog_expression.rb +48 -48
  41. data/lib/glimmer/dsl/swt/font_expression.rb +49 -49
  42. data/lib/glimmer/dsl/swt/image_expression.rb +50 -50
  43. data/lib/glimmer/dsl/swt/layout_data_expression.rb +46 -46
  44. data/lib/glimmer/dsl/swt/layout_expression.rb +50 -50
  45. data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +65 -65
  46. data/lib/glimmer/dsl/swt/menu_bar_expression.rb +54 -54
  47. data/lib/glimmer/dsl/swt/menu_expression.rb +53 -53
  48. data/lib/glimmer/dsl/swt/message_box_expression.rb +54 -54
  49. data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -53
  50. data/lib/glimmer/dsl/swt/observe_expression.rb +53 -53
  51. data/lib/glimmer/dsl/swt/property_expression.rb +46 -46
  52. data/lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb +61 -61
  53. data/lib/glimmer/dsl/swt/rgb_expression.rb +33 -33
  54. data/lib/glimmer/dsl/swt/rgba_expression.rb +33 -33
  55. data/lib/glimmer/dsl/swt/shape_expression.rb +54 -54
  56. data/lib/glimmer/dsl/swt/shell_expression.rb +46 -46
  57. data/lib/glimmer/dsl/swt/swt_expression.rb +46 -46
  58. data/lib/glimmer/dsl/swt/sync_exec_expression.rb +36 -36
  59. data/lib/glimmer/dsl/swt/tab_item_expression.rb +54 -54
  60. data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +52 -52
  61. data/lib/glimmer/dsl/swt/timer_exec_expression.rb +35 -0
  62. data/lib/glimmer/dsl/swt/transform_expression.rb +55 -55
  63. data/lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb +52 -52
  64. data/lib/glimmer/dsl/swt/tree_properties_expression.rb +47 -47
  65. data/lib/glimmer/dsl/swt/widget_expression.rb +66 -66
  66. data/lib/glimmer/dsl/swt/widget_listener_expression.rb +53 -53
  67. data/lib/glimmer/rake_task.rb +220 -220
  68. data/lib/glimmer/rake_task/list.rb +97 -97
  69. data/lib/glimmer/rake_task/package.rb +139 -139
  70. data/lib/glimmer/rake_task/scaffold.rb +765 -765
  71. data/lib/glimmer/swt/color_proxy.rb +107 -107
  72. data/lib/glimmer/swt/cursor_proxy.rb +66 -66
  73. data/lib/glimmer/swt/custom/animation.rb +243 -243
  74. data/lib/glimmer/swt/custom/checkbox_group.rb +181 -181
  75. data/lib/glimmer/swt/custom/code_text.rb +150 -93
  76. data/lib/glimmer/swt/custom/drawable.rb +49 -52
  77. data/lib/glimmer/swt/custom/radio_group.rb +176 -176
  78. data/lib/glimmer/swt/custom/shape.rb +297 -253
  79. data/lib/glimmer/swt/date_time_proxy.rb +85 -85
  80. data/lib/glimmer/swt/directory_dialog_proxy.rb +65 -65
  81. data/lib/glimmer/swt/display_proxy.rb +166 -155
  82. data/lib/glimmer/swt/dnd_proxy.rb +51 -51
  83. data/lib/glimmer/swt/expand_item_proxy.rb +97 -97
  84. data/lib/glimmer/swt/file_dialog_proxy.rb +66 -66
  85. data/lib/glimmer/swt/font_proxy.rb +94 -94
  86. data/lib/glimmer/swt/image_proxy.rb +184 -173
  87. data/lib/glimmer/swt/layout_data_proxy.rb +105 -105
  88. data/lib/glimmer/swt/layout_proxy.rb +112 -109
  89. data/lib/glimmer/swt/menu_proxy.rb +126 -126
  90. data/lib/glimmer/swt/message_box_proxy.rb +89 -89
  91. data/lib/glimmer/swt/packages.rb +37 -37
  92. data/lib/glimmer/swt/properties.rb +49 -49
  93. data/lib/glimmer/swt/sash_form_proxy.rb +53 -53
  94. data/lib/glimmer/swt/scrolled_composite_proxy.rb +37 -37
  95. data/lib/glimmer/swt/shell_proxy.rb +4 -1
  96. data/lib/glimmer/swt/style_constantizable.rb +157 -157
  97. data/lib/glimmer/swt/styled_text_proxy.rb +38 -38
  98. data/lib/glimmer/swt/swt_proxy.rb +59 -59
  99. data/lib/glimmer/swt/tab_item_proxy.rb +91 -91
  100. data/lib/glimmer/swt/table_column_proxy.rb +57 -57
  101. data/lib/glimmer/swt/table_proxy.rb +2 -2
  102. data/lib/glimmer/swt/transform_proxy.rb +109 -109
  103. data/lib/glimmer/swt/tree_proxy.rb +145 -145
  104. data/lib/glimmer/swt/widget_listener_proxy.rb +64 -64
  105. data/lib/glimmer/swt/widget_proxy.rb +957 -949
  106. data/lib/glimmer/ui/custom_shell.rb +82 -82
  107. data/lib/glimmer/ui/custom_widget.rb +315 -315
  108. data/lib/glimmer/util/proc_tracker.rb +39 -39
  109. data/samples/elaborate/contact_manager.rb +142 -142
  110. data/samples/elaborate/contact_manager/contact.rb +32 -32
  111. data/samples/elaborate/contact_manager/contact_manager_presenter.rb +47 -47
  112. data/samples/elaborate/contact_manager/contact_repository.rb +169 -169
  113. data/samples/elaborate/login.rb +123 -123
  114. data/samples/elaborate/meta_sample.rb +14 -3
  115. data/samples/elaborate/tetris.rb +16 -6
  116. data/samples/elaborate/tetris/model/block.rb +48 -48
  117. data/samples/elaborate/tetris/model/game.rb +2 -3
  118. data/samples/elaborate/tetris/model/past_game.rb +39 -39
  119. data/samples/elaborate/tetris/view/block.rb +1 -1
  120. data/samples/elaborate/tetris/view/high_score_dialog.rb +0 -7
  121. data/samples/elaborate/tetris/view/playfield.rb +1 -1
  122. data/samples/elaborate/tetris/view/tetris_menu_bar.rb +13 -11
  123. data/samples/elaborate/tic_tac_toe.rb +76 -76
  124. data/samples/elaborate/tic_tac_toe/board.rb +145 -145
  125. data/samples/elaborate/tic_tac_toe/cell.rb +48 -48
  126. data/samples/elaborate/user_profile.rb +76 -76
  127. data/samples/hello/hello_browser.rb +31 -31
  128. data/samples/hello/hello_button.rb +46 -46
  129. data/samples/hello/hello_canvas.rb +64 -63
  130. data/samples/hello/hello_canvas_animation.rb +3 -3
  131. data/samples/hello/hello_canvas_transform.rb +1 -1
  132. data/samples/hello/hello_checkbox.rb +85 -85
  133. data/samples/hello/hello_checkbox_group.rb +71 -71
  134. data/samples/hello/hello_code_text.rb +104 -84
  135. data/samples/hello/hello_combo.rb +63 -63
  136. data/samples/hello/hello_computed.rb +96 -96
  137. data/samples/hello/hello_computed/contact.rb +42 -42
  138. data/samples/hello/hello_custom_shell.rb +155 -155
  139. data/samples/hello/hello_custom_widget.rb +86 -86
  140. data/samples/hello/hello_date_time.rb +63 -63
  141. data/samples/hello/hello_dialog.rb +78 -78
  142. data/samples/hello/hello_directory_dialog.rb +60 -60
  143. data/samples/hello/hello_drag_and_drop.rb +50 -50
  144. data/samples/hello/hello_expand_bar.rb +110 -110
  145. data/samples/hello/hello_file_dialog.rb +60 -60
  146. data/samples/hello/hello_group.rb +104 -104
  147. data/samples/hello/hello_link.rb +80 -80
  148. data/samples/hello/hello_list_multi_selection.rb +74 -74
  149. data/samples/hello/hello_list_single_selection.rb +59 -59
  150. data/samples/hello/hello_menu_bar.rb +241 -241
  151. data/samples/hello/hello_message_box.rb +37 -37
  152. data/samples/hello/hello_pop_up_context_menu.rb +84 -84
  153. data/samples/hello/hello_radio.rb +108 -108
  154. data/samples/hello/hello_radio_group.rb +87 -87
  155. data/samples/hello/hello_sash_form.rb +137 -137
  156. data/samples/hello/hello_spinner.rb +69 -69
  157. data/samples/hello/hello_styled_text.rb +138 -138
  158. data/samples/hello/hello_tab.rb +50 -50
  159. data/samples/hello/hello_table.rb +7 -4
  160. data/samples/hello/hello_table/baseball_park.png +0 -0
  161. data/samples/hello/hello_world.rb +29 -29
  162. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d3b93ed7e1bfaddf902080def3c370528f1f7d199f470e504cab6c60cc78934
4
- data.tar.gz: 5cd60a864c6b5ba100ba5293632e7eb85411da636ef87338d4f8ef090190b726
3
+ metadata.gz: e3ffed4c3ed197bc87d7305ccd7420ff3e69629fc76ea72155f1168ecafb811d
4
+ data.tar.gz: 534c6db1da7ce8da7fc2f5f3f989dfefc11ce614514eb3dd5729cea8544cf8ce
5
5
  SHA512:
6
- metadata.gz: a53eea373c988e58a5a5e021eeb8ba5e0be74254a53e7a50c7ab1bf716df6db9fc9ce0fed70169d88b3f6ffa54cdb39bd4ba9cdc415ae1f9feeb3980c84c9538
7
- data.tar.gz: 5965bb2ba7ebda9858228a06dddc74309032f435b13426c9fe4922d646f2698d77f045f4025d04085775e36fc1ea5e3529b77d309776579ef084009ebfbfca1a
6
+ metadata.gz: 4284f7f88a78ad3395a220f557818d55ef712f0f6a7b612a6f1e2dca927eaad188c7ea876ee480c78023f54bc99bec68551fc83086b959d56ad51050f3b66c22
7
+ data.tar.gz: 6de15b00ed4116774eb028c796f5d5b545e019bdafcd20bce1667a6b04618f2c7ac0fb88bf86d475f32ce6b05d725f15a622a3382d6f9ef34cdf90f533f53c63
data/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.4.4
4
+
5
+ - Ensure code_text line numbers text font matches that of the actual styled_text widget
6
+ - Use after_read data binding option to update top pixel in code text line numbers after updating text (ensuring top_pixel remains in sync after text changes)
7
+ - Remove unnecessary image copies in hello canvas transform and meta-sample samples
8
+
9
+ ### 4.18.4.3
10
+
11
+ - Fix flashing issue when using ShellProxy#pack_same_size on Windows
12
+ - Double buffer Hello, Canvas Animation! Sample to remove flickering
13
+ - Tetris - Added `:double_buffered` SWT style for Tetris Playfield and Block to avoid rendering flicker on Windows
14
+ - Tetris - Substituted command key with control on Windows/Linux to make Tetris menu shortcuts work (e.g. CTRL+P pauses)
15
+ - Tetris - Workaround for Windows issue with tetromino down invisibility upon holding down arrow key (now holding down does only one down)
16
+
17
+ ### 4.18.4.2
18
+
19
+ - Remove Tetris Clear button from High Score dialog (since it is available via menu and is rarely used)
20
+ - Make right control button rotate right with Tetris
21
+ - Avoid adding the widget listeners for read_only data-binding (instead of just relying on ModelBinding raising exceptions)
22
+ - Clean up the meta sample code_text style by removing root composite margins/spacing
23
+ - Made background for top label of Hello, Table! transparent for Windows
24
+ - Fix `glimmer samples` command and Meta-Sample on Windows
25
+ - Fix Tetris on Windows
26
+ - Fix Hello, Canvas on Windows
27
+ - Fix Hello, Canvas Transform when launched from `glimmer samples`
28
+ - Fix Table editing write_on_cancel option use on Windows
29
+ - Fix issue with adding content to the end of a styled text widget breaking line number scrolling
30
+ - Fix issue with code_text not showing line numbers for extra new lines at the end
31
+
32
+ ### 4.18.4.1
33
+
34
+ - Support data-binding of `code_text` with lines enabled.
35
+ - Upgrade the Glimmer Meta-Sample with code_text lines: {width: 2}
36
+ - With code_text lines enabled, support setting/data-binding properties on root composite via nesting `root { }` underneath
37
+ - With code_text lines enabled, support setting/data-binding properties on line numbers styled text widget via nesting `line_numbers { }` underneath
38
+ - Update the Hello, Code Text! sample to remove borders and line numbers background in the JavaScript example
39
+ - Fix issue with updating layout upon later reopening layout/layout data via `proxy.content {}` method
40
+
41
+ ### 4.18.4.0
42
+
43
+ - Extract line numbers part of text_editor widget from Gladiator into Glimmer code_text and make it an option (e.g. lines: true or lines: {width: 4})
44
+ - code_text support select all via CMD+A
45
+ - code_text support end of line via CTRL+E and beginning of line via CTRL+A
46
+ - Support automatic inferrence of Canvas Shape DSL gradient option (just like fill option)
47
+ - Support automatic inferrence of Canvas Shape DSL round option (just like fill option)
48
+ - Add a background image to Hello, Table! Sample + font/color changes
49
+ - Make Canvas patterns auto-reused and auto-disposed when canvas is disposed
50
+ - Make Canvas images auto-dispose themselves when canvas is disposed
51
+ - Update Hello, Code Text!
52
+ - Change Glimmer Tetris Sample up arrow default to rotate left
53
+ - Fix issue with "undefined method lex for nil:NilClass" in `code_text`
54
+
3
55
  ### 4.18.3.5
4
56
 
5
57
  - Add `write_on_cancel: true` option for TableProxy#edit_table_item to make cancel behave just like save for special cases where you cannot cancel except the edit mode itself
data/LICENSE.txt CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2007-2021 Andy Maleh
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2007-2021 Andy Maleh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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 SWT 4.18.3.5
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 SWT 4.18.4.4
2
2
  ## JRuby Desktop Development GUI Framework
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
4
4
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
@@ -28,9 +28,10 @@ Glimmer DSL gems:
28
28
 
29
29
  ## Examples
30
30
 
31
- ### Hello, World!
31
+ ### Hello, World! Sample
32
+
33
+ Glimmer GUI DSL code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
32
34
 
33
- Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
34
35
  ```ruby
35
36
  include Glimmer
36
37
 
@@ -52,169 +53,164 @@ Glimmer app:
52
53
 
53
54
  ![Hello World](images/glimmer-hello-world.png)
54
55
 
55
- ### Tic Tac Toe
56
+ Learn more about [Hello, World!](#hello-world).
57
+
58
+ ### Hello, Table! Sample
56
59
 
57
- Glimmer code (from [samples/elaborate/tic_tac_toe.rb](samples/elaborate/tic_tac_toe.rb)):
60
+ Glimmer GUI DSL code (from [samples/hello/hello_table.rb](samples/hello/hello_table.rb)):
58
61
 
59
62
  ```ruby
60
- # ...
61
- @shell = shell {
62
- text "Tic-Tac-Toe"
63
- minimum_size 150, 178
64
- composite {
65
- grid_layout 3, true
66
- (1..3).each { |row|
67
- (1..3).each { |column|
68
- button {
69
- layout_data :fill, :fill, true, true
70
- text bind(@tic_tac_toe_board[row, column], :sign)
71
- enabled bind(@tic_tac_toe_board[row, column], :empty)
72
- font style: :bold, height: 20
73
- on_widget_selected {
74
- @tic_tac_toe_board.mark(row, column)
75
- }
76
- }
77
- }
63
+ # ... model code precedes
64
+ shell {
65
+ grid_layout
66
+
67
+ text 'Hello, Table!'
68
+ background_image File.expand_path('hello_table/baseball_park.png', __dir__)
69
+
70
+ label {
71
+ layout_data :center, :center, true, false
72
+
73
+ text 'BASEBALL PLAYOFF SCHEDULE'
74
+ background :transparent
75
+ foreground rgb(94, 107, 103)
76
+ font name: 'Optima', height: 38, style: :bold
77
+ }
78
+
79
+ combo(:read_only) {
80
+ layout_data :center, :center, true, false
81
+ selection bind(BaseballGame, :playoff_type)
82
+ font height: 14
83
+ }
84
+
85
+ table(:editable) { |table_proxy|
86
+ layout_data :fill, :fill, true, true
87
+
88
+ table_column {
89
+ text 'Game Date'
90
+ width 150
91
+ sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
92
+ editor :date_drop_down, property: :date_time
93
+ }
94
+ table_column {
95
+ text 'Game Time'
96
+ width 150
97
+ sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
98
+ editor :time, property: :date_time
99
+ }
100
+ table_column {
101
+ text 'Ballpark'
102
+ width 180
103
+ editor :none
104
+ }
105
+ table_column {
106
+ text 'Home Team'
107
+ width 150
108
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
109
+ }
110
+ table_column {
111
+ text 'Away Team'
112
+ width 150
113
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
114
+ }
115
+ table_column {
116
+ text 'Promotion'
117
+ width 150
118
+ # default text editor is used here
119
+ }
120
+
121
+ # Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
122
+ items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
123
+
124
+ # Data-bind table selection
125
+ selection bind(BaseballGame, :selected_game)
126
+
127
+ # Default initial sort property
128
+ sort_property :date
129
+
130
+ # Sort by these additional properties after handling sort by the column the user clicked
131
+ additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
132
+
133
+ menu {
134
+ menu_item {
135
+ text 'Book'
136
+
137
+ on_widget_selected {
138
+ book_selected_game
78
139
  }
79
140
  }
80
141
  }
142
+ }
143
+
144
+ button {
145
+ text 'Book Selected Game'
146
+ layout_data :center, :center, true, false
147
+ font height: 14
148
+ enabled bind(BaseballGame, :selected_game)
149
+
150
+ on_widget_selected {
151
+ book_selected_game
152
+ }
153
+ }
154
+ }.open
81
155
  # ...
82
156
  ```
83
157
 
84
158
  Run via `glimmer samples` or directly:
85
159
 
86
160
  ```
87
- glimmer samples/elaborate/tic_tac_toe.rb
161
+ glimmer samples/hello/hello_table.rb
88
162
  ```
89
163
 
90
- Glimmer app:
164
+ Glimmer App:
91
165
 
92
- ![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
166
+ ![Hello Table](images/glimmer-hello-table.png)
167
+
168
+ Learn more about [Hello, Table!](#hello-table).
93
169
 
94
- ### Contact Manager
170
+ ### Tetris
95
171
 
96
- Glimmer code (from [samples/elaborate/contact_manager.rb](samples/elaborate/contact_manager.rb)):
172
+ Glimmer GUI DSL code (from [samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)):
97
173
 
98
174
  ```ruby
99
- # ...
100
- shell {
101
- text "Contact Manager"
102
- composite {
103
- group {
104
- grid_layout(2, false) {
105
- margin_width 0
106
- margin_height 0
107
- }
108
- layout_data :fill, :center, true, false
109
- text 'Lookup Contacts'
110
- font height: 24
111
-
112
- label {
113
- layout_data :right, :center, false, false
114
- text "First &Name: "
115
- font height: 16
116
- }
117
- text {
118
- layout_data :fill, :center, true, false
119
- text bind(@contact_manager_presenter, :first_name)
120
- on_key_pressed {|key_event|
121
- @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
122
- }
123
- }
124
-
125
- label {
126
- layout_data :right, :center, false, false
127
- text "&Last Name: "
128
- font height: 16
129
- }
130
- text {
131
- layout_data :fill, :center, true, false
132
- text bind(@contact_manager_presenter, :last_name)
133
- on_key_pressed {|key_event|
134
- @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
135
- }
136
- }
137
-
138
- label {
139
- layout_data :right, :center, false, false
140
- text "&Email: "
141
- font height: 16
142
- }
143
- text {
144
- layout_data :fill, :center, true, false
145
- text bind(@contact_manager_presenter, :email)
146
- on_key_pressed {|key_event|
147
- @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
148
- }
149
- }
150
-
151
- composite {
152
- row_layout {
153
- margin_width 0
154
- margin_height 0
155
- }
156
- layout_data(:right, :center, false, false) {
157
- horizontal_span 2
158
- }
159
-
160
- button {
161
- text "&Find"
162
- on_widget_selected { @contact_manager_presenter.find }
163
- on_key_pressed {|key_event|
164
- @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
165
- }
166
- }
167
-
168
- button {
169
- text "&List All"
170
- on_widget_selected { @contact_manager_presenter.list }
171
- on_key_pressed {|key_event|
172
- @contact_manager_presenter.list if key_event.keyCode == swt(:cr)
173
- }
174
- }
175
- }
176
- }
175
+ # ... more code resides in other files (navigate sample files to learn more)
176
+ shell(:no_resize) {
177
+ grid_layout {
178
+ num_columns 2
179
+ make_columns_equal_width false
180
+ margin_width 0
181
+ margin_height 0
182
+ horizontal_spacing 0
183
+ }
184
+
185
+ text 'Glimmer Tetris'
186
+ minimum_size 475, 500
187
+ image tetris_icon
177
188
 
178
- table(:multi) { |table_proxy|
179
- layout_data {
180
- horizontal_alignment :fill
181
- vertical_alignment :fill
182
- grab_excess_horizontal_space true
183
- grab_excess_vertical_space true
184
- height_hint 200
185
- }
186
- table_column {
187
- text "First Name"
188
- width 80
189
- }
190
- table_column {
191
- text "Last Name"
192
- width 80
193
- }
194
- table_column {
195
- text "Email"
196
- width 200
197
- }
198
- items bind(@contact_manager_presenter, :results),
199
- column_properties(:first_name, :last_name, :email)
200
- on_mouse_up { |event|
201
- table_proxy.edit_table_item(event.table_item, event.column_index)
202
- }
203
- }
204
- }
205
- }.open
189
+ tetris_menu_bar(game: game)
190
+
191
+ playfield(game_playfield: game.playfield, playfield_width: playfield_width, playfield_height: playfield_height, block_size: BLOCK_SIZE)
192
+
193
+ score_lane(game: game, block_size: BLOCK_SIZE) {
194
+ layout_data(:fill, :fill, true, true)
195
+ }
196
+
197
+ on_widget_disposed {
198
+ deregister_observers
199
+ }
200
+ }
206
201
  # ...
207
202
  ```
208
203
 
209
204
  Run via `glimmer samples` or directly:
210
205
 
211
206
  ```
212
- glimmer samples/elaborate/contact_manager.rb
207
+ glimmer samples/elaborate/tetris.rb
213
208
  ```
214
209
 
215
- Glimmer App:
210
+ Glimmer app:
211
+
212
+ ![Tetris](images/glimmer-tetris.png)
216
213
 
217
- ![Contact Manager](images/glimmer-contact-manager.png)
218
214
 
219
215
  ### Desktop Apps Built with Glimmer DSL for SWT
220
216
 
@@ -235,9 +231,9 @@ If you see anything that needs to be improved, please do not hesitate to contact
235
231
 
236
232
  - [Glimmer (JRuby Desktop Development GUI Framework)](#jruby-desktop-development-gui-framework)
237
233
  - [Examples](#examples)
238
- - [Hello, World!](#hello-world)
239
- - [Tic Tac Toe](#tic-tac-toe)
240
- - [Contact Manager](#contact-manager)
234
+ - [Hello, World! Sample](#hello-world-sample)
235
+ - [Hello, Table! Sample](#hello-table-sample)
236
+ - [Tetris](#tetris)
241
237
  - [Desktop Apps Built with Glimmer DSL for SWT](#desktop-apps-built-with-glimmer-dsl-for-swt)
242
238
  - [Table of contents](#table-of-contents)
243
239
  - [Background](#background)
@@ -276,6 +272,8 @@ If you see anything that needs to be improved, please do not hesitate to contact
276
272
  - [Multi-Threading](#multi-threading)
277
273
  - [Menus](#menus)
278
274
  - [ScrolledComposite](#scrolledcomposite)
275
+ - [Sash Form Widget](#sash-form-widget)
276
+ - [Browser Widget](#browser-widget)
279
277
  - [Widget Styles](#widget-styles)
280
278
  - [Explicit SWT Style Bit](#explicit-swt-style-bit)
281
279
  - [Negative SWT Style Bits](#negative-swt-style-bits)
@@ -307,7 +305,12 @@ If you see anything that needs to be improved, please do not hesitate to contact
307
305
  - [Lifecycle Hooks Example](#lifecycle-hooks-example)
308
306
  - [Custom Widget API](#custom-widget-api)
309
307
  - [Content/Options Example](#contentoptions-example)
310
- - [Gotcha](#gotcha)
308
+ - [Custom Widget Gotchas](#custom-widget-gotchas)
309
+ - [Built-In Custom Widgets](#built-in-custom-widgets)
310
+ - [Checkbox Group Custom Widget](#checkbox-group-custom-widget)
311
+ - [Radio Group Custom Widget](#radio-group-custom-widget)
312
+ - [Code Text Custom Widget](#code-text-custom-widget)
313
+ - [Video Custom Widget](#video-custom-widget)
311
314
  - [Custom Widget Final Notes](#custom-widget-final-notes)
312
315
  - [Custom Shells](#custom-shells)
313
316
  - [Drag and Drop](#drag-and-drop)
@@ -315,12 +318,6 @@ If you see anything that needs to be improved, please do not hesitate to contact
315
318
  - [Multi-DSL Support](#multi-dsl-support)
316
319
  - [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
317
320
  - [App Name and Version](#app-name-and-version)
318
- - [Checkbox Group Widget](#checkbox-group-widget)
319
- - [Radio Group Widget](#radio-group-widget)
320
- - [Code Text Widget](#code-text-widget)
321
- - [Video Widget](#video-widget)
322
- - [Sash Form Widget](#sash-form-widget)
323
- - [Browser Widget](#browser-widget)
324
321
  - [Glimmer Configuration](#glimmer-configuration)
325
322
  - [logger](#logger)
326
323
  - [logging_devices](#loggingdevices)
@@ -332,7 +329,6 @@ If you see anything that needs to be improved, please do not hesitate to contact
332
329
  - [excluded_keyword_checkers](#excludedkeywordcheckers)
333
330
  - [log_excluded_keywords](#logexcludedkeywords)
334
331
  - [Glimmer Style Guide](#glimmer-style-guide)
335
- - [SWT Reference](#swt-reference)
336
332
  - [Samples](#samples)
337
333
  - [Hello Samples](#hello-samples)
338
334
  - [Hello, World! Sample](#hello-world-sample)
@@ -364,15 +360,16 @@ If you see anything that needs to be improved, please do not hesitate to contact
364
360
  - [Hello, Button!](#hello-button)
365
361
  - [Hello, Link!](#hello-link)
366
362
  - [Hello, Dialog!](#hello-dialog)
363
+ - [Hello, Code Text!](#hello-code-text)
367
364
  - [Hello, Canvas!](#hello-canvas)
368
365
  - [Hello, Canvas Animation!](#hello-canvas-animation)
369
366
  - [Hello, Canvas Transform!](#hello-canvas-transform)
370
367
  - [Elaborate Samples](#elaborate-samples)
371
368
  - [User Profile](#user-profile)
372
369
  - [Login](#login)
373
- - [Tic Tac Toe Sample](#tic-tac-toe-sample)
374
- - [Contact Manager Sample](#contact-manager-sample)
375
- - [Tetris](#tetris)
370
+ - [Tic Tac Toe Sample](#tic-tac-toe)
371
+ - [Contact Manager Sample](#contact-manager)
372
+ - [Glimmer Tetris](#glimmer-tetris)
376
373
  - [External Samples](#external-samples)
377
374
  - [Glimmer Calculator](#glimmer-calculator)
378
375
  - [Gladiator](#gladiator)
@@ -394,6 +391,7 @@ If you see anything that needs to be improved, please do not hesitate to contact
394
391
  - [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
395
392
  - [Glimmer Process](#glimmer-process)
396
393
  - [Resources](#resources)
394
+ - [SWT Reference](#swt-reference)
397
395
  - [Help](#help)
398
396
  - [Issues](#issues)
399
397
  - [Chat](#chat)
@@ -459,9 +457,10 @@ https://www.eclipse.org/swt/faq.php
459
457
 
460
458
  ## Pre-requisites
461
459
 
462
- - JDK 8u241 (1.8.0_241) (find at https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html)
460
+ - JDK 8u241 (1.8.0_241) (find at https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html / On Windows, ensure PATH includes Java bin directory like C:\Program Files\Java\jdk1.8.0_241\bin for javapackager to work during packaging Glimmer applications)
463
461
  - JRuby 9.2.14.0 (supporting Ruby 2.5.x syntax) (get via [RVM](http://rvm.io) on Mac and Linux or find at [https://www.jruby.org/download](https://www.jruby.org/download) for Windows)
464
462
  - SWT 4.18 (already included in the [glimmer-dsl-swt](https://rubygems.org/gems/glimmer-dsl-swt) gem)
463
+ - Git (comes with Mac and Linux. Install on Windows: https://git-scm.com/download/win )
465
464
 
466
465
  To obtain JRuby through [RVM](http://rvm.io), you may run:
467
466
 
@@ -481,7 +480,7 @@ If you intend to build a Glimmer app from scratch with [scaffolding](#scaffoldin
481
480
 
482
481
  Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](#scaffolding).
483
482
 
484
- Note: if you encounter any [issues](https://github.com/AndyObtiva/glimmer-dsl-swt/issues), please [report](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) and then install a previous version instead from the list of [Glimmer Releases](https://rubygems.org/gems/glimmer-dsl-swt/versions).
483
+ **Note:** if you encounter any [issues](https://github.com/AndyObtiva/glimmer-dsl-swt/issues), please [report](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) and then install a previous version instead from the list of [Glimmer Releases](https://rubygems.org/gems/glimmer-dsl-swt/versions) (keep looking back till you find one that works). Do not be disheartened as nearly everything is only a few days of work away. That said, keep in mind that this project is free and open source, meaning provided as is, so do not expect anything, but if you help with reporting and contributing, you could speed things up or even become part of the project.
485
484
 
486
485
  ### Option 1: Direct Install
487
486
  (Use for [Scaffolding](#scaffolding))
@@ -493,9 +492,7 @@ jgem install glimmer-dsl-swt
493
492
 
494
493
  Or this command if you want a specific version:
495
494
  ```
496
- jgem install glimmer-dsl-swt -v 4.18.3.5
497
-
498
-
495
+ jgem install glimmer-dsl-swt -v 4.18.4.4
499
496
  ```
500
497
 
501
498
  `jgem` is JRuby's version of `gem` command.
@@ -513,8 +510,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
513
510
 
514
511
  Add the following to `Gemfile`:
515
512
  ```
516
- gem 'glimmer-dsl-swt', '~> 4.18.3.5
517
- '
513
+ gem 'glimmer-dsl-swt', '~> 4.18.4.4'
518
514
  ```
519
515
 
520
516
  And, then run:
@@ -572,9 +568,7 @@ bin/glimmer samples
572
568
  Below are the full usage instructions that come up when running `glimmer` without args.
573
569
 
574
570
  ```
575
- Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.3.5
576
-
577
-
571
+ Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.4.4
578
572
 
579
573
  Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
580
574
 
@@ -596,8 +590,8 @@ Tasks are run via rake. Some tasks take arguments in square brackets.
596
590
 
597
591
  Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
598
592
 
599
- Select a Glimmer task to run: (Press ↑/↓ arrow to move, Enter to select and letters to filter)
600
- glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
593
+ Select a Glimmer task to run: (Press ↑/↓ arrow to move, Enter to select and letters to filter)
594
+ ‣ glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
601
595
  glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
602
596
  glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
603
597
  glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
@@ -1053,9 +1047,7 @@ Output:
1053
1047
 
1054
1048
  Css glimmer-dsl-css 1.1.0 AndyMaleh Glimmer DSL for CSS
1055
1049
  Opal glimmer-dsl-opal 0.10.2 AndyMaleh Glimmer DSL for Opal
1056
- Swt glimmer-dsl-swt 4.18.3.5
1057
-
1058
- AndyMaleh Glimmer DSL for SWT
1050
+ Swt glimmer-dsl-swt 4.18.4.4 AndyMaleh Glimmer DSL for SWT
1059
1051
  Tk glimmer-dsl-tk 0.0.6 AndyMaleh Glimmer DSL for Tk
1060
1052
  Xml glimmer-dsl-xml 1.1.0 AndyMaleh Glimmer DSL for XML
1061
1053
  ```
@@ -1140,6 +1132,8 @@ If you need a more GUI interactive option to experiement with Glimmer GUI DSL Sy
1140
1132
 
1141
1133
  ## Glimmer GUI DSL Syntax
1142
1134
 
1135
+ This guide should help you get started with Glimmer DSL for SWT. For more advanced SWT details, please refer to the [SWT Reference](#swt-reference).
1136
+
1143
1137
  Glimmer's core is a GUI DSL with a lightweight visual syntax that makes it easy to visualize the nesting of widgets in the GUI hierarchy tree.
1144
1138
 
1145
1139
  It is available through mixing in the `Glimmer` module, which makes [Glimmer GUI DSL Keywords](#glimmer-gui-dsl-keywords) available to both the instance scope and class scope:
@@ -1895,6 +1889,79 @@ Glimmer provides smart defaults for the `scrolled_composite` widget by:
1895
1889
  - Automatically setting the :h_scroll and :v_scroll SWT styles (can be set manually if only one of either :h_scroll or :v_scroll is desired )
1896
1890
  - Automatically setting the expand horizontal and expand vertical SWT properties to `true`
1897
1891
 
1892
+ #### Sash Form Widget
1893
+
1894
+ `sash_form` is an SWT built-in custom widget that provides a resizable sash that splits a window area into two or more panes.
1895
+
1896
+ It can be customized with the `weights` attribute by setting initial weights to size the panes at first display.
1897
+
1898
+ One noteworthy thing about the Glimmer implementation is that, unlike behavior in SWT, it allows declaring `weights` before the content of the `sash_form`, thus providing more natural and convenient syntax (Glimmer automatically takes care of sending that declaration to SWT at the end of declaring `sash_form` content as per the SWT requirements)
1899
+
1900
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1901
+
1902
+ ```ruby
1903
+ shell {
1904
+ text 'Sash Form Example'
1905
+ sash_form {
1906
+ label {
1907
+ text '(resize >>)'
1908
+ background :dark_green
1909
+ foreground :white
1910
+ font height: 20
1911
+ }
1912
+ label {
1913
+ text '(<< resize)'
1914
+ background :red
1915
+ foreground :white
1916
+ font height: 20
1917
+ }
1918
+ weights 1, 2
1919
+ }
1920
+ }.open
1921
+ ```
1922
+
1923
+ You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash-form)
1924
+
1925
+ ![Hello Sash Form](images/glimmer-hello-sash-form.png)
1926
+
1927
+ #### Browser Widget
1928
+
1929
+ ![Hello Browser](images/glimmer-hello-browser.png)
1930
+
1931
+ Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
1932
+
1933
+ Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1934
+
1935
+ ```ruby
1936
+ shell {
1937
+ minimum_size 1024, 860
1938
+ browser {
1939
+ url 'http://brightonresort.com/about'
1940
+ }
1941
+ }.open
1942
+ ```
1943
+
1944
+ Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command) provided you install and require [glimmer-dsl-xml gem](https://github.com/AndyObtiva/glimmer-dsl-xml)):
1945
+
1946
+ ```ruby
1947
+ shell {
1948
+ minimum_size 130, 130
1949
+ @browser = browser {
1950
+ text html {
1951
+ head {
1952
+ meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
1953
+ }
1954
+ body {
1955
+ h1 { "Hello, World!" }
1956
+ }
1957
+ }
1958
+ on_completed { # on load of the page execute this JavaScript
1959
+ @browser.swt_widget.execute("alert('Hello, World!');")
1960
+ }
1961
+ }
1962
+ }.open
1963
+ ```
1964
+
1898
1965
  ### Widget Styles
1899
1966
 
1900
1967
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -2339,25 +2406,28 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
2339
2406
 
2340
2407
  ### Canvas Shape DSL
2341
2408
 
2409
+ **(ALPHA FEATURE)**
2410
+
2342
2411
  Glimmer supports drawing graphics directly on a `canvas` widget via SWT (or any widget for that matter though `canvas` is recommended for drawing).
2343
2412
 
2344
2413
  This is accomplished via the Shape DSL a sub-DSL of the Glimmer GUI DSL, which makes it possible to draw graphics declaratively with very understandable and maintainable syntax.
2345
2414
 
2346
2415
  Shape keywords and their args (including defaults) are listed below (they basically match method names and arguments on [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) minus the `draw` or `fill` prefix in downcase):
2347
- - `arc(x, y, width, height, startAngle, arcAngle, fill: false)` arc is part of a circle within an oval area, denoted by start angle (degrees) and end angle (degrees)
2348
- - `focus(x, y, width, height)` this is just like rectangle but its foreground color is always that of the OS widget focus color (useful when capturing user interaction via a shape)
2416
+ - `arc(x, y, width, height, startAngle, arcAngle, fill: false)` arc is part of a circle within an oval area, denoted by start angle (degrees) and end angle (degrees)
2417
+ - `focus(x, y, width, height)` this is just like rectangle but its foreground color is always that of the OS widget focus color (useful when capturing user interaction via a shape)
2349
2418
  - `image(image, x, y)` [image](#image)
2350
2419
  - `line(x1, y1, x2, y2)` line
2351
2420
  - `oval(x, y, width, height, fill: false)` oval if width does not match heigh and circle if width matches height. Can be optionally filled.
2352
- - `point(x, y)` point
2421
+ - `point(x, y)` point
2353
2422
  - `polygon(pointArray, fill: false)` polygon consisting of points, which close automatically to form a shape that can be optionally filled (when points only form a line, it does not show up as filled)
2354
2423
  - `polyline(pointArray)` polyline is just like a polygon, but it does not close up to form a shape, remaining open (unless the points close themselves by having the last point or an intermediate point match the first)
2355
2424
  - `rectangle(x, y, width, height, fill: false)` standard rectangle, which can be optionally filled
2356
2425
  - `rectangle(x, y, width, height, arcWidth = 60, arcHeight = 60, fill: false, round: true)` round rectangle, which can be optionally filled, and takes optional extra round angle arguments
2357
- - `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
2426
+ - `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
2358
2427
  - `text(string, x, y, flags = nil)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be :draw_delimiter (i.e. new lines), :draw_tab, :draw_mnemonic, and :draw_transparent as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
2359
2428
 
2360
2429
  Shape keywords that can be filled with color can take an keyword argument `fill: true`. Defaults to false when not specified unless background is set with no foreground (or foreground is set with no background), in which case a smart default is applied.
2430
+ Smart defaults can be applied to automatically infer `gradient: true` (rectangle with both foreground and background) and `round: true` (rectangle with more than 4 args, the extra args are numeric) as well.
2361
2431
 
2362
2432
  Optionally, a shape keyword takes a block that can set any attributes from [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) (methods starting with `set`), which enable setting the `background` for filling and `foreground` for drawing.
2363
2433
 
@@ -2367,7 +2437,7 @@ Here is a list of supported attributes nestable within a block under shapes:
2367
2437
  - `antialias` enables antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
2368
2438
  - `background` sets fill color for fillable shapes (standard color symbol (e.g. `:red`), `rgb(red_integer, green_integer, blue_integer)` color, or Color/ColorProxy object directly)
2369
2439
  - `background_pattern` sets fill gradient/image pattern for fillable shape background (takes the same arguments as the SWT [Pattern](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Pattern.html) class [e.g. `background_pattern 2.3, 4.2, 5.4, 7.2, :red, :blue`] / note: this feature isn't extensively tested yet)
2370
- - `clipping` clips area of painting (numeric values for `(x, y, width, height)`)
2440
+ - `clipping` clips area of painting (numeric values for `(x, y, width, height)`)
2371
2441
  - `fill_rule` sets filling rule (SWT style value of `:fill_even_odd` or `:fill_winding`)
2372
2442
  - `font` sets font (Hash of `:name`, `:height`, and `:style` just like standard widget font property, or Font/FontProxy object directly)
2373
2443
  - `foreground` sets draw color for drawable shapes (standard color symbol (e.g. `:red`), `rgb(red_integer, green_integer, blue_integer)` color, or Color/ColorProxy object directly)
@@ -2381,6 +2451,8 @@ Here is a list of supported attributes nestable within a block under shapes:
2381
2451
  - `text_anti_alias` enables text antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
2382
2452
  - `transform` sets transform object using [Canvas Transform DSL](#canvas-transform-dsl) syntax
2383
2453
 
2454
+ Keep in mind that ordering of shapes matters as it is followed in painting. For example, it is recommended you paint filled shapes first and then drawn ones.
2455
+
2384
2456
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
2385
2457
 
2386
2458
  ```ruby
@@ -2567,6 +2639,8 @@ shell {
2567
2639
 
2568
2640
  ### Canvas Transform DSL
2569
2641
 
2642
+ **(ALPHA FEATURE)**
2643
+
2570
2644
  The transform DSL builds [org.eclipse.swt.graphics.Transform](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Transform.html) objects with a nice declarative syntax.
2571
2645
 
2572
2646
  `transform` keyword builds a `Transform` object. It optionally takes the transformation matrix elements: (m11, m12, m21, m22, dx, dy)
@@ -2649,6 +2723,8 @@ Learn more at the [Hello, Canvas Transform! Sample](#hello-canvas-transform).
2649
2723
 
2650
2724
  ### Canvas Animation DSL
2651
2725
 
2726
+ **(EARLY ALPHA FEATURE)**
2727
+
2652
2728
  (note: this is a very new feature of Glimmer. It may change a bit while getting battle tested. As always, you could default to basic SWT usage if needed.)
2653
2729
 
2654
2730
  Glimmer additionally provides built-in support for animations via a declarative Animation DSL, another sub-DSL of the Glimmer GUI DSL.
@@ -2709,6 +2785,12 @@ Learn more at the [Hello, Canvas Animation! Sample](#hello-canvas-animation).
2709
2785
 
2710
2786
  If there is anything missing you would like added to the Glimmer Animation DSL that you saw available in the SWT APIs, you may [report an issue](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) or implement yourself and [contribute](#contributing) via a Pull Request.
2711
2787
 
2788
+ #### Animation via Data-Binding
2789
+
2790
+ Animation could be alternatively implemented without the `animation` keyword through a loop that invokes model methods inside `sync_exec {}` (or `async_exec {}`), which indirectly cause updates to the GUI via data-binding.
2791
+
2792
+ The [Glimmer Tetris](#glimmer-tetris) sample provides a good example of that.
2793
+
2712
2794
  ### Data-Binding
2713
2795
 
2714
2796
  Data-binding is done with `bind` command following widget property to bind and taking model and bindable attribute as arguments.
@@ -3211,7 +3293,7 @@ https://help.eclipse.org/2019-12/index.jsp?topic=%2Forg.eclipse.platform.doc.isv
3211
3293
 
3212
3294
  It has `addSelectionListener`. Additionally, under its `Control` super class, it has `addControlListener`, `addDragDetectListener`, `addFocusListener`, `addGestureListener`, `addHelpListener`, `addKeyListener`, `addMenuDetectListener`, `addMouseListener`, `addMouseMoveListener`, `addMouseTrackListener`, `addMouseWheelListener`, `addPaintListener`, `addTouchListener`, and `addTraverseListener`
3213
3295
 
3214
- Suppose, we select `addSelectionListener`, which is responsible for what happens when a user selects a button (clicks it). Then, open its argument `SelectionListener` SWT API, and you find the event (instance) methods: `widgetDefaultSelected` and `widgetSelected​`. Let's select the second one, which is what gets invoked when a button is clicked.
3296
+ Suppose, we select `addSelectionListener`, which is responsible for what happens when a user selects a button (clicks it). Then, open its argument `SelectionListener` SWT API, and you find the event (instance) methods: `widgetDefaultSelected` and `widgetSelected`. Let's select the second one, which is what gets invoked when a button is clicked.
3215
3297
 
3216
3298
  Now, Glimmer simplifies the process of hooking into that listener (observer) by neither requiring you to call the `addSelectionListener` method nor requiring you to implement/extend the `SelectionListener` API.
3217
3299
 
@@ -3526,7 +3608,7 @@ shell {
3526
3608
 
3527
3609
  Notice how `:no_focus` was the `swt_style` value, followed by the `options` hash `{orientation: :horizontal, bg_color: :white}`, and finally the `content` block containing the label with `'SANDWICH CONTENT'`
3528
3610
 
3529
- #### Gotcha
3611
+ #### Custom Widget Gotchas
3530
3612
 
3531
3613
  Beware of defining a custom attribute that is a common SWT widget property name.
3532
3614
  For example, if you define `text=` and `text` methods to accept a custom text and then later you write this body:
@@ -3556,481 +3638,103 @@ body {
3556
3638
 
3557
3639
  The `text` method invoked in the custom widget body will call the one you defined above it. To avoid this gotcha, simply name the text property above something else, like `custom_text`.
3558
3640
 
3559
- #### Custom Widget Final Notes
3641
+ #### Built-In Custom Widgets
3560
3642
 
3561
- This [Eclipse guide](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm) for how to write custom SWT widgets is also applicable to Glimmer Custom Widgets written in Ruby. I recommend reading it:
3562
- [https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm)
3643
+ ##### Checkbox Group Custom Widget
3563
3644
 
3564
- Also, you may check out [Hello, Custom Widget!](#hello-custom-widget) for another example.
3645
+ `checkbox_group` (or alias `check_group`) is a Glimmer built-in custom widget that displays a list of `checkbox` buttons (`button(:check)`) based on its `items` property.
3565
3646
 
3566
- ### Custom Shells
3647
+ `checkbox_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `checkbox` (`button(:check)`) widgets.
3567
3648
 
3568
- Custom shells are a kind of custom widgets that have shells only as the body root. They can be self-contained applications that may be opened and hidden/closed independently of the main app.
3649
+ The `selection` property determines which `checkbox` buttons are checked. It expects an `Array` of `String` objects
3650
+ The `selection_indices` property determines which `checkbox` button indices are checked. It expects an `Array` of index `Integer` objects that are zero-based.
3651
+ The `checkboxes` property returns the list of nested `checkbox` widgets.
3569
3652
 
3570
- They may also be chained in a wizard fashion.
3653
+ When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `activities_options` for `activities`) to provide an `Array` of `String` objects for `checkbox` buttons.
3571
3654
 
3572
- You can find out about [published Glimmer Custom Shells](https://github.com/AndyObtiva/glimmer-dsl-swt#gem-listing) by running the `glimmer list:gems:customshell` command
3655
+ You may see an example at the [Hello, Checkbox Group!](#hello-checkbox-group) sample.
3573
3656
 
3574
- Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3657
+ ![Hello Checkbox Group](images/glimmer-hello-checkbox-group.png)
3575
3658
 
3576
- ```ruby
3577
- class WizardStep
3578
- include Glimmer::UI::CustomShell
3659
+ ##### Radio Group Custom Widget
3579
3660
 
3580
- options :number, :step_count
3661
+ `radio_group` is a Glimmer built-in custom widget that displays a list of `radio` buttons (`button(:radio)`) based on its `items` property, which expects an `Array` of `String` objects.
3581
3662
 
3582
- before_body {
3583
- @title = "Step #{number}"
3584
- }
3663
+ `radio_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `radio` widgets.
3585
3664
 
3586
- body {
3587
- shell {
3588
- text "Wizard - #{@title}"
3589
- minimum_size 200, 100
3590
- fill_layout :vertical
3591
- label(:center) {
3592
- text @title
3593
- font height: 30
3594
- }
3595
- if number < step_count
3596
- button {
3597
- text "Go To Next Step"
3598
- on_widget_selected {
3599
- body_root.hide
3600
- }
3601
- }
3602
- end
3603
- }
3665
+ The `selection` property determines which `radio` button is selected. It expects a `String`
3666
+ The `selection_index` property determines which `radio` button index is selected. It expects an index integer that is zero-based.
3667
+ The `radios` property returns the list of nested `radio` widgets.
3668
+
3669
+ When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `country_options` for `country`) to provide text for `radio` buttons.
3670
+
3671
+ This custom widget is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
3672
+
3673
+ ![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
3674
+
3675
+ Glimmer Meta-Sample Code Example:
3676
+
3677
+ ```ruby
3678
+ # ...
3679
+ radio_group { |radio_group_proxy|
3680
+ row_layout(:vertical) {
3681
+ fill true
3604
3682
  }
3605
- end
3683
+ selection bind(sample_directory, :selected_sample_name)
3684
+ font height: 24
3685
+ }
3606
3686
 
3607
- shell { |app_shell|
3608
- text "Wizard"
3609
- minimum_size 200, 100
3610
- @current_step_number = 1
3611
- @wizard_steps = 5.times.map { |n|
3612
- wizard_step(number: n+1, step_count: 5) {
3613
- on_swt_hide {
3614
- if @current_step_number < 5
3615
- @current_step_number += 1
3616
- app_shell.hide
3617
- @wizard_steps[@current_step_number - 1].open
3618
- end
3619
- }
3620
- }
3621
- }
3622
- button {
3623
- text "Start"
3624
- font height: 40
3625
- on_widget_selected {
3626
- app_shell.hide
3627
- @wizard_steps[@current_step_number - 1].open
3628
- }
3629
- }
3630
- }.open
3631
- ```
3632
-
3633
- If you use a Custom Shell as the top-level app shell, you may invoke the class method `::launch` instead to avoid building an app class yourself or including Glimmer into the top-level namespace (e.g. `Tetris.launch` instead of `include Glimmer; tetris.open`)
3634
-
3635
- You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
3636
-
3637
- ### Drag and Drop
3638
-
3639
- Glimmer s Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
3640
-
3641
- You may learn more about SWT Drag and Drop support over here: [https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html](https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
3642
-
3643
- To get started, simply follow these steps:
3644
- 1. On the drag source widget, add `on_drag_set_data` [DragSourceListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceListener.html) event handler block at minimum (you may also add `on_drag_start` and `on_drag_finished` if needed)
3645
- 1. Set `event.data` to transfer via drag and drop inside the `on_drag_set_data` event handler block (defaults to `transfer` type of `:text`, as in a Ruby String)
3646
- 1. On the drop target widget, add `on_drop` [DropTargetListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetListener.html) event handler block at minimum (you may also add `on_drag_enter` [must set [`event.detail`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEvent.html#detail) if added], `on_drag_over`, `on_drag_leave`, `on_drag_operation_changed` and `on_drop_accept` if needed)
3647
- 1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
3648
-
3649
- Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3650
-
3651
- ```ruby
3652
- class Location
3653
- attr_accessor :country
3654
-
3655
- def country_options
3656
- %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
3657
- end
3658
- end
3659
-
3660
- @location = Location.new
3661
-
3662
- include Glimmer
3663
-
3664
- shell {
3665
- text 'Hello, Drag and Drop!'
3666
- list {
3667
- selection bind(@location, :country)
3668
- on_drag_set_data { |event|
3669
- list = event.widget.getControl
3670
- event.data = list.getSelection.first
3671
- }
3672
- }
3673
- label(:center) {
3674
- text 'Drag a country here!'
3675
- font height: 20
3676
- on_drop { |event|
3677
- event.widget.getControl.setText(event.data)
3678
- }
3679
- }
3680
- }.open
3681
- ```
3682
-
3683
- ![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
3684
-
3685
- Optional steps:
3686
- - Set a `transfer` property (defaults to `:text`). Values may be: :text (default), :html :image, :rtf, :url, and :file, or an array of multiple values. The `transfer` property will automatically convert your option into a [Transfer](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/Transfer.html) object as per the SWT API.
3687
- - Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
3688
- - Specify `drag_source_effect` (Check [DragSourceEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceEffect.html) SWT API for details)
3689
- - Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
3690
- - Specify `drop_target_effect` (Check [DropTargetEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEffect.html) SWT API for details)
3691
- - Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
3692
-
3693
- ### Miscellaneous
3694
-
3695
- #### Multi-DSL Support
3696
-
3697
- Glimmer is a DSL engine that supports multiple DSLs (Domain Specific Languages):
3698
- - [SWT](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
3699
- - [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
3700
- - [XML](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML) - Useful with [SWT Browser Widget](#browser-widget)
3701
- - [CSS](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets) - Useful with [SWT Browser Widget](#browser-widget)
3702
-
3703
- Glimmer automatically recognizes top-level keywords in each DSL and activates DSL accordingly. Glimmer allows mixing DSLs, which comes in handy when doing things like using the SWT Browser widget with XML and CSS. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
3704
-
3705
- ##### SWT
3706
-
3707
- The SWT DSL was already covered in detail. However, for the sake of mixing DSLs, you need to know that the SWT DSL has the following top-level keywords:
3708
- - `shell`
3709
- - `display`
3710
- - `color`
3711
- - `observe`
3712
- - `async_exec`
3713
- - `sync_exec`
3714
-
3715
- ##### Opal
3716
-
3717
- Full instructions are found in the [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL page.
3718
-
3719
- The [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL is simply a web GUI adapter for desktop apps written in Glimmer. As such, it supports all the DSL keywords of the SWT DSL and shares the same top-level keywords.
3720
-
3721
- ##### XML
3722
-
3723
- Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
3724
- Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
3725
-
3726
- Here are all the Glimmer XML DSL top-level keywords:
3727
- - `html`
3728
- - `tag`: enables custom tag creation for exceptional cases by passing tag name as '_name' attribute
3729
- - `name_space`: enables namespacing html tags
3730
-
3731
- Element properties are typically passed as a key/value hash (e.g. `section(id: 'main', class: 'accordion')`) . However, for properties like "selected" or "checked", you must leave value `nil` or otherwise pass in front of the hash (e.g. `input(:checked, type: 'checkbox')` )
3732
-
3733
- Example (basic HTML / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3734
-
3735
- ```ruby
3736
- @xml = html {
3737
- head {
3738
- meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
3739
- }
3740
- body {
3741
- h1 { "Hello, World!" }
3742
- }
3743
- }
3744
- puts @xml
3745
- ```
3746
-
3747
- Output:
3748
-
3749
- ```
3750
- <html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
3751
- ```
3752
-
3753
- Example (explicit XML tag / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3754
-
3755
- ```ruby
3756
- puts tag(:_name => "DOCUMENT")
3687
+ # ...
3757
3688
  ```
3758
3689
 
3759
- Output:
3690
+ You may see another example at the [Hello, Radio Group!](#hello-radio-group) sample.
3760
3691
 
3761
- ```
3762
- <DOCUMENT/>
3763
- ```
3692
+ ##### Code Text Custom Widget
3764
3693
 
3765
- Example (XML namespaces using `name_space` keyword / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3694
+ **(BETA FEATURE)**
3766
3695
 
3767
- ```ruby
3768
- @xml = name_space(:w3c) {
3769
- html(:id => "thesis", :class => "document") {
3770
- body(:id => "main") {
3771
- }
3772
- }
3773
- }
3774
- puts @xml
3775
- ```
3696
+ `code_text` is a Glimmer built-in custom widget that displays syntax highlighted Ruby code in a customized SWT [StyledText](https://help.eclipse.org/2020-09/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/StyledText.html) widget.
3776
3697
 
3777
- Output:
3698
+ It is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
3778
3699
 
3779
- ```
3780
- <w3c:html id="thesis" class="document"><w3c:body id="main"></w3c:body></w3c:html>
3781
- ```
3700
+ ![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
3782
3701
 
3783
- Example (XML namespaces using dot operator / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3702
+ Glimmer Meta-Sample Code Example:
3784
3703
 
3785
3704
  ```ruby
3786
- @xml = tag(:_name => "DOCUMENT") {
3787
- document.body(document.id => "main") {
3788
- }
3705
+ # ...
3706
+ @code_text = code_text {
3707
+ text bind(SampleDirectory, 'selected_sample.code', read_only: true)
3708
+ editable bind(SampleDirectory, 'selected_sample.editable')
3789
3709
  }
3790
- puts @xml
3791
- ```
3792
-
3793
- Output:
3794
-
3795
- ```
3796
- <DOCUMENT><document:body document:id="main"></document:body></DOCUMENT>
3710
+ # ...
3797
3711
  ```
3798
3712
 
3799
- ##### CSS
3800
-
3801
- Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
3802
- Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
3803
-
3804
- `css` is the only top-level keyword in the Glimmer CSS DSL
3713
+ To use, simply use `code_text` in place of the `text` or `styled_text` widget. If you set its `text` value to Ruby code, it automatically styles it with syntax highlighting.
3805
3714
 
3806
- Selectors may be specified by `s` keyword or HTML element keyword directly (e.g. `body`)
3807
- Rule property values may be specified by `pv` keyword or underscored property name directly (e.g. `font_size`)
3715
+ ###### Options
3808
3716
 
3809
- Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3717
+ **lines**
3718
+ (default: `false`)
3810
3719
 
3811
- ```ruby
3812
- @css = css {
3813
- body {
3814
- font_size '1.1em'
3815
- pv 'background', 'white'
3816
- }
3817
-
3818
- s('body > h1') {
3819
- background_color :red
3820
- pv 'font-size', '2em'
3821
- }
3822
- }
3823
- puts @css
3824
- ```
3720
+ Shows line numbers when set to true.
3825
3721
 
3826
- ##### Listing / Enabling / Disabling DSLs
3722
+ If set to a hash like `{width: 4}`, it sets the initial width of the line numbers lane in character count (default: 4)
3827
3723
 
3828
- Glimmer provides a number of methods on Glimmer::DSL::Engine to configure DSL support or inquire about it:
3829
- - `Glimmer::DSL::Engine.dsls`: Lists available Glimmer DSLs
3830
- - `Glimmer::DSL::Engine.disable_dsl(dsl_name)`: Disables a specific DSL. Useful when there is no need for certain DSLs in a certain application.
3831
- - `Glimmer::DSL::Engine.disabled_dsls': Lists disabled DSLs
3832
- - `Glimmer::DSL::Engine.enable_dsl(dsl_name)`: Re-enables disabled DSL
3833
- - `Glimmer::DSL::Engine.enabled_dsls=(dsl_names)`: Disables all DSLs except the ones specified.
3724
+ Keep in mind that if the text grows and required a wider line numbers area, it grows automatically regardless of initial width.
3834
3725
 
3835
- #### Application Menu Items (About/Preferences)
3726
+ **theme**
3727
+ (default: `'glimmer'`)
3836
3728
 
3837
- Mac applications always have About and Preferences menu items. Glimmer provides widget observer hooks for them on the `display`:
3838
- - `on_about`: executes code when user selects App Name -> About
3839
- - `on_preferences`: executes code when user selects App Name -> Preferences or hits 'CMD+,' on the Mac
3729
+ Changes syntax color highlighting theme. Can be one of the following:
3730
+ - glimmer
3731
+ - github
3732
+ - pastie
3840
3733
 
3841
- Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3734
+ **language**
3735
+ (default: `'ruby'`)
3842
3736
 
3843
- ```ruby
3844
- class Example
3845
- def initialize
3846
- display {
3847
- on_about {
3848
- message_box(@shell_proxy) {
3849
- text 'About'
3850
- message 'About Application'
3851
- }.open
3852
- }
3853
- on_preferences {
3854
- preferences_dialog = dialog {
3855
- text 'Preferences'
3856
- row_layout {
3857
- type :vertical
3858
- margin_left 15
3859
- margin_top 15
3860
- margin_right 15
3861
- margin_bottom 15
3862
- }
3863
- label {
3864
- text 'Check one of these options:'
3865
- }
3866
- button(:radio) {
3867
- text 'Option 1'
3868
- }
3869
- button(:radio) {
3870
- text 'Option 2'
3871
- }
3872
- }
3873
- preferences_dialog.open
3874
- }
3875
- }
3876
- @shell_proxy = shell {
3877
- text 'Application Menu Items'
3878
- fill_layout {
3879
- margin_width 15
3880
- margin_height 15
3881
- }
3882
- label {
3883
- text 'Application Menu Items'
3884
- font height: 30
3885
- }
3886
- }
3887
- @shell_proxy.open
3888
- end
3889
- end
3890
-
3891
- Example.new
3892
- ```
3893
-
3894
- #### App Name and Version
3895
-
3896
- Application name (shows up on the Mac in top menu bar) and version may be specified upon [packaging](#packaging--distribution) by specifying "-Bmac.CFBundleName" and "-Bmac.CFBundleVersion" options.
3897
-
3898
- Still, if you would like proper application name to show up on the Mac top menu bar during development, you may do so by invoking the SWT `Display.app_name=` method before any Display object has been instantiated (i.e. before any Glimmer widget like shell has been declared).
3899
-
3900
- Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3901
-
3902
- ```ruby
3903
- Display.app_name = 'Glimmer Demo'
3904
-
3905
- shell(:no_resize) {
3906
- text "Glimmer"
3907
- label {
3908
- text "Hello, World!"
3909
- }
3910
- }.open
3911
- ```
3912
-
3913
- Also, you may invoke `Display.app_version = '1.0.0'` if needed for OS app version identification reasons during development, replacing `'1.0.0'` with your application version.
3914
-
3915
- #### Performance Profiling
3916
-
3917
- JRuby comes with built-in support for performance profiling via the `--profile` option (with some code shown below), which can be accepted by the `glimmer` command too:
3918
-
3919
- `glimmer --profile path_to_glimmer_app.rb`
3920
-
3921
- Additionally, add this code to monitor Glimmer app performance around its launch method:
3922
-
3923
- ```ruby
3924
- require 'jruby/profiler'
3925
- profile_data = JRuby::Profiler.profile do
3926
- SomeGlimmerApp.launch
3927
- end
3928
-
3929
- profile_printer = JRuby::Profiler::HtmlProfilePrinter.new(profile_data)
3930
- ps = java.io.PrintStream.new(STDOUT.to_outputstream)
3931
- ```
3932
-
3933
- When monitoring app startup time performance, make sure to add a hook to the top-level `shell` `on_swt_show` event that exits the app as soon as the shell shows up to end performance profiling and get the results.
3934
-
3935
- Example:
3936
-
3937
- ```ruby
3938
- shell {
3939
- # some code
3940
- on_swt_show {
3941
- exit(0)
3942
- }
3943
- }
3944
- ```
3945
-
3946
- You may run `glimmer` with the `--profile.graph` instead for a more detailed output.
3947
-
3948
- Learn more at the [JRuby Performance Profile WIKI page](https://github.com/jruby/jruby/wiki/Profiling-JRuby).
3949
-
3950
- #### Checkbox Group Widget
3951
-
3952
- `checkbox_group` (or alias `check_group`) is a Glimmer built-in custom widget that displays a list of `checkbox` buttons (`button(:check)`) based on its `items` property.
3953
-
3954
- `checkbox_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `checkbox` (`button(:check)`) widgets.
3955
-
3956
- The `selection` property determines which `checkbox` buttons are checked. It expects an `Array` of `String` objects
3957
- The `selection_indices` property determines which `checkbox` button indices are checked. It expects an `Array` of index `Integer` objects that are zero-based.
3958
- The `checkboxes` property returns the list of nested `checkbox` widgets.
3959
-
3960
- When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `activities_options` for `activities`) to provide an `Array` of `String` objects for `checkbox` buttons.
3961
-
3962
- You may see an example at the [Hello, Checkbox Group!](#hello-checkbox-group) sample.
3963
-
3964
- ![Hello Checkbox Group](images/glimmer-hello-checkbox-group.png)
3965
-
3966
- #### Radio Group Widget
3967
-
3968
- `radio_group` is a Glimmer built-in custom widget that displays a list of `radio` buttons (`button(:radio)`) based on its `items` property, which expects an `Array` of `String` objects.
3969
-
3970
- `radio_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `radio` widgets.
3971
-
3972
- The `selection` property determines which `radio` button is selected. It expects a `String`
3973
- The `selection_index` property determines which `radio` button index is selected. It expects an index integer that is zero-based.
3974
- The `radios` property returns the list of nested `radio` widgets.
3975
-
3976
- When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `country_options` for `country`) to provide text for `radio` buttons.
3977
-
3978
- This custom widget is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
3979
-
3980
- ![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
3981
-
3982
- Glimmer Meta-Sample Code Example:
3983
-
3984
- ```ruby
3985
- # ...
3986
- radio_group { |radio_group_proxy|
3987
- row_layout(:vertical) {
3988
- fill true
3989
- }
3990
- selection bind(sample_directory, :selected_sample_name)
3991
- font height: 24
3992
- }
3993
-
3994
- # ...
3995
- ```
3996
-
3997
- You may see another example at the [Hello, Radio Group!](#hello-radio-group) sample.
3998
-
3999
- #### Code Text Widget
4000
-
4001
- `code_text` is a Glimmer built-in custom widget that displays syntax highlighted Ruby code in a customized SWT [StyledText](https://help.eclipse.org/2020-09/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/StyledText.html) widget.
4002
-
4003
- It is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
4004
-
4005
- ![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
4006
-
4007
- Glimmer Meta-Sample Code Example:
4008
-
4009
- ```ruby
4010
- # ...
4011
- @code_text = code_text {
4012
- text bind(SampleDirectory, 'selected_sample.code', read_only: true)
4013
- editable bind(SampleDirectory, 'selected_sample.editable')
4014
- }
4015
- # ...
4016
- ```
4017
-
4018
- To use, simply use `code_text` in place of the `text` or `styled_text` widget. If you set its `text` value to Ruby code, it automatically styles it with syntax highlighting.
4019
-
4020
- ##### Options
4021
-
4022
- **theme**
4023
- (default: 'glimmer')
4024
-
4025
- Changes syntax color highlighting theme. Can be one of the following:
4026
- - glimmer
4027
- - github
4028
- - pastie
4029
-
4030
- **language**
4031
- (default: `'ruby'`)
4032
-
4033
- Sets the code language, which can be one of the following supported rouge gem languages:
3737
+ Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
4034
3738
  - abap
4035
3739
  - actionscript
4036
3740
  - ada
@@ -4236,87 +3940,417 @@ Sets the code language, which can be one of the following supported rouge gem la
4236
3940
  - yang
4237
3941
  - zig
4238
3942
 
4239
- #### Video Widget
3943
+ **default_behavior**
3944
+ (default: true)
3945
+
3946
+ This adds some default keyboard shortcuts:
3947
+ - CMD+A (CTRL+A on Windows/Linux) to select all
3948
+ - CTRL+A on Mac to jump to beginning of line
3949
+ - CTRL+E on Mac to jump to end of line
3950
+
3951
+ If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
3952
+
3953
+ Learn more at [Hello, Code Text!](#hello-code-text)
3954
+
3955
+ ##### Video Custom Custom Widget
3956
+
3957
+ [![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
3958
+
3959
+ Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT, which was originally a Glimmer built-in custom widget, but has been later extracted into its own [Ruby gem](https://rubygems.org/gems/glimmer-cw-video).
3960
+
3961
+ Simply install the [glimmer-cw-video](https://rubygems.org/gems/glimmer-cw-video) gem.
3962
+
3963
+ #### Custom Widget Final Notes
3964
+
3965
+ This [Eclipse guide](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm) for how to write custom SWT widgets is also applicable to Glimmer Custom Widgets written in Ruby. I recommend reading it:
3966
+ [https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm)
3967
+
3968
+ Also, you may check out [Hello, Custom Widget!](#hello-custom-widget) for another example.
3969
+
3970
+ ### Custom Shells
3971
+
3972
+ Custom shells are a kind of custom widgets that have shells only as the body root. They can be self-contained applications that may be opened and hidden/closed independently of the main app.
3973
+
3974
+ They may also be chained in a wizard fashion.
3975
+
3976
+ You can find out about [published Glimmer Custom Shells](https://github.com/AndyObtiva/glimmer-dsl-swt#gem-listing) by running the `glimmer list:gems:customshell` command
3977
+
3978
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
3979
+
3980
+ ```ruby
3981
+ class WizardStep
3982
+ include Glimmer::UI::CustomShell
3983
+
3984
+ options :number, :step_count
3985
+
3986
+ before_body {
3987
+ @title = "Step #{number}"
3988
+ }
3989
+
3990
+ body {
3991
+ shell {
3992
+ text "Wizard - #{@title}"
3993
+ minimum_size 200, 100
3994
+ fill_layout :vertical
3995
+ label(:center) {
3996
+ text @title
3997
+ font height: 30
3998
+ }
3999
+ if number < step_count
4000
+ button {
4001
+ text "Go To Next Step"
4002
+ on_widget_selected {
4003
+ body_root.hide
4004
+ }
4005
+ }
4006
+ end
4007
+ }
4008
+ }
4009
+ end
4010
+
4011
+ shell { |app_shell|
4012
+ text "Wizard"
4013
+ minimum_size 200, 100
4014
+ @current_step_number = 1
4015
+ @wizard_steps = 5.times.map { |n|
4016
+ wizard_step(number: n+1, step_count: 5) {
4017
+ on_swt_hide {
4018
+ if @current_step_number < 5
4019
+ @current_step_number += 1
4020
+ app_shell.hide
4021
+ @wizard_steps[@current_step_number - 1].open
4022
+ end
4023
+ }
4024
+ }
4025
+ }
4026
+ button {
4027
+ text "Start"
4028
+ font height: 40
4029
+ on_widget_selected {
4030
+ app_shell.hide
4031
+ @wizard_steps[@current_step_number - 1].open
4032
+ }
4033
+ }
4034
+ }.open
4035
+ ```
4036
+
4037
+ If you use a Custom Shell as the top-level app shell, you may invoke the class method `::launch` instead to avoid building an app class yourself or including Glimmer into the top-level namespace (e.g. `Tetris.launch` instead of `include Glimmer; tetris.open`)
4038
+
4039
+ You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
4040
+
4041
+ ### Drag and Drop
4042
+
4043
+ Glimmer s Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
4044
+
4045
+ You may learn more about SWT Drag and Drop support over here: [https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html](https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
4046
+
4047
+ To get started, simply follow these steps:
4048
+ 1. On the drag source widget, add `on_drag_set_data` [DragSourceListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceListener.html) event handler block at minimum (you may also add `on_drag_start` and `on_drag_finished` if needed)
4049
+ 1. Set `event.data` to transfer via drag and drop inside the `on_drag_set_data` event handler block (defaults to `transfer` type of `:text`, as in a Ruby String)
4050
+ 1. On the drop target widget, add `on_drop` [DropTargetListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetListener.html) event handler block at minimum (you may also add `on_drag_enter` [must set [`event.detail`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEvent.html#detail) if added], `on_drag_over`, `on_drag_leave`, `on_drag_operation_changed` and `on_drop_accept` if needed)
4051
+ 1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
4052
+
4053
+ Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4054
+
4055
+ ```ruby
4056
+ class Location
4057
+ attr_accessor :country
4058
+
4059
+ def country_options
4060
+ %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
4061
+ end
4062
+ end
4063
+
4064
+ @location = Location.new
4065
+
4066
+ include Glimmer
4067
+
4068
+ shell {
4069
+ text 'Hello, Drag and Drop!'
4070
+ list {
4071
+ selection bind(@location, :country)
4072
+ on_drag_set_data { |event|
4073
+ list = event.widget.getControl
4074
+ event.data = list.getSelection.first
4075
+ }
4076
+ }
4077
+ label(:center) {
4078
+ text 'Drag a country here!'
4079
+ font height: 20
4080
+ on_drop { |event|
4081
+ event.widget.getControl.setText(event.data)
4082
+ }
4083
+ }
4084
+ }.open
4085
+ ```
4086
+
4087
+ ![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
4088
+
4089
+ Optional steps:
4090
+ - Set a `transfer` property (defaults to `:text`). Values may be: :text (default), :html :image, :rtf, :url, and :file, or an array of multiple values. The `transfer` property will automatically convert your option into a [Transfer](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/Transfer.html) object as per the SWT API.
4091
+ - Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
4092
+ - Specify `drag_source_effect` (Check [DragSourceEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceEffect.html) SWT API for details)
4093
+ - Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
4094
+ - Specify `drop_target_effect` (Check [DropTargetEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEffect.html) SWT API for details)
4095
+ - Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
4096
+
4097
+ ### Miscellaneous
4098
+
4099
+ #### Multi-DSL Support
4100
+
4101
+ Glimmer is a DSL engine that supports multiple DSLs (Domain Specific Languages):
4102
+ - [SWT](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
4103
+ - [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
4104
+ - [XML](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML) - Useful with [SWT Browser Widget](#browser-widget)
4105
+ - [CSS](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets) - Useful with [SWT Browser Widget](#browser-widget)
4106
+
4107
+ Glimmer automatically recognizes top-level keywords in each DSL and activates DSL accordingly. Glimmer allows mixing DSLs, which comes in handy when doing things like using the SWT Browser widget with XML and CSS. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
4108
+
4109
+ ##### SWT
4110
+
4111
+ The SWT DSL was already covered in detail. However, for the sake of mixing DSLs, you need to know that the SWT DSL has the following top-level keywords:
4112
+ - `shell`
4113
+ - `display`
4114
+ - `color`
4115
+ - `observe`
4116
+ - `async_exec`
4117
+ - `sync_exec`
4118
+
4119
+ ##### Opal
4120
+
4121
+ Full instructions are found in the [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL page.
4122
+
4123
+ The [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL is simply a web GUI adapter for desktop apps written in Glimmer. As such, it supports all the DSL keywords of the SWT DSL and shares the same top-level keywords.
4124
+
4125
+ ##### XML
4126
+
4127
+ Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
4128
+ Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
4129
+
4130
+ Here are all the Glimmer XML DSL top-level keywords:
4131
+ - `html`
4132
+ - `tag`: enables custom tag creation for exceptional cases by passing tag name as '_name' attribute
4133
+ - `name_space`: enables namespacing html tags
4134
+
4135
+ Element properties are typically passed as a key/value hash (e.g. `section(id: 'main', class: 'accordion')`) . However, for properties like "selected" or "checked", you must leave value `nil` or otherwise pass in front of the hash (e.g. `input(:checked, type: 'checkbox')` )
4136
+
4137
+ Example (basic HTML / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4138
+
4139
+ ```ruby
4140
+ @xml = html {
4141
+ head {
4142
+ meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
4143
+ }
4144
+ body {
4145
+ h1 { "Hello, World!" }
4146
+ }
4147
+ }
4148
+ puts @xml
4149
+ ```
4150
+
4151
+ Output:
4152
+
4153
+ ```
4154
+ <html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
4155
+ ```
4156
+
4157
+ Example (explicit XML tag / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4158
+
4159
+ ```ruby
4160
+ puts tag(:_name => "DOCUMENT")
4161
+ ```
4162
+
4163
+ Output:
4164
+
4165
+ ```
4166
+ <DOCUMENT/>
4167
+ ```
4168
+
4169
+ Example (XML namespaces using `name_space` keyword / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4170
+
4171
+ ```ruby
4172
+ @xml = name_space(:w3c) {
4173
+ html(:id => "thesis", :class => "document") {
4174
+ body(:id => "main") {
4175
+ }
4176
+ }
4177
+ }
4178
+ puts @xml
4179
+ ```
4180
+
4181
+ Output:
4182
+
4183
+ ```
4184
+ <w3c:html id="thesis" class="document"><w3c:body id="main"></w3c:body></w3c:html>
4185
+ ```
4186
+
4187
+ Example (XML namespaces using dot operator / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4188
+
4189
+ ```ruby
4190
+ @xml = tag(:_name => "DOCUMENT") {
4191
+ document.body(document.id => "main") {
4192
+ }
4193
+ }
4194
+ puts @xml
4195
+ ```
4196
+
4197
+ Output:
4198
+
4199
+ ```
4200
+ <DOCUMENT><document:body document:id="main"></document:body></DOCUMENT>
4201
+ ```
4202
+
4203
+ ##### CSS
4204
+
4205
+ Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
4206
+ Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
4207
+
4208
+ `css` is the only top-level keyword in the Glimmer CSS DSL
4209
+
4210
+ Selectors may be specified by `s` keyword or HTML element keyword directly (e.g. `body`)
4211
+ Rule property values may be specified by `pv` keyword or underscored property name directly (e.g. `font_size`)
4212
+
4213
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4214
+
4215
+ ```ruby
4216
+ @css = css {
4217
+ body {
4218
+ font_size '1.1em'
4219
+ pv 'background', 'white'
4220
+ }
4221
+
4222
+ s('body > h1') {
4223
+ background_color :red
4224
+ pv 'font-size', '2em'
4225
+ }
4226
+ }
4227
+ puts @css
4228
+ ```
4229
+
4230
+ ##### Listing / Enabling / Disabling DSLs
4240
4231
 
4241
- [![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
4232
+ Glimmer provides a number of methods on Glimmer::DSL::Engine to configure DSL support or inquire about it:
4233
+ - `Glimmer::DSL::Engine.dsls`: Lists available Glimmer DSLs
4234
+ - `Glimmer::DSL::Engine.disable_dsl(dsl_name)`: Disables a specific DSL. Useful when there is no need for certain DSLs in a certain application.
4235
+ - `Glimmer::DSL::Engine.disabled_dsls': Lists disabled DSLs
4236
+ - `Glimmer::DSL::Engine.enable_dsl(dsl_name)`: Re-enables disabled DSL
4237
+ - `Glimmer::DSL::Engine.enabled_dsls=(dsl_names)`: Disables all DSLs except the ones specified.
4242
4238
 
4243
- Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
4239
+ #### Application Menu Items (About/Preferences)
4244
4240
 
4245
- You may obtain via `glimmer-cw-video` gem.
4241
+ Mac applications always have About and Preferences menu items. Glimmer provides widget observer hooks for them on the `display`:
4242
+ - `on_about`: executes code when user selects App Name -> About
4243
+ - `on_preferences`: executes code when user selects App Name -> Preferences or hits 'CMD+,' on the Mac
4246
4244
 
4247
- #### Sash Form Widget
4245
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4248
4246
 
4249
- `sash_form` is an SWT built-in custom widget that provides a resizable sash that splits a window area into two or more panes.
4247
+ ```ruby
4248
+ class Example
4249
+ def initialize
4250
+ display {
4251
+ on_about {
4252
+ message_box(@shell_proxy) {
4253
+ text 'About'
4254
+ message 'About Application'
4255
+ }.open
4256
+ }
4257
+ on_preferences {
4258
+ preferences_dialog = dialog {
4259
+ text 'Preferences'
4260
+ row_layout {
4261
+ type :vertical
4262
+ margin_left 15
4263
+ margin_top 15
4264
+ margin_right 15
4265
+ margin_bottom 15
4266
+ }
4267
+ label {
4268
+ text 'Check one of these options:'
4269
+ }
4270
+ button(:radio) {
4271
+ text 'Option 1'
4272
+ }
4273
+ button(:radio) {
4274
+ text 'Option 2'
4275
+ }
4276
+ }
4277
+ preferences_dialog.open
4278
+ }
4279
+ }
4280
+ @shell_proxy = shell {
4281
+ text 'Application Menu Items'
4282
+ fill_layout {
4283
+ margin_width 15
4284
+ margin_height 15
4285
+ }
4286
+ label {
4287
+ text 'Application Menu Items'
4288
+ font height: 30
4289
+ }
4290
+ }
4291
+ @shell_proxy.open
4292
+ end
4293
+ end
4250
4294
 
4251
- It can be customized with the `weights` attribute by setting initial weights to size the panes at first display.
4295
+ Example.new
4296
+ ```
4252
4297
 
4253
- One noteworthy thing about the Glimmer implementation is that, unlike behavior in SWT, it allows declaring `weights` before the content of the `sash_form`, thus providing more natural and convenient syntax (Glimmer automatically takes care of sending that declaration to SWT at the end of declaring `sash_form` content as per the SWT requirements)
4298
+ #### App Name and Version
4299
+
4300
+ Application name (shows up on the Mac in top menu bar) and version may be specified upon [packaging](#packaging--distribution) by specifying "-Bmac.CFBundleName" and "-Bmac.CFBundleVersion" options.
4301
+
4302
+ Still, if you would like proper application name to show up on the Mac top menu bar during development, you may do so by invoking the SWT `Display.app_name=` method before any Display object has been instantiated (i.e. before any Glimmer widget like shell has been declared).
4254
4303
 
4255
4304
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4256
4305
 
4257
4306
  ```ruby
4258
- shell {
4259
- text 'Sash Form Example'
4260
- sash_form {
4261
- label {
4262
- text '(resize >>)'
4263
- background :dark_green
4264
- foreground :white
4265
- font height: 20
4266
- }
4267
- label {
4268
- text '(<< resize)'
4269
- background :red
4270
- foreground :white
4271
- font height: 20
4272
- }
4273
- weights 1, 2
4307
+ Display.app_name = 'Glimmer Demo'
4308
+
4309
+ shell(:no_resize) {
4310
+ text "Glimmer"
4311
+ label {
4312
+ text "Hello, World!"
4274
4313
  }
4275
4314
  }.open
4276
4315
  ```
4277
4316
 
4278
- You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash-form)
4279
-
4280
- ![Hello Sash Form](images/glimmer-hello-sash-form.png)
4317
+ Also, you may invoke `Display.app_version = '1.0.0'` if needed for OS app version identification reasons during development, replacing `'1.0.0'` with your application version.
4281
4318
 
4282
- #### Browser Widget
4319
+ #### Performance Profiling
4283
4320
 
4284
- ![Hello Browser](images/glimmer-hello-browser.png)
4321
+ JRuby comes with built-in support for performance profiling via the `--profile` option (with some code shown below), which can be accepted by the `glimmer` command too:
4285
4322
 
4286
- Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
4323
+ `glimmer --profile path_to_glimmer_app.rb`
4287
4324
 
4288
- Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
4325
+ Additionally, add this code to monitor Glimmer app performance around its launch method:
4289
4326
 
4290
4327
  ```ruby
4291
- shell {
4292
- minimum_size 1024, 860
4293
- browser {
4294
- url 'http://brightonresort.com/about'
4295
- }
4296
- }.open
4328
+ require 'jruby/profiler'
4329
+ profile_data = JRuby::Profiler.profile do
4330
+ SomeGlimmerApp.launch
4331
+ end
4332
+
4333
+ profile_printer = JRuby::Profiler::HtmlProfilePrinter.new(profile_data)
4334
+ ps = java.io.PrintStream.new(STDOUT.to_outputstream)
4297
4335
  ```
4298
4336
 
4299
- Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command) provided you install and require [glimmer-dsl-xml gem](https://github.com/AndyObtiva/glimmer-dsl-xml)):
4337
+ When monitoring app startup time performance, make sure to add a hook to the top-level `shell` `on_swt_show` event that exits the app as soon as the shell shows up to end performance profiling and get the results.
4338
+
4339
+ Example:
4300
4340
 
4301
4341
  ```ruby
4302
4342
  shell {
4303
- minimum_size 130, 130
4304
- @browser = browser {
4305
- text html {
4306
- head {
4307
- meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
4308
- }
4309
- body {
4310
- h1 { "Hello, World!" }
4311
- }
4312
- }
4313
- on_completed { # on load of the page execute this JavaScript
4314
- @browser.swt_widget.execute("alert('Hello, World!');")
4315
- }
4343
+ # some code
4344
+ on_swt_show {
4345
+ exit(0)
4316
4346
  }
4317
- }.open
4347
+ }
4318
4348
  ```
4319
4349
 
4350
+ You may run `glimmer` with the `--profile.graph` instead for a more detailed output.
4351
+
4352
+ Learn more at the [JRuby Performance Profile WIKI page](https://github.com/jruby/jruby/wiki/Profiling-JRuby).
4353
+
4320
4354
  ##### SWT Browser Style Options
4321
4355
 
4322
4356
  The `browser` widget can use a particular desktop browser by setting the SWT Style to:
@@ -4529,50 +4563,6 @@ Keep in mind the caveat that it would force redraws on every minor changein the
4529
4563
  - Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
4530
4564
  - Custom widgets receive additional arguments to SWT style called options. These are passed as the last argument inside the parentheses, a hash of option names pointing to values.
4531
4565
 
4532
- ## SWT Reference
4533
-
4534
- https://www.eclipse.org/swt/docs.php
4535
-
4536
- Here is the SWT API:
4537
-
4538
- https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
4539
-
4540
- Here is a visual list of SWT widgets:
4541
-
4542
- https://www.eclipse.org/swt/widgets/
4543
-
4544
- Here is a textual list of SWT widgets:
4545
-
4546
- https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
4547
-
4548
- Here is a list of SWT style bits as used in widget declaration:
4549
-
4550
- https://wiki.eclipse.org/SWT_Widget_Style_Bits
4551
-
4552
- Here is a SWT style bit constant reference:
4553
-
4554
- https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
4555
-
4556
- Here is an SWT Drag and Drop guide:
4557
-
4558
- https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
4559
-
4560
- Here is an SWT Custom Widget guide:
4561
-
4562
- https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
4563
-
4564
- Here is an SWT Image guide:
4565
-
4566
- https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html
4567
-
4568
- Here is an SWT Graphics / Canvas-Drawing guide:
4569
-
4570
- https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html
4571
-
4572
- Here is the Nebula Project (custom widget library) homepage:
4573
-
4574
- https://www.eclipse.org/nebula/
4575
-
4576
4566
  ## Samples
4577
4567
 
4578
4568
  Check the [samples](samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer samples` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`).
@@ -4599,7 +4589,7 @@ bin/glimmer samples/hello/hello_canvas_transform.rb
4599
4589
 
4600
4590
  For hello-type simple samples, check the following.
4601
4591
 
4602
- #### Hello, World! Sample
4592
+ #### Hello, World!
4603
4593
 
4604
4594
  Code:
4605
4595
 
@@ -5054,6 +5044,26 @@ Hello, Dialog! Open Dialog
5054
5044
 
5055
5045
  ![Hello Dialog Open Dialog](images/glimmer-hello-dialog-open-dialog.png)
5056
5046
 
5047
+ #### Hello, Code Text!
5048
+
5049
+ This sample demonstrates the Glimmer Built-In [Code Text Custom Widget](#code-text-custom-widget).
5050
+
5051
+ Code:
5052
+
5053
+ [samples/hello/hello_code_text.rb](samples/hello/hello_code_text.rb)
5054
+
5055
+ Hello, Code Text! Ruby Language / Glimmer Theme / Show Line Numbers (default width of 4)
5056
+
5057
+ ![Hello Code Text Ruby](images/glimmer-hello-code-text-ruby.png)
5058
+
5059
+ Hello, Code Text! JavaScript Language / Pastie Theme / Show Line Numbers (custom width of 2)
5060
+
5061
+ ![Hello Code Text JavaScript](images/glimmer-hello-code-text-javascript.png)
5062
+
5063
+ Hello, Code Text! HTML Language / GitHub Theme / No Line Numbers
5064
+
5065
+ ![Hello Code Text HTML](images/glimmer-hello-code-text-html.png)
5066
+
5057
5067
  #### Hello, Canvas!
5058
5068
 
5059
5069
  This sample demonstrates the use of the `canvas` widget and [Shape DSL](#canvas-shape-dsl) in Glimmer.
@@ -5123,7 +5133,7 @@ Code:
5123
5133
  ![Login Filled In](images/glimmer-login-filled-in.png)
5124
5134
  ![Login Logged In](images/glimmer-login-logged-in.png)
5125
5135
 
5126
- #### Tic Tac Toe Sample
5136
+ #### Tic Tac Toe
5127
5137
 
5128
5138
  This sample demonstrates a full MVC application, including GUI layout, text and enablement data-binding, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/tic_tac_toe/board_spec.rb)).
5129
5139
 
@@ -5137,7 +5147,7 @@ Code:
5137
5147
  ![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
5138
5148
  ![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
5139
5149
 
5140
- #### Contact Manager Sample
5150
+ #### Contact Manager
5141
5151
 
5142
5152
  This sample demonstrates table data-binding, sorting, filtering, GUI layout, MVP pattern, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/contact_manager/contact_manager_presenter_spec.rb)).
5143
5153
 
@@ -5165,10 +5175,12 @@ Contact Manager - Edit Done
5165
5175
 
5166
5176
  ![Contact Manager](images/glimmer-contact-manager-edit-done.png)
5167
5177
 
5168
- #### Tetris
5178
+ #### Glimmer Tetris
5169
5179
 
5170
5180
  This sample demonstrates how to build an interactive animated game with MVC architecture, custom-shell/custom-widgets, multi-threading, asynchronous programming, data-binding, canvas shape graphic decorations, canvas shape icon image generation, and keyboard events/shortcuts.
5171
5181
 
5182
+ Note that it works optimally on the Mac. It is very new, so it has not been optimized for Windows and Linux yet given their minor differences from the Mac.
5183
+
5172
5184
  Code:
5173
5185
 
5174
5186
  [samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)
@@ -5242,7 +5254,7 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
5242
5254
 
5243
5255
  ## Packaging & Distribution
5244
5256
 
5245
- Note: this section mostly applies to Mac and Windows. On Linux, you can just run `glimmer package:gem` and after installing the gem, you get an executable matching the name of the app/custom-shell-gem you are building (e.g. `calculator` command becomes available after installing the [glimmer-cs-calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) gem)
5257
+ Note: this section mostly applies to Mac and Windows. On Linux, you can just run `glimmer package:gem` and after installing the gem, you get an executable matching the name of the app/custom-shell-gem you are building (e.g. `calculator` command becomes available after installing the [glimmer-cs-calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) gem). On Windows, ensure system PATH includes Java bin directory like "C:\Program Files\Java\jdk1.8.0_241\bin" for javapackager command to work during packaging Glimmer applications.
5246
5258
 
5247
5259
  Note 2: Glimmer packaging has a strong dependency on JDK8 at the moment. JDK9 & JDK10 might work, but JDK11 and onward definitely won't since they dropped javapackager, which later came back as jpackage in JDK14, but it's not ready for prime time yet. Just stick to JDK8 for now, strongly supported by Oracle for the next 6 years at least.
5248
5260
 
@@ -5252,7 +5264,7 @@ Glimmer simplifies the process of native-executable packaging and distribution o
5252
5264
  glimmer package
5253
5265
  ```
5254
5266
 
5255
- It works out of the box for any application scaffolded by [Glimmer Scaffolding](#scaffolding), generating all available packaging types on the current platform (e.g. `DMG`, `PKG`, `APP` on the Mac) and displaying a message indicating what pre-requisite setup tools are needed if not installed already (e.g. [Wix Toolset](https://wixtoolset.org/) to generate MSI files on Windows)
5267
+ It works out of the box for any application scaffolded by [Glimmer Scaffolding](#scaffolding), generating all available packaging types on the current platform (e.g. `DMG`, `PKG`, `APP` on the Mac) and displaying a message indicating what pre-requisite setup tools are needed if not installed already (e.g. [Wix Toolset](https://wixtoolset.org/) to generate MSI files on Windows). If you install Wix, make sure it is on the system PATH by adding for example "C:\Program Files (x86)\WiX Toolset v3.11\bin" to the Windows Environment Variables.
5256
5268
 
5257
5269
  You may choose to generate a specific type of packaging instead by addionally passing in the `[type]` option. For example, this generates an MSI setup file on Windows:
5258
5270
 
@@ -5400,7 +5412,7 @@ Glimmer::RakeTask::Package.javapackager_extra_args = '-Bmac.signing-key-develope
5400
5412
 
5401
5413
  Now, when you run `glimmer package`, it builds a self-signed DMG file. When you make available online, and users download, upon launching application, they are presented with your certificate, which they have to sign if they trust you in order to use the application.
5402
5414
 
5403
- ### Gotchas
5415
+ ### Packaging Gotchas
5404
5416
 
5405
5417
  1. Specifying License File
5406
5418
 
@@ -5433,6 +5445,16 @@ You can get around that in zsh by running glimmer package commands with `bash -c
5433
5445
  bash -c 'glimmer package'
5434
5446
  ```
5435
5447
 
5448
+ 4. Java on Windows System PATH
5449
+
5450
+ If you get any errors running Java on Windows, keep in mind that you need to have the Java binaries on the Windows System PATH environment variable:
5451
+ c:\program files\java\jre1.8.0_241
5452
+
5453
+ The problem is Oracle seems to be adding an indirect Java path junction in later versions of their installer:
5454
+ C:\Program Files (x86)\Common Files\Oracle\Java\javapath
5455
+
5456
+ Simply replace with the simple one above (setting the correct version number) and then reinstall JRuby to have it use Java from the right path.
5457
+
5436
5458
  ## App Updates
5437
5459
 
5438
5460
  Glimmer already supports automatic (and manual) app updates via the Mac App Store for Mac apps. Simply run the `glimmer package` command with the Mac App Store keys configured as per [Mac Application Distribution](mac-application-distribution) instructions and you get automatic (and manual) app update support courtesy of the Mac App Store.
@@ -5467,6 +5489,50 @@ Learn more by reading the [GPG](https://github.com/AndyObtiva/glimmer/blob/maste
5467
5489
  * [MountainWest RubyConf 2011 Video](https://confreaks.tv/videos/mwrc2011-whatever-happened-to-desktop-development-in-ruby)
5468
5490
  * [RubyConf 2008 Video](https://confreaks.tv/videos/rubyconf2008-desktop-development-with-glimmer)
5469
5491
 
5492
+ ### SWT Reference
5493
+
5494
+ https://www.eclipse.org/swt/docs.php
5495
+
5496
+ Here is the SWT API:
5497
+
5498
+ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
5499
+
5500
+ Here is a visual list of SWT widgets:
5501
+
5502
+ https://www.eclipse.org/swt/widgets/
5503
+
5504
+ Here is a textual list of SWT widgets:
5505
+
5506
+ https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
5507
+
5508
+ Here is a list of SWT style bits as used in widget declaration:
5509
+
5510
+ https://wiki.eclipse.org/SWT_Widget_Style_Bits
5511
+
5512
+ Here is a SWT style bit constant reference:
5513
+
5514
+ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
5515
+
5516
+ Here is an SWT Drag and Drop guide:
5517
+
5518
+ https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
5519
+
5520
+ Here is an SWT Custom Widget guide:
5521
+
5522
+ https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
5523
+
5524
+ Here is an SWT Image guide:
5525
+
5526
+ https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html
5527
+
5528
+ Here is an SWT Graphics / Canvas-Drawing guide:
5529
+
5530
+ https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html
5531
+
5532
+ Here is the Nebula Project (custom widget library) homepage:
5533
+
5534
+ https://www.eclipse.org/nebula/
5535
+
5470
5536
  ## Help
5471
5537
 
5472
5538
  ### Issues