glimmer-dsl-swt 4.18.4.9 → 4.18.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -0
  3. data/README.md +14 -5
  4. data/VERSION +1 -1
  5. data/bin/glimmer +3 -3
  6. data/docs/reference/GLIMMER_CONFIGURATION.md +7 -3
  7. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +464 -149
  8. data/docs/reference/GLIMMER_SAMPLES.md +91 -4
  9. data/glimmer-dsl-swt.gemspec +24 -13
  10. data/lib/ext/glimmer/config.rb +3 -7
  11. data/lib/glimmer/data_binding/list_selection_binding.rb +13 -7
  12. data/lib/glimmer/data_binding/table_items_binding.rb +22 -17
  13. data/lib/glimmer/data_binding/tree_items_binding.rb +19 -15
  14. data/lib/glimmer/data_binding/widget_binding.rb +13 -15
  15. data/lib/glimmer/dsl/swt/{file_dialog_expression.rb → auto_exec_expression.rb} +6 -18
  16. data/lib/glimmer/dsl/swt/checkbox_group_selection_data_binding_expression.rb +9 -6
  17. data/lib/glimmer/dsl/swt/color_expression.rb +1 -1
  18. data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +16 -14
  19. data/lib/glimmer/dsl/swt/custom_widget_expression.rb +4 -1
  20. data/lib/glimmer/dsl/swt/data_binding_expression.rb +2 -2
  21. data/lib/glimmer/dsl/swt/dialog_expression.rb +18 -9
  22. data/lib/glimmer/dsl/swt/dsl.rb +1 -0
  23. data/lib/glimmer/dsl/swt/exec_expression.rb +1 -1
  24. data/lib/glimmer/dsl/swt/font_expression.rb +1 -1
  25. data/lib/glimmer/dsl/swt/image_expression.rb +16 -2
  26. data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +11 -8
  27. data/lib/glimmer/dsl/swt/pixel_expression.rb +1 -1
  28. data/lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb +8 -5
  29. data/lib/glimmer/dsl/swt/shape_expression.rb +2 -2
  30. data/lib/glimmer/dsl/swt/shell_expression.rb +5 -2
  31. data/lib/glimmer/dsl/swt/widget_expression.rb +8 -4
  32. data/lib/glimmer/launcher.rb +3 -0
  33. data/lib/glimmer/rake_task/scaffold.rb +3 -0
  34. data/lib/glimmer/swt/color_proxy.rb +1 -1
  35. data/lib/glimmer/swt/custom/code_text.rb +33 -11
  36. data/lib/glimmer/swt/custom/drawable.rb +55 -0
  37. data/lib/glimmer/swt/custom/shape.rb +187 -43
  38. data/lib/glimmer/swt/custom/shape/arc.rb +60 -0
  39. data/lib/glimmer/{dsl/swt/directory_dialog_expression.rb → swt/custom/shape/focus.rb} +15 -20
  40. data/lib/glimmer/swt/custom/shape/image.rb +99 -0
  41. data/lib/glimmer/swt/custom/shape/line.rb +65 -0
  42. data/lib/glimmer/swt/custom/shape/oval.rb +61 -0
  43. data/lib/glimmer/swt/custom/shape/point.rb +54 -0
  44. data/lib/glimmer/swt/custom/shape/polygon.rb +73 -0
  45. data/lib/glimmer/swt/custom/shape/polyline.rb +74 -0
  46. data/lib/glimmer/swt/custom/shape/rectangle.rb +101 -0
  47. data/lib/glimmer/swt/custom/shape/text.rb +85 -0
  48. data/lib/glimmer/swt/date_time_proxy.rb +9 -3
  49. data/lib/glimmer/swt/dialog_proxy.rb +92 -0
  50. data/lib/glimmer/swt/display_proxy.rb +62 -2
  51. data/lib/glimmer/swt/expand_item_proxy.rb +18 -12
  52. data/lib/glimmer/swt/font_proxy.rb +13 -7
  53. data/lib/glimmer/swt/image_proxy.rb +15 -4
  54. data/lib/glimmer/swt/layout_data_proxy.rb +21 -15
  55. data/lib/glimmer/swt/layout_proxy.rb +19 -15
  56. data/lib/glimmer/swt/menu_proxy.rb +2 -2
  57. data/lib/glimmer/swt/message_box_proxy.rb +21 -7
  58. data/lib/glimmer/swt/properties.rb +3 -0
  59. data/lib/glimmer/swt/proxy_properties.rb +145 -0
  60. data/lib/glimmer/swt/scrolled_composite_proxy.rb +6 -2
  61. data/lib/glimmer/swt/shell_proxy.rb +96 -80
  62. data/lib/glimmer/swt/swt_proxy.rb +17 -0
  63. data/lib/glimmer/swt/tab_item_proxy.rb +5 -3
  64. data/lib/glimmer/swt/table_proxy.rb +32 -11
  65. data/lib/glimmer/swt/transform_proxy.rb +39 -35
  66. data/lib/glimmer/swt/tree_proxy.rb +11 -16
  67. data/lib/glimmer/swt/widget_listener_proxy.rb +6 -2
  68. data/lib/glimmer/swt/widget_proxy.rb +192 -141
  69. data/lib/glimmer/ui.rb +5 -0
  70. data/lib/glimmer/ui/custom_shell.rb +13 -7
  71. data/lib/glimmer/ui/custom_widget.rb +4 -5
  72. data/samples/elaborate/contact_manager.rb +7 -7
  73. data/samples/elaborate/login.rb +25 -21
  74. data/samples/elaborate/mandelbrot_fractal.rb +87 -31
  75. data/samples/elaborate/meta_sample.rb +1 -1
  76. data/samples/elaborate/tetris.rb +1 -0
  77. data/samples/elaborate/tic_tac_toe.rb +16 -14
  78. data/samples/elaborate/tic_tac_toe/board.rb +5 -5
  79. data/samples/elaborate/tic_tac_toe/cell.rb +5 -5
  80. data/samples/hello/hello_button.rb +7 -7
  81. data/samples/hello/hello_canvas.rb +143 -41
  82. data/samples/hello/hello_checkbox.rb +16 -14
  83. data/samples/hello/hello_checkbox_group.rb +11 -9
  84. data/samples/hello/hello_color_dialog.rb +66 -0
  85. data/samples/hello/hello_combo.rb +14 -12
  86. data/samples/hello/hello_computed.rb +7 -7
  87. data/samples/hello/hello_cursor.rb +2 -1
  88. data/samples/hello/hello_custom_shell.rb +17 -21
  89. data/samples/hello/hello_custom_widget.rb +4 -6
  90. data/samples/hello/hello_date_time.rb +14 -12
  91. data/samples/hello/hello_directory_dialog.rb +7 -7
  92. data/samples/hello/hello_expand_bar.rb +8 -8
  93. data/samples/hello/hello_file_dialog.rb +7 -7
  94. data/samples/hello/hello_font_dialog.rb +82 -0
  95. data/samples/hello/hello_group.rb +18 -16
  96. data/samples/hello/hello_list_multi_selection.rb +13 -11
  97. data/samples/hello/hello_list_single_selection.rb +13 -11
  98. data/samples/hello/hello_progress_bar.rb +125 -0
  99. data/samples/hello/hello_radio.rb +18 -16
  100. data/samples/hello/hello_radio_group.rb +14 -12
  101. data/samples/hello/hello_spinner.rb +7 -7
  102. data/samples/hello/hello_tab.rb +5 -5
  103. data/samples/hello/hello_table.rb +10 -5
  104. data/samples/hello/hello_tree.rb +485 -0
  105. metadata +22 -22
  106. data/lib/glimmer/swt/directory_dialog_proxy.rb +0 -65
  107. data/lib/glimmer/swt/file_dialog_proxy.rb +0 -66
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 641e17b39e98692f1c617da255c89361cdc49431fd77b20304fc08d4dc5fc301
4
- data.tar.gz: 69549df2a3bf84d28445a9ba33cac1a3c4fb546927c3cb706c7cf5078e8094bb
3
+ metadata.gz: 03f0ab47e7617c3d595a737c755ddc05e877074fb9139cacca042c6c31f7999e
4
+ data.tar.gz: f80117653d4ce70cfde372cbe660ab4d0a7ae181a24df76c79226fcb43c68549
5
5
  SHA512:
6
- metadata.gz: da95d92eadd7d0f768ab4945f57e9a6f582d7de7f1e4ac4eac65acc28de8628549aa2f0575ebbe34b964afb3e8616fe68e99fb8b9cc2084269707bd8edebf501
7
- data.tar.gz: 77d070eaccd04104effb26b1fcc6914d5a9a0f4b381950220090293ac1a20cd1d8fe73daf55e00ba677b31a043038f557d75200b610237eec36c8f30893d7bd8
6
+ metadata.gz: a543129ea30b6a18306341b9fad1f62a36f919d83cedc27ea5b6e62c18e13827b28e05cbb01c81e0d8639d5412aeb6ba2e81de60e4c7f0ba5052b474eb07b7f3
7
+ data.tar.gz: 8d757538764f6018a381bcc68583b2d2660d23c9a2f8f1b15c90ad904b84316b1a4e61197f1f618a2bb42ad5d2114cc087e9aaebe1538514a24b330bdf8ce44f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,78 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.5.2
4
+
5
+ - Support checking if an `arc` shape accurately includes a point x,y coordinates within pie region only
6
+ - Support checking if an `oval` shape includes a point x,y coordinates in oval region only (not its rectangular region)
7
+ - Support checking if a `focus` shape includes a point x,y coordinates
8
+ - Support checking point inclusion differently in drawed vs filled Rectangle (only check the drawn border when not filled)
9
+ - Support checking point inclusion differently in drawed vs filled Oval (only check the drawn border when not filled)
10
+ - Support checking point inclusion differently in drawed vs filled Arc (only check the drawn border when not filled)
11
+ - Support `#include?(x, y)` and `#contain?(x, y)` methods in `text` shape
12
+ - Fix point inclusion check for polyline
13
+ - Fix issue with `polygon` check if it includes a point x,y coordinates (replace with available `java.awt` robust geometry algorithms)
14
+ - Fix issue with transforms not working after the latest changes
15
+
16
+ ### 4.18.5.1
17
+
18
+ - Hello, Color Dialog! Sample
19
+ - Hello, Font Dialog! Sample
20
+ - Handle SWT RGB color data objects when setting colors on widgets (e.g. background)
21
+ - Enhance Hello, Canvas! with Color selector via right-click menu
22
+ - Fixed issue with tree multi selection throwing an exception
23
+
24
+ ### 4.18.5.0
25
+
26
+ - Automatic `sync_exec` usage from threads other than the GUI thread, thus absolving software engineers from the need to use `sync_exec` explicitly anymore.
27
+ - `auto_exec` keyword to automatically use `sync_exec` with SWT code when needed (running from a thread other than GUI thread)
28
+ - Implement `sync_exec:` option in `bind` keyword with table, tree, combo, and list data-binding (other data-binding types than the standard)
29
+ - Add `async_exec` option to `bind` keyword (covering `data_binding_expression.rb` with `async_exec` properly)
30
+ - Support tree multi-selection data-binding
31
+ - Hello, Tree! sample
32
+ - Enhance Hello, Canvas! with Shape Movement
33
+ - Add Jars.lock to scaffold .gitignore file
34
+ - Add Glimmer::GUI alias for Glimmer::UI module, thus permitting inclusion of Glimmer::GUI::CustomWidget, Glimmer::GUI::CustomShell, and Glimmer::GUI::CustomWindow
35
+ - Provide a quick method for grabbing all available cursor/color options off of SWTProxy (SWTProxy.cursor_options, SWTProxy.cursor_styles, SWTProxy.color_options, SWTProxy.color_styles)
36
+ - Remove explicit git gem dependency given that it is installed via juwelier during scaffolding and is not needed otherwise
37
+ - Support partial image shape drawing by passing source and destination dimensions to `image` shape [documented in docs]
38
+ - Support alternate Canvas Shape DSL syntax for `image` by passing nested properties
39
+ - Canvas Shape DSL argument data-binding support for `image`
40
+ - Support alternate Canvas Shape DSL syntax for `rectangle` by passing nested properties
41
+ - Canvas Shape DSL argument data-binding support for `rectangle(x, y, width, height, fill: false)` standard rectangle, which can be optionally filled
42
+ - Canvas Shape DSL argument data-binding support for `rectangle(x, y, width, height, arcWidth = 60, arcHeight = 60, fill: false, round: true)` round rectangle, which can be optionally filled, and takes optional extra round angle arguments
43
+ - Canvas Shape DSL argument data-binding support for `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
44
+ - Canvas Shape DSL argument data-binding support for `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)
45
+ - Canvas Shape DSL argument data-binding support for `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)
46
+ - Canvas Shape DSL argument data-binding support for `line(x1, y1, x2, y2)` line
47
+ - Canvas Shape DSL argument data-binding support for `oval(x, y, width, height, fill: false)` oval if width does not match heigh and circle if width matches height. Can be optionally filled.
48
+ - Canvas Shape DSL argument data-binding support for `point(x, y)` point
49
+ - Canvas Shape DSL argument data-binding support for `polygon(pointArray, fill: false)` polygon consisting of points, which close automatically to form a shape that can be optionally filled (when points only form a line, it does not show up as filled)
50
+ - Canvas Shape DSL argument data-binding support for `polyline(pointArray)` polyline is just like a polygon, but it does not close up to form a shape, remaining open (unless the points close themselves by having the last point or an intermediate point match the first)
51
+ - Canvas Shape DSL argument data-binding support for `text(string, x, y, flags = nil)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be :draw_delimiter (i.e. new lines), :draw_tab, :draw_mnemonic, and :draw_transparent as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
52
+ - Update Hello, Button!, Hello, Table! sample, Hello, Checkbox Group! sample, Hello, Radio Group! sample, Hello, Combo! sample, Hello, List Single Selection! sample, Hello, List Multi Selection! sample to utilize a CustomShell
53
+ - Refactor all samples to rely on Glimmer::UI::CustomShell given its new class launch method for productive app declaration
54
+ - Fix issue with logging remaining async in debug mode
55
+ - Fix issue with combo, list, radio group, and checkbox group not supporting nested data-binding
56
+
57
+ ### 4.18.4.11
58
+
59
+ - 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
60
+ - Add proper indentation in code_text upon hitting ENTER
61
+ - Reset Canvas Shape DSL alpha value to 255 when not explicitly set on a shape (Apply in Hello, Canvas! Sample)
62
+ - Provide terse syntax for building canvas objects (autodetecting its width and height)
63
+ - Provide terse syntax for building `:image_double_buffered` canvas objects (autodetecting its width and height):
64
+ - Center mandelbrot where mouse is clicked upon zoom
65
+ - Fix issue with Mandelbrot sample off by one error on Cores selected via Menu
66
+ - Fix use of on_events in code_text widget with lines mode true
67
+
68
+ ### 4.18.4.10
69
+
70
+ - Hello, Progress Bar!
71
+ - 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
72
+ - `bind` option of `async_exec` or `sync_exec` (e.g. `bind(model, :property, async_exec: true)`) to perform GUI updates from another thread safely
73
+ - Show progress bar for Mandelbrot calculation
74
+ - Mandelbrot Cores menu options to switch the number of CPU cores being used for calculation on the next zoom calculation cycle
75
+
3
76
  ### 4.18.4.9
4
77
 
5
78
  - 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.9
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.5.2
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.9
345
+ jgem install glimmer-dsl-swt -v 4.18.5.2
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.9'
363
+ gem 'glimmer-dsl-swt', '~> 4.18.5.2'
364
364
  ```
365
365
 
366
366
  And, then run:
@@ -404,10 +404,19 @@ Glimmer configuration may be done via the `Glimmer::Config` module.
404
404
 
405
405
  ## Samples
406
406
 
407
- Check the [samples](samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer samples` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`).
407
+ See a listing of samples over here, including screenshots and explanations of what each sample demonstrates:
408
408
 
409
409
  [docs/reference/GLIMMER_SAMPLES.md](docs/reference/GLIMMER_SAMPLES.md)
410
410
 
411
+ Check the [samples](samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer-dsl-swt` gem first and then run:
412
+ ```
413
+ glimmer samples
414
+ ```
415
+
416
+ (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`)
417
+
418
+ ![Glimmer Meta-Sample](/images/glimmer-meta-sample.png)
419
+
411
420
  ## In Production
412
421
 
413
422
  The following production apps have been built with Glimmer.
@@ -432,7 +441,7 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
432
441
 
433
442
  ### Connector
434
443
 
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 web browser
444
+ [<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
445
 
437
446
  ## Packaging & Distribution
438
447
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.4.9
1
+ 4.18.5.2
data/bin/glimmer CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env jruby
2
2
 
3
3
  # Copyright (c) 2007-2021 Andy Maleh
4
- #
4
+ #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining
6
6
  # a copy of this software and associated documentation files (the
7
7
  # "Software"), to deal in the Software without restriction, including
@@ -9,10 +9,10 @@
9
9
  # distribute, sublicense, and/or sell copies of the Software, and to
10
10
  # permit persons to whom the Software is furnished to do so, subject to
11
11
  # the following conditions:
12
- #
12
+ #
13
13
  # The above copyright notice and this permission notice shall be
14
14
  # included in all copies or substantial portions of the Software.
15
- #
15
+ #
16
16
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
17
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
18
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -170,11 +170,15 @@ This just tells Glimmer whether to log excluded keywords or not (at the debug le
170
170
 
171
171
  ### auto_sync_exec
172
172
 
173
- (default = false)
173
+ (default = true)
174
+
175
+ This automatically uses sync_exec on GUI calls from threads other than the main GUI thread instead of requiring users to manually use sync_exec.
174
176
 
175
- This automatically uses sync_exec on GUI calls from threads other than the main GUI thread instead of requiring users to manually use sync_exec. Default value to false.
177
+ Keep in mind that this could cause redraws on every minor change in the models instead of applying large scope changes together.
178
+ In rare cases where you need to avoid causing stutter in the GUI as a result, you can wrap large-scale GUI updates in `auto_exec` manually.
176
179
 
177
- Keep in mind the caveat that it would force redraws on every minor changein the models instead of applying large scope changes all together, thus causing too much drawing/stutter in the GUI. As such, this is a good fit for simpler GUIs, not ones used with highly sophisticated 2D graphics. It may be mitigated in the future by introducing the idea of large-scale observation events that wrap around smaller events. Until then, keep the caveat in mind or just use sync_exec manually as usually done with Java SWT apps.
180
+ As such, this saves developers a lot of headache by not requiring wrapping every bit of GUI update in other threads with `sync_exec`, yet only
181
+ large scale updates in the rare cases where optimization is needed.
178
182
 
179
183
  ## License
180
184
 
@@ -1,7 +1,96 @@
1
- ## Glimmer GUI DSL Syntax
2
-
3
1
  This guide should help you get started with Glimmer DSL for SWT. For more advanced SWT details, please refer to the [SWT Reference](/README.md#swt-reference).
4
2
 
3
+ - [Glimmer GUI DSL Syntax](#glimmer-gui-dsl-syntax)
4
+ - [DSL Auto-Expansion](#dsl-auto-expansion)
5
+ - [Widgets](#widgets)
6
+ - [Glimmer GUI DSL Keywords](#glimmer-gui-dsl-keywords)
7
+ - [SWT Proxies](#swt-proxies)
8
+ - [swt_widget](#swt_widget)
9
+ - [Shell widget proxy methods](#shell-widget-proxy-methods)
10
+ - [Widget Content Block](#widget-content-block)
11
+ - [Shell Icon](#shell-icon)
12
+ - [Shell Icon Tip for Packaging on Windows](#shell-icon-tip-for-packaging-on-windows)
13
+ - [Dialog](#dialog)
14
+ - [message_box](#message_box)
15
+ - [Display](#display)
16
+ - [Multi-Threading](#multi-threading)
17
+ - [async_exec](#async_exec)
18
+ - [sync_exec](#sync_exec)
19
+ - [timer_exec](#timer_exec)
20
+ - [Menus](#menus)
21
+ - [ScrolledComposite](#scrolledcomposite)
22
+ - [Sash Form Widget](#sash-form-widget)
23
+ - [Browser Widget](#browser-widget)
24
+ - [Widget Styles](#widget-styles)
25
+ - [Explicit SWT Style Bit](#explicit-swt-style-bit)
26
+ - [Negative SWT Style Bits](#negative-swt-style-bits)
27
+ - [Extra SWT Styles](#extra-swt-styles)
28
+ - [Non-resizable Window](#non-resizable-window)
29
+ - [Widget Properties](#widget-properties)
30
+ - [Color](#color)
31
+ - [`#swt_color`](#swt_color)
32
+ - [Font](#font)
33
+ - [Image](#image)
34
+ - [Image Options](#image-options)
35
+ - [Cursor](#cursor)
36
+ - [Layouts](#layouts)
37
+ - [Layout Data](#layout-data)
38
+ - [Canvas Shape DSL](#canvas-shape-dsl)
39
+ - [Shapes inside a Widget](#shapes-inside-a-widget)
40
+ - [Shapes inside an Image](#shapes-inside-an-image)
41
+ - [Canvas Shape API](#canvas-shape-api)
42
+ - [Pixel Graphics](#pixel-graphics)
43
+ - [Canvas Transform DSL](#canvas-transform-dsl)
44
+ - [Top-Level Transform Fluent Interface](#top-level-transform-fluent-interface)
45
+ - [Canvas Animation DSL](#canvas-animation-dsl)
46
+ - [Animation via Data-Binding](#animation-via-data-binding)
47
+ - [Data-Binding](#data-binding)
48
+ - [General Examples](#general-examples)
49
+ - [Combo](#combo)
50
+ - [List](#list)
51
+ - [Table](#table)
52
+ - [Table Selection](#table-selection)
53
+ - [Table Editing](#table-editing)
54
+ - [Table Sorting](#table-sorting)
55
+ - [Tree](#tree)
56
+ - [DateTime](#datetime)
57
+ - [Observer](#observer)
58
+ - [Observing Widgets](#observing-widgets)
59
+ - [Alternative Syntax](#alternative-syntax)
60
+ - [Observing Models](#observing-models)
61
+ - [Custom Widgets](#custom-widgets)
62
+ - [Simple Example](#simple-example)
63
+ - [Method-Based Custom Widget Example](#method-based-custom-widget-example)
64
+ - [Class-Based Custom Widget Example](#class-based-custom-widget-example)
65
+ - [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
66
+ - [Lifecycle Hooks Example](#lifecycle-hooks-example)
67
+ - [Custom Widget API](#custom-widget-api)
68
+ - [Content/Options Example](#contentoptions-example)
69
+ - [Custom Widget Gotchas](#custom-widget-gotchas)
70
+ - [Built-In Custom Widgets](#built-in-custom-widgets)
71
+ - [Checkbox Group Custom Widget](#checkbox-group-custom-widget)
72
+ - [Radio Group Custom Widget](#radio-group-custom-widget)
73
+ - [Code Text Custom Widget](#code-text-custom-widget)
74
+ - [Options](#options)
75
+ - [Video Custom Custom Widget](#video-custom-custom-widget)
76
+ - [Custom Widget Final Notes](#custom-widget-final-notes)
77
+ - [Custom Shells](#custom-shells)
78
+ - [Drag and Drop](#drag-and-drop)
79
+ - [Miscellaneous](#miscellaneous)
80
+ - [Multi-DSL Support](#multi-dsl-support)
81
+ - [SWT](#swt)
82
+ - [Opal](#opal)
83
+ - [XML](#xml)
84
+ - [CSS](#css)
85
+ - [Listing / Enabling / Disabling DSLs](#listing--enabling--disabling-dsls)
86
+ - [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
87
+ - [App Name and Version](#app-name-and-version)
88
+ - [Performance Profiling](#performance-profiling)
89
+ - [SWT Browser Style Options](#swt-browser-style-options)
90
+ - [License](#license)
91
+
92
+ ## Glimmer GUI DSL Syntax
93
+
5
94
  Glimmer's core is a GUI DSL with a lightweight visual syntax that makes it easy to visualize the nesting of widgets in the GUI hierarchy tree.
6
95
 
7
96
  It is available through mixing in the `Glimmer` module, which makes [Glimmer GUI DSL Keywords](#glimmer-gui-dsl-keywords) available to both the instance scope and class scope:
@@ -201,62 +290,63 @@ https://www.eclipse.org/nebula/
201
290
  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
291
 
203
292
  **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)
293
+ - `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)
294
+ - `browser`: featured in [Hello, Browser!](GLIMMER_SAMPLES.md#hello-browser)
295
+ - `calendar`: featured in [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
296
+ - `checkbox`: featured in [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) / [Hello, Checkbox!](GLIMMER_SAMPLES.md#hello-checkbox)
297
+ - `checkbox_group`: featured in [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group)
298
+ - `combo`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Combo!](GLIMMER_SAMPLES.md#hello-combo)
299
+ - `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)
300
+ - `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)
301
+ - `date_drop_down`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
302
+ - `group`: featured in [Hello, Group!](GLIMMER_SAMPLES.md#hello-group) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
303
+ - `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)
304
+ - `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)
305
+ - `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)
306
+ - `menu_bar`: featured in [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
307
+ - `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)
308
+ - `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)
309
+ - `radio`: featured in [Hello, Radio!](GLIMMER_SAMPLES.md#hello-radio) / [Hello, Group!](GLIMMER_SAMPLES.md#hello-group)
310
+ - `radio_group`: featured in [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group)
222
311
  - `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)
312
+ - `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)
313
+ - `tab_folder`: featured in [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab)
314
+ - `tab_item`: featured in [Hello, Tab!](GLIMMER_SAMPLES.md#hello-tab)
315
+ - `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)
316
+ - `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)
317
+ - `text`: featured in [Hello, Computed!](GLIMMER_SAMPLES.md#hello-computed) / [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
318
+ - `time`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time)
319
+ - Glimmer::UI::CustomWidget: ability to define any keyword as a custom widget - featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget)
320
+ - 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
321
 
233
322
  **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)
323
+ - `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)
324
+ - `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)
325
+ - `fill_layout`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget)
326
+ - `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
327
 
239
328
  **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)
329
+ - `color`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Menu Bar!](GLIMMER_SAMPLES.md#hello-menu-bar)
330
+ - `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
331
  - `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)
332
+ - `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
333
 
245
334
  **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)
335
+ - `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)
336
+ - `observe`: featured in [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) / [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
337
+ - `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
338
  - `on_modify_text`
250
- - `on_key_pressed` (and SWT alias `on_swt_keydown`) - featured in [Login](#login) / [Contact Manager](#contact-manager)
339
+ - `on_key_pressed` (and SWT alias `on_swt_keydown`) - featured in [Login](GLIMMER_SAMPLES.md#login) / [Contact Manager](GLIMMER_SAMPLES.md#contact-manager)
251
340
  - `on_key_released` (and SWT alias `on_swt_keyup`)
252
341
  - `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)
342
+ - `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
343
 
255
344
  **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)
345
+ - `display`: featured in [Tic Tac Toe](GLIMMER_SAMPLES.md#tic-tac-toe)
346
+ - `async_exec`: featured in [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) / [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell)
258
347
  - `sync_exec`: executes a block on the event loop synchronously (usually from another thread)
259
348
  - `timer_exec`: executes a block after a delay of time has passed
349
+ - `auto_exec`: executes a block on the event loop synchronously only when needed (when running from a thread other than GUI thread)
260
350
 
261
351
  #### SWT Proxies
262
352
 
@@ -334,7 +424,7 @@ shell {
334
424
 
335
425
  ###### Shell Icon Tip for Packaging on Windows
336
426
 
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'`)
427
+ 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
428
 
339
429
  #### Dialog
340
430
 
@@ -342,7 +432,7 @@ Dialog is a variation on Shell. It is basically a shell that is modal (blocks wh
342
432
 
343
433
  Glimmer facilitates building dialogs by using the `dialog` keyword, which automatically adds the SWT.DIALOG_TRIM and SWT.APPLICATION_MODAL [widget styles](#widget-styles) needed for a dialog.
344
434
 
345
- Check out [Hello, Dialog!](#hello-dialog) sample to learn more.
435
+ Check out [Hello, Dialog!](GLIMMER_SAMPLES.md#hello-dialog) sample to learn more.
346
436
 
347
437
  ##### message_box
348
438
 
@@ -411,6 +501,15 @@ Although SWT Display is not technically a widget, it has similar APIs and DSL su
411
501
 
412
502
  [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
503
 
504
+ 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).
505
+
506
+ 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).
507
+
508
+ One thing Glimmer DSL for SWT innovates over plain old SWT is not requiring developers to explicitly use `Display.syncExec` from threads other than the GUI threads.
509
+ Glimmer automatically detects if you're running in a different thread and uses `Display.syncExec` automatically using its own enhanced `auto_exec`
510
+
511
+ In any case, Glimmer still allows developers to manually use `sync_exec`, `async_exec`, `timer_exec`, and `auto_exec` when needed. M
512
+
414
513
  ##### async_exec
415
514
 
416
515
  `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.
@@ -441,7 +540,11 @@ Thread.new {
441
540
 
442
541
  ##### sync_exec
443
542
 
444
- `sync_exec {}` works just like `async_exec` except it executes the block synchronously at the earliest opportunity possible, waiting for the block to be finished.
543
+ `sync_exec {}` is required by SWT when running GUI update from a thread other than the GUI thread. In Glimmer, it is automatically invoked for you so that you wouldn't have to worry about it. It works just like `async_exec` except it executes the block synchronously at the earliest opportunity possible, waiting for the block to be finished.
544
+
545
+ ##### auto_exec
546
+
547
+ `auto_exec(override_sync_exec:, override_async_exec) {}` only executes code block with `sync_exec` when necessary (running from a thread other than the GUI thread). It is used automatically all over the Glimmer DSL for SWT codebase, so you wouldn't need it unless you grab a direct handle on `swt_widget` from a widget proxy.
445
548
 
446
549
  ##### timer_exec
447
550
 
@@ -792,7 +895,7 @@ shell {
792
895
  }.open
793
896
  ```
794
897
 
795
- You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash-form)
898
+ You may check out a more full-fledged example in [Hello, Sash Form!](GLIMMER_SAMPLES.md#hello-sash-form)
796
899
 
797
900
  ![Hello Sash Form](/images/glimmer-hello-sash-form.png)
798
901
 
@@ -1284,7 +1387,7 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
1284
1387
 
1285
1388
  Glimmer supports drawing graphics directly on a `canvas` widget via SWT (or any widget for that matter though `canvas` is recommended for drawing).
1286
1389
 
1287
- `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)`)
1390
+ `canvas` has the `:double_buffered` SWT style by default on platforms that need it (Windows & Linux) 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)`)
1288
1391
 
1289
1392
  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.
1290
1393
 
@@ -1292,6 +1395,7 @@ Shape keywords and their args (including defaults) are listed below (they basica
1292
1395
  - `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)
1293
1396
  - `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)
1294
1397
  - `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
1398
+ - `image(image, source_x, source_y, source_width, source_height, destination_x, destination_y, destination_width, destination_height)` sets part of an [image](#image) and scales it to fit destination dimensions on parent canvas/widget
1295
1399
  - `line(x1, y1, x2, y2)` line
1296
1400
  - `oval(x, y, width, height, fill: false)` oval if width does not match heigh and circle if width matches height. Can be optionally filled.
1297
1401
  - `point(x, y)` point
@@ -1300,9 +1404,10 @@ Shape keywords and their args (including defaults) are listed below (they basica
1300
1404
  - `rectangle(x, y, width, height, fill: false)` standard rectangle, which can be optionally filled
1301
1405
  - `rectangle(x, y, width, height, arcWidth = 60, arcHeight = 60, fill: false, round: true)` round rectangle, which can be optionally filled, and takes optional extra round angle arguments
1302
1406
  - `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
1303
- - `text(string, x, y, flags = nil)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be :draw_delimiter (i.e. new lines), :draw_tab, :draw_mnemonic, and :draw_transparent as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
1407
+ - `text(string, x, y, is_transparent = true)` text with optional is_transparent to indicate if background is transparent (default is true)
1408
+ - `text(string, x, y, flags)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be :draw_delimiter (i.e. new lines), :draw_tab, :draw_mnemonic, and :draw_transparent as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
1304
1409
 
1305
- Shape keywords that can be filled with color can take an keyword argument `fill: true`. Defaults to false when not specified unless background is set with no foreground (or foreground is set with no background), in which case a smart default is applied.
1410
+ Shape keywords that can be filled with color can take a keyword argument `fill: true`. Defaults to false when not specified unless background is set with no foreground (or foreground is set with no background), in which case a smart default is applied.
1306
1411
  Smart defaults can be applied to automatically infer `gradient: true` (rectangle with both foreground and background) and `round: true` (rectangle with more than 4 args, the extra args are numeric) as well.
1307
1412
 
1308
1413
  Optionally, a shape keyword takes a block that can set any attributes from [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) (methods starting with `set`), which enable setting the `background` for filling and `foreground` for drawing.
@@ -1369,7 +1474,111 @@ Screenshot:
1369
1474
 
1370
1475
  ![Canvas Animation Example](/images/glimmer-example-canvas.png)
1371
1476
 
1372
- Learn more at the [Hello, Canvas! Sample](#hello-canvas).
1477
+ The round and gradient options could be dropped since Glimmer DSL for SWT supports auto-inference of them based on shape parameters.
1478
+
1479
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1480
+
1481
+ ```ruby
1482
+ include Glimmer
1483
+
1484
+ # image object has to be declared outside the canvas and shell to avoid confusing with canvas image property
1485
+ image_object = image(File.expand_path('./icons/scaffold_app.png'), width: 100)
1486
+
1487
+ shell {
1488
+ text 'Canvas Example'
1489
+ minimum_size 320, 400
1490
+
1491
+ canvas {
1492
+ background :dark_yellow
1493
+ rectangle(0, 0, 220, 400) {
1494
+ background :dark_red
1495
+ }
1496
+ rectangle(50, 20, 300, 150, 30, 50) {
1497
+ background :yellow
1498
+ }
1499
+ rectangle(150, 200, 100, 70, true) {
1500
+ background :dark_red
1501
+ foreground :yellow
1502
+ }
1503
+ text('Glimmer', 208, 83) {
1504
+ font height: 25, style: :bold
1505
+ }
1506
+ rectangle(200, 80, 108, 36) {
1507
+ foreground :black
1508
+ line_width 3
1509
+ }
1510
+ image(image_object, 70, 50)
1511
+ }
1512
+ }.open
1513
+ ```
1514
+
1515
+ Notice how the shape declaration parameters perfectly match the method parameters in the [SWT org.eclipse.swt.graphics.GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html). This is useful for developers coming to Glimmer DSL for SWT from SWT.
1516
+
1517
+ Of course, Glimmer DSL for SWT still supports an alternative syntax that is more declarative and consistent with the rest of the Glimmer GUI DSL syntax. This syntax in fact offers the extra-benefit of data-binding for shape parameter values (meaning you could use `bind(...)` syntax with them instead of setting values directly)
1518
+
1519
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1520
+
1521
+ ```ruby
1522
+ include Glimmer
1523
+
1524
+ # image object has to be declared outside the canvas and shell to avoid confusing with canvas image property
1525
+ image_object = image(File.expand_path('./icons/scaffold_app.png'), width: 100)
1526
+
1527
+ shell {
1528
+ text 'Canvas Example'
1529
+ minimum_size 320, 400
1530
+
1531
+ canvas {
1532
+ background :dark_yellow
1533
+ rectangle {
1534
+ x 0
1535
+ y 0
1536
+ width 220
1537
+ height 400
1538
+ background :dark_red
1539
+ }
1540
+ rectangle {
1541
+ x 50
1542
+ x 20
1543
+ width 300
1544
+ height 150
1545
+ arc_width 30
1546
+ arc_height 50
1547
+ background :yellow
1548
+ }
1549
+ rectangle {
1550
+ x 150
1551
+ y 200
1552
+ width 100
1553
+ height 70
1554
+ vertical true
1555
+ background :dark_red
1556
+ foreground :yellow
1557
+ }
1558
+ text {
1559
+ string 'Glimmer'
1560
+ x 208
1561
+ y 83
1562
+ font height: 25, style: :bold
1563
+ }
1564
+ rectangle {
1565
+ x 200
1566
+ y 80
1567
+ width 108
1568
+ height 36
1569
+ foreground :black
1570
+ line_width 3
1571
+ }
1572
+ image {
1573
+ image image_object
1574
+ x 70
1575
+ y 50
1576
+ }
1577
+ }
1578
+ }.open
1579
+ ```
1580
+
1581
+ Learn more at the [Hello, Canvas! Sample](GLIMMER_SAMPLES.md#hello-canvas).
1373
1582
 
1374
1583
  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).
1375
1584
 
@@ -1411,6 +1620,119 @@ shell {
1411
1620
  }.open
1412
1621
  ```
1413
1622
 
1623
+ #### Shapes inside a Widget
1624
+
1625
+ 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](GLIMMER_SAMPLES.md#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`.
1626
+
1627
+ #### Shapes inside an Image
1628
+
1629
+ You can build an image using the Canvas Shape DSL (including setting the icon of the application).
1630
+
1631
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1632
+
1633
+ ```
1634
+ include Glimmer
1635
+
1636
+ shell {
1637
+ text 'Image Shape DSL Example'
1638
+ label {
1639
+ bevel_constant = 20
1640
+ icon_block_size = 64
1641
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
1642
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1643
+ icon_size = 8
1644
+ icon_pixel_size = icon_block_size * icon_size
1645
+ image(icon_pixel_size, icon_pixel_size) {
1646
+ icon_size.times { |row|
1647
+ icon_size.times { |column|
1648
+ colored = row >= 1 && column.between?(1, 6)
1649
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1650
+ x = column * icon_block_size
1651
+ y = row * icon_block_size
1652
+ rectangle(x, y, icon_block_size, icon_block_size) {
1653
+ background color
1654
+ }
1655
+ polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1656
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1657
+ }
1658
+ polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
1659
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1660
+ }
1661
+ polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
1662
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1663
+ }
1664
+ polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1665
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1666
+ }
1667
+ }
1668
+ }
1669
+ }
1670
+ }
1671
+ }.open
1672
+ ```
1673
+
1674
+ ![Image Shape DSL](/images/glimmer-example-image-shape-dsl.png)
1675
+
1676
+ Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1677
+
1678
+ ```
1679
+ include Glimmer
1680
+
1681
+ shell {
1682
+ text 'Image Shape DSL Example'
1683
+ label {
1684
+ text 'Image Shape DSL Example'
1685
+ font height: 30
1686
+ }
1687
+ bevel_constant = 20
1688
+ icon_block_size = 64
1689
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
1690
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1691
+ icon_size = 8
1692
+ icon_pixel_size = icon_block_size * icon_size
1693
+ image(icon_pixel_size, icon_pixel_size) {
1694
+ icon_size.times { |row|
1695
+ icon_size.times { |column|
1696
+ colored = row >= 1 && column.between?(1, 6)
1697
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1698
+ x = column * icon_block_size
1699
+ y = row * icon_block_size
1700
+ rectangle(x, y, icon_block_size, icon_block_size) {
1701
+ background color
1702
+ }
1703
+ polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1704
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1705
+ }
1706
+ polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
1707
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1708
+ }
1709
+ polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
1710
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1711
+ }
1712
+ polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1713
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1714
+ }
1715
+ }
1716
+ }
1717
+ }
1718
+ }.open
1719
+ ```
1720
+
1721
+ ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1722
+
1723
+ #### Canvas Shape API
1724
+
1725
+ These Canvas Shape API methods help with manipulating shapes upon user interaction, such as mouse clicking a specific shape.
1726
+
1727
+ They are implemented with the help of the highly robust Java built-in shape geometry algorithms.
1728
+
1729
+ - `WidgetProxy#shape_at_location(x, y)` : returns shape object at x, y location from a widget proxy like canvas
1730
+ - `Shape#contain?(x, y)` : indicates if shape contains x, y point
1731
+ - `Shape#include?(x, y)` : indicates if shape includes x, y point on the edge if drawn or inside if filled (include uses contain for filled shapes)
1732
+ - `Shape#move_by(x_delta, y_delta)` : moves shape object at x, y location
1733
+
1734
+ Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example.
1735
+
1414
1736
  #### Pixel Graphics
1415
1737
 
1416
1738
  **(Early Alpha Feature)**
@@ -1440,6 +1762,21 @@ Result:
1440
1762
 
1441
1763
  ![glimmer example pixel graphics](/images/glimmer-example-pixel-graphics.png)
1442
1764
 
1765
+ 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:
1766
+
1767
+ ```ruby
1768
+ include Glimmer
1769
+
1770
+ shell {
1771
+ minimum_size 250, 265
1772
+ text 'Pixel Graphics Example'
1773
+
1774
+ canvas { |x, y|
1775
+ [y%255, x%255, (x+y)%255]
1776
+ }
1777
+ }.open
1778
+ ```
1779
+
1443
1780
  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).
1444
1781
 
1445
1782
  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)):
@@ -1465,6 +1802,8 @@ shell {
1465
1802
  }.open
1466
1803
  ```
1467
1804
 
1805
+ (the code could be optimized further if you are repeating colors by simply reusing `Color` objects instead of re-constructing them)
1806
+
1468
1807
  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.
1469
1808
 
1470
1809
  Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
@@ -1501,127 +1840,80 @@ If you need a transparent background for the image, replace the image constructi
1501
1840
 
1502
1841
  That way, wherever you don't draw a point, you get transparency (seeing what is behind the image).
1503
1842
 
1504
- 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)
1505
-
1506
- Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1843
+ 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.
1507
1844
 
1508
1845
  ```ruby
1509
1846
  include Glimmer
1510
1847
 
1848
+ @the_image = image(250, 250) {|x, y|
1849
+ [y%255, x%255, (x+y)%255]
1850
+ }
1851
+
1511
1852
  shell {
1512
1853
  minimum_size 250, 265
1513
1854
  text 'Pixel Graphics Example'
1855
+ image @the_image
1514
1856
 
1515
- canvas(:image_double_buffered) {
1516
- 250.times {|y|
1517
- 250.times {|x|
1518
- pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1519
- }
1520
- }
1857
+ canvas {
1858
+ image @the_image
1521
1859
  }
1522
1860
  }.open
1523
1861
  ```
1524
1862
 
1525
- #### Shapes inside a Widget
1863
+ 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).
1526
1864
 
1527
- 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`.
1865
+ ```ruby
1866
+ include Glimmer
1528
1867
 
1529
- #### Shapes inside an Image
1868
+ shell {
1869
+ minimum_size 250, 265
1870
+ text 'Pixel Graphics Example'
1871
+
1872
+ canvas {
1873
+ image image(250, 250, top_level: true) {|x, y|
1874
+ [y%255, x%255, (x+y)%255]
1875
+ }
1876
+ }
1877
+ }.open
1878
+ ```
1530
1879
 
1531
- You can build an image using the Canvas Shape DSL (including setting the icon of the application).
1880
+ 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)
1532
1881
 
1533
1882
  Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1534
1883
 
1535
- ```
1884
+ ```ruby
1536
1885
  include Glimmer
1537
1886
 
1538
1887
  shell {
1539
- text 'Image Shape DSL Example'
1540
- label {
1541
- bevel_constant = 20
1542
- icon_block_size = 64
1543
- icon_bevel_size = icon_block_size.to_f / 25.to_f
1544
- icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1545
- icon_size = 8
1546
- icon_pixel_size = icon_block_size * icon_size
1547
- image(icon_pixel_size, icon_pixel_size) {
1548
- icon_size.times { |row|
1549
- icon_size.times { |column|
1550
- colored = row >= 1 && column.between?(1, 6)
1551
- color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1552
- x = column * icon_block_size
1553
- y = row * icon_block_size
1554
- rectangle(x, y, icon_block_size, icon_block_size) {
1555
- background color
1556
- }
1557
- polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1558
- background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1559
- }
1560
- polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
1561
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1562
- }
1563
- polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
1564
- background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1565
- }
1566
- polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1567
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1568
- }
1569
- }
1888
+ minimum_size 250, 265
1889
+ text 'Pixel Graphics Example'
1890
+
1891
+ canvas(:image_double_buffered) {
1892
+ 250.times {|y|
1893
+ 250.times {|x|
1894
+ pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1570
1895
  }
1571
1896
  }
1572
1897
  }
1573
1898
  }.open
1574
1899
  ```
1575
1900
 
1576
- ![Image Shape DSL](/images/glimmer-example-image-shape-dsl.png)
1901
+ Of course, you could also take advantage of the pixel-less terser syntax:
1577
1902
 
1578
- Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1579
-
1580
- ```
1903
+ ```ruby
1581
1904
  include Glimmer
1582
1905
 
1583
1906
  shell {
1584
- text 'Image Shape DSL Example'
1585
- label {
1586
- text 'Image Shape DSL Example'
1587
- font height: 30
1588
- }
1589
- bevel_constant = 20
1590
- icon_block_size = 64
1591
- icon_bevel_size = icon_block_size.to_f / 25.to_f
1592
- icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1593
- icon_size = 8
1594
- icon_pixel_size = icon_block_size * icon_size
1595
- image(icon_pixel_size, icon_pixel_size) {
1596
- icon_size.times { |row|
1597
- icon_size.times { |column|
1598
- colored = row >= 1 && column.between?(1, 6)
1599
- color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1600
- x = column * icon_block_size
1601
- y = row * icon_block_size
1602
- rectangle(x, y, icon_block_size, icon_block_size) {
1603
- background color
1604
- }
1605
- polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1606
- background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1607
- }
1608
- polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
1609
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1610
- }
1611
- polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
1612
- background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1613
- }
1614
- polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
1615
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1616
- }
1617
- }
1618
- }
1907
+ minimum_size 250, 265
1908
+ text 'Pixel Graphics Example'
1909
+
1910
+ canvas(:image_double_buffered) { |x, y|
1911
+ [y%255, x%255, (x+y)%255]
1619
1912
  }
1620
1913
  }.open
1621
1914
  ```
1622
1915
 
1623
- ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1624
-
1916
+ 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.
1625
1917
 
1626
1918
  ### Canvas Transform DSL
1627
1919
 
@@ -1705,7 +1997,7 @@ transform(1, 1, 4, 2, 2, 4).
1705
1997
  translate(3, 7)
1706
1998
  ```
1707
1999
 
1708
- Learn more at the [Hello, Canvas Transform! Sample](#hello-canvas-transform).
2000
+ Learn more at the [Hello, Canvas Transform! Sample](GLIMMER_SAMPLES.md#hello-canvas-transform).
1709
2001
 
1710
2002
  ### Canvas Animation DSL
1711
2003
 
@@ -1771,7 +2063,7 @@ API of Animation Object (returned from `animation` keyword):
1771
2063
  - `#cycle_limited?` returns true if `cycle_count` is specified
1772
2064
  - `#duration_limited?` returns true if `duration_limit` is specified
1773
2065
 
1774
- Learn more at the [Hello, Canvas Animation! Sample](#hello-canvas-animation).
2066
+ Learn more at the [Hello, Canvas Animation! Sample](GLIMMER_SAMPLES.md#hello-canvas-animation).
1775
2067
 
1776
2068
  If there is anything missing you would like added to the Glimmer Animation DSL that you saw available in the SWT APIs, you may [report an issue](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) or implement yourself and [contribute](#contributing) via a Pull Request.
1777
2069
 
@@ -1779,7 +2071,7 @@ If there is anything missing you would like added to the Glimmer Animation DSL t
1779
2071
 
1780
2072
  Animation could be alternatively implemented without the `animation` keyword through a loop that invokes model methods inside `sync_exec {}` (or `async_exec {}`), which indirectly cause updates to the GUI via data-binding.
1781
2073
 
1782
- The [Glimmer Tetris](#glimmer-tetris) sample provides a good example of that.
2074
+ The [Glimmer Tetris](GLIMMER_SAMPLES.md#tetris) sample provides a good example of that.
1783
2075
 
1784
2076
  ### Data-Binding
1785
2077
 
@@ -1800,6 +2092,18 @@ the address of a contact. This is called nested property data binding.
1800
2092
 
1801
2093
  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
2094
 
2095
+ `text bind(contact, 'address.street', sync_exec: true)`
2096
+
2097
+ **(ALPHA FEATURE)**
2098
+
2099
+ This example forces GUI updates via [sync_exec](#sync_exec) assuming they are coming from another thread (different from the GUI thread)
2100
+
2101
+ `text bind(contact, 'address.street', async_exec: true)`
2102
+
2103
+ **(ALPHA FEATURE)**
2104
+
2105
+ This example forces GUI updates via [async_exec](#async_exec) assuming they are coming from another thread (different from the GUI thread)
2106
+
1803
2107
  `text bind(contact, 'address.street', on_read: lambda { |s| s[0..10] })`
1804
2108
 
1805
2109
  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`
@@ -2128,7 +2432,7 @@ shell {
2128
2432
  }
2129
2433
  ```
2130
2434
 
2131
- Check out [Hello, Table!](#hello-table) for an actual example including table editors.
2435
+ Check out [Hello, Table!](GLIMMER_SAMPLES.md#hello-table) for an actual example including table editors.
2132
2436
 
2133
2437
  [Are We There Yet?](#are-we-there-yet) is an actual production Glimmer application that takes full advantage of table capabilities, storing model data in a database via ActiveRecord. As such, it's an excellent demonstration of how to use Glimmer DSL for SWT with a database.
2134
2438
 
@@ -2136,7 +2440,7 @@ Check out [Hello, Table!](#hello-table) for an actual example including table ed
2136
2440
 
2137
2441
  Glimmer automatically adds sorting support to the SWT `Table` widget.
2138
2442
 
2139
- Check out the [Contact Manager](#contact-manager) sample for an example.
2443
+ Check out the [Contact Manager](GLIMMER_SAMPLES.md#contact-manager) sample for an example.
2140
2444
  You may click on any column and it will sort by ascending order first and descending if you click again.
2141
2445
 
2142
2446
  Glimmer automatic table sorting supports `String`, `Integer`, and `Float` columns out of the box as well as any column data that is comparable.
@@ -2235,6 +2539,8 @@ This finds the root node. The array is a Java array. This enables easy passing o
2235
2539
  To edit a tree, you must invoke `TreeProxy#edit_selected_tree_item` or `TreeProxy#edit_tree_item`. This automatically leverages the SWT TreeEditor custom class behind the scenes, displaying
2236
2540
  a text widget to the user to change the selected or passed tree item text into something else. It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
2237
2541
 
2542
+ Learn more at the [Hello, Tree!](GLIMMER_SAMPLES.md#hello-tree) and [Gladiator](GLIMMER_SAMPLES.md#gladiator) samples.
2543
+
2238
2544
  #### DateTime
2239
2545
 
2240
2546
  `date_time` represents the SWT DateTime widget.
@@ -2256,7 +2562,7 @@ You can data-bind any of these properties:
2256
2562
  - `minutes bind(model, :property)`: produces an integer
2257
2563
  - `seconds bind(model, :property)`: produces an integer
2258
2564
 
2259
- Learn more at the [Hello, Date Time!](#hello-date-time) sample.
2565
+ Learn more at the [Hello, Date Time!](GLIMMER_SAMPLES.md#hello-date-time) sample.
2260
2566
 
2261
2567
  If you need a better widget with the ability to customize the date format pattern, check out the [Nebula CDateTime Glimmer Custom Widget](https://github.com/AndyObtiva/glimmer-cw-cdatetime-nebula)
2262
2568
 
@@ -2642,7 +2948,7 @@ The `checkboxes` property returns the list of nested `checkbox` widgets.
2642
2948
 
2643
2949
  When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `activities_options` for `activities`) to provide an `Array` of `String` objects for `checkbox` buttons.
2644
2950
 
2645
- You may see an example at the [Hello, Checkbox Group!](#hello-checkbox-group) sample.
2951
+ You may see an example at the [Hello, Checkbox Group!](GLIMMER_SAMPLES.md#hello-checkbox-group) sample.
2646
2952
 
2647
2953
  ![Hello Checkbox Group](/images/glimmer-hello-checkbox-group.png)
2648
2954
 
@@ -2677,7 +2983,7 @@ radio_group { |radio_group_proxy|
2677
2983
  # ...
2678
2984
  ```
2679
2985
 
2680
- You may see another example at the [Hello, Radio Group!](#hello-radio-group) sample.
2986
+ You may see another example at the [Hello, Radio Group!](GLIMMER_SAMPLES.md#hello-radio-group) sample.
2681
2987
 
2682
2988
  ##### Code Text Custom Widget
2683
2989
 
@@ -2707,6 +3013,8 @@ To use, simply use `code_text` in place of the `text` or `styled_text` widget. I
2707
3013
  **lines**
2708
3014
  (default: `false`)
2709
3015
 
3016
+ **(BETA FEATURE)**
3017
+
2710
3018
  Shows line numbers when set to true.
2711
3019
 
2712
3020
  If set to a hash like `{width: 4}`, it sets the initial width of the line numbers lane in character count (default: 4)
@@ -2716,6 +3024,8 @@ Keep in mind that if the text grows and required a wider line numbers area, it g
2716
3024
  **theme**
2717
3025
  (default: `'glimmer'`)
2718
3026
 
3027
+ **(BETA FEATURE)**
3028
+
2719
3029
  Changes syntax color highlighting theme. Can be one of the following:
2720
3030
  - glimmer
2721
3031
  - github
@@ -2724,6 +3034,8 @@ Changes syntax color highlighting theme. Can be one of the following:
2724
3034
  **language**
2725
3035
  (default: `'ruby'`)
2726
3036
 
3037
+ **(BETA FEATURE)**
3038
+
2727
3039
  Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
2728
3040
  - abap
2729
3041
  - actionscript
@@ -2933,14 +3245,17 @@ Sets the code language, which can be one of the following [rouge gem](#https://r
2933
3245
  **default_behavior**
2934
3246
  (default: true)
2935
3247
 
3248
+ **(BETA FEATURE)**
3249
+
2936
3250
  This adds some default keyboard shortcuts:
2937
3251
  - CMD+A (CTRL+A on Windows/Linux) to select all
2938
3252
  - CTRL+A on Mac to jump to beginning of line
2939
3253
  - CTRL+E on Mac to jump to end of line
3254
+ - Attempts to add proper indentation upon adding a new line when hitting ENTER (currently supporting Ruby only)
2940
3255
 
2941
3256
  If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
2942
3257
 
2943
- Learn more at [Hello, Code Text!](#hello-code-text)
3258
+ Learn more at [Hello, Code Text!](GLIMMER_SAMPLES.md#hello-code-text)
2944
3259
 
2945
3260
  ##### Video Custom Custom Widget
2946
3261
 
@@ -2955,7 +3270,7 @@ Simply install the [glimmer-cw-video](https://rubygems.org/gems/glimmer-cw-video
2955
3270
  This [Eclipse guide](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm) for how to write custom SWT widgets is also applicable to Glimmer Custom Widgets written in Ruby. I recommend reading it:
2956
3271
  [https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm)
2957
3272
 
2958
- Also, you may check out [Hello, Custom Widget!](#hello-custom-widget) for another example.
3273
+ Also, you may check out [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) for another example.
2959
3274
 
2960
3275
  ### Custom Shells
2961
3276
 
@@ -3026,7 +3341,7 @@ shell { |app_shell|
3026
3341
 
3027
3342
  If you use a Custom Shell as the top-level app shell, you may invoke the class method `::launch` instead to avoid building an app class yourself or including Glimmer into the top-level namespace (e.g. `Tetris.launch` instead of `include Glimmer; tetris.open`)
3028
3343
 
3029
- You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
3344
+ You may check out [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) for another example.
3030
3345
 
3031
3346
  ### Drag and Drop
3032
3347
 
@@ -3040,7 +3355,7 @@ To get started, simply follow these steps:
3040
3355
  1. On the drop target widget, add `on_drop` [DropTargetListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetListener.html) event handler block at minimum (you may also add `on_drag_enter` [must set [`event.detail`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEvent.html#detail) if added], `on_drag_over`, `on_drag_leave`, `on_drag_operation_changed` and `on_drop_accept` if needed)
3041
3356
  1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
3042
3357
 
3043
- Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
3358
+ Example (taken from [samples/hello/hello_drag_and_drop.rb](GLIMMER_SAMPLES.md#hello-drag-and-drop) / you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
3044
3359
 
3045
3360
  ```ruby
3046
3361
  class Location