glimmer-dsl-swt 4.18.4.8 → 4.18.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -0
  3. data/README.md +24 -11
  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 +353 -145
  8. data/docs/reference/GLIMMER_SAMPLES.md +207 -41
  9. data/glimmer-dsl-swt.gemspec +33 -15
  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 +18 -3
  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 +9 -5
  29. data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
  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 +50 -2
  37. data/lib/glimmer/swt/custom/radio_group.rb +2 -1
  38. data/lib/glimmer/swt/custom/shape.rb +166 -34
  39. data/lib/glimmer/{dsl/swt/directory_dialog_expression.rb → swt/custom/shape/arc.rb} +15 -20
  40. data/lib/glimmer/swt/custom/shape/focus.rb +43 -0
  41. data/lib/glimmer/swt/custom/shape/image.rb +86 -0
  42. data/lib/glimmer/swt/custom/shape/line.rb +58 -0
  43. data/lib/glimmer/swt/custom/shape/oval.rb +43 -0
  44. data/lib/glimmer/swt/custom/shape/point.rb +52 -0
  45. data/lib/glimmer/swt/custom/shape/polygon.rb +73 -0
  46. data/lib/glimmer/swt/custom/shape/polyline.rb +73 -0
  47. data/lib/glimmer/swt/custom/shape/rectangle.rb +87 -0
  48. data/lib/glimmer/swt/custom/shape/text.rb +73 -0
  49. data/lib/glimmer/swt/date_time_proxy.rb +9 -3
  50. data/lib/glimmer/swt/dialog_proxy.rb +92 -0
  51. data/lib/glimmer/swt/display_proxy.rb +62 -2
  52. data/lib/glimmer/swt/expand_item_proxy.rb +18 -12
  53. data/lib/glimmer/swt/font_proxy.rb +13 -7
  54. data/lib/glimmer/swt/image_proxy.rb +16 -5
  55. data/lib/glimmer/swt/layout_data_proxy.rb +21 -15
  56. data/lib/glimmer/swt/layout_proxy.rb +19 -15
  57. data/lib/glimmer/swt/menu_proxy.rb +2 -2
  58. data/lib/glimmer/swt/message_box_proxy.rb +21 -7
  59. data/lib/glimmer/swt/properties.rb +3 -0
  60. data/lib/glimmer/swt/proxy_properties.rb +145 -0
  61. data/lib/glimmer/swt/scrolled_composite_proxy.rb +20 -7
  62. data/lib/glimmer/swt/shell_proxy.rb +96 -80
  63. data/lib/glimmer/swt/swt_proxy.rb +17 -0
  64. data/lib/glimmer/swt/tab_item_proxy.rb +6 -3
  65. data/lib/glimmer/swt/table_proxy.rb +32 -11
  66. data/lib/glimmer/swt/transform_proxy.rb +26 -38
  67. data/lib/glimmer/swt/tree_proxy.rb +11 -16
  68. data/lib/glimmer/swt/widget_listener_proxy.rb +6 -2
  69. data/lib/glimmer/swt/widget_proxy.rb +194 -137
  70. data/lib/glimmer/ui.rb +5 -0
  71. data/lib/glimmer/ui/custom_shell.rb +13 -7
  72. data/lib/glimmer/ui/custom_widget.rb +4 -5
  73. data/samples/elaborate/contact_manager.rb +7 -7
  74. data/samples/elaborate/login.rb +25 -21
  75. data/samples/elaborate/mandelbrot_fractal.rb +346 -39
  76. data/samples/elaborate/meta_sample.rb +1 -1
  77. data/samples/elaborate/tetris.rb +1 -0
  78. data/samples/elaborate/tic_tac_toe.rb +16 -14
  79. data/samples/elaborate/tic_tac_toe/board.rb +5 -5
  80. data/samples/elaborate/tic_tac_toe/cell.rb +5 -5
  81. data/samples/hello/hello_button.rb +7 -7
  82. data/samples/hello/hello_canvas.rb +145 -41
  83. data/samples/hello/hello_checkbox.rb +16 -14
  84. data/samples/hello/hello_checkbox_group.rb +11 -9
  85. data/samples/hello/hello_color_dialog.rb +66 -0
  86. data/samples/hello/hello_combo.rb +14 -12
  87. data/samples/hello/hello_computed.rb +7 -7
  88. data/samples/hello/hello_cursor.rb +58 -0
  89. data/samples/hello/hello_custom_shell.rb +17 -21
  90. data/samples/hello/hello_custom_widget.rb +4 -6
  91. data/samples/hello/hello_date_time.rb +14 -12
  92. data/samples/hello/hello_directory_dialog.rb +7 -7
  93. data/samples/hello/hello_expand_bar.rb +8 -8
  94. data/samples/hello/hello_file_dialog.rb +7 -7
  95. data/samples/hello/hello_font_dialog.rb +82 -0
  96. data/samples/hello/hello_group.rb +18 -16
  97. data/samples/hello/hello_list_multi_selection.rb +13 -11
  98. data/samples/hello/hello_list_single_selection.rb +13 -11
  99. data/samples/hello/hello_progress_bar.rb +125 -0
  100. data/samples/hello/hello_radio.rb +18 -16
  101. data/samples/hello/hello_radio_group.rb +14 -12
  102. data/samples/hello/hello_spinner.rb +7 -7
  103. data/samples/hello/hello_tab.rb +5 -5
  104. data/samples/hello/hello_table.rb +10 -5
  105. data/samples/hello/hello_tree.rb +485 -0
  106. metadata +30 -23
  107. data/lib/glimmer/swt/directory_dialog_proxy.rb +0 -65
  108. 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: 89ea3be1af753358a8beaffbf28c8dfd6602eae3903b01a884e6999f0dbf6cfb
4
- data.tar.gz: 672422abf1637420ac51706373824ac821682eab77afe86b91e22b21f1e00eb6
3
+ metadata.gz: e3086c3823faac7765ca33e069111da2f027462fc9d09a2a9799a2ff094d6692
4
+ data.tar.gz: be7070377808b55cfa4bde48543b8a98fdff77205c9db0c07d0f4ac42078e00e
5
5
  SHA512:
6
- metadata.gz: 7b502b353aa06f6b26e39487859ae8f4d9f8ee47d74a4a97a224b14dfa8b18acba6d8e48b6a66ee518a8075cd90a6303f1864726a22812edf98515f6a2754aa2
7
- data.tar.gz: a5926f825b0247d4b521bfa2f857d1b1f88d731dba9651690960cf7c516ef2a1c5aca9c6cce86878162358fb416a0913b3ba945b0589be19f78f94454848d0b5
6
+ metadata.gz: 79e966ac5b7c342d8a9b936387e59f299f4895ae93c01600f8289cc06448b4d90beb0bd6e24073728d7a379172e1513b3cdf05fb3cdd4361ee08bd337870f491
7
+ data.tar.gz: 3c89781755c57a6cfc2990d85352bb37674e41a8d2f55f50c26c0d44f948ab26342b58bc98fcc9f93818cf19036ea0032a84b1565397abc7b7aa93a029b8c851
data/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.5.1
4
+
5
+ - Hello, Color Dialog! Sample
6
+ - Hello, Font Dialog! Sample
7
+ - Handle SWT RGB color data objects when setting colors on widgets (e.g. background)
8
+ - Enhance Hello, Canvas! with Color selector via right-click menu
9
+ - Fixed issue with tree multi selection throwing an exception
10
+
11
+ ### 4.18.5.0
12
+
13
+ - Automatic `sync_exec` usage from threads other than the GUI thread, thus absolving software engineers from the need to use `sync_exec` explicitly anymore.
14
+ - `auto_exec` keyword to automatically use `sync_exec` with SWT code when needed (running from a thread other than GUI thread)
15
+ - Implement `sync_exec:` option in `bind` keyword with table, tree, combo, and list data-binding (other data-binding types than the standard)
16
+ - Add `async_exec` option to `bind` keyword (covering `data_binding_expression.rb` with `async_exec` properly)
17
+ - Support tree multi-selection data-binding
18
+ - Hello, Tree! sample
19
+ - Enhance Hello, Canvas! with Shape Movement
20
+ - Add Jars.lock to scaffold .gitignore file
21
+ - Add Glimmer::GUI alias for Glimmer::UI module, thus permitting inclusion of Glimmer::GUI::CustomWidget, Glimmer::GUI::CustomShell, and Glimmer::GUI::CustomWindow
22
+ - 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)
23
+ - Remove explicit git gem dependency given that it is installed via juwelier during scaffolding and is not needed otherwise
24
+ - Support partial image shape drawing by passing source and destination dimensions to `image` shape [documented in docs]
25
+ - Support alternate Canvas Shape DSL syntax for `image` by passing nested properties
26
+ - Canvas Shape DSL argument data-binding support for `image`
27
+ - Support alternate Canvas Shape DSL syntax for `rectangle` by passing nested properties
28
+ - Canvas Shape DSL argument data-binding support for `rectangle(x, y, width, height, fill: false)` standard rectangle, which can be optionally filled
29
+ - 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
30
+ - 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
31
+ - 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)
32
+ - 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)
33
+ - Canvas Shape DSL argument data-binding support for `line(x1, y1, x2, y2)` line
34
+ - 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.
35
+ - Canvas Shape DSL argument data-binding support for `point(x, y)` point
36
+ - 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)
37
+ - 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)
38
+ - 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))
39
+ - 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
40
+ - Refactor all samples to rely on Glimmer::UI::CustomShell given its new class launch method for productive app declaration
41
+ - Fix issue with logging remaining async in debug mode
42
+ - Fix issue with combo, list, radio group, and checkbox group not supporting nested data-binding
43
+
44
+ ### 4.18.4.11
45
+
46
+ - 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
47
+ - Add proper indentation in code_text upon hitting ENTER
48
+ - Reset Canvas Shape DSL alpha value to 255 when not explicitly set on a shape (Apply in Hello, Canvas! Sample)
49
+ - Provide terse syntax for building canvas objects (autodetecting its width and height)
50
+ - Provide terse syntax for building `:image_double_buffered` canvas objects (autodetecting its width and height):
51
+ - Center mandelbrot where mouse is clicked upon zoom
52
+ - Fix issue with Mandelbrot sample off by one error on Cores selected via Menu
53
+ - Fix use of on_events in code_text widget with lines mode true
54
+
55
+ ### 4.18.4.10
56
+
57
+ - Hello, Progress Bar!
58
+ - 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
59
+ - `bind` option of `async_exec` or `sync_exec` (e.g. `bind(model, :property, async_exec: true)`) to perform GUI updates from another thread safely
60
+ - Show progress bar for Mandelbrot calculation
61
+ - Mandelbrot Cores menu options to switch the number of CPU cores being used for calculation on the next zoom calculation cycle
62
+
63
+ ### 4.18.4.9
64
+
65
+ - Hello, Cursor! Sample
66
+ - Log errors that occur in widget event listener blocks to help with troubleshooting
67
+ - disposed? method for Shape objects
68
+ - Add `dispose_images: false, dispose_patterns: false` options to `Shape#dispose` to avoid disposing images/patterns when needed
69
+ - Mandelbrot background thread pre-calculation of future zoom levels
70
+ - Mandelbrot menu bar menu items
71
+ - Mandelbrot panning via scrollbars or dragging
72
+
3
73
  ### 4.18.4.8
4
74
 
5
75
  - Make `image` a top-level expression keyword
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.8
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.1
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.8
345
+ jgem install glimmer-dsl-swt -v 4.18.5.1
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.8'
363
+ gem 'glimmer-dsl-swt', '~> 4.18.5.1'
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.
@@ -403,10 +404,14 @@ Glimmer configuration may be done via the `Glimmer::Config` module.
403
404
 
404
405
  ## Samples
405
406
 
406
- 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 Glimmer DSL for SWT samples over here, including screenshots and explanations of what each sample demonstrates:
407
408
 
408
409
  [docs/reference/GLIMMER_SAMPLES.md](docs/reference/GLIMMER_SAMPLES.md)
409
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 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`).
412
+
413
+ ![Glimmer Meta-Sample](/images/glimmer-meta-sample.png)
414
+
410
415
  ## In Production
411
416
 
412
417
  The following production apps have been built with Glimmer.
@@ -425,6 +430,14 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
425
430
 
426
431
  [<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
432
 
433
+ ### Glimmer Gab
434
+
435
+ [<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
436
+
437
+ ### Connector
438
+
439
+ [<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
440
+
428
441
  ## Packaging & Distribution
429
442
 
430
443
  Glimmer simplifies the process of native-executable packaging and distribution on Mac and Windows via a single `glimmer package` command:
@@ -438,7 +451,7 @@ Glimmer already supports automatic (and manual) app updates via the Mac App Stor
438
451
  ## Glimmer Supporting Libraries
439
452
 
440
453
  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)
454
+ - [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
455
  - [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
456
  - [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
457
  - [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.8
1
+ 4.18.5.1
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
 
@@ -284,7 +374,7 @@ Shell widget proxy has extra methods specific to SWT Shell:
284
374
  - `#show`: Alias for `#open`
285
375
  - `#hide`: Hides a shell setting "visible" property to false
286
376
  - `#close`: Closes the shell
287
- - `#center`: Centers the shell within monitor it is in
377
+ - `#center_within_display`: Centers the shell within monitor it is in
288
378
  - `#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
379
  - `#visible?`: Returns whether a shell is visible
290
380
  - `#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 +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
 
@@ -800,7 +903,7 @@ You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash
800
903
 
801
904
  ![Hello Browser](/images/glimmer-hello-browser.png)
802
905
 
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).
906
+ 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
907
 
805
908
  Example loading a URL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
806
909
 
@@ -834,6 +937,8 @@ shell {
834
937
  }.open
835
938
  ```
836
939
 
940
+ 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.
941
+
837
942
  ### Widget Styles
838
943
 
839
944
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -1290,6 +1395,7 @@ Shape keywords and their args (including defaults) are listed below (they basica
1290
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)
1291
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)
1292
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
1293
1399
  - `line(x1, y1, x2, y2)` line
1294
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.
1295
1401
  - `point(x, y)` point
@@ -1367,7 +1473,7 @@ Screenshot:
1367
1473
 
1368
1474
  ![Canvas Animation Example](/images/glimmer-example-canvas.png)
1369
1475
 
1370
- Learn more at the [Hello, Canvas! Sample](#hello-canvas).
1476
+ Learn more at the [Hello, Canvas! Sample](GLIMMER_SAMPLES.md#hello-canvas).
1371
1477
 
1372
1478
  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).
1373
1479
 
@@ -1409,6 +1515,116 @@ shell {
1409
1515
  }.open
1410
1516
  ```
1411
1517
 
1518
+ #### Shapes inside a Widget
1519
+
1520
+ 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`.
1521
+
1522
+ #### Shapes inside an Image
1523
+
1524
+ You can build an image using the Canvas Shape DSL (including setting the icon of the application).
1525
+
1526
+ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1527
+
1528
+ ```
1529
+ include Glimmer
1530
+
1531
+ shell {
1532
+ text 'Image Shape DSL Example'
1533
+ label {
1534
+ bevel_constant = 20
1535
+ icon_block_size = 64
1536
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
1537
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1538
+ icon_size = 8
1539
+ icon_pixel_size = icon_block_size * icon_size
1540
+ image(icon_pixel_size, icon_pixel_size) {
1541
+ icon_size.times { |row|
1542
+ icon_size.times { |column|
1543
+ colored = row >= 1 && column.between?(1, 6)
1544
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1545
+ x = column * icon_block_size
1546
+ y = row * icon_block_size
1547
+ rectangle(x, y, icon_block_size, icon_block_size) {
1548
+ background color
1549
+ }
1550
+ 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) {
1551
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1552
+ }
1553
+ 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) {
1554
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1555
+ }
1556
+ 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) {
1557
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1558
+ }
1559
+ 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) {
1560
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1561
+ }
1562
+ }
1563
+ }
1564
+ }
1565
+ }
1566
+ }.open
1567
+ ```
1568
+
1569
+ ![Image Shape DSL](/images/glimmer-example-image-shape-dsl.png)
1570
+
1571
+ Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1572
+
1573
+ ```
1574
+ include Glimmer
1575
+
1576
+ shell {
1577
+ text 'Image Shape DSL Example'
1578
+ label {
1579
+ text 'Image Shape DSL Example'
1580
+ font height: 30
1581
+ }
1582
+ bevel_constant = 20
1583
+ icon_block_size = 64
1584
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
1585
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1586
+ icon_size = 8
1587
+ icon_pixel_size = icon_block_size * icon_size
1588
+ image(icon_pixel_size, icon_pixel_size) {
1589
+ icon_size.times { |row|
1590
+ icon_size.times { |column|
1591
+ colored = row >= 1 && column.between?(1, 6)
1592
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1593
+ x = column * icon_block_size
1594
+ y = row * icon_block_size
1595
+ rectangle(x, y, icon_block_size, icon_block_size) {
1596
+ background color
1597
+ }
1598
+ 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) {
1599
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1600
+ }
1601
+ 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) {
1602
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1603
+ }
1604
+ 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) {
1605
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1606
+ }
1607
+ 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) {
1608
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1609
+ }
1610
+ }
1611
+ }
1612
+ }
1613
+ }.open
1614
+ ```
1615
+
1616
+ ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1617
+
1618
+ #### Canvas Shape API
1619
+
1620
+ These Canvas Shape API methods help with manipulating shapes upon user interaction, such as mouse clicking a specific shape.
1621
+
1622
+ - `WidgetProxy#shape_at_location(x, y)` : returns shape object at x, y location from a widget proxy like canvas
1623
+ - `Shape#include?(x, y)` : indicates if shape includes x, y point (`arc` and `oval` shapes currently include their entire rectangular region in their checks, `text` shapes always return false)
1624
+ - `Shape#move_by(x_delta, y_delta)` : moves shape object at x, y location
1625
+
1626
+ Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example.
1627
+
1412
1628
  #### Pixel Graphics
1413
1629
 
1414
1630
  **(Early Alpha Feature)**
@@ -1438,6 +1654,21 @@ Result:
1438
1654
 
1439
1655
  ![glimmer example pixel graphics](/images/glimmer-example-pixel-graphics.png)
1440
1656
 
1657
+ 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:
1658
+
1659
+ ```ruby
1660
+ include Glimmer
1661
+
1662
+ shell {
1663
+ minimum_size 250, 265
1664
+ text 'Pixel Graphics Example'
1665
+
1666
+ canvas { |x, y|
1667
+ [y%255, x%255, (x+y)%255]
1668
+ }
1669
+ }.open
1670
+ ```
1671
+
1441
1672
  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).
1442
1673
 
1443
1674
  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)):
@@ -1463,6 +1694,8 @@ shell {
1463
1694
  }.open
1464
1695
  ```
1465
1696
 
1697
+ (the code could be optimized further if you are repeating colors by simply reusing `Color` objects instead of re-constructing them)
1698
+
1466
1699
  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.
1467
1700
 
1468
1701
  Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
@@ -1471,11 +1704,10 @@ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1471
1704
  include Glimmer
1472
1705
 
1473
1706
  @the_image = image(250, 250)
1474
- gc = org.eclipse.swt.graphics.GC.new(@the_image)
1475
1707
  250.times {|y|
1476
1708
  250.times {|x|
1477
- gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1478
- gc.draw_point(x, y)
1709
+ @the_image.gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1710
+ @the_image.gc.draw_point(x, y)
1479
1711
  }
1480
1712
  }
1481
1713
 
@@ -1500,127 +1732,80 @@ If you need a transparent background for the image, replace the image constructi
1500
1732
 
1501
1733
  That way, wherever you don't draw a point, you get transparency (seeing what is behind the image).
1502
1734
 
1503
- 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)
1504
-
1505
- Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1735
+ 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.
1506
1736
 
1507
1737
  ```ruby
1508
1738
  include Glimmer
1509
1739
 
1740
+ @the_image = image(250, 250) {|x, y|
1741
+ [y%255, x%255, (x+y)%255]
1742
+ }
1743
+
1510
1744
  shell {
1511
1745
  minimum_size 250, 265
1512
1746
  text 'Pixel Graphics Example'
1747
+ image @the_image
1513
1748
 
1514
- canvas(:image_double_buffered) {
1515
- 250.times {|y|
1516
- 250.times {|x|
1517
- pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1518
- }
1519
- }
1749
+ canvas {
1750
+ image @the_image
1520
1751
  }
1521
1752
  }.open
1522
1753
  ```
1523
1754
 
1524
- #### Shapes inside a Widget
1755
+ 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).
1525
1756
 
1526
- 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`.
1757
+ ```ruby
1758
+ include Glimmer
1527
1759
 
1528
- #### Shapes inside an Image
1760
+ shell {
1761
+ minimum_size 250, 265
1762
+ text 'Pixel Graphics Example'
1763
+
1764
+ canvas {
1765
+ image image(250, 250, top_level: true) {|x, y|
1766
+ [y%255, x%255, (x+y)%255]
1767
+ }
1768
+ }
1769
+ }.open
1770
+ ```
1529
1771
 
1530
- You can build an image using the Canvas Shape DSL (including setting the icon of the application).
1772
+ 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)
1531
1773
 
1532
1774
  Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1533
1775
 
1534
- ```
1776
+ ```ruby
1535
1777
  include Glimmer
1536
1778
 
1537
1779
  shell {
1538
- text 'Image Shape DSL Example'
1539
- label {
1540
- bevel_constant = 20
1541
- icon_block_size = 64
1542
- icon_bevel_size = icon_block_size.to_f / 25.to_f
1543
- icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1544
- icon_size = 8
1545
- icon_pixel_size = icon_block_size * icon_size
1546
- image(icon_pixel_size, icon_pixel_size) {
1547
- icon_size.times { |row|
1548
- icon_size.times { |column|
1549
- colored = row >= 1 && column.between?(1, 6)
1550
- color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1551
- x = column * icon_block_size
1552
- y = row * icon_block_size
1553
- rectangle(x, y, icon_block_size, icon_block_size) {
1554
- background color
1555
- }
1556
- 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) {
1557
- background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1558
- }
1559
- 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) {
1560
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1561
- }
1562
- 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) {
1563
- background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1564
- }
1565
- 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) {
1566
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1567
- }
1568
- }
1780
+ minimum_size 250, 265
1781
+ text 'Pixel Graphics Example'
1782
+
1783
+ canvas(:image_double_buffered) {
1784
+ 250.times {|y|
1785
+ 250.times {|x|
1786
+ pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
1569
1787
  }
1570
1788
  }
1571
1789
  }
1572
1790
  }.open
1573
1791
  ```
1574
1792
 
1575
- ![Image Shape DSL](/images/glimmer-example-image-shape-dsl.png)
1576
-
1577
- Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1793
+ Of course, you could also take advantage of the pixel-less terser syntax:
1578
1794
 
1579
- ```
1795
+ ```ruby
1580
1796
  include Glimmer
1581
1797
 
1582
1798
  shell {
1583
- text 'Image Shape DSL Example'
1584
- label {
1585
- text 'Image Shape DSL Example'
1586
- font height: 30
1587
- }
1588
- bevel_constant = 20
1589
- icon_block_size = 64
1590
- icon_bevel_size = icon_block_size.to_f / 25.to_f
1591
- icon_bevel_pixel_size = 0.16*icon_block_size.to_f
1592
- icon_size = 8
1593
- icon_pixel_size = icon_block_size * icon_size
1594
- image(icon_pixel_size, icon_pixel_size) {
1595
- icon_size.times { |row|
1596
- icon_size.times { |column|
1597
- colored = row >= 1 && column.between?(1, 6)
1598
- color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
1599
- x = column * icon_block_size
1600
- y = row * icon_block_size
1601
- rectangle(x, y, icon_block_size, icon_block_size) {
1602
- background color
1603
- }
1604
- 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) {
1605
- background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
1606
- }
1607
- 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) {
1608
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1609
- }
1610
- 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) {
1611
- background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
1612
- }
1613
- 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) {
1614
- background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
1615
- }
1616
- }
1617
- }
1799
+ minimum_size 250, 265
1800
+ text 'Pixel Graphics Example'
1801
+
1802
+ canvas(:image_double_buffered) { |x, y|
1803
+ [y%255, x%255, (x+y)%255]
1618
1804
  }
1619
1805
  }.open
1620
1806
  ```
1621
1807
 
1622
- ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1623
-
1808
+ 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.
1624
1809
 
1625
1810
  ### Canvas Transform DSL
1626
1811
 
@@ -1704,7 +1889,7 @@ transform(1, 1, 4, 2, 2, 4).
1704
1889
  translate(3, 7)
1705
1890
  ```
1706
1891
 
1707
- Learn more at the [Hello, Canvas Transform! Sample](#hello-canvas-transform).
1892
+ Learn more at the [Hello, Canvas Transform! Sample](GLIMMER_SAMPLES.md#hello-canvas-transform).
1708
1893
 
1709
1894
  ### Canvas Animation DSL
1710
1895
 
@@ -1770,7 +1955,7 @@ API of Animation Object (returned from `animation` keyword):
1770
1955
  - `#cycle_limited?` returns true if `cycle_count` is specified
1771
1956
  - `#duration_limited?` returns true if `duration_limit` is specified
1772
1957
 
1773
- Learn more at the [Hello, Canvas Animation! Sample](#hello-canvas-animation).
1958
+ Learn more at the [Hello, Canvas Animation! Sample](GLIMMER_SAMPLES.md#hello-canvas-animation).
1774
1959
 
1775
1960
  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.
1776
1961
 
@@ -1778,7 +1963,7 @@ If there is anything missing you would like added to the Glimmer Animation DSL t
1778
1963
 
1779
1964
  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.
1780
1965
 
1781
- The [Glimmer Tetris](#glimmer-tetris) sample provides a good example of that.
1966
+ The [Glimmer Tetris](#tetris) sample provides a good example of that.
1782
1967
 
1783
1968
  ### Data-Binding
1784
1969
 
@@ -1799,6 +1984,18 @@ the address of a contact. This is called nested property data binding.
1799
1984
 
1800
1985
  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)
1801
1986
 
1987
+ `text bind(contact, 'address.street', sync_exec: true)`
1988
+
1989
+ **(ALPHA FEATURE)**
1990
+
1991
+ This example forces GUI updates via [sync_exec](#sync_exec) assuming they are coming from another thread (different from the GUI thread)
1992
+
1993
+ `text bind(contact, 'address.street', async_exec: true)`
1994
+
1995
+ **(ALPHA FEATURE)**
1996
+
1997
+ This example forces GUI updates via [async_exec](#async_exec) assuming they are coming from another thread (different from the GUI thread)
1998
+
1802
1999
  `text bind(contact, 'address.street', on_read: lambda { |s| s[0..10] })`
1803
2000
 
1804
2001
  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`
@@ -2234,6 +2431,8 @@ This finds the root node. The array is a Java array. This enables easy passing o
2234
2431
  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
2235
2432
  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.
2236
2433
 
2434
+ Learn more at the [Hello, Tree!](GLIMMER_SAMPLES.md#hello-tree) and [Gladiator](GLIMMER_SAMPLES.md#gladiator) samples.
2435
+
2237
2436
  #### DateTime
2238
2437
 
2239
2438
  `date_time` represents the SWT DateTime widget.
@@ -2706,6 +2905,8 @@ To use, simply use `code_text` in place of the `text` or `styled_text` widget. I
2706
2905
  **lines**
2707
2906
  (default: `false`)
2708
2907
 
2908
+ **(BETA FEATURE)**
2909
+
2709
2910
  Shows line numbers when set to true.
2710
2911
 
2711
2912
  If set to a hash like `{width: 4}`, it sets the initial width of the line numbers lane in character count (default: 4)
@@ -2715,6 +2916,8 @@ Keep in mind that if the text grows and required a wider line numbers area, it g
2715
2916
  **theme**
2716
2917
  (default: `'glimmer'`)
2717
2918
 
2919
+ **(BETA FEATURE)**
2920
+
2718
2921
  Changes syntax color highlighting theme. Can be one of the following:
2719
2922
  - glimmer
2720
2923
  - github
@@ -2723,6 +2926,8 @@ Changes syntax color highlighting theme. Can be one of the following:
2723
2926
  **language**
2724
2927
  (default: `'ruby'`)
2725
2928
 
2929
+ **(BETA FEATURE)**
2930
+
2726
2931
  Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
2727
2932
  - abap
2728
2933
  - actionscript
@@ -2932,10 +3137,13 @@ Sets the code language, which can be one of the following [rouge gem](#https://r
2932
3137
  **default_behavior**
2933
3138
  (default: true)
2934
3139
 
3140
+ **(BETA FEATURE)**
3141
+
2935
3142
  This adds some default keyboard shortcuts:
2936
3143
  - CMD+A (CTRL+A on Windows/Linux) to select all
2937
3144
  - CTRL+A on Mac to jump to beginning of line
2938
3145
  - CTRL+E on Mac to jump to end of line
3146
+ - Attempts to add proper indentation upon adding a new line when hitting ENTER (currently supporting Ruby only)
2939
3147
 
2940
3148
  If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
2941
3149
 
@@ -2954,7 +3162,7 @@ Simply install the [glimmer-cw-video](https://rubygems.org/gems/glimmer-cw-video
2954
3162
  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:
2955
3163
  [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)
2956
3164
 
2957
- Also, you may check out [Hello, Custom Widget!](#hello-custom-widget) for another example.
3165
+ Also, you may check out [Hello, Custom Widget!](GLIMMER_SAMPLES.md#hello-custom-widget) for another example.
2958
3166
 
2959
3167
  ### Custom Shells
2960
3168
 
@@ -3025,7 +3233,7 @@ shell { |app_shell|
3025
3233
 
3026
3234
  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`)
3027
3235
 
3028
- You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
3236
+ You may check out [Hello, Custom Shell!](GLIMMER_SAMPLES.md#hello-custom-shell) for another example.
3029
3237
 
3030
3238
  ### Drag and Drop
3031
3239
 
@@ -3039,7 +3247,7 @@ To get started, simply follow these steps:
3039
3247
  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)
3040
3248
  1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
3041
3249
 
3042
- Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
3250
+ 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)):
3043
3251
 
3044
3252
  ```ruby
3045
3253
  class Location