glimmer 0.4.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +324 -59
  3. data/lib/glimmer.rb +54 -63
  4. data/lib/glimmer/data_binding/list_selection_binding.rb +52 -0
  5. data/lib/glimmer/{swt → data_binding}/model_binding.rb +33 -5
  6. data/lib/glimmer/{swt → data_binding}/observable.rb +6 -3
  7. data/lib/glimmer/{swt → data_binding}/observable_array.rb +3 -1
  8. data/lib/glimmer/{swt → data_binding}/observable_model.rb +3 -2
  9. data/lib/glimmer/data_binding/observable_widget.rb +17 -0
  10. data/lib/glimmer/{swt → data_binding}/observer.rb +3 -3
  11. data/lib/glimmer/{shine.rb → data_binding/shine.rb} +2 -2
  12. data/lib/glimmer/{swt → data_binding}/table_items_binding.rb +12 -11
  13. data/lib/glimmer/{swt → data_binding}/tree_items_binding.rb +15 -12
  14. data/lib/glimmer/{swt → data_binding}/widget_binding.rb +2 -1
  15. data/lib/glimmer/dsl.rb +26 -0
  16. data/lib/glimmer/dsl/async_exec_expression.rb +12 -0
  17. data/lib/glimmer/dsl/bind_expression.rb +44 -0
  18. data/lib/glimmer/dsl/color_expression.rb +28 -0
  19. data/lib/glimmer/dsl/column_properties_expression.rb +22 -0
  20. data/lib/glimmer/dsl/combo_selection_data_binding_expression.rb +40 -0
  21. data/lib/glimmer/dsl/custom_widget_expression.rb +35 -0
  22. data/lib/glimmer/dsl/data_binding_expression.rb +33 -0
  23. data/lib/glimmer/dsl/display_expression.rb +12 -0
  24. data/lib/glimmer/dsl/engine.rb +80 -0
  25. data/lib/glimmer/dsl/exec_expression.rb +23 -0
  26. data/lib/glimmer/dsl/expression.rb +44 -0
  27. data/lib/glimmer/dsl/expression_handler.rb +48 -0
  28. data/lib/glimmer/dsl/layout_data_expression.rb +24 -0
  29. data/lib/glimmer/dsl/layout_expression.rb +26 -0
  30. data/lib/glimmer/dsl/list_selection_data_binding_expression.rb +42 -0
  31. data/lib/glimmer/dsl/observe_expression.rb +27 -0
  32. data/lib/glimmer/dsl/parent_expression.rb +12 -0
  33. data/lib/glimmer/dsl/property_expression.rb +20 -0
  34. data/lib/glimmer/dsl/shell_expression.rb +15 -0
  35. data/lib/glimmer/dsl/static_expression.rb +38 -0
  36. data/lib/glimmer/dsl/swt_expression.rb +23 -0
  37. data/lib/glimmer/dsl/sync_exec_expression.rb +13 -0
  38. data/lib/glimmer/dsl/tab_item_expression.rb +31 -0
  39. data/lib/glimmer/dsl/table_items_data_binding_expression.rb +29 -0
  40. data/lib/glimmer/dsl/tree_items_data_binding_expression.rb +30 -0
  41. data/lib/glimmer/dsl/tree_properties_expression.rb +24 -0
  42. data/lib/glimmer/dsl/widget_expression.rb +26 -0
  43. data/lib/glimmer/dsl/widget_listener_expression.rb +27 -0
  44. data/lib/glimmer/error.rb +6 -0
  45. data/lib/glimmer/invalid_keyword_error.rb +6 -0
  46. data/lib/glimmer/launcher.rb +39 -23
  47. data/lib/glimmer/swt/color_proxy.rb +48 -0
  48. data/lib/glimmer/swt/display_proxy.rb +49 -0
  49. data/lib/glimmer/swt/font_proxy.rb +72 -0
  50. data/lib/glimmer/swt/layout_data_proxy.rb +73 -0
  51. data/lib/glimmer/swt/{g_layout.rb → layout_proxy.rb} +24 -25
  52. data/lib/glimmer/swt/packages.rb +13 -0
  53. data/lib/glimmer/swt/shell_proxy.rb +108 -0
  54. data/lib/glimmer/swt/{g_swt.rb → swt_proxy.rb} +12 -5
  55. data/lib/glimmer/swt/tab_item_proxy.rb +59 -0
  56. data/lib/glimmer/swt/widget_listener_proxy.rb +17 -0
  57. data/lib/glimmer/swt/widget_proxy.rb +366 -0
  58. data/lib/glimmer/{swt → ui}/custom_shell.rb +4 -4
  59. data/lib/glimmer/{swt → ui}/custom_widget.rb +67 -51
  60. data/lib/glimmer/{swt → ui}/video.rb +13 -13
  61. data/lib/glimmer/{swt → util}/proc_tracker.rb +1 -1
  62. data/vendor/swt/linux/swt.jar +0 -0
  63. data/vendor/swt/mac/swt.jar +0 -0
  64. data/vendor/swt/windows/swt.jar +0 -0
  65. metadata +66 -70
  66. data/lib/glimmer/command_handler.rb +0 -15
  67. data/lib/glimmer/command_handler_chain_factory.rb +0 -32
  68. data/lib/glimmer/command_handler_chain_link.rb +0 -25
  69. data/lib/glimmer/command_handlers.rb +0 -46
  70. data/lib/glimmer/ext/module.rb +0 -20
  71. data/lib/glimmer/parent.rb +0 -7
  72. data/lib/glimmer/swt/command_handlers/bind_command_handler.rb +0 -56
  73. data/lib/glimmer/swt/command_handlers/color_command_handler.rb +0 -30
  74. data/lib/glimmer/swt/command_handlers/combo_selection_data_binding_command_handler.rb +0 -44
  75. data/lib/glimmer/swt/command_handlers/custom_widget_command_handler.rb +0 -26
  76. data/lib/glimmer/swt/command_handlers/data_binding_command_handler.rb +0 -40
  77. data/lib/glimmer/swt/command_handlers/display_command_handler.rb +0 -20
  78. data/lib/glimmer/swt/command_handlers/layout_command_handler.rb +0 -27
  79. data/lib/glimmer/swt/command_handlers/layout_data_command_handler.rb +0 -27
  80. data/lib/glimmer/swt/command_handlers/list_selection_data_binding_command_handler.rb +0 -49
  81. data/lib/glimmer/swt/command_handlers/observe_command_handler.rb +0 -35
  82. data/lib/glimmer/swt/command_handlers/property_command_handler.rb +0 -24
  83. data/lib/glimmer/swt/command_handlers/shell_command_handler.rb +0 -20
  84. data/lib/glimmer/swt/command_handlers/tab_item_command_handler.rb +0 -34
  85. data/lib/glimmer/swt/command_handlers/table_column_properties_data_binding_command_handler.rb +0 -29
  86. data/lib/glimmer/swt/command_handlers/table_items_data_binding_command_handler.rb +0 -34
  87. data/lib/glimmer/swt/command_handlers/tree_items_data_binding_command_handler.rb +0 -33
  88. data/lib/glimmer/swt/command_handlers/tree_properties_data_binding_command_handler.rb +0 -29
  89. data/lib/glimmer/swt/command_handlers/widget_command_handler.rb +0 -27
  90. data/lib/glimmer/swt/command_handlers/widget_listener_command_handler.rb +0 -48
  91. data/lib/glimmer/swt/g_color.rb +0 -41
  92. data/lib/glimmer/swt/g_display.rb +0 -36
  93. data/lib/glimmer/swt/g_font.rb +0 -71
  94. data/lib/glimmer/swt/g_layout_data.rb +0 -56
  95. data/lib/glimmer/swt/g_runnable.rb +0 -15
  96. data/lib/glimmer/swt/g_shell.rb +0 -106
  97. data/lib/glimmer/swt/g_tab_item_composite.rb +0 -41
  98. data/lib/glimmer/swt/g_widget.rb +0 -349
  99. data/lib/glimmer/swt/g_widget_listener.rb +0 -12
  100. data/lib/glimmer/swt/list_selection_binding.rb +0 -47
  101. data/lib/glimmer/swt_packages.rb +0 -15
  102. data/lib/glimmer/xml/command_handlers/html_command_handler.rb +0 -50
  103. data/lib/glimmer/xml/command_handlers/xml_command_handler.rb +0 -23
  104. data/lib/glimmer/xml/command_handlers/xml_name_space_command_handler.rb +0 -36
  105. data/lib/glimmer/xml/command_handlers/xml_tag_command_handler.rb +0 -28
  106. data/lib/glimmer/xml/command_handlers/xml_text_command_handler.rb +0 -24
  107. data/lib/glimmer/xml/depth_first_search_iterator.rb +0 -20
  108. data/lib/glimmer/xml/name_space_visitor.rb +0 -21
  109. data/lib/glimmer/xml/node.rb +0 -84
  110. data/lib/glimmer/xml/node_visitor.rb +0 -13
  111. data/lib/glimmer/xml/xml_visitor.rb +0 -63
  112. data/lib/glimmer/xml_command_handlers.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 218ad434685b90c53d096b5ebc117c4eb790f5e724f8bd59d91ea3cc57683b74
4
- data.tar.gz: a4568fdf1521441848af186a804c54c6ac6c3d29ba6ccabb3c1726630d9067d1
3
+ metadata.gz: 3a01513e043e5d19086d90cb571aa4043235a2753b3164413e680591073f6644
4
+ data.tar.gz: 56949c7c670c1864804e5ed28d33f7efddcdca7b0b50d465011b149ca7585969
5
5
  SHA512:
6
- metadata.gz: f0f19afe707d602e34a8c47708b40660fb149061a56e00bf3404d100ee12aab2ac9baaaad8a6fd6247a91fafc818d154848feaab1d14b3fab10c1f0d55a4999c
7
- data.tar.gz: 6f5b8ce1b0562fbef375699f919fbd5cfe3cf746c64f2ef55e4cc50162bfcc4ac33f0d520ec0e8192644ae43e2efaf9fd3155504a1d3140e6dce0b708f2964d6
6
+ metadata.gz: dce0753c615d6c148d7065741463dc3eb95fa3bd437082c757be5ec8569ae812af8ef993fa726a43cdda99e32b748f4201b709c46b10666f78866f27317809f7
7
+ data.tar.gz: 3a764178e11e57d1b8ac15b5089decdc4933846b3392b0e7904511114c2dab1ae0635f77ac6be644e3151723350caee7f248bc9c19ce36c018879deb302a7a38
@@ -1,7 +1,7 @@
1
- # Glimmer 0.4.9 Beta (JRuby Desktop UI DSL + Data-Binding)
1
+ # Glimmer 0.5.0 Beta (JRuby Desktop UI DSL + Data-Binding)
2
2
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
3
3
 
4
- Glimmer is a cross-platform Ruby desktop development library. Glimmer's main innovation is a JRuby DSL that enables easy and efficient authoring of desktop application user-interfaces while relying on the robust platform-independent Eclipse SWT library. Glimmer additionally innovates by having built-in desktop UI data-binding support to greatly facilitate synchronizing the UI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about UI concerns, or alternatively drive development UI-first, and then write clean business components test-first afterward.
4
+ Glimmer is a native-UI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust platform-native Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the UI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about UI concerns, or alternatively drive development UI-first, and then write clean business components test-first afterwards.
5
5
 
6
6
  ## Examples
7
7
 
@@ -14,7 +14,7 @@ include Glimmer
14
14
  shell {
15
15
  text "Glimmer"
16
16
  label {
17
- text "Hello World!"
17
+ text "Hello, World!"
18
18
  }
19
19
  }.open
20
20
  ```
@@ -78,27 +78,31 @@ Glimmer runs on the following platforms:
78
78
  - Windows
79
79
  - Linux
80
80
 
81
- SWT uses Win32 on Windows, Cocoa on Mac, and GTK on Linux according to Eclipse WIKI:
82
-
83
- https://wiki.eclipse.org/SWT/Devel/Gtk/Dev_guide#Win32.2FCocoa.2FGTK
81
+ Glimmer's UI has the native look and feel of each operating system it runs on since it uses SWT behind the scenes, which leverages the following native libraries:
82
+ - Win32 on Windows
83
+ - Cocoa on Mac
84
+ - GTK on Linux
84
85
 
85
- The SWT FAQ has further details:
86
+ More info about the SWT UI on various platforms can be found on the Eclipse WIKI and SWT FAQ:
86
87
 
88
+ https://wiki.eclipse.org/SWT/Devel/Gtk/Dev_guide#Win32.2FCocoa.2FGTK
87
89
  https://www.eclipse.org/swt/faq.php
88
90
 
89
91
 
90
92
  ## Pre-requisites
91
93
 
92
94
  * Java SE Runtime Environment 7 or higher (find at https://www.oracle.com/java/technologies/javase-downloads.html)
93
- * JRuby 9.2.10.0 (supporting Ruby 2.5.x syntax) (find at https://www.jruby.org/download)
94
- * SWT 4.14 (comes included in Glimmer)
95
+ * JRuby 9.2.11.1 (supporting Ruby 2.5.x syntax) (find at https://www.jruby.org/download)
96
+ * SWT 4.15 (comes included in Glimmer gem)
95
97
 
96
98
  On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
97
99
 
98
100
  ```bash
99
- rvm install jruby-9.2.10.0
101
+ rvm install jruby-9.2.11.1
100
102
  ```
101
103
 
104
+ Glimmer might still work on lower versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
105
+
102
106
  ## Setup
103
107
 
104
108
  Please follow these instructions to make the `glimmer` command available on your system.
@@ -107,14 +111,14 @@ Please follow these instructions to make the `glimmer` command available on your
107
111
 
108
112
  Run this command to install directly:
109
113
  ```
110
- jgem install glimmer -v 0.4.9
114
+ jgem install glimmer -v 0.5.0
111
115
  ```
112
116
 
113
117
  ### Option 2: Bundler
114
118
 
115
119
  Add the following to `Gemfile`:
116
120
  ```
117
- gem 'glimmer', '~> 0.4.9'
121
+ gem 'glimmer', '~> 0.5.0'
118
122
  ```
119
123
 
120
124
  And, then run:
@@ -124,7 +128,8 @@ bundle install
124
128
 
125
129
  ## Glimmer Command
126
130
 
127
- Usage:
131
+ ### Basic Usage
132
+
128
133
  ```
129
134
  glimmer application.rb
130
135
  ```
@@ -136,14 +141,69 @@ Example:
136
141
  ```
137
142
  glimmer samples/hello_world.rb
138
143
  ```
139
- This runs the Glimmer application hello_world.rb
144
+ This runs the Glimmer "Hello, World!" sample.
145
+
146
+ If you cloned this project locally, you may run `bin/glimmer` instead.
147
+
148
+ Example:
149
+ ```
150
+ bin/glimmer samples/hello_world.rb
151
+ ```
152
+
153
+ ### Advanced Usage
154
+
155
+ ```
156
+ glimmer [[-jruby-option]...] application.rb [[application2.rb]...]
157
+ ```
158
+
159
+ Accepts JRuby options and multiple Glimmer applications to run simultaneously, each in a JRuby thread.
160
+
161
+ Example (JRuby option):
162
+ ```
163
+ glimmer --debug samples/hello_world.rb
164
+ ```
165
+
166
+ Runs Glimmer application with JRuby debug option to enable JRuby debugging.
167
+
168
+ Example (Multiple apps):
169
+ ```
170
+ glimmer samples/hello_world.rb samples/hello_tab.rb
171
+ ```
172
+
173
+ Launches samples/hello_world.rb and samples/hello_tab.rb at the same time, each in a separate JRuby thread.
140
174
 
141
175
  ## Girb (Glimmer irb) Command
142
176
 
143
177
  With Glimmer installed, you may want to run `girb` instead of standard `irb` to have SWT preloaded and the Glimmer library required and included for quick Glimmer coding/testing.
144
178
 
179
+ ```
180
+ girb
181
+ ```
182
+
183
+ If you cloned this project locally, you may run `bin/girb` instead.
184
+
185
+ ```
186
+ bin/girb
187
+ ```
188
+
145
189
  ## Glimmer DSL Syntax
146
190
 
191
+ Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
192
+
193
+ Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `rgb`, and `bind`.
194
+
195
+ Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `text`.
196
+
197
+ The only reason to distinguish between both types of Glimmer DSL keywords is to realize that importing new Java SWT custom widget libraries and Ruby custom widgets automatically expands Glimmer's available DSL syntax via new dynamic keywords.
198
+
199
+ For example, if a project adds this custom SWT library:
200
+
201
+ https://www.eclipse.org/nebula/widgets/cdatetime/cdatetime.php?page=operation
202
+
203
+ Glimmer will automatically support using the keyword `c_date_time`
204
+
205
+ You will learn more about widgets next.
206
+
147
207
  ### Widgets
148
208
 
149
209
  Glimmer UIs (user interfaces) are modeled with widgets, which are wrappers around the SWT library widgets found here:
@@ -179,7 +239,7 @@ For example, if we were to revisit `samples/hello_world.rb` above (you may copy/
179
239
  shell {
180
240
  text "Glimmer"
181
241
  label {
182
- text "Hello World!"
242
+ text "Hello, World!"
183
243
  }
184
244
  }.open
185
245
  ```
@@ -192,14 +252,14 @@ Note that `shell` instantiates the outer shell **widget**, in other words, the w
192
252
  # ...
193
253
  text "Glimmer" # text property of shell
194
254
  label { # label widget declaration as content of shell
195
- text "Hello World!" # text property of label
255
+ text "Hello, World!" # text property of label
196
256
  }
197
257
  # ...
198
258
  ```
199
259
 
200
260
  The first line declares a **property** called `text`, which sets the title of the shell (window) to `"Glimmer"`. **Properties** always have ***arguments*** (not wrapped by parenthesis according to [Glimmer coding style](#glimmer-coding-style)), such as the text `"Glimmer"` in this case, and do **NOT** have a ***block*** (this distinguishes them from **widget** declarations).
201
261
 
202
- The second line declares the `label` **widget**, which is followed by a Ruby **content** ***block*** that contains its `text` **property** with value `"Hello World!"`
262
+ The second line declares the `label` **widget**, which is followed by a Ruby **content** ***block*** that contains its `text` **property** with value `"Hello, World!"`
203
263
 
204
264
  Note that The `shell` widget is always the outermost widget containing all others in a Glimmer desktop windowed application.
205
265
 
@@ -230,7 +290,7 @@ shell {
230
290
  tab_item {
231
291
  text "Tab 1"
232
292
  label {
233
- text "Hello World!"
293
+ text "Hello, World!"
234
294
  }
235
295
  }
236
296
  tab_item {
@@ -243,9 +303,51 @@ shell {
243
303
  }.open
244
304
  ```
245
305
 
246
- #### `#widget`
306
+ #### SWT Proxies
307
+
308
+ Glimmer follows Proxy Design Pattern by having Ruby proxy wrappers for all SWT objects:
309
+ - `Glimmer::SWT:WidgetProxy` wraps all descendants of `org.eclipse.swt.widgets.Widget` except the ones that have their own wrappers.
310
+ - `Glimmer::SWT::ShellProxy` wraps `org.eclipse.swt.widgets.Shell`
311
+ - `Glimmer::SWT:TabItemProxy` wraps `org.eclipse.swt.widget.TabItem` (also adds a composite to enable adding content under tab items directly in Glimmer)
312
+ - `Glimmer::SWT:LayoutProxy` wraps all descendants of `org.eclipse.swt.widget.Layout`
313
+ - `Glimmer::SWT:LayoutDataProxy` wraps all layout data objects
314
+ - `Glimmer::SWT:DisplayProxy` wraps `org.eclipse.swt.widget.Display` (manages displaying UI)
315
+ - `Glimmer::SWT:ColorProxy` wraps `org.eclipse.swt.graphics.Color`
316
+ - `Glimmer::SWT:FontProxy` wraps `org.eclipse.swt.graphics.Font`
317
+ - `Glimmer::SWT::WidgetListenerProxy` wraps all widget listeners
318
+
319
+ These proxy objects have an API and provide some convenience methods, some of which are mentioned below.
320
+
321
+
322
+ ##### `#content { ... }`
247
323
 
248
- Glimmer widget objects come with an instance method `#widget` that returns the actual SWT `Widget` object wrapped by the Glimmer widget object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
324
+ Glimmer allows re-opening any widget and adding properties or extra content after it has been constructed already by using the `#content` method.
325
+
326
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
327
+
328
+ ```ruby
329
+ @shell = shell {
330
+ text "Application"
331
+ row_layout
332
+ @label1 = label {
333
+ text "Hello,"
334
+ }
335
+ }
336
+ @shell.content {
337
+ minimum_size 130, 130
338
+ label {
339
+ text "World!"
340
+ }
341
+ }
342
+ @label1.content {
343
+ foreground :red
344
+ }
345
+ @shell.open
346
+ ```
347
+
348
+ ##### `#swt_widget`
349
+
350
+ Glimmer widget objects come with an instance method `#swt_widget` that returns the actual SWT `Widget` object wrapped by the Glimmer widget object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
249
351
 
250
352
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
251
353
 
@@ -264,6 +366,19 @@ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
264
366
  @shell.open
265
367
  ```
266
368
 
369
+ ##### Shell widget proxy methods
370
+
371
+ Shell widget proxy has extra methods specific to SWT Shell:
372
+ - `#open`: Opens the shell, making it visible and active, and starting the SWT Event Loop (you may learn more about it here: https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/Display.html). If shell was already open, but hidden, it makes the shell visible.
373
+ - `#show`: Alias for `#open`
374
+ - `#hide`: Hides a shell setting "visible" property to false
375
+ - `#close`: Closes the shell
376
+ - `#center`: Centers the shell within monitor it is in
377
+ - `#start_event_loop`: (happens as part of `#open`) Starts SWT Event Loop (you may learn more about it here: https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/Display.html). This method is not needed except in rare circumstances where there is a need to start the SWT Event Loop before opening the shell.
378
+ - `#visible?`: Returns whether a shell is visible
379
+ - `#opened_before?`: Returns whether a shell has been opened at least once before (additionally implying the SWT Event Loop has been started already)
380
+ - `#visible=`: Setting to true opens/shows shell. Setting to false hides the shell.
381
+
267
382
  ### Widget Styles
268
383
 
269
384
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -322,11 +437,11 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
322
437
 
323
438
  When building a widget-related SWT object manually (e.g. `GridData.new(...)`), you are expected to use `SWT::CONSTANT` directly or BIT-OR a few SWT constants together like `SWT::BORDER | SWT::V_SCROLL`.
324
439
 
325
- Glimmer facilitates that with `GSWT` class by allowing you to pass multiple styles as an argument array of symbols instead of dealing with BIT-OR. For example: `GSWT[:border, :v_scroll]`
440
+ Glimmer facilitates that with `SWTProxy` class by allowing you to pass multiple styles as an argument array of symbols instead of dealing with BIT-OR. For example: `SWTProxy[:border, :v_scroll]`
326
441
 
327
442
  #### Non-resizable Window
328
443
 
329
- SWT Shell widget by default is resizable. To make it non-resizable, one must pass a complicated style bit concoction like `GSWT[:shell_trim] & (~GSWT[:resize]) & (~GSWT[:max])`.
444
+ SWT Shell widget by default is resizable. To make it non-resizable, one must pass a complicated style bit concoction like `SWTProxy[:shell_trim] & (~SWTProxy[:resize]) & (~SWTProxy[:max])`.
330
445
 
331
446
  Glimmer makes this easier by alternatively offering `:no_resize` extra SWT style, added for convenience. This makes declaring an non-resizable window as easy as:
332
447
  ```ruby
@@ -347,12 +462,12 @@ Code examples:
347
462
  ```ruby
348
463
  # ...
349
464
  label {
350
- text "Hello World!" # SWT properties go inside {} block
465
+ text "Hello, World!" # SWT properties go inside {} block
351
466
  }
352
467
  # ...
353
468
  ```
354
469
 
355
- In the above example, the `label` widget `text` property was set to "Hello World!".
470
+ In the above example, the `label` widget `text` property was set to "Hello, World!".
356
471
 
357
472
  ```ruby
358
473
  # ...
@@ -403,13 +518,13 @@ You may check out all available standard colors in `SWT` over here (having `COLO
403
518
  https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
404
519
 
405
520
 
406
- ##### `#color`
521
+ ##### `#swt_color`
407
522
 
408
- Glimmer color objects come with an instance method `#color` that returns the actual SWT `Color` object wrapped by the Glimmer color object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
523
+ Glimmer color objects come with an instance method `#swt_color` that returns the actual SWT `Color` object wrapped by the Glimmer color object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
409
524
 
410
- ##### `GColor.color_for(display = nil, standard_color)`
525
+ ##### `Glimmer::SWT::ColorProxy.new(display = nil, standard_color).swt_color`
411
526
 
412
- Glimmer `GColor` class comes with `.color_for` method that builds an actual SWT `Color` object from a standard color string or symbol. Passing a `display` is optional. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
527
+ Glimmer `ColorProxy` class comes with `.color_for` method that builds an actual SWT `Color` object from a standard color string or symbol. Passing a `display` is optional. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
413
528
 
414
529
  #### Fonts
415
530
 
@@ -605,7 +720,7 @@ composite {
605
720
  grid_layout 3, false # grid layout with 3 columns not of equal width
606
721
  label {
607
722
  # layout data set explicitly via an object (helps in rare cases that break convention)
608
- layout_data GridData.new(GSWT[:fill], GSWT[:end], true, false)
723
+ layout_data GridData.new(SWTProxy[:fill], SWTProxy[:end], true, false)
609
724
  }
610
725
  }
611
726
  # ...
@@ -906,7 +1021,7 @@ class TicTacToe
906
1021
  end
907
1022
  ```
908
1023
 
909
- Alternatively, one can use a default Observer::Proc implementation via Observer.proc method:
1024
+ Alternatively, one can use a default Observer.proc implementation via Observer.proc method:
910
1025
  ```ruby
911
1026
  observer = Observer.proc { |new_value| puts new_value }
912
1027
  observer.observe(@tic_tac_toe_board, :game_status)
@@ -954,20 +1069,20 @@ end
954
1069
 
955
1070
  Glimmer supports creating custom widgets with minimal code, which automatically extends Glimmer's DSL syntax with an underscored lowercase keyword.
956
1071
 
957
- Simply create a new class that includes `Glimmer::SWT::CustomWidget` and put Glimmer DSL code in its `#body` method (its return value is stored in `#body_root` attribute). Glimmer will then automatically recognize this class by convention when it encounters a keyword matching the class name converted to underscored lowercase (and namespace double-colons `::` replaced with double-underscores `__`)
1072
+ Simply create a new class that includes `Glimmer::UI::CustomWidget` and put Glimmer DSL code in its `#body` block (its return value is stored in `#body_root` attribute). Glimmer will then automatically recognize this class by convention when it encounters a keyword matching the class name converted to underscored lowercase (and namespace double-colons `::` replaced with double-underscores `__`)
958
1073
 
959
1074
  #### Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
960
1075
 
961
1076
  Definition:
962
1077
  ```ruby
963
1078
  class RedLabel
964
- include Glimmer::SWT::CustomWidget
1079
+ include Glimmer::UI::CustomWidget
965
1080
 
966
- def body
1081
+ body {
967
1082
  label(swt_style) {
968
1083
  background :red
969
1084
  }
970
- end
1085
+ }
971
1086
  end
972
1087
  ```
973
1088
 
@@ -988,13 +1103,17 @@ Definition:
988
1103
  ```ruby
989
1104
  module Red
990
1105
  class Composite
991
- include Glimmer::SWT::CustomWidget
1106
+ include Glimmer::UI::CustomWidget
1107
+
1108
+ before_body {
1109
+ @color = :red
1110
+ }
992
1111
 
993
- def body
1112
+ body {
994
1113
  composite(swt_style) {
995
- background :red
1114
+ background @color
996
1115
  }
997
- end
1116
+ }
998
1117
  end
999
1118
  end
1000
1119
  ```
@@ -1011,13 +1130,15 @@ shell {
1011
1130
  }.open
1012
1131
  ```
1013
1132
 
1014
- Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention.
1133
+ Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention. Additionally, `before_body` hook was utilized to set a `@color` variable and use inside the `body`.
1015
1134
 
1016
1135
  Custom Widgets have the following attributes (attribute readers) available to call from inside the `#body` method:
1017
1136
  - `#parent`: Glimmer object parenting custom widget
1018
1137
  - `#swt_style`: SWT style integer. Can be useful if you want to allow consumers to customize a widget inside the custom widget body
1019
1138
  - `#options`: a hash of options passed in parentheses when declaring a custom widget (useful for passing in model data) (e.g. `calendar(events: events)`). Custom widget class can declare option names (array) with `.options` method as shown below, which generates attribute readers for every option (not to be confused with `#options` instance method for retrieving options hash containing names & values)
1020
1139
  - `#content`: nested block underneath custom widget. It will be automatically called at the end of processing the custom widget body. Alternatively, the custom widget body may call `content.call` at the place where the content is needed to show up as shown in the following example.
1140
+ - `#body_root`: top-most (root) widget returned from `#body` method.
1141
+ - `#swt_widget`: actual SWT widget for `body_root`
1021
1142
 
1022
1143
  Additionally, custom widgets can call the following class methods:
1023
1144
  - `.options`: declares a list of options by taking an option name array (symbols/strings). This generates option attribute readers (e.g. `options :orientation, :bg_color` generates `#orientation` and `#bg_color` attribute readers)
@@ -1028,12 +1149,12 @@ Additionally, custom widgets can call the following class methods:
1028
1149
  Definition:
1029
1150
  ```ruby
1030
1151
  class Sandwich
1031
- include Glimmer::SWT::CustomWidget
1152
+ include Glimmer::UI::CustomWidget
1032
1153
 
1033
1154
  options :orientation, :bg_color
1034
1155
  option :fg_color, :black
1035
1156
 
1036
- def body
1157
+ body {
1037
1158
  composite(swt_style) { # gets custom widget style
1038
1159
  fill_layout orientation # using orientation option
1039
1160
  background bg_color # using container_background option
@@ -1045,7 +1166,7 @@ class Sandwich
1045
1166
  text 'SANDWICH BOTTOM'
1046
1167
  }
1047
1168
  }
1048
- end
1169
+ }
1049
1170
  end
1050
1171
  ```
1051
1172
 
@@ -1063,9 +1184,139 @@ shell {
1063
1184
 
1064
1185
  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'`
1065
1186
 
1066
- The following additional attributes may be called from outside a custom widget in addition to the attributes mentioned above, assuming it's been captured in a variable:
1067
- - `#body_root`: top-most root Glimmer widget returned in `#body` method
1068
- - `#widget`: actual SWT widget for `body_root`
1187
+ Last but not least, these are the available hooks:
1188
+ - `before_body`: takes a block that executes in the custom widget instance scope before calling `body`. Useful for initializing variables to later use in `body`
1189
+ - `after_body`: takes a block that executes in the custom widget instance scope after calling `body`. Useful for setting up observers on widgets built in `body` (set in instance variables) and linking to other shells.
1190
+
1191
+ ### Custom Shells
1192
+
1193
+ 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.
1194
+
1195
+ They may also be chained in a wizard fashion.
1196
+
1197
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1198
+
1199
+ ```ruby
1200
+ class WizardStep
1201
+ include Glimmer::UI::CustomShell
1202
+
1203
+ options :number, :step_count
1204
+
1205
+ before_body {
1206
+ @title = "Step #{number}"
1207
+ }
1208
+
1209
+ body {
1210
+ shell {
1211
+ text "Wizard - #{@title}"
1212
+ minimum_size 200, 100
1213
+ fill_layout :vertical
1214
+ label(:center) {
1215
+ text @title
1216
+ font height: 30
1217
+ }
1218
+ if number < step_count
1219
+ button {
1220
+ text "Go To Next Step"
1221
+ on_widget_selected {
1222
+ body_root.hide
1223
+ }
1224
+ }
1225
+ end
1226
+ }
1227
+ }
1228
+ end
1229
+
1230
+ shell { |app_shell|
1231
+ text "Wizard"
1232
+ minimum_size 200, 100
1233
+ @current_step_number = 1
1234
+ @wizard_steps = 5.times.map { |n|
1235
+ wizard_step(number: n+1, step_count: 5) {
1236
+ on_event_hide {
1237
+ if @current_step_number < 5
1238
+ @current_step_number += 1
1239
+ app_shell.hide
1240
+ @wizard_steps[@current_step_number - 1].open
1241
+ end
1242
+ }
1243
+ }
1244
+ }
1245
+ button {
1246
+ text "Start"
1247
+ font height: 40
1248
+ on_widget_selected {
1249
+ app_shell.hide
1250
+ @wizard_steps[@current_step_number - 1].open
1251
+ }
1252
+ }
1253
+ }.open
1254
+ ```
1255
+
1256
+ ### Custom Shells
1257
+
1258
+ 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.
1259
+
1260
+ They may also be chained in a wizard fashion.
1261
+
1262
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1263
+
1264
+ ```ruby
1265
+ class WizardStep
1266
+ include Glimmer::UI::CustomShell
1267
+
1268
+ options :number, :step_count
1269
+
1270
+ before_body {
1271
+ @title = "Step #{number}"
1272
+ }
1273
+
1274
+ body {
1275
+ shell {
1276
+ text "Wizard - #{@title}"
1277
+ minimum_size 200, 100
1278
+ fill_layout :vertical
1279
+ label(:center) {
1280
+ text @title
1281
+ font height: 30
1282
+ }
1283
+ if number < step_count
1284
+ button {
1285
+ text "Go To Next Step"
1286
+ on_widget_selected {
1287
+ body_root.hide
1288
+ }
1289
+ }
1290
+ end
1291
+ }
1292
+ }
1293
+ end
1294
+
1295
+ shell { |app_shell|
1296
+ text "Wizard"
1297
+ minimum_size 200, 100
1298
+ @current_step_number = 1
1299
+ @wizard_steps = 5.times.map { |n|
1300
+ wizard_step(number: n+1, step_count: 5) {
1301
+ on_event_hide {
1302
+ if @current_step_number < 5
1303
+ @current_step_number += 1
1304
+ app_shell.hide
1305
+ @wizard_steps[@current_step_number - 1].open
1306
+ end
1307
+ }
1308
+ }
1309
+ }
1310
+ button {
1311
+ text "Start"
1312
+ font height: 40
1313
+ on_widget_selected {
1314
+ app_shell.hide
1315
+ @wizard_steps[@current_step_number - 1].open
1316
+ }
1317
+ }
1318
+ }.open
1319
+ ```
1069
1320
 
1070
1321
  ### Miscellaneous
1071
1322
 
@@ -1149,19 +1400,20 @@ shell {
1149
1400
 
1150
1401
  - Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
1151
1402
  - Widget declarations may optionally have arguments and be followed by a block (to contain properties and content)
1152
- - Widget blocks are always declared with curly brackets
1403
+ - Widget blocks are always declared with curly braces
1153
1404
  - Widget arguments are always wrapped inside parentheses
1154
1405
  - Widget properties are declared with underscored lowercase versions of the SWT properties
1155
1406
  - Widget property declarations always have arguments and never take a block
1156
1407
  - Widget property arguments are never wrapped inside parentheses
1157
1408
  - Widget listeners are always declared starting with `on_` prefix and affixing listener event method name afterwards in underscored lowercase form
1158
- - Widget listeners are always followed by a block using curly brackets
1409
+ - Widget listeners are always followed by a block using curly braces (Only when declared in DSL. When invoked on widget object directly outside of UI declarations, standard Ruby conventions apply)
1159
1410
  - Data-binding is done via `bind` keyword, which always takes arguments wrapped in parentheses
1411
+ - Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
1160
1412
  - 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.
1161
1413
 
1162
1414
  ## Samples
1163
1415
 
1164
- Check the [samples](samples) directory 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` 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 --dev`).
1416
+ Check the [samples](samples) directory 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` 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`).
1165
1417
 
1166
1418
  Examples:
1167
1419
 
@@ -1207,24 +1459,37 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
1207
1459
 
1208
1460
  Glimmer automatically imports all SWT Java packages upon adding `include Glimmer` to a class or module.
1209
1461
 
1210
- Still, if you'd like to import manually elsewhere, you may add the following lines to your code (in the class or module body) to import SWT Java packages using `include_package`:
1211
-
1212
- ```ruby
1213
- include_package 'org.eclipse.swt'
1214
- include_package 'org.eclipse.swt.widgets'
1215
- include_package 'org.eclipse.swt.layout'
1216
- include_package 'org.eclipse.swt.graphics'
1462
+ Here are the Java packages imported:
1463
+ ```
1464
+ org.eclipse.swt.*
1465
+ org.eclipse.swt.widgets.*
1466
+ org.eclipse.swt.layout.*
1467
+ org.eclipse.swt.graphics.*
1468
+ org.eclipse.swt.browser.*
1469
+ org.eclipse.swt.custom.*
1217
1470
  ```
1218
1471
 
1219
- To import a specific SWT Java class using `java_import`, add the following:
1472
+ This allows you to call SWT Java classes from Ruby without mentioning Java package references.
1473
+
1474
+ For example, after imports, `org.eclipse.swt.graphics.Color` can be referenced by just `Color`
1475
+
1476
+ Nonetheless, you can disable automatic import if needed via this Glimmer configuration option:
1220
1477
 
1221
1478
  ```ruby
1222
- java_import 'org.eclipse.swt.SWT'
1479
+ Glimmer.import_swt_packages = false
1223
1480
  ```
1224
1481
 
1225
- This allows you to call SWT Java classes from Ruby without mentioning package namespaces.
1482
+ To import SWT Java packages manually instead, you have 2 options:
1226
1483
 
1227
- For example, after imports, `org.eclipse.swt.graphics.Color` can be referenced by just `Color`
1484
+ 1. `include Glimmer::SwtPackages`: lazily imports all SWT Java packages to your class, lazy-loading SWT Java class constants on first reference.
1485
+
1486
+ 2. `java_import swt_package_class_string`: immediately imports a specific Java class where `swt_package_class_string` is the Java full package reference of a Java class (e.g. `java_import 'org.eclipse.swt.SWT'`)
1487
+
1488
+ Note: Glimmer relies on [`nested_imported_jruby_include_package`](https://github.com/AndyObtiva/nested_inherited_jruby_include_package), which automatically brings packages to nested-modules/nested-classes and sub-modules/sub-classes.
1489
+
1490
+ You can learn more about importing Java packages into Ruby code at this JRuby WIKI page:
1491
+
1492
+ https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
1228
1493
 
1229
1494
  ## Logging
1230
1495