glimmer-dsl-swt 4.18.4.9 → 4.18.4.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +3 -3
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +50 -42
- data/docs/reference/GLIMMER_SAMPLES.md +15 -1
- data/glimmer-dsl-swt.gemspec +3 -2
- data/lib/glimmer/data_binding/widget_binding.rb +16 -3
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +2 -1
- data/lib/glimmer/dsl/swt/shell_expression.rb +4 -1
- data/lib/glimmer/swt/shell_proxy.rb +2 -0
- data/lib/glimmer/swt/swt_proxy.rb +1 -0
- data/lib/glimmer/swt/widget_proxy.rb +15 -3
- data/lib/glimmer/ui/custom_shell.rb +3 -3
- data/samples/elaborate/mandelbrot_fractal.rb +78 -16
- data/samples/hello/hello_progress_bar.rb +127 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f06f3cbda7f10f81702dcdff893c91f4b7e381d5e7309c34786993e7000d8fc0
|
4
|
+
data.tar.gz: d08c04bababf1eb91a6a137ca725a082d66ec2479c71e0ef3f093dd472c68616
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95fbd9e1be14bf90eb36fd92b6e0d86c3a4a3848c1451f1b17234a8fb3521e544c0893d423c04f32bf750c538b6972969407a8ab6fa84e6a3d9ff0181c3fb144
|
7
|
+
data.tar.gz: 32ddd1acf980524c63fef1722ad1f006cf84d08bd1496b387cd0e6a180dd517b920fc458df34c58b2ac489f2c9b48b6a430a1891a21d9789219e965dc86c8f2b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.4.10
|
4
|
+
|
5
|
+
- Hello, Progress Bar!
|
6
|
+
- Alias shell as window, Glimmer::UI::CustomShell as Glimmer::UI::CustomWindow, on_shell_xyz events as on_window_xyz events, and :shell_trim SWT style as :window_trim SWT Glimmer custom style
|
7
|
+
- `bind` option of `async_exec` or `sync_exec` (e.g. `bind(model, :property, async_exec: true)`) to perform GUI updates from another thread safely
|
8
|
+
- Show progress bar for Mandelbrot calculation
|
9
|
+
- Mandelbrot Cores menu options to switch the number of CPU cores being used for calculation on the next zoom calculation cycle
|
10
|
+
|
3
11
|
### 4.18.4.9
|
4
12
|
|
5
13
|
- Hello, Cursor! Sample
|
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.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.4.10
|
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)
|
@@ -342,7 +342,7 @@ jgem install glimmer-dsl-swt
|
|
342
342
|
|
343
343
|
Or this command if you want a specific version:
|
344
344
|
```
|
345
|
-
jgem install glimmer-dsl-swt -v 4.18.4.
|
345
|
+
jgem install glimmer-dsl-swt -v 4.18.4.10
|
346
346
|
```
|
347
347
|
|
348
348
|
`jgem` is JRuby's version of `gem` command.
|
@@ -360,7 +360,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
360
360
|
|
361
361
|
Add the following to `Gemfile`:
|
362
362
|
```
|
363
|
-
gem 'glimmer-dsl-swt', '~> 4.18.4.
|
363
|
+
gem 'glimmer-dsl-swt', '~> 4.18.4.10'
|
364
364
|
```
|
365
365
|
|
366
366
|
And, then run:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.18.4.
|
1
|
+
4.18.4.10
|
@@ -201,60 +201,60 @@ https://www.eclipse.org/nebula/
|
|
201
201
|
This is not an exaustive list, but should give you a good start in learning Glimmer GUI DSL keywords, keeping in mind that the full list can be derived from the [SWT documentation](https://www.eclipse.org/swt/widgets/). More will be explained in the following sections.
|
202
202
|
|
203
203
|
**Widgets:**
|
204
|
-
- `button`: featured in [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Message Box!](#hello-message-box) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login)
|
205
|
-
- `browser`: featured in [Hello, Browser!](#hello-browser)
|
206
|
-
- `calendar`: featured in [Hello, Date Time!](#hello-date-time)
|
207
|
-
- `checkbox`: featured in [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox)
|
208
|
-
- `checkbox_group`: featured in [Hello, Checkbox Group!](#hello-checkbox-group)
|
209
|
-
- `combo`: featured in [Hello, Table!](#hello-table) / [Hello, Combo!](#hello-combo)
|
210
|
-
- `composite`: featured in [Hello, Radio!](#hello-radio) / [Hello, Computed!](#hello-computed) / [Hello, Checkbox!](#hello-checkbox) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login) / [Contact Manager](#contact-manager)
|
211
|
-
- `date`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Shell!](#hello-custom-shell) / [Tic Tac Toe](#tic-tac-toe)
|
212
|
-
- `date_drop_down`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time)
|
213
|
-
- `group`: featured in [Hello, Group!](#hello-group) / [Contact Manager](#contact-manager)
|
214
|
-
- `label`: featured in [Hello, Computed!](#hello-computed) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, World!](#hello-world) / [Hello, Table!](#hello-table) / [Hello, Tab!](#hello-tab) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager) / [Login](#login)
|
215
|
-
- `list` (w/ optional `:multi` SWT style): featured in [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Contact Manager](#contact-manager)
|
216
|
-
- `menu`: featured in [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Table!](#hello-table)
|
217
|
-
- `menu_bar`: featured in [Hello, Menu Bar!](#hello-menu-bar)
|
218
|
-
- `menu_item`: featured in [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar)
|
219
|
-
- `message_box`: featured in [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Message Box!](#hello-message-box) / [Hello, Menu Bar!](#hello-menu-bar)
|
220
|
-
- `radio`: featured in [Hello, Radio!](#hello-radio) / [Hello, Group!](#hello-group)
|
221
|
-
- `radio_group`: featured in [Hello, Radio Group!](#hello-radio-group)
|
204
|
+
- `button`: featured in [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, Button!](GLIMMER_SAMPLES.md#hello-button) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Message Box!](GLIMMER_SAMPLES.md#hello-message-box) / [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe) / [Login](GLIMMER_SAMPLES.md#login)
|
205
|
+
- `browser`: featured in [Hello, Browser!](GLIMMER_SAMPLES.md#hello-browser)
|
206
|
+
- `calendar`: featured in [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
|
207
|
+
- `checkbox`: featured in [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox)
|
208
|
+
- `checkbox_group`: featured in [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group)
|
209
|
+
- `combo`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo)
|
210
|
+
- `composite`: featured in [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe) / [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
211
|
+
- `date`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
212
|
+
- `date_drop_down`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
|
213
|
+
- `group`: featured in [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
214
|
+
- `label`: featured in [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, World!](GLIMMER_SAMPLES.md#hello-world) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Login](GLIMMER_SAMPLES.md#login)
|
215
|
+
- `list` (w/ optional `:multi` SWT style): featured in [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
216
|
+
- `menu`: featured in [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table)
|
217
|
+
- `menu_bar`: featured in [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
|
218
|
+
- `menu_item`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
|
219
|
+
- `message_box`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Message Box!](GLIMMER_SAMPLES.md#hello-message-box) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
|
220
|
+
- `radio`: featured in [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group)
|
221
|
+
- `radio_group`: featured in [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group)
|
222
222
|
- `scrolled_composite`
|
223
|
-
- `shell`: featured in [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Tab!](#hello-tab) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe) / [Login](#login)
|
224
|
-
- `tab_folder`: featured in [Hello, Tab!](#hello-tab)
|
225
|
-
- `tab_item`: featured in [Hello, Tab!](#hello-tab)
|
226
|
-
- `table`: featured in [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Table!](#hello-table) / [Contact Manager](#contact-manager)
|
227
|
-
- `table_column`: featured in [Hello, Table!](#hello-table) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager)
|
228
|
-
- `text`: featured in [Hello, Computed!](#hello-computed) / [Login](#login) / [Contact Manager](#contact-manager)
|
229
|
-
- `time`: featured in [Hello, Table!](#hello-table) / [Hello, Date Time!](#hello-date-time)
|
230
|
-
- Glimmer::UI::CustomWidget: ability to define any keyword as a custom widget - featured in [Hello, Custom Widget!](#hello-custom-widget)
|
231
|
-
- Glimmer::UI::CustomShell: ability to define any keyword as a custom shell (aka custom window) that opens in a new browser window (tab) automatically unless there is no shell open in the current browser window (tab) - featured in [Hello, Custom Shell!](#hello-custom-shell)
|
223
|
+
- `shell`: featured in [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, Button!](GLIMMER_SAMPLES.md#hello-button) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe) / [Login](GLIMMER_SAMPLES.md#login)
|
224
|
+
- `tab_folder`: featured in [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab)
|
225
|
+
- `tab_item`: featured in [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab)
|
226
|
+
- `table`: featured in [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
227
|
+
- `table_column`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
228
|
+
- `text`: featured in [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
229
|
+
- `time`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
|
230
|
+
- Glimmer::UI::CustomWidget: ability to define any keyword as a custom widget - featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget)
|
231
|
+
- Glimmer::UI::CustomShell: ability to define any keyword as a custom shell (aka custom window) that opens in a new browser window (tab) automatically unless there is no shell open in the current browser window (tab) - featured in [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell)
|
232
232
|
|
233
233
|
**Layouts:**
|
234
|
-
- `grid_layout`: featured in [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Hello, Table!](#hello-table) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Contact Manager](#contact-manager) / [Login](#login) / [Tic Tac Toe](#tic-tac-toe)
|
235
|
-
- `row_layout`: featured in [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Contact Manager](#contact-manager)
|
236
|
-
- `fill_layout`: featured in [Hello, Custom Widget!](#hello-custom-widget)
|
237
|
-
- `layout_data`: featured in [Hello, Table!](#hello-table) / [Hello, Custom Shell!](#hello-custom-shell) / [Hello, Computed!](#hello-computed) / [Tic Tac Toe](#tic-tac-toe) / [Contact Manager](#contact-manager)
|
234
|
+
- `grid_layout`: featured in [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar) / [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Login](GLIMMER_SAMPLES.md#login) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
235
|
+
- `row_layout`: featured in [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
236
|
+
- `fill_layout`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget)
|
237
|
+
- `layout_data`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
238
238
|
|
239
239
|
**Graphics/Style:**
|
240
|
-
- `color`: featured in [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Menu Bar!](#hello-menu-bar)
|
241
|
-
- `font`: featured in [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe)
|
240
|
+
- `color`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
|
241
|
+
- `font`: featured in [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
242
242
|
- `Point` class used in setting location on widgets
|
243
|
-
- `swt` and `SWT` class to set SWT styles on widgets - featured in [Hello, Custom Shell!](#hello-custom-shell) / [Login](#login) / [Contact Manager](#contact-manager)
|
243
|
+
- `swt` and `SWT` class to set SWT styles on widgets - featured in [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
244
244
|
|
245
245
|
**Data-Binding/Observers:**
|
246
|
-
- `bind`: featured in [Hello, Computed!](#hello-computed) / [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Hello, Date Time!](#hello-date-time) / [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell) / [Login](#login) / [Contact Manager](#contact-manager) / [Tic Tac Toe](#tic-tac-toe)
|
247
|
-
- `observe`: featured in [Hello, Table!](#hello-table) / [Tic Tac Toe](#tic-tac-toe)
|
248
|
-
- `on_widget_selected`: featured in [Hello, Combo!](#hello-combo) / [Hello, Checkbox Group!](#hello-checkbox-group) / [Hello, Checkbox!](#hello-checkbox) / [Hello, Button!](#hello-button) / [Hello, Table!](#hello-table) / [Hello, Radio Group!](#hello-radio-group) / [Hello, Radio!](#hello-radio) / [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu) / [Hello, Message Box!](#hello-message-box) / [Hello, Menu Bar!](#hello-menu-bar) / [Hello, List Single Selection!](#hello-list-single-selection) / [Hello, List Multi Selection!](#hello-list-multi-selection) / [Hello, Group!](#hello-group) / [Contact Manager](#contact-manager) / [Login](#login) / [Tic Tac Toe](#tic-tac-toe)
|
246
|
+
- `bind`: featured in [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, Button!](GLIMMER_SAMPLES.md#hello-button) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) / [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
247
|
+
- `observe`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
248
|
+
- `on_widget_selected`: featured in [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo) / [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox) / [Hello, Button!](GLIMMER_SAMPLES.md#hello-button) / [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) / [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Pop Up Context Menu!](GLIMMER_SAMPLES.md#hello-pop-up-context-menu) / [Hello, Message Box!](GLIMMER_SAMPLES.md#hello-message-box) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar) / [Hello, List Single Selection!](GLIMMER_SAMPLES.md#hello-list-single-selection) / [Hello, List Multi Selection!](GLIMMER_SAMPLES.md#hello-list-multi-selection) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) / [Login](GLIMMER_SAMPLES.md#login) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
249
249
|
- `on_modify_text`
|
250
|
-
- `on_key_pressed` (and SWT alias `on_swt_keydown`) - featured in [Login](#login) / [Contact Manager](#contact-manager)
|
250
|
+
- `on_key_pressed` (and SWT alias `on_swt_keydown`) - featured in [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
251
251
|
- `on_key_released` (and SWT alias `on_swt_keyup`)
|
252
252
|
- `on_mouse_down` (and SWT alias `on_swt_mousedown`)
|
253
|
-
- `on_mouse_up` (and SWT alias `on_swt_mouseup`) - featured in [Hello, Custom Shell!](#hello-custom-shell) / [Contact Manager](#contact-manager)
|
253
|
+
- `on_mouse_up` (and SWT alias `on_swt_mouseup`) - featured in [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
|
254
254
|
|
255
255
|
**Event loop:**
|
256
|
-
- `display`: featured in [Tic Tac Toe](#tic-tac-toe)
|
257
|
-
- `async_exec`: featured in [Hello, Custom Widget!](#hello-custom-widget) / [Hello, Custom Shell!](#hello-custom-shell)
|
256
|
+
- `display`: featured in [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
|
257
|
+
- `async_exec`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell)
|
258
258
|
- `sync_exec`: executes a block on the event loop synchronously (usually from another thread)
|
259
259
|
- `timer_exec`: executes a block after a delay of time has passed
|
260
260
|
|
@@ -334,7 +334,7 @@ shell {
|
|
334
334
|
|
335
335
|
###### Shell Icon Tip for Packaging on Windows
|
336
336
|
|
337
|
-
When setting shell icon for a [packaged](#packaging--distribution) app, which has a JAR file at its core, you can reference the `ico` file that ships with the app by going one level up (e.g. `'../AppName.ico'`)
|
337
|
+
When setting shell icon for a [packaged](GLIMMER_PACKAGING_AND_DISTRIBUTION.md#packaging--distribution) app, which has a JAR file at its core, you can reference the `ico` file that ships with the app by going one level up (e.g. `'../AppName.ico'`)
|
338
338
|
|
339
339
|
#### Dialog
|
340
340
|
|
@@ -1800,6 +1800,14 @@ the address of a contact. This is called nested property data binding.
|
|
1800
1800
|
|
1801
1801
|
This example adds on the one above it by specifying converters on read and write of the model property, like in the case of a `text` widget. The text widget will then displays the street upper case and the model will store it lower case. When specifying converters, read and write operations must be symmetric (to avoid an infinite update loop between the widget and the model since the widget checks first if value changed before updating)
|
1802
1802
|
|
1803
|
+
`text bind(contact, 'address.street', sync_exec: true)`
|
1804
|
+
|
1805
|
+
This example adds does GUI updates via [sync_exec](#sync_exec) assuming they are coming from another thread (different from the GUI thread)
|
1806
|
+
|
1807
|
+
`text bind(contact, 'address.street', async_exec: true)`
|
1808
|
+
|
1809
|
+
This example adds does GUI updates via [async_exec](#async_exec) assuming they are coming from another thread (different from the GUI thread)
|
1810
|
+
|
1803
1811
|
`text bind(contact, 'address.street', on_read: lambda { |s| s[0..10] })`
|
1804
1812
|
|
1805
1813
|
This example also specifies a converter on read of the model property, but via a lambda, which truncates the street to 10 characters only. Note that the read and write operations are assymetric. This is fine in the case of formatting data for a read-only widget like `label`
|
@@ -36,6 +36,7 @@
|
|
36
36
|
- [Hello, Canvas Animation!](#hello-canvas-animation)
|
37
37
|
- [Hello, Canvas Transform!](#hello-canvas-transform)
|
38
38
|
- [Hello, Cursor!](#hello-cursor)
|
39
|
+
- [Hello, Progress Bar!](#hello-progress-bar)
|
39
40
|
- [Elaborate Samples](#elaborate-samples)
|
40
41
|
- [User Profile](#user-profile)
|
41
42
|
- [Login](#login)
|
@@ -600,6 +601,17 @@ Hello, Cursor!
|
|
600
601
|
|
601
602
|
![Hello Cursor](/images/glimmer-hello-cursor.gif)
|
602
603
|
|
604
|
+
#### Hello, Progress Bar!
|
605
|
+
|
606
|
+
This sample demonstrates the use of the `progress_bar` widget keyword.
|
607
|
+
|
608
|
+
Code:
|
609
|
+
|
610
|
+
[samples/hello/hello_progress_bar.rb](/samples/hello/hello_progress_bar.rb)
|
611
|
+
|
612
|
+
Hello, Progress Bar!
|
613
|
+
|
614
|
+
![Hello Progress Bar](/images/glimmer-hello-progress-bar.gif)
|
603
615
|
|
604
616
|
### Elaborate Samples
|
605
617
|
|
@@ -705,7 +717,9 @@ This sample demonstrates how to render canvas graphics with multi-threaded proce
|
|
705
717
|
|
706
718
|
It renders the famous Mandelbrot Fractal, enabling zooming and panning (go to Help -> Instructions for more details)
|
707
719
|
|
708
|
-
The Mandelbrot Fractal is known to take a long time to render, but thanks to multi-core processing, the app starts in about 10 seconds (runs faster the more cores you have)
|
720
|
+
The Mandelbrot Fractal is known to take a long time to render, but thanks to multi-core processing, the app starts in about 10 seconds with 4 CPU cores (runs faster the more cores you have)
|
721
|
+
|
722
|
+
Lower the cores in the menu to get more responsive interaction (e.g. zooming/panning). Once you change the cores, the change will not take effect till the next zoom calculation cycle.
|
709
723
|
|
710
724
|
Code:
|
711
725
|
|
data/glimmer-dsl-swt.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-swt 4.18.4.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.4.10 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-swt".freeze
|
9
|
-
s.version = "4.18.4.
|
9
|
+
s.version = "4.18.4.10"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
@@ -193,6 +193,7 @@ Gem::Specification.new do |s|
|
|
193
193
|
"samples/hello/hello_menu_bar.rb",
|
194
194
|
"samples/hello/hello_message_box.rb",
|
195
195
|
"samples/hello/hello_pop_up_context_menu.rb",
|
196
|
+
"samples/hello/hello_progress_bar.rb",
|
196
197
|
"samples/hello/hello_radio.rb",
|
197
198
|
"samples/hello/hello_radio_group.rb",
|
198
199
|
"samples/hello/hello_sash_form.rb",
|
@@ -32,10 +32,12 @@ module Glimmer
|
|
32
32
|
include Observer
|
33
33
|
|
34
34
|
attr_reader :widget, :property
|
35
|
-
def initialize(widget, property, translator = nil)
|
35
|
+
def initialize(widget, property, translator = nil, sync_exec: false, async_exec: false)
|
36
36
|
@widget = widget
|
37
37
|
@property = property
|
38
38
|
@translator = translator || proc {|value| value} #TODO check on this it doesn't seem used
|
39
|
+
@sync_exec = sync_exec
|
40
|
+
@async_exec = async_exec
|
39
41
|
|
40
42
|
if @widget.respond_to?(:on_widget_disposed)
|
41
43
|
@widget.on_widget_disposed do |dispose_event|
|
@@ -54,8 +56,10 @@ module Glimmer
|
|
54
56
|
end
|
55
57
|
@widget.set_attribute(@property, converted_value) unless evaluate_property == converted_value
|
56
58
|
end
|
57
|
-
if Config.auto_sync_exec? && Config.require_sync_exec?
|
59
|
+
if @sync_exec || Config.auto_sync_exec? && Config.require_sync_exec?
|
58
60
|
SWT::DisplayProxy.instance.sync_exec(&update_operation)
|
61
|
+
elsif @async_exec
|
62
|
+
SWT::DisplayProxy.instance.async_exec(&update_operation)
|
59
63
|
else
|
60
64
|
update_operation.call
|
61
65
|
end
|
@@ -66,7 +70,16 @@ module Glimmer
|
|
66
70
|
unregister_all_observables
|
67
71
|
return
|
68
72
|
end
|
69
|
-
|
73
|
+
read_operation = lambda do
|
74
|
+
@widget.get_attribute(@property)
|
75
|
+
end
|
76
|
+
if @sync_exec || Config.auto_sync_exec? && Config.require_sync_exec?
|
77
|
+
SWT::DisplayProxy.instance.sync_exec(&read_operation)
|
78
|
+
elsif @async_exec
|
79
|
+
SWT::DisplayProxy.instance.async_exec(&read_operation)
|
80
|
+
else
|
81
|
+
read_operation.call
|
82
|
+
end
|
70
83
|
end
|
71
84
|
end
|
72
85
|
end
|
@@ -22,6 +22,7 @@
|
|
22
22
|
require 'glimmer/dsl/expression'
|
23
23
|
require 'glimmer/data_binding/model_binding'
|
24
24
|
require 'glimmer/data_binding/widget_binding'
|
25
|
+
require 'glimmer/swt/display_proxy'
|
25
26
|
|
26
27
|
module Glimmer
|
27
28
|
module DSL
|
@@ -41,7 +42,7 @@ module Glimmer
|
|
41
42
|
|
42
43
|
def interpret(parent, keyword, *args, &block)
|
43
44
|
model_binding = args[0]
|
44
|
-
widget_binding_parameters = [parent, keyword]
|
45
|
+
widget_binding_parameters = [parent, keyword, {async_exec: model_binding.binding_options[:async_exec], sync_exec: model_binding.binding_options[:sync_exec]}]
|
45
46
|
widget_binding = DataBinding::WidgetBinding.new(*widget_binding_parameters)
|
46
47
|
widget_binding.call(model_binding.evaluate_property)
|
47
48
|
#TODO make this options observer dependent and all similar observers in widget specific data binding handlers
|
@@ -32,7 +32,7 @@ module Glimmer
|
|
32
32
|
include ParentExpression
|
33
33
|
|
34
34
|
def can_interpret?(parent, keyword, *args, &block)
|
35
|
-
|
35
|
+
super and
|
36
36
|
(parent.nil? or parent.is_a?(Glimmer::SWT::ShellProxy))
|
37
37
|
end
|
38
38
|
|
@@ -41,6 +41,9 @@ module Glimmer
|
|
41
41
|
Glimmer::SWT::ShellProxy.send(:new, *args)
|
42
42
|
end
|
43
43
|
end
|
44
|
+
class WindowExpression < ShellExpression
|
45
|
+
# Alias
|
46
|
+
end
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
@@ -597,7 +597,7 @@ module Glimmer
|
|
597
597
|
end
|
598
598
|
|
599
599
|
def ensure_drop_target_proxy(style=[])
|
600
|
-
@drop_target_proxy ||=
|
600
|
+
@drop_target_proxy ||= WidgetProxy.new('drop_target', self, style).tap do |proxy|
|
601
601
|
proxy.set_attribute(:transfer, :text)
|
602
602
|
proxy.on_drag_enter { |event|
|
603
603
|
event.detail = DNDProxy[:drop_copy]
|
@@ -608,7 +608,7 @@ module Glimmer
|
|
608
608
|
# TODO eliminate duplication in the following methods perhaps by relying on exceptions
|
609
609
|
|
610
610
|
def can_handle_observation_request?(observation_request)
|
611
|
-
observation_request = observation_request
|
611
|
+
observation_request = normalize_observation_request(observation_request)
|
612
612
|
if observation_request.start_with?('on_swt_')
|
613
613
|
constant_name = observation_request.sub(/^on_swt_/, '')
|
614
614
|
SWTProxy.has_constant?(constant_name)
|
@@ -646,7 +646,7 @@ module Glimmer
|
|
646
646
|
end
|
647
647
|
|
648
648
|
def handle_observation_request(observation_request, &block)
|
649
|
-
observation_request = observation_request
|
649
|
+
observation_request = normalize_observation_request(observation_request)
|
650
650
|
if observation_request.start_with?('on_swt_')
|
651
651
|
constant_name = observation_request.sub(/^on_swt_/, '')
|
652
652
|
add_swt_event_listener(constant_name, &block)
|
@@ -788,6 +788,10 @@ module Glimmer
|
|
788
788
|
def widget_custom_attribute_mapping
|
789
789
|
# TODO scope per widget class type just like other mappings
|
790
790
|
@swt_widget_custom_attribute_mapping ||= {
|
791
|
+
'window' => {
|
792
|
+
getter: {name: 'getShell'},
|
793
|
+
setter: {name: 'getShell', invoker: lambda { |widget, args| @swt_widget.getShell }}, # No Op
|
794
|
+
},
|
791
795
|
'focus' => {
|
792
796
|
getter: {name: 'isFocusControl'},
|
793
797
|
setter: {name: 'setFocus', invoker: lambda { |widget, args| @swt_widget.setFocus if args.first }},
|
@@ -840,6 +844,14 @@ module Glimmer
|
|
840
844
|
ensure_drop_target_proxy
|
841
845
|
@drop_target_proxy.set_attribute(:drop_target_effect, args)
|
842
846
|
end
|
847
|
+
|
848
|
+
def normalize_observation_request(observation_request)
|
849
|
+
observation_request = observation_request.to_s
|
850
|
+
if @swt_widget.is_a?(Shell) && observation_request.downcase.include?('window')
|
851
|
+
observation_request = observation_request.sub('window', 'shell').sub('Window', 'Shell')
|
852
|
+
end
|
853
|
+
observation_request
|
854
|
+
end
|
843
855
|
|
844
856
|
def apply_property_type_converters(attribute_name, args)
|
845
857
|
value = args
|
@@ -28,8 +28,6 @@ module Glimmer
|
|
28
28
|
include Glimmer::UI::CustomWidget
|
29
29
|
|
30
30
|
class << self
|
31
|
-
attr_reader :launched_custom_shell
|
32
|
-
|
33
31
|
def launch(*args, &content)
|
34
32
|
@launched_custom_shell = send(keyword, *args, &content) if @launched_custom_shell.nil? || @launched_custom_shell.disposed?
|
35
33
|
@launched_custom_shell.swt_widget.set_data('launched', true)
|
@@ -40,7 +38,8 @@ module Glimmer
|
|
40
38
|
def initialize(parent, *swt_constants, options, &content)
|
41
39
|
super
|
42
40
|
@swt_widget.set_data('custom_shell', self)
|
43
|
-
|
41
|
+
@swt_widget.set_data('custom_window', self)
|
42
|
+
raise Error, 'Invalid custom shell (window) body root! Must be a shell (window) or another custom shell (window).' unless body_root.swt_widget.is_a?(org.eclipse.swt.widgets.Shell)
|
44
43
|
end
|
45
44
|
|
46
45
|
# Classes may override
|
@@ -78,5 +77,6 @@ module Glimmer
|
|
78
77
|
body_root.start_event_loop
|
79
78
|
end
|
80
79
|
end
|
80
|
+
CustomWindow = CustomShell
|
81
81
|
end
|
82
82
|
end
|
@@ -20,7 +20,6 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'complex'
|
23
|
-
require 'bigdecimal'
|
24
23
|
require 'concurrent-ruby'
|
25
24
|
|
26
25
|
# Mandelbrot multi-threaded implementation leveraging all processor cores.
|
@@ -30,8 +29,12 @@ class Mandelbrot
|
|
30
29
|
Y_END = 1.0
|
31
30
|
X_START = -2.0
|
32
31
|
X_END = 0.5
|
32
|
+
PROGRESS_MAX = 40
|
33
33
|
|
34
34
|
class << self
|
35
|
+
attr_accessor :progress, :work_in_progress
|
36
|
+
attr_writer :processor_count
|
37
|
+
|
35
38
|
def for(max_iterations:, zoom:, background: false)
|
36
39
|
key = [max_iterations, zoom]
|
37
40
|
creation_mutex.synchronize do
|
@@ -50,6 +53,10 @@ class Mandelbrot
|
|
50
53
|
def creation_mutex
|
51
54
|
@creation_mutex ||= Mutex.new
|
52
55
|
end
|
56
|
+
|
57
|
+
def processor_count
|
58
|
+
@processor_count ||= Concurrent.processor_count
|
59
|
+
end
|
53
60
|
end
|
54
61
|
|
55
62
|
attr_accessor :max_iterations, :background
|
@@ -63,7 +70,6 @@ class Mandelbrot
|
|
63
70
|
def initialize(max_iterations:, zoom: 1.0, background: false)
|
64
71
|
@max_iterations = max_iterations
|
65
72
|
@zoom = zoom
|
66
|
-
@background = background
|
67
73
|
end
|
68
74
|
|
69
75
|
def step
|
@@ -90,28 +96,31 @@ class Mandelbrot
|
|
90
96
|
@points ||= calculate_points
|
91
97
|
end
|
92
98
|
|
93
|
-
def thread_count
|
94
|
-
@background ? [Concurrent.processor_count - 1, 1].max : Concurrent.processor_count
|
95
|
-
end
|
96
|
-
|
97
99
|
def calculate_points
|
98
100
|
puts "Background calculation activated at zoom #{zoom}" if @background
|
99
101
|
if @points_calculated
|
100
102
|
puts "Points calculated already. Returning previously calculated points..."
|
101
103
|
return @points
|
102
104
|
end
|
103
|
-
thread_pool = Concurrent::FixedThreadPool.new(
|
105
|
+
thread_pool = Concurrent::FixedThreadPool.new(Mandelbrot.processor_count, fallback_policy: :discard)
|
104
106
|
@points = Concurrent::Array.new(height)
|
107
|
+
Mandelbrot.work_in_progress = "Calculating Mandelbrot Points for Zoom #{zoom}x"
|
108
|
+
Mandelbrot.progress = 0
|
109
|
+
point_index = 0
|
110
|
+
point_count = width*height
|
105
111
|
height.times do |y|
|
106
112
|
@points[y] ||= Concurrent::Array.new(width)
|
107
113
|
width.times do |x|
|
108
114
|
thread_pool.post do
|
109
115
|
@points[y][x] = calculate(x_array[x], y_array[y]).last
|
116
|
+
point_index += 1
|
117
|
+
Mandelbrot.progress += 1 if (point_index.to_f / point_count.to_f)*PROGRESS_MAX >= Mandelbrot.progress
|
110
118
|
end
|
111
119
|
end
|
112
120
|
end
|
113
121
|
thread_pool.shutdown
|
114
122
|
thread_pool.wait_for_termination
|
123
|
+
Mandelbrot.progress = PROGRESS_MAX
|
115
124
|
@points_calculated = true
|
116
125
|
@points
|
117
126
|
end
|
@@ -132,9 +141,11 @@ end
|
|
132
141
|
|
133
142
|
class MandelbrotFractal
|
134
143
|
include Glimmer::UI::CustomShell
|
135
|
-
|
136
|
-
COMMAND = OS.mac? ? :command : :ctrl
|
137
144
|
|
145
|
+
COMMAND = OS.mac? ? :command : :ctrl
|
146
|
+
|
147
|
+
attr_accessor :mandelbrot_shell_title
|
148
|
+
|
138
149
|
option :zoom, default: 1.0
|
139
150
|
|
140
151
|
before_body {
|
@@ -144,6 +155,12 @@ class MandelbrotFractal
|
|
144
155
|
}
|
145
156
|
|
146
157
|
after_body {
|
158
|
+
observe(Mandelbrot, :work_in_progress) {
|
159
|
+
update_mandelbrot_shell_title!
|
160
|
+
}
|
161
|
+
observe(Mandelbrot, :zoom) {
|
162
|
+
update_mandelbrot_shell_title!
|
163
|
+
}
|
147
164
|
# pre-calculate zoomed mandelbrot images even before the user zooms in
|
148
165
|
puts 'Starting background calculation thread...'
|
149
166
|
Thread.new {
|
@@ -154,7 +171,6 @@ class MandelbrotFractal
|
|
154
171
|
pixels = the_mandelbrot.calculate_points
|
155
172
|
build_mandelbrot_image(mandelbrot_zoom: future_zoom)
|
156
173
|
sync_exec {
|
157
|
-
swt_widget.text = mandelbrot_shell_title
|
158
174
|
@canvas.cursor = :cross
|
159
175
|
}
|
160
176
|
future_zoom += 0.5
|
@@ -164,11 +180,21 @@ class MandelbrotFractal
|
|
164
180
|
|
165
181
|
body {
|
166
182
|
shell(:no_resize) {
|
167
|
-
|
168
|
-
|
183
|
+
grid_layout
|
184
|
+
text bind(self, :mandelbrot_shell_title, sync_exec: true)
|
185
|
+
minimum_size mandelbrot.width + 29, mandelbrot.height + 77
|
169
186
|
image @mandelbrot_image
|
170
187
|
|
188
|
+
progress_bar {
|
189
|
+
layout_data :fill, :center, true, false
|
190
|
+
|
191
|
+
minimum 0
|
192
|
+
maximum Mandelbrot::PROGRESS_MAX
|
193
|
+
selection bind(Mandelbrot, :progress, sync_exec: true)
|
194
|
+
}
|
195
|
+
|
171
196
|
@scrolled_composite = scrolled_composite {
|
197
|
+
layout_data :fill, :fill, true, true
|
172
198
|
@canvas = canvas {
|
173
199
|
image @mandelbrot_image
|
174
200
|
cursor :no
|
@@ -236,6 +262,31 @@ class MandelbrotFractal
|
|
236
262
|
on_widget_selected { perform_zoom(mandelbrot_zoom: 1.0) }
|
237
263
|
}
|
238
264
|
}
|
265
|
+
menu {
|
266
|
+
text '&Cores'
|
267
|
+
|
268
|
+
Concurrent.processor_count.times {|n|
|
269
|
+
processor_number = n + 1
|
270
|
+
menu_item(:radio) {
|
271
|
+
text "&#{processor_number}"
|
272
|
+
|
273
|
+
case processor_number
|
274
|
+
when 0..9
|
275
|
+
accelerator COMMAND, processor_number.to_s
|
276
|
+
when 10..19
|
277
|
+
accelerator COMMAND, :shift, (processor_number - 10).to_s
|
278
|
+
when 20..29
|
279
|
+
accelerator COMMAND, :alt, (processor_number - 20).to_s
|
280
|
+
end
|
281
|
+
|
282
|
+
selection true if processor_number == Concurrent.processor_count
|
283
|
+
|
284
|
+
on_widget_selected {
|
285
|
+
Mandelbrot.processor_count = n
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
239
290
|
menu {
|
240
291
|
text '&Help'
|
241
292
|
|
@@ -251,9 +302,11 @@ class MandelbrotFractal
|
|
251
302
|
}
|
252
303
|
}
|
253
304
|
}
|
254
|
-
|
255
|
-
def
|
256
|
-
"Mandelbrot Fractal - Zoom #{zoom}x (Calculated Max: #{flyweight_mandelbrot_images.keys.max}x)"
|
305
|
+
|
306
|
+
def update_mandelbrot_shell_title!
|
307
|
+
new_title = "Mandelbrot Fractal - Zoom #{zoom}x (Calculated Max: #{flyweight_mandelbrot_images.keys.max}x)"
|
308
|
+
new_title += " - #{Mandelbrot.work_in_progress}" if Mandelbrot.work_in_progress
|
309
|
+
self.mandelbrot_shell_title = new_title
|
257
310
|
end
|
258
311
|
|
259
312
|
def build_mandelbrot_image(mandelbrot_zoom: nil)
|
@@ -266,14 +319,22 @@ class MandelbrotFractal
|
|
266
319
|
new_mandelbrot_image = image(width, height, top_level: true) # invoke as a top-level parentless keyword to avoid nesting under any widget
|
267
320
|
new_mandelbrot_image_gc = new_mandelbrot_image.gc
|
268
321
|
current_foreground = nil
|
322
|
+
Mandelbrot.work_in_progress = "Consuming Points To Build Image for Zoom #{mandelbrot_zoom}x"
|
323
|
+
Mandelbrot.progress = Mandelbrot::PROGRESS_MAX
|
324
|
+
point_index = 0
|
325
|
+
point_count = width*height
|
269
326
|
height.times { |y|
|
270
327
|
width.times { |x|
|
271
328
|
new_foreground = color_palette[pixels[y][x]]
|
272
329
|
new_mandelbrot_image_gc.foreground = current_foreground = new_foreground unless new_foreground == current_foreground
|
273
330
|
new_mandelbrot_image_gc.draw_point x, y
|
331
|
+
point_index += 1
|
332
|
+
Mandelbrot.progress -= 1 if (Mandelbrot::PROGRESS_MAX - (point_index.to_f / point_count.to_f)*Mandelbrot::PROGRESS_MAX) < Mandelbrot.progress
|
274
333
|
}
|
275
334
|
}
|
335
|
+
Mandelbrot.progress = 0
|
276
336
|
flyweight_mandelbrot_images[mandelbrot_zoom] = new_mandelbrot_image
|
337
|
+
update_mandelbrot_shell_title!
|
277
338
|
end
|
278
339
|
flyweight_mandelbrot_images[mandelbrot_zoom]
|
279
340
|
end
|
@@ -330,8 +391,8 @@ class MandelbrotFractal
|
|
330
391
|
@scrolled_composite.set_origin(factor*@location_x, factor*@location_y)
|
331
392
|
@location_x = @location_y = nil
|
332
393
|
end
|
394
|
+
update_mandelbrot_shell_title!
|
333
395
|
@canvas.cursor = :cross
|
334
|
-
swt_widget.text = mandelbrot_shell_title
|
335
396
|
end
|
336
397
|
|
337
398
|
def display_help_instructions
|
@@ -343,6 +404,7 @@ class MandelbrotFractal
|
|
343
404
|
Left-click to zoom in.
|
344
405
|
Right-click to zoom out.
|
345
406
|
Scroll or drag to pan.
|
407
|
+
Lower cores to get more responsive interaction.
|
346
408
|
|
347
409
|
Enjoy!
|
348
410
|
MULTI_LINE_STRING
|
@@ -0,0 +1,127 @@
|
|
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.
|
21
|
+
|
22
|
+
class HelloProgressBar
|
23
|
+
include Glimmer::UI::CustomWindow
|
24
|
+
|
25
|
+
class ProgressModel
|
26
|
+
attr_accessor :minimum, :maximum, :selection, :delay
|
27
|
+
end
|
28
|
+
|
29
|
+
before_body {
|
30
|
+
@progress_model = ProgressModel.new
|
31
|
+
@progress_model.minimum = 0
|
32
|
+
@progress_model.maximum = 100
|
33
|
+
@progress_model.selection = 0
|
34
|
+
@progress_model.delay = 0.01
|
35
|
+
}
|
36
|
+
|
37
|
+
body {
|
38
|
+
shell {
|
39
|
+
grid_layout(4, true)
|
40
|
+
|
41
|
+
text 'Hello, Progress Bar!'
|
42
|
+
|
43
|
+
progress_bar(:indeterminate) {
|
44
|
+
layout_data(:fill, :center, true, false) {
|
45
|
+
horizontal_span 4
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
label {
|
50
|
+
text 'Minimum'
|
51
|
+
}
|
52
|
+
|
53
|
+
label {
|
54
|
+
text 'Maximum'
|
55
|
+
}
|
56
|
+
|
57
|
+
label {
|
58
|
+
text 'Selection'
|
59
|
+
}
|
60
|
+
|
61
|
+
label {
|
62
|
+
text 'Delay in Seconds'
|
63
|
+
}
|
64
|
+
|
65
|
+
spinner {
|
66
|
+
selection bind(@progress_model, :minimum)
|
67
|
+
}
|
68
|
+
|
69
|
+
spinner {
|
70
|
+
selection bind(@progress_model, :maximum)
|
71
|
+
}
|
72
|
+
|
73
|
+
spinner {
|
74
|
+
selection bind(@progress_model, :selection)
|
75
|
+
}
|
76
|
+
|
77
|
+
spinner {
|
78
|
+
digits 2
|
79
|
+
minimum 1
|
80
|
+
maximum 200
|
81
|
+
selection bind(@progress_model, :delay, on_read: ->(v) {v.to_f*100.0}, on_write: ->(v) {v.to_f/100.0})
|
82
|
+
}
|
83
|
+
|
84
|
+
progress_bar {
|
85
|
+
layout_data(:fill, :center, true, false) {
|
86
|
+
horizontal_span 4
|
87
|
+
}
|
88
|
+
minimum bind(@progress_model, :minimum)
|
89
|
+
maximum bind(@progress_model, :maximum)
|
90
|
+
selection bind(@progress_model, :selection)
|
91
|
+
}
|
92
|
+
|
93
|
+
progress_bar(:vertical) {
|
94
|
+
layout_data(:fill, :center, true, false) {
|
95
|
+
horizontal_span 4
|
96
|
+
}
|
97
|
+
minimum bind(@progress_model, :minimum)
|
98
|
+
maximum bind(@progress_model, :maximum)
|
99
|
+
selection bind(@progress_model, :selection)
|
100
|
+
}
|
101
|
+
|
102
|
+
button {
|
103
|
+
layout_data(:fill, :center, true, false) {
|
104
|
+
horizontal_span 4
|
105
|
+
}
|
106
|
+
text "Start"
|
107
|
+
|
108
|
+
on_widget_selected {
|
109
|
+
# if a previous thread is running, then kill first
|
110
|
+
# (killing is not dangerous since it is only a thread about updating progress)
|
111
|
+
@current_thread&.kill
|
112
|
+
@current_thread = Thread.new {
|
113
|
+
sync_exec { @progress_model.selection = @progress_model.minimum }
|
114
|
+
(@progress_model.minimum..@progress_model.maximum).to_a.each do |n|
|
115
|
+
sync_exec {
|
116
|
+
@progress_model.selection = n
|
117
|
+
}
|
118
|
+
sleep(@progress_model.delay)
|
119
|
+
end
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
HelloProgressBar.launch
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.18.4.
|
4
|
+
version: 4.18.4.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
@@ -526,6 +526,7 @@ files:
|
|
526
526
|
- samples/hello/hello_menu_bar.rb
|
527
527
|
- samples/hello/hello_message_box.rb
|
528
528
|
- samples/hello/hello_pop_up_context_menu.rb
|
529
|
+
- samples/hello/hello_progress_bar.rb
|
529
530
|
- samples/hello/hello_radio.rb
|
530
531
|
- samples/hello/hello_radio_group.rb
|
531
532
|
- samples/hello/hello_sash_form.rb
|