glimmer-dsl-swt 4.18.4.6 → 4.18.4.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/README.md +20 -11
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +273 -66
  6. data/docs/reference/GLIMMER_SAMPLES.md +144 -41
  7. data/glimmer-dsl-swt.gemspec +13 -5
  8. data/lib/glimmer/data_binding/widget_binding.rb +16 -3
  9. data/lib/glimmer/dsl/swt/color_expression.rb +1 -1
  10. data/lib/glimmer/dsl/swt/custom_widget_expression.rb +4 -1
  11. data/lib/glimmer/dsl/swt/data_binding_expression.rb +2 -1
  12. data/lib/glimmer/dsl/swt/image_expression.rb +14 -3
  13. data/lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb +1 -0
  14. data/lib/glimmer/dsl/swt/shell_expression.rb +4 -1
  15. data/lib/glimmer/dsl/swt/widget_expression.rb +4 -1
  16. data/lib/glimmer/swt/color_proxy.rb +5 -4
  17. data/lib/glimmer/swt/custom/animation.rb +1 -0
  18. data/lib/glimmer/swt/custom/code_text.rb +22 -0
  19. data/lib/glimmer/swt/custom/drawable.rb +80 -4
  20. data/lib/glimmer/swt/custom/radio_group.rb +2 -1
  21. data/lib/glimmer/swt/custom/shape.rb +80 -46
  22. data/lib/glimmer/swt/image_proxy.rb +30 -8
  23. data/lib/glimmer/swt/scrolled_composite_proxy.rb +15 -6
  24. data/lib/glimmer/swt/shell_proxy.rb +2 -0
  25. data/lib/glimmer/swt/swt_proxy.rb +1 -0
  26. data/lib/glimmer/swt/tab_item_proxy.rb +1 -0
  27. data/lib/glimmer/swt/widget_proxy.rb +24 -5
  28. data/lib/glimmer/ui/custom_shell.rb +3 -3
  29. data/samples/elaborate/mandelbrot_fractal.rb +348 -39
  30. data/samples/elaborate/meta_sample.rb +1 -1
  31. data/samples/elaborate/tetris.rb +5 -5
  32. data/samples/hello/hello_combo.rb +1 -1
  33. data/samples/hello/hello_cursor.rb +57 -0
  34. data/samples/hello/hello_list_multi_selection.rb +1 -1
  35. data/samples/hello/hello_list_single_selection.rb +1 -1
  36. data/samples/hello/hello_progress_bar.rb +129 -0
  37. data/samples/hello/hello_table.rb +1 -1
  38. data/samples/hello/hello_table/baseball_park.png +0 -0
  39. metadata +11 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0074aec37350a556b6078426d3fbeb0e03799f0593158814c6a91439973b07a
4
- data.tar.gz: bf615d4a2aed63e654bebbad0055fd62218ad5747f2fc6edfe7a298e2f30d074
3
+ metadata.gz: cb72ad5f93c5c27a2f2ead87225e0ee045e2663e50b04346f5be6065fbf269c2
4
+ data.tar.gz: 394f955a01f7d5b568ae433dcab240f86b48749e5db428296299388ceaff5773
5
5
  SHA512:
6
- metadata.gz: 9499a1e9ca375bcf89f1cfaba1573a27e80a32995a53c351872f82c69661305bd4fde1bb6dbe3b5d5354aaf24e74245c353079de59906693a05828b86943ba31
7
- data.tar.gz: 471ca571d01081e9c461bb003ebcd3b64cb11193d3cdc2be7ecdc91b94997bcd8591cec6ef49b23d8790cc721bcb827549b1e406b97fa36a9eba0752a81870fd
6
+ metadata.gz: 18dd1f7062fdb14e063820d29168815df77b70f04275559fc812b605d2daf6053815b94579030a749cfc942188115150db093b0f0fc9863247177d112d165d90
7
+ data.tar.gz: c1809fda609b22045fd5872624cbc234b1353173522f2430767b8f36e4afd096063d5b4fe5fc41b0a24b0f96ec00d9fc0aada8df9537201d1d87fe8eebe26d59
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.4.11
4
+
5
+ - Support creating images pixel by pixel with `image(width, height) {|x,y| [r, g, b]}` keyword, which takes a block with x, y coordinates based on the image width and height and returns a pixel foreground color per point
6
+ - Add proper indentation in code_text upon hitting ENTER
7
+ - Reset Canvas Shape DSL alpha value to 255 when not explicitly set on a shape (Apply in Hello, Canvas! Sample)
8
+ - Provide terse syntax for building canvas objects (autodetecting its width and height)
9
+ - Provide terse syntax for building `:image_double_buffered` canvas objects (autodetecting its width and height):
10
+ - Center mandelbrot where mouse is clicked upon zoom
11
+ - Fix issue with Mandelbrot sample off by one error on Cores selected via Menu
12
+ - Fix use of on_events in code_text widget with lines mode true
13
+
14
+ ### 4.18.4.10
15
+
16
+ - Hello, Progress Bar!
17
+ - 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
18
+ - `bind` option of `async_exec` or `sync_exec` (e.g. `bind(model, :property, async_exec: true)`) to perform GUI updates from another thread safely
19
+ - Show progress bar for Mandelbrot calculation
20
+ - Mandelbrot Cores menu options to switch the number of CPU cores being used for calculation on the next zoom calculation cycle
21
+
22
+ ### 4.18.4.9
23
+
24
+ - Hello, Cursor! Sample
25
+ - Log errors that occur in widget event listener blocks to help with troubleshooting
26
+ - disposed? method for Shape objects
27
+ - Add `dispose_images: false, dispose_patterns: false` options to `Shape#dispose` to avoid disposing images/patterns when needed
28
+ - Mandelbrot background thread pre-calculation of future zoom levels
29
+ - Mandelbrot menu bar menu items
30
+ - Mandelbrot panning via scrollbars or dragging
31
+
32
+ ### 4.18.4.8
33
+
34
+ - Make `image` a top-level expression keyword
35
+ - Default placing image on Canvas at coordinates 0, 0 if they are not specified (e.g. canvas {image some_image})
36
+ - Support passing in color args directly to the `pixel` keyword as an rgb value array without using the `color`/`rgb` keyword, to improve performance for large pixel counts
37
+ - Support Image Double Buffering by nesting an `image` built from shapes within a `canvas`
38
+ - Shrink image of baseball background for Hello, Table! Sample to reduce the glimmer-dsl-swt gem size (recently bloated)
39
+ - Fix issue with closing a canvas shell with pixel graphics freezing temporarily for a long time while disposing shapes
40
+ - Fix issue with disposing `image` having shapes
41
+
42
+ ### 4.18.4.7
43
+
44
+ - Fixed issue with Tetris breaking with the latest Canvas Shape/Animation DSL performance optimizations
45
+
3
46
  ### 4.18.4.6
4
47
 
5
48
  - Mandlebrot Fractal Elaborate 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.6
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.11
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)
@@ -326,14 +326,14 @@ Please follow these instructions to make the `glimmer` command available on your
326
326
 
327
327
  If you intend to learn the basics of Glimmer but are not ready to build a Glimmer app yet, pick Option 1 ([Direct Install](#option-1-direct-install)).
328
328
 
329
- If you intend to build a Glimmer app from scratch with [scaffolding](#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
329
+ If you intend to build a Glimmer app from scratch with [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
330
330
 
331
- Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](#scaffolding).
331
+ Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding).
332
332
 
333
333
  **Note:** if you encounter any [issues](https://github.com/AndyObtiva/glimmer-dsl-swt/issues), please [report](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) and then install a previous version instead from the list of [Glimmer Releases](https://rubygems.org/gems/glimmer-dsl-swt/versions) (keep looking back till you find one that works). Do not be disheartened as nearly everything is only a few days of work away. That said, keep in mind that this project is free and open source, meaning provided as is, so do not expect anything, but if you help with reporting and contributing, you could speed things up or even become part of the project.
334
334
 
335
335
  ### Option 1: Direct Install
336
- (Use for [Scaffolding](#scaffolding))
336
+ (Use for [Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding))
337
337
 
338
338
  Run this command to install directly:
339
339
  ```
@@ -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.6
345
+ jgem install glimmer-dsl-swt -v 4.18.4.11
346
346
  ```
347
347
 
348
348
  `jgem` is JRuby's version of `gem` command.
@@ -351,7 +351,7 @@ Otherwise, you may also run `jruby -S gem install ...`
351
351
 
352
352
  If you are new to Glimmer and would like to continue learning the basics, you may continue to the [Glimmer Command](https://github.com/AndyObtiva/glimmer#glimmer-command) section.
353
353
 
354
- Otherwise, if you are ready to build a Glimmer app, you can jump to the [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer#scaffolding) section next.
354
+ Otherwise, if you are ready to build a Glimmer app, you can jump to the [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding) section next.
355
355
 
356
356
  Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
357
357
 
@@ -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.6'
363
+ gem 'glimmer-dsl-swt', '~> 4.18.4.11'
364
364
  ```
365
365
 
366
366
  And, then run:
@@ -386,11 +386,12 @@ You can use `girb` as an alternative to `irb` when prototyping Glimmer DSL for S
386
386
 
387
387
  ## Glimmer GUI DSL Syntax
388
388
 
389
- This guide should help you get started with Glimmer DSL for SWT. For more advanced SWT details, please refer to the [SWT Reference](#swt-reference).
390
-
389
+ This guide should help you get started with Glimmer DSL for SWT.
391
390
 
392
391
  [docs/reference/GLIMMER_GUI_DSL_SYNTAX.md](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md)
393
392
 
393
+ For more advanced SWT details, please refer to the [SWT Reference](#swt-reference).
394
+
394
395
  ## Glimmer Configuration
395
396
 
396
397
  Glimmer configuration may be done via the `Glimmer::Config` module.
@@ -425,6 +426,14 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
425
426
 
426
427
  [<img alt="Garderie Rainbow Daily Agenda Logo" src="https://github.com/AndyObtiva/garderie_rainbow_daily_agenda/raw/master/images/garderie_rainbow_daily_agenda_logo.png" width="40" />Garderie Rainbow Daily Agenda](https://github.com/AndyObtiva/garderie_rainbow_daily_agenda): A child nursery daily agenda reporting desktop app
427
428
 
429
+ ### Glimmer Gab
430
+
431
+ [<img alt="Glimmer Gab Logo" src="https://raw.githubusercontent.com/AndyObtiva/glimmer_gab/master/package/linux/Glimmer%20Gab.png" height=40 /> Glimmer Gab](https://github.com/AndyObtiva/glimmer_gab): Desktop App for Gab.com
432
+
433
+ ### Connector
434
+
435
+ [<img alt="Connector Logo" src="https://raw.githubusercontent.com/AndyObtiva/connector/master/package/linux/Connector.png" height=40 /> Connector](https://github.com/AndyObtiva/connector): A minimalist open-source multi-engine web browser
436
+
428
437
  ## Packaging & Distribution
429
438
 
430
439
  Glimmer simplifies the process of native-executable packaging and distribution on Mac and Windows via a single `glimmer package` command:
@@ -433,12 +442,12 @@ Glimmer simplifies the process of native-executable packaging and distribution o
433
442
 
434
443
  ## App Updates
435
444
 
436
- Glimmer should already support automatic (and manual) app updates via the Mac App Store for Mac apps (though I haven't personally tried. Be my guest if you want to call shotgun on this, and share your experience with us). Simply run the `glimmer package` command with the Mac App Store keys configured as per [Mac Application Distribution](mac-application-distribution) instructions and you get automatic (and manual) app update support courtesy of the Mac App Store.
445
+ Glimmer already supports automatic (and manual) app updates via the Mac App Store for Mac apps. Simply run the `glimmer package` command with the Mac App Store keys configured as per [Mac Application Distribution](mac-application-distribution) instructions and you get automatic (and manual) app update support courtesy of the Mac App Store.
437
446
 
438
447
  ## Glimmer Supporting Libraries
439
448
 
440
449
  Here is a list of notable 3rd party gems used by Glimmer:
441
- - [juwelier](https://rubygems.org/gems/juwelier): generates app gems during [Glimmer Scaffolding](#scaffolding)
450
+ - [juwelier](https://rubygems.org/gems/juwelier): generates app gems during [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding)
442
451
  - [logging](https://github.com/TwP/logging): provides extra logging capabilities not available in Ruby Logger such as multi-threaded buffered asynchronous logging (to avoid affecting app performance) and support for multiple appenders such as stdout, syslog, and log files (the last one is needed on Windows where syslog is not supported)
443
452
  - [nested_inherited_jruby_include_package](https://github.com/AndyObtiva/nested_inherited_jruby_include_package): makes included [SWT](https://www.eclipse.org/swt/)/[Java](https://www.java.com/en/) packages available to all classes/modules that mix in the Glimmer module without having to manually reimport
444
453
  - [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.4.6
1
+ 4.18.4.11
@@ -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
 
@@ -284,7 +284,7 @@ Shell widget proxy has extra methods specific to SWT Shell:
284
284
  - `#show`: Alias for `#open`
285
285
  - `#hide`: Hides a shell setting "visible" property to false
286
286
  - `#close`: Closes the shell
287
- - `#center`: Centers the shell within monitor it is in
287
+ - `#center_within_display`: Centers the shell within monitor it is in
288
288
  - `#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.
289
289
  - `#visible?`: Returns whether a shell is visible
290
290
  - `#opened_before?`: Returns whether a shell has been opened at least once before (additionally implying the SWT Event Loop has been started already)
@@ -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
 
@@ -411,6 +411,10 @@ Although SWT Display is not technically a widget, it has similar APIs and DSL su
411
411
 
412
412
  [JRuby](https://www.jruby.org/) supports [truly parallel multi-threading](https://github.com/jruby/jruby/wiki/Concurrency-in-jruby) since it relies on the JVM (Java Virtual Machine). As such, it enables development of highly-interactive desktop applications that can do background work while the user is interacting with the GUI. However, any code that interacts with the GUI from a thread other than the main (first) GUI thread must do so only through sync_exec (if it is standard synchronous code) or async_exec.
413
413
 
414
+ Most of the time, you simply get away with Ruby [Threads](https://ruby-doc.org/core-2.5.7/Thread.html) and [Mutexes](https://ruby-doc.org/core-2.5.7/Mutex.html).
415
+
416
+ Otherwise, if you need more advanced concurrency, Glimmer includes the [concurrent-ruby gem](https://rubygems.org/gems/concurrent-ruby), which supports many helpful concurrency techniques such as [Thread Pools](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html) (used in the [Mandelbrot Fractal](GLIMMER_SAMPLES.md#mandelbrot-fractal) sample).
417
+
414
418
  ##### async_exec
415
419
 
416
420
  `async_exec {}` is a Glimmer DSL keyword in addition to being a method on `display`. It accepts a block and when invoked, adds the block to the end of a queue of GUI events scheduled to run on the SWT event loop, executing asynchronously.
@@ -800,7 +804,7 @@ You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash
800
804
 
801
805
  ![Hello Browser](/images/glimmer-hello-browser.png)
802
806
 
803
- Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
807
+ Glimmer supports the [SWT Browser widget](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/Browser.html), which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
804
808
 
805
809
  Example loading a URL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
806
810
 
@@ -834,6 +838,8 @@ shell {
834
838
  }.open
835
839
  ```
836
840
 
841
+ Learn more at the [SWT Browser widget](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/Browser.html) API.
842
+
837
843
  ### Widget Styles
838
844
 
839
845
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -1282,12 +1288,14 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
1282
1288
 
1283
1289
  Glimmer supports drawing graphics directly on a `canvas` widget via SWT (or any widget for that matter though `canvas` is recommended for drawing).
1284
1290
 
1291
+ `canvas` has the `:double_buffered` SWT style by default to ensure flicker-free rendering. If you need to disable it for whatever reason, just pass the `:none` SWT style instead (e.g. `canvas(:none)`)
1292
+
1285
1293
  This is accomplished via the Shape DSL a sub-DSL of the Glimmer GUI DSL, which makes it possible to draw graphics declaratively with very understandable and maintainable syntax.
1286
1294
 
1287
1295
  Shape keywords and their args (including defaults) are listed below (they basically match method names and arguments on [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) minus the `draw` or `fill` prefix in downcase):
1288
1296
  - `arc(x, y, width, height, startAngle, arcAngle, fill: false)` arc is part of a circle within an oval area, denoted by start angle (degrees) and end angle (degrees)
1289
1297
  - `focus(x, y, width, height)` this is just like rectangle but its foreground color is always that of the OS widget focus color (useful when capturing user interaction via a shape)
1290
- - `image(image, x, y)` [image](#image)
1298
+ - `image(image, x = 0, y = 0)` sets [image](#image), which could be an [org.eclipse.swt.graphics.Image](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Image.html) object or just a file path string
1291
1299
  - `line(x1, y1, x2, y2)` line
1292
1300
  - `oval(x, y, width, height, fill: false)` oval if width does not match heigh and circle if width matches height. Can be optionally filled.
1293
1301
  - `point(x, y)` point
@@ -1367,15 +1375,15 @@ Screenshot:
1367
1375
 
1368
1376
  Learn more at the [Hello, Canvas! Sample](#hello-canvas).
1369
1377
 
1370
- If you get extremely stuck, remember that you could always default to direct [SWT GC usage]([org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) and learn more at the [SWT Graphics Guide](https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html) and [SWT Image Guide](https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html#Saving%20Images).
1378
+ If you ever have special needs or optimizations, you could always default to direct SWT painting via [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) instead. Learn more at the [SWT Graphics Guide](https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html) and [SWT Image Guide](https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html#Saving%20Images).
1371
1379
 
1372
- Example of manually doing the same things as in the above example without relying on the declarative Glimmer Shape DSL:
1380
+ Example of manually doing the same things as in the previous example without relying on the declarative Glimmer Shape DSL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1373
1381
 
1374
1382
  ```ruby
1375
- image_object = image(File.expand_path('./icons/scaffold_app.png'), width: 100)
1376
-
1377
1383
  include Glimmer
1378
1384
 
1385
+ image_object = image(File.expand_path('./icons/scaffold_app.png'), width: 100)
1386
+
1379
1387
  shell {
1380
1388
  text 'Canvas Manual Example'
1381
1389
  minimum_size 320, 400
@@ -1383,31 +1391,30 @@ shell {
1383
1391
  canvas {
1384
1392
  background :yellow
1385
1393
 
1386
- on_paint_control { |event|
1387
- event.gc.set_background(color(:red).swt_color)
1388
- event.gc.fill_rectangle(0, 0, 220, 400)
1394
+ on_paint_control { |paint_event|
1395
+ gc = paint_event.gc
1396
+ gc.background = color(:red).swt_color
1397
+ gc.fill_rectangle(0, 0, 220, 400)
1389
1398
 
1390
- event.gc.set_background(color(:magenta).swt_color)
1391
- event.gc.fill_roundRectangle(50, 20, 300, 150, 30, 50)
1399
+ gc.background = color(:magenta).swt_color
1400
+ gc.fill_roundRectangle(50, 20, 300, 150, 30, 50)
1392
1401
 
1393
- event.gc.set_background(color(:dark_magenta).swt_color)
1394
- event.gc.fill_gradientRectangle(150, 200, 100, 70, true)
1402
+ gc.background = color(:dark_magenta).swt_color
1403
+ gc.fill_gradientRectangle(150, 200, 100, 70, true)
1395
1404
 
1396
- event.gc.set_foreground(color(:dark_blue).swt_color)
1397
- event.gc.draw_rectangle(200, 80, 108, 36)
1405
+ gc.foreground = color(:dark_blue).swt_color
1406
+ gc.draw_rectangle(200, 80, 108, 36)
1398
1407
 
1399
- event.gc.set_foreground(color(:black).swt_color)
1400
- event.gc.set_lineWidth(3)
1401
- event.gc.draw_rectangle(200, 80, 108, 36)
1408
+ gc.foreground = color(:black).swt_color
1409
+ gc.line_width = 3
1410
+ gc.draw_rectangle(200, 80, 108, 36)
1402
1411
 
1403
- event.gc.draw_image(image_object.swt_image, 70, 50)
1412
+ gc.draw_image(image_object.swt_image, 70, 50)
1404
1413
  }
1405
1414
  }
1406
1415
  }.open
1407
1416
  ```
1408
1417
 
1409
- In any case, if there is anything missing you would like added to the Glimmer Shape DSL that you saw available in the SWT APIs, you may [report an issue](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) or implement yourself and [contribute](#contributing) via a [Pull Request](https://github.com/AndyObtiva/glimmer-dsl-swt/pulls).
1410
-
1411
1418
  #### Shapes inside a Widget
1412
1419
 
1413
1420
  Keep in mind that the Shape DSL can be used inside any widget, not just `canvas`. Unlike shapes on a `canvas`, which are standalone graphics, when included in a widget, which already has its own look and feel, shapes are used as a decorative add-on that complements its look by getting painted on top of it. For example, shapes were used to decorate `composite` blocks in the [Tetris](#tetris) sample to have a more bevel look. In summary, Shapes can be used in a hybrid approach (shapes inside a widget), not just standalone in a `canvas`.
@@ -1508,6 +1515,187 @@ shell {
1508
1515
 
1509
1516
  ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1510
1517
 
1518
+ #### Pixel Graphics
1519
+
1520
+ **(Early Alpha Feature)**
1521
+
1522
+ If you need to paint pixel graphics, use the optimized `pixel` keyword alternative to `point`, which takes foreground as a hash argument and bypasses the [Glimmer DSL Engine chain of responsibility](https://github.com/AndyObtiva/glimmer#dsl-engine), thus rendering faster when having very large pixel counts.
1523
+
1524
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1525
+
1526
+ ```ruby
1527
+ include Glimmer
1528
+
1529
+ shell {
1530
+ minimum_size 250, 265
1531
+ text 'Pixel Graphics Example'
1532
+
1533
+ canvas {
1534
+ 250.times {|y|
1535
+ 250.times {|x|
1536
+ pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1537
+ }
1538
+ }
1539
+ }
1540
+ }.open
1541
+ ```
1542
+
1543
+ Result:
1544
+
1545
+ ![glimmer example pixel graphics](/images/glimmer-example-pixel-graphics.png)
1546
+
1547
+ If you are strictly dealing with pixels (no other shapes), you could even avoid the `pixel` keyword altogether and just provide direct foreground colors by passing a block that receives x, y coordinates:
1548
+
1549
+ ```ruby
1550
+ include Glimmer
1551
+
1552
+ shell {
1553
+ minimum_size 250, 265
1554
+ text 'Pixel Graphics Example'
1555
+
1556
+ canvas { |x, y|
1557
+ [y%255, x%255, (x+y)%255]
1558
+ }
1559
+ }.open
1560
+ ```
1561
+
1562
+ Remember that you could always default to direct SWT painting via [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) too for even faster performance when needed in rare circumstances. Learn more at the [SWT Graphics Guide](https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html) and [SWT Image Guide](https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html#Saving%20Images).
1563
+
1564
+ Example of manually doing the same things as in the previous example without relying on the declarative Glimmer Shape DSL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1565
+
1566
+ ```ruby
1567
+ include Glimmer
1568
+
1569
+ shell {
1570
+ minimum_size 250, 265
1571
+ text 'Pixel Graphics Example'
1572
+
1573
+ canvas {
1574
+ on_paint_control { |paint_event|
1575
+ gc = paint_event.gc
1576
+ 250.times {|y|
1577
+ 250.times {|x|
1578
+ gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1579
+ gc.draw_point(x, y)
1580
+ }
1581
+ }
1582
+ }
1583
+ }
1584
+ }.open
1585
+ ```
1586
+
1587
+ (the code could be optimized further if you are repeating colors by simply reusing `Color` objects instead of re-constructing them)
1588
+
1589
+ The only downside with the approach above is that it repaints all pixels on repaints to the window (e.g. during window resize). To get around that, we can rely on a technique called **Image Double-Buffering**. That is to buffer the graphics on an Image first and then set it on the Canvas so that resizes of the shell dont cause a repaint of all the pixels. Additionally, this gives us the added benefit of being able to use the image as a Shell icon via its `image` property.
1590
+
1591
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1592
+
1593
+ ```ruby
1594
+ include Glimmer
1595
+
1596
+ @the_image = image(250, 250)
1597
+ 250.times {|y|
1598
+ 250.times {|x|
1599
+ @the_image.gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1600
+ @the_image.gc.draw_point(x, y)
1601
+ }
1602
+ }
1603
+
1604
+ shell {
1605
+ minimum_size 250, 265
1606
+ text 'Pixel Graphics Example'
1607
+ image @the_image
1608
+
1609
+ canvas {
1610
+ image @the_image
1611
+ }
1612
+ }.open
1613
+ ```
1614
+
1615
+ If you need a transparent background for the image, replace the image construction line with the following:
1616
+
1617
+ ```ruby
1618
+ @the_image = image(250, 250)
1619
+ @the_image.image_data.alpha = 0
1620
+ @the_image = image(@the_image.image_data)
1621
+ ```
1622
+
1623
+ That way, wherever you don't draw a point, you get transparency (seeing what is behind the image).
1624
+
1625
+ Alternatively, with a very minor performance penalty, Glimmer enables you to build the image pixel by pixel with a friendly Ruby syntax by passing a block that takes the x and y coordinates and returns a foreground color rgb array or Color/ColorProxy object.
1626
+
1627
+ ```ruby
1628
+ include Glimmer
1629
+
1630
+ @the_image = image(250, 250) {|x, y|
1631
+ [y%255, x%255, (x+y)%255]
1632
+ }
1633
+
1634
+ shell {
1635
+ minimum_size 250, 265
1636
+ text 'Pixel Graphics Example'
1637
+ image @the_image
1638
+
1639
+ canvas {
1640
+ image @the_image
1641
+ }
1642
+ }.open
1643
+ ```
1644
+
1645
+ If you don't need a `shell` image (icon), you can nest the image directly under the canvas by passing in the `top_level` keyword to treat `image` as a top-level keyword (pretending it is built outside the shell).
1646
+
1647
+ ```ruby
1648
+ include Glimmer
1649
+
1650
+ shell {
1651
+ minimum_size 250, 265
1652
+ text 'Pixel Graphics Example'
1653
+
1654
+ canvas {
1655
+ image image(250, 250, top_level: true) {|x, y|
1656
+ [y%255, x%255, (x+y)%255]
1657
+ }
1658
+ }
1659
+ }.open
1660
+ ```
1661
+
1662
+ If you don't need a `shell` image (icon) and `pixel` performance is enough, you can automatically apply **Image Double-Buffering** with the `:image_double_buffered` SWT style (custom Glimmer style not available in SWT itself)
1663
+
1664
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1665
+
1666
+ ```ruby
1667
+ include Glimmer
1668
+
1669
+ shell {
1670
+ minimum_size 250, 265
1671
+ text 'Pixel Graphics Example'
1672
+
1673
+ canvas(:image_double_buffered) {
1674
+ 250.times {|y|
1675
+ 250.times {|x|
1676
+ pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1677
+ }
1678
+ }
1679
+ }
1680
+ }.open
1681
+ ```
1682
+
1683
+ Of course, you could also take advantage of the pixel-less terser syntax:
1684
+
1685
+ ```ruby
1686
+ include Glimmer
1687
+
1688
+ shell {
1689
+ minimum_size 250, 265
1690
+ text 'Pixel Graphics Example'
1691
+
1692
+ canvas(:image_double_buffered) { |x, y|
1693
+ [y%255, x%255, (x+y)%255]
1694
+ }
1695
+ }.open
1696
+ ```
1697
+
1698
+ As they say, there are many ways to skin a cat! This is in line with the Ruby way of providing more ways than one. Pick and choose the right tool for the job just like true software engineers.
1511
1699
 
1512
1700
  ### Canvas Transform DSL
1513
1701
 
@@ -1574,7 +1762,7 @@ shell {
1574
1762
 
1575
1763
  #### Top-Level Transform Fluent Interface
1576
1764
 
1577
- When using a transform at the top-level (outside of shell), you get a fluent interface to faciliate manual constructioni and use.
1765
+ When using a transform at the top-level (outside of shell), you get a fluent interface to faciliate manual construction and use.
1578
1766
 
1579
1767
  Example:
1580
1768
 
@@ -1595,7 +1783,7 @@ Learn more at the [Hello, Canvas Transform! Sample](#hello-canvas-transform).
1595
1783
 
1596
1784
  ### Canvas Animation DSL
1597
1785
 
1598
- **(EARLY ALPHA FEATURE)**
1786
+ **(ALPHA FEATURE)**
1599
1787
 
1600
1788
  (note: this is a very new feature of Glimmer. It may change a bit while getting battle tested. As always, you could default to basic SWT usage if needed.)
1601
1789
 
@@ -1605,6 +1793,8 @@ Animations take advantage of multi-threading, automatically running each animati
1605
1793
 
1606
1794
  Multiple simultaneous animations are supported by declaring an animation per `canvas` (or widget) parent.
1607
1795
 
1796
+ `canvas` has the `:double_buffered` SWT style by default to ensure flicker-free rendering. If you need to disable it for whatever reason, just pass the `:none` SWT style instead (e.g. `canvas(:none)`)
1797
+
1608
1798
  This example says it all (it moves a tiny red square across a blue background) (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1609
1799
 
1610
1800
  ```ruby
@@ -1684,6 +1874,14 @@ the address of a contact. This is called nested property data binding.
1684
1874
 
1685
1875
  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)
1686
1876
 
1877
+ `text bind(contact, 'address.street', sync_exec: true)`
1878
+
1879
+ This example adds does GUI updates via [sync_exec](#sync_exec) assuming they are coming from another thread (different from the GUI thread)
1880
+
1881
+ `text bind(contact, 'address.street', async_exec: true)`
1882
+
1883
+ This example adds does GUI updates via [async_exec](#async_exec) assuming they are coming from another thread (different from the GUI thread)
1884
+
1687
1885
  `text bind(contact, 'address.street', on_read: lambda { |s| s[0..10] })`
1688
1886
 
1689
1887
  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`
@@ -2591,6 +2789,8 @@ To use, simply use `code_text` in place of the `text` or `styled_text` widget. I
2591
2789
  **lines**
2592
2790
  (default: `false`)
2593
2791
 
2792
+ **(BETA FEATURE)**
2793
+
2594
2794
  Shows line numbers when set to true.
2595
2795
 
2596
2796
  If set to a hash like `{width: 4}`, it sets the initial width of the line numbers lane in character count (default: 4)
@@ -2600,6 +2800,8 @@ Keep in mind that if the text grows and required a wider line numbers area, it g
2600
2800
  **theme**
2601
2801
  (default: `'glimmer'`)
2602
2802
 
2803
+ **(BETA FEATURE)**
2804
+
2603
2805
  Changes syntax color highlighting theme. Can be one of the following:
2604
2806
  - glimmer
2605
2807
  - github
@@ -2608,6 +2810,8 @@ Changes syntax color highlighting theme. Can be one of the following:
2608
2810
  **language**
2609
2811
  (default: `'ruby'`)
2610
2812
 
2813
+ **(BETA FEATURE)**
2814
+
2611
2815
  Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
2612
2816
  - abap
2613
2817
  - actionscript
@@ -2817,10 +3021,13 @@ Sets the code language, which can be one of the following [rouge gem](#https://r
2817
3021
  **default_behavior**
2818
3022
  (default: true)
2819
3023
 
3024
+ **(BETA FEATURE)**
3025
+
2820
3026
  This adds some default keyboard shortcuts:
2821
3027
  - CMD+A (CTRL+A on Windows/Linux) to select all
2822
3028
  - CTRL+A on Mac to jump to beginning of line
2823
3029
  - CTRL+E on Mac to jump to end of line
3030
+ - Attempts to add proper indentation upon adding a new line when hitting ENTER (currently supporting Ruby only)
2824
3031
 
2825
3032
  If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
2826
3033