glimmer 0.4.9 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +324 -59
- data/lib/glimmer.rb +54 -63
- data/lib/glimmer/data_binding/list_selection_binding.rb +52 -0
- data/lib/glimmer/{swt → data_binding}/model_binding.rb +33 -5
- data/lib/glimmer/{swt → data_binding}/observable.rb +6 -3
- data/lib/glimmer/{swt → data_binding}/observable_array.rb +3 -1
- data/lib/glimmer/{swt → data_binding}/observable_model.rb +3 -2
- data/lib/glimmer/data_binding/observable_widget.rb +17 -0
- data/lib/glimmer/{swt → data_binding}/observer.rb +3 -3
- data/lib/glimmer/{shine.rb → data_binding/shine.rb} +2 -2
- data/lib/glimmer/{swt → data_binding}/table_items_binding.rb +12 -11
- data/lib/glimmer/{swt → data_binding}/tree_items_binding.rb +15 -12
- data/lib/glimmer/{swt → data_binding}/widget_binding.rb +2 -1
- data/lib/glimmer/dsl.rb +26 -0
- data/lib/glimmer/dsl/async_exec_expression.rb +12 -0
- data/lib/glimmer/dsl/bind_expression.rb +44 -0
- data/lib/glimmer/dsl/color_expression.rb +28 -0
- data/lib/glimmer/dsl/column_properties_expression.rb +22 -0
- data/lib/glimmer/dsl/combo_selection_data_binding_expression.rb +40 -0
- data/lib/glimmer/dsl/custom_widget_expression.rb +35 -0
- data/lib/glimmer/dsl/data_binding_expression.rb +33 -0
- data/lib/glimmer/dsl/display_expression.rb +12 -0
- data/lib/glimmer/dsl/engine.rb +80 -0
- data/lib/glimmer/dsl/exec_expression.rb +23 -0
- data/lib/glimmer/dsl/expression.rb +44 -0
- data/lib/glimmer/dsl/expression_handler.rb +48 -0
- data/lib/glimmer/dsl/layout_data_expression.rb +24 -0
- data/lib/glimmer/dsl/layout_expression.rb +26 -0
- data/lib/glimmer/dsl/list_selection_data_binding_expression.rb +42 -0
- data/lib/glimmer/dsl/observe_expression.rb +27 -0
- data/lib/glimmer/dsl/parent_expression.rb +12 -0
- data/lib/glimmer/dsl/property_expression.rb +20 -0
- data/lib/glimmer/dsl/shell_expression.rb +15 -0
- data/lib/glimmer/dsl/static_expression.rb +38 -0
- data/lib/glimmer/dsl/swt_expression.rb +23 -0
- data/lib/glimmer/dsl/sync_exec_expression.rb +13 -0
- data/lib/glimmer/dsl/tab_item_expression.rb +31 -0
- data/lib/glimmer/dsl/table_items_data_binding_expression.rb +29 -0
- data/lib/glimmer/dsl/tree_items_data_binding_expression.rb +30 -0
- data/lib/glimmer/dsl/tree_properties_expression.rb +24 -0
- data/lib/glimmer/dsl/widget_expression.rb +26 -0
- data/lib/glimmer/dsl/widget_listener_expression.rb +27 -0
- data/lib/glimmer/error.rb +6 -0
- data/lib/glimmer/invalid_keyword_error.rb +6 -0
- data/lib/glimmer/launcher.rb +39 -23
- data/lib/glimmer/swt/color_proxy.rb +48 -0
- data/lib/glimmer/swt/display_proxy.rb +49 -0
- data/lib/glimmer/swt/font_proxy.rb +72 -0
- data/lib/glimmer/swt/layout_data_proxy.rb +73 -0
- data/lib/glimmer/swt/{g_layout.rb → layout_proxy.rb} +24 -25
- data/lib/glimmer/swt/packages.rb +13 -0
- data/lib/glimmer/swt/shell_proxy.rb +108 -0
- data/lib/glimmer/swt/{g_swt.rb → swt_proxy.rb} +12 -5
- data/lib/glimmer/swt/tab_item_proxy.rb +59 -0
- data/lib/glimmer/swt/widget_listener_proxy.rb +17 -0
- data/lib/glimmer/swt/widget_proxy.rb +366 -0
- data/lib/glimmer/{swt → ui}/custom_shell.rb +4 -4
- data/lib/glimmer/{swt → ui}/custom_widget.rb +67 -51
- data/lib/glimmer/{swt → ui}/video.rb +13 -13
- data/lib/glimmer/{swt → util}/proc_tracker.rb +1 -1
- data/vendor/swt/linux/swt.jar +0 -0
- data/vendor/swt/mac/swt.jar +0 -0
- data/vendor/swt/windows/swt.jar +0 -0
- metadata +66 -70
- data/lib/glimmer/command_handler.rb +0 -15
- data/lib/glimmer/command_handler_chain_factory.rb +0 -32
- data/lib/glimmer/command_handler_chain_link.rb +0 -25
- data/lib/glimmer/command_handlers.rb +0 -46
- data/lib/glimmer/ext/module.rb +0 -20
- data/lib/glimmer/parent.rb +0 -7
- data/lib/glimmer/swt/command_handlers/bind_command_handler.rb +0 -56
- data/lib/glimmer/swt/command_handlers/color_command_handler.rb +0 -30
- data/lib/glimmer/swt/command_handlers/combo_selection_data_binding_command_handler.rb +0 -44
- data/lib/glimmer/swt/command_handlers/custom_widget_command_handler.rb +0 -26
- data/lib/glimmer/swt/command_handlers/data_binding_command_handler.rb +0 -40
- data/lib/glimmer/swt/command_handlers/display_command_handler.rb +0 -20
- data/lib/glimmer/swt/command_handlers/layout_command_handler.rb +0 -27
- data/lib/glimmer/swt/command_handlers/layout_data_command_handler.rb +0 -27
- data/lib/glimmer/swt/command_handlers/list_selection_data_binding_command_handler.rb +0 -49
- data/lib/glimmer/swt/command_handlers/observe_command_handler.rb +0 -35
- data/lib/glimmer/swt/command_handlers/property_command_handler.rb +0 -24
- data/lib/glimmer/swt/command_handlers/shell_command_handler.rb +0 -20
- data/lib/glimmer/swt/command_handlers/tab_item_command_handler.rb +0 -34
- data/lib/glimmer/swt/command_handlers/table_column_properties_data_binding_command_handler.rb +0 -29
- data/lib/glimmer/swt/command_handlers/table_items_data_binding_command_handler.rb +0 -34
- data/lib/glimmer/swt/command_handlers/tree_items_data_binding_command_handler.rb +0 -33
- data/lib/glimmer/swt/command_handlers/tree_properties_data_binding_command_handler.rb +0 -29
- data/lib/glimmer/swt/command_handlers/widget_command_handler.rb +0 -27
- data/lib/glimmer/swt/command_handlers/widget_listener_command_handler.rb +0 -48
- data/lib/glimmer/swt/g_color.rb +0 -41
- data/lib/glimmer/swt/g_display.rb +0 -36
- data/lib/glimmer/swt/g_font.rb +0 -71
- data/lib/glimmer/swt/g_layout_data.rb +0 -56
- data/lib/glimmer/swt/g_runnable.rb +0 -15
- data/lib/glimmer/swt/g_shell.rb +0 -106
- data/lib/glimmer/swt/g_tab_item_composite.rb +0 -41
- data/lib/glimmer/swt/g_widget.rb +0 -349
- data/lib/glimmer/swt/g_widget_listener.rb +0 -12
- data/lib/glimmer/swt/list_selection_binding.rb +0 -47
- data/lib/glimmer/swt_packages.rb +0 -15
- data/lib/glimmer/xml/command_handlers/html_command_handler.rb +0 -50
- data/lib/glimmer/xml/command_handlers/xml_command_handler.rb +0 -23
- data/lib/glimmer/xml/command_handlers/xml_name_space_command_handler.rb +0 -36
- data/lib/glimmer/xml/command_handlers/xml_tag_command_handler.rb +0 -28
- data/lib/glimmer/xml/command_handlers/xml_text_command_handler.rb +0 -24
- data/lib/glimmer/xml/depth_first_search_iterator.rb +0 -20
- data/lib/glimmer/xml/name_space_visitor.rb +0 -21
- data/lib/glimmer/xml/node.rb +0 -84
- data/lib/glimmer/xml/node_visitor.rb +0 -13
- data/lib/glimmer/xml/xml_visitor.rb +0 -63
- data/lib/glimmer/xml_command_handlers.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a01513e043e5d19086d90cb571aa4043235a2753b3164413e680591073f6644
|
4
|
+
data.tar.gz: 56949c7c670c1864804e5ed28d33f7efddcdca7b0b50d465011b149ca7585969
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dce0753c615d6c148d7065741463dc3eb95fa3bd437082c757be5ec8569ae812af8ef993fa726a43cdda99e32b748f4201b709c46b10666f78866f27317809f7
|
7
|
+
data.tar.gz: 3a764178e11e57d1b8ac15b5089decdc4933846b3392b0e7904511114c2dab1ae0635f77ac6be644e3151723350caee7f248bc9c19ce36c018879deb302a7a38
|
data/README.markdown
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# Glimmer 0.
|
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
|
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
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
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.
|
94
|
-
* SWT 4.
|
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.
|
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.
|
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.
|
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
|
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
|
-
####
|
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
|
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 `
|
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 `
|
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
|
-
##### `#
|
521
|
+
##### `#swt_color`
|
407
522
|
|
408
|
-
Glimmer color objects come with an instance method `#
|
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
|
-
##### `
|
525
|
+
##### `Glimmer::SWT::ColorProxy.new(display = nil, standard_color).swt_color`
|
411
526
|
|
412
|
-
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(
|
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
|
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::
|
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::
|
1079
|
+
include Glimmer::UI::CustomWidget
|
965
1080
|
|
966
|
-
|
1081
|
+
body {
|
967
1082
|
label(swt_style) {
|
968
1083
|
background :red
|
969
1084
|
}
|
970
|
-
|
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::
|
1106
|
+
include Glimmer::UI::CustomWidget
|
1107
|
+
|
1108
|
+
before_body {
|
1109
|
+
@color = :red
|
1110
|
+
}
|
992
1111
|
|
993
|
-
|
1112
|
+
body {
|
994
1113
|
composite(swt_style) {
|
995
|
-
background
|
1114
|
+
background @color
|
996
1115
|
}
|
997
|
-
|
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::
|
1152
|
+
include Glimmer::UI::CustomWidget
|
1032
1153
|
|
1033
1154
|
options :orientation, :bg_color
|
1034
1155
|
option :fg_color, :black
|
1035
1156
|
|
1036
|
-
|
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
|
-
|
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
|
-
|
1067
|
-
-
|
1068
|
-
-
|
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
|
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
|
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
|
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
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
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
|
-
|
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
|
-
|
1479
|
+
Glimmer.import_swt_packages = false
|
1223
1480
|
```
|
1224
1481
|
|
1225
|
-
|
1482
|
+
To import SWT Java packages manually instead, you have 2 options:
|
1226
1483
|
|
1227
|
-
|
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
|
|