glimmer-dsl-swt 4.18.2.5 → 4.18.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -0
  3. data/README.md +344 -35
  4. data/VERSION +1 -1
  5. data/glimmer-dsl-swt.gemspec +13 -7
  6. data/lib/ext/glimmer/config.rb +24 -7
  7. data/lib/glimmer/data_binding/table_items_binding.rb +8 -5
  8. data/lib/glimmer/data_binding/widget_binding.rb +22 -4
  9. data/lib/glimmer/dsl/swt/dsl.rb +1 -0
  10. data/lib/glimmer/dsl/swt/image_expression.rb +14 -6
  11. data/lib/glimmer/dsl/swt/layout_data_expression.rb +4 -4
  12. data/lib/glimmer/dsl/swt/layout_expression.rb +5 -3
  13. data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -0
  14. data/lib/glimmer/dsl/swt/property_expression.rb +4 -2
  15. data/{samples/elaborate/tetris/view/game_over_dialog.rb → lib/glimmer/dsl/swt/transform_expression.rb} +29 -46
  16. data/lib/glimmer/swt/custom/drawable.rb +4 -3
  17. data/lib/glimmer/swt/custom/shape.rb +37 -14
  18. data/lib/glimmer/swt/directory_dialog_proxy.rb +3 -3
  19. data/lib/glimmer/swt/display_proxy.rb +26 -5
  20. data/lib/glimmer/swt/file_dialog_proxy.rb +3 -3
  21. data/lib/glimmer/swt/image_proxy.rb +68 -1
  22. data/lib/glimmer/swt/shell_proxy.rb +23 -3
  23. data/lib/glimmer/swt/table_proxy.rb +31 -7
  24. data/lib/glimmer/swt/transform_proxy.rb +109 -0
  25. data/lib/glimmer/swt/widget_listener_proxy.rb +14 -5
  26. data/lib/glimmer/swt/widget_proxy.rb +7 -3
  27. data/lib/glimmer/ui/custom_shell.rb +11 -9
  28. data/lib/glimmer/ui/custom_widget.rb +32 -17
  29. data/samples/elaborate/meta_sample.rb +81 -24
  30. data/samples/elaborate/tetris.rb +146 -42
  31. data/samples/elaborate/tetris/model/game.rb +258 -137
  32. data/samples/elaborate/tetris/model/past_game.rb +26 -0
  33. data/samples/elaborate/tetris/model/tetromino.rb +45 -29
  34. data/samples/elaborate/tetris/view/block.rb +8 -13
  35. data/samples/elaborate/tetris/view/high_score_dialog.rb +133 -0
  36. data/samples/elaborate/tetris/view/playfield.rb +1 -1
  37. data/samples/elaborate/tetris/view/score_lane.rb +11 -11
  38. data/samples/elaborate/tetris/view/tetris_menu_bar.rb +139 -0
  39. data/samples/elaborate/tic_tac_toe.rb +4 -4
  40. data/samples/hello/hello_canvas.rb +4 -4
  41. data/samples/hello/hello_canvas_animation.rb +3 -3
  42. data/samples/hello/hello_canvas_transform.rb +40 -0
  43. data/samples/hello/hello_link.rb +1 -1
  44. metadata +11 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d0dbd3170cb9c04be90cd8d7cfa83a68c491eaa89d3752d2ab5ac8d1e5f22c4
4
- data.tar.gz: 368a549d962ecd554a02c2257c05e476f7b6b3843193b5a7197a9725ed74e9aa
3
+ metadata.gz: 63410b8b302bc061b5089d24bcadaacbd54b83bbb581ffecd0a46c7c026329c1
4
+ data.tar.gz: 60da9c410a221130713e209c0e6127d3e04f17feccbcb29788c2234a90802bb9
5
5
  SHA512:
6
- metadata.gz: 18ce78d054b799add79df4a7536237a863b1a9b408498af4d78e899575f2784921b15af7364f287921ddfe5223810845d1ec4b6b39b02f55106ea27ad6a9041a
7
- data.tar.gz: be2ad49fabf44c811eb153293bf26b6dbb922ad0a757b06f110bbe014b6f9a2a87a5f4ac5a263f8ed11f125bd4754685ec07c6e1bfeef10dd2b4d66338db8814
6
+ metadata.gz: 81a1feac2ef1bf9c7329d26714d0d7c61b926f710a785f0b7d2e1a424b2548cf159604ada03f368996c99cb45d0834bb362a715cbfae0fa5ec1b4e5af659ee8b
7
+ data.tar.gz: a4c1e06cf9aa7f3b656e9d5d22d56883f1def62865b1aa56555041c8238c07e0f333f17cd6f6108ada800e1738294f148757752e4609e1dd34dcbdc8183bd1ba
@@ -1,5 +1,61 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.3.4
4
+
5
+ - Support building Image objects with the Glimmer Canvas Shape DSL
6
+ - Tetris build icon image in-game by nesting Glimmer Shape DSL syntax
7
+ - Canvas Make shapes auto-fill if you specify a background only (no need to say fill: true) or not fill if you specify a foreground only
8
+ - Tetris option to switch Up Arrow between Instant Down, Rotate Right, and Rotate Left
9
+
10
+ ### 4.18.3.3
11
+
12
+ - Support Table data binding read_only_sort: true option to allow visual sorting without affecting model data
13
+ - on_quit to
14
+ - Tetris Add lines and level to High Score Dialog
15
+ - Tetris Immediate Drop on Arrow Up
16
+ - Tetris Pause on showing High Score Dialog
17
+ - Tetris Make High Scores -> Show a check menu item
18
+ - Tetris Disable pause button upon showing High Score Dialog
19
+ - Fix Quit Tetris CMD+Q shortcut by adding on_quit event to display
20
+ - Tetris Fix escape button upon entering high score name
21
+ - If WidgetBinding encounters a disposed widget, it deregisters all observables that it is observing
22
+
23
+ ### 4.18.3.2
24
+
25
+ - Tetris High Scores
26
+ - Tetris Modify High Score Player Name
27
+ - Tetris Show High Scores (Menu Item + Accelerator)
28
+ - Tetris add a menu item with beep enablement option
29
+ - Tetris Clear High Scores
30
+ - Tetris Add left and right alt (option) buttons as alternative to shift for rotation. Use left ctrl as rotate left. Use a, s, d as left, down, right.
31
+ - Fix issues relating to setting parenthood with custom widgets before building their body (instead of after)
32
+ - Fix issues relating to not respecting arity of passed in table editing callbacks: before_write, after_write, and after_cancel
33
+
34
+ ### 4.18.3.1
35
+
36
+ - Provide an auto_sync_exec all data-binding config option to automatically sync_exec GUI calls from other threads instead of requiring users to use sync_exec on model attribute-change logic. Default value to false.
37
+ - Have CustomShell::launch method take options to pass to custom shell keyword invocation
38
+ - Update Glimmer Meta-Sample to load entire gem into user directory (since some new samples rely on images)
39
+ - Update Glimmer Meta-Sample to display errors in a `dialog` instead of a `message_box` to allow scrolling
40
+ - Removed newly added CustomShell::shutdown as unnecessary (could just do CustomShell::launchd_custom_shell.close)
41
+ - Supporting deregistering Display listeners just like standard listeners via deregister
42
+ - Enhance performance of excluded keyword check
43
+ - Remove CustomWidget support for multiple before_body/after_body blocks instead of one each since it is not needed.
44
+ - Add new :fill_screen style for `shell` to start app filling the screen size (not full screen mode though)
45
+ - Tetris Menu Bar with Game Menu -> Start, Pause, Restart, and Exit
46
+ - Tetris refactor mutation methods to end with bangs
47
+ - Tetris Stop game if user does not play again in the end (instead of closing it)
48
+ - End Tetris Thread loop gracefully if game over is encountered
49
+ - Tetris use more observers instead of callbacks to Game
50
+ - Turn Tetris::Model::Game class from a singleton class to a standard class supporting instances
51
+ - Fix issue of `tetris` keyword not found when run from meta-sample app
52
+
53
+ ### 4.18.3.0
54
+
55
+ - Canvas Transform DSL (DSL declared Transform objects are auto-disposed after getting used by their parent shape)
56
+ - Canvas support a top-level Transform DSL fluent interface for methods that use Transform arguments manually (e.g. tr1 = transform.rotate(90).translate(0, -100))
57
+ - Hello, Canvas Transformation!
58
+
3
59
  ### 4.18.2.5
4
60
 
5
61
  - ColorProxy args now are automatically fit into 0..255 bounds upon use of the `color`/`rgb`/`rgba` keywords
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.2.5
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.3.4
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)
@@ -8,7 +8,7 @@
8
8
 
9
9
  **[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
10
10
 
11
- [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster JVM version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI [widgets](#widgets), but it also supports drawing Canvas Graphics like [Shapes](#canvas-shape-dsl) and [Animations](#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) offers [scaffolding](#scaffolding) options for [Apps](#in-production), [Gems](#custom-shell-gem), and [Custom Widgets](#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and [Gem Packaged Shell Scripts](#custom-shell-gem) on [Linux](https://www.linux.org/).
11
+ [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster JVM version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI [widgets](#widgets), but it also supports drawing Canvas Graphics like [Shapes](#canvas-shape-dsl) and [Animations](#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) s [scaffolding](#scaffolding) options for [Apps](#in-production), [Gems](#custom-shell-gem), and [Custom Widgets](#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and [Gem Packaged Shell Scripts](#custom-shell-gem) on [Linux](https://www.linux.org/).
12
12
 
13
13
  [Glimmer receives two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer](https://rubygems.org/gems/glimmer) with your Ruby desktop GUI development needs. Please make [Glimmer](https://rubygems.org/gems/glimmer) even better by providing feedback and [contributing](#contributing) when possible.
14
14
 
@@ -24,7 +24,7 @@ Glimmer DSL gems:
24
24
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
25
25
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
26
26
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
27
- - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
27
+ - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
28
28
 
29
29
  ## Examples
30
30
 
@@ -226,7 +226,7 @@ Glimmer App:
226
226
 
227
227
  [![Math Bowling App Screenshot](https://raw.githubusercontent.com/AndyObtiva/MathBowling/master/Math-Bowling-Screenshot.png)](https://github.com/AndyObtiva/MathBowling)
228
228
 
229
- **Note:** I offer Glimmer as an open-source project that represents my interests in Ruby Programming, Desktop GUI application development with SWT, Object Oriented Design, Design Patterns, and Software Architecture.
229
+ **Note:** I offer Glimmer DSL for SWT as a free and open-source [Ruby Gem](https://rubygems.org/gems/glimmer-dsl-swt) that represents my interests in Ruby Programming, Desktop GUI application development with SWT, Object Oriented Design, Design Patterns, and Software Architecture.
230
230
  Additionally, I am sharing my professional experience and expertise in Eclipse SWT given that I am an [EclipseCon](http://andymaleh.blogspot.com/2007/03/eclipsecon-2007-day-3.html)/[EclipseWorld](http://andymaleh.blogspot.com/2008/11/eclipseworld-2008-highlights.html) presenter and have built professional applications in SWT/JFace/RCP for Obtiva and the Pampered Chef in the past. This is also done in the hopes that it would indirectly bring me work in a field I am extremely passionate about.
231
231
  That said, please keep in mind that I myself am learning topics in Software Engineering too everyday, including newer editions of SWT and JRuby, which seem to pop up every quarter.
232
232
  If you see anything that needs to be improved, please do not hesitate to contact me on [Gitter](https://gitter.im/AndyObtiva/glimmer) or submit [Issues](https://github.com/AndyObtiva/glimmer-dsl-swt/issues)/[Pull-Requests](https://github.com/AndyObtiva/glimmer-dsl-swt/pulls).
@@ -241,6 +241,7 @@ If you see anything that needs to be improved, please do not hesitate to contact
241
241
  - [Desktop Apps Built with Glimmer DSL for SWT](#desktop-apps-built-with-glimmer-dsl-for-swt)
242
242
  - [Table of contents](#table-of-contents)
243
243
  - [Background](#background)
244
+ - [Software Architecture](#software-architecture)
244
245
  - [Platform Support](#platform-support)
245
246
  - [Pre-requisites](#pre-requisites)
246
247
  - [Setup](#setup)
@@ -288,6 +289,7 @@ If you see anything that needs to be improved, please do not hesitate to contact
288
289
  - [Layouts](#layouts)
289
290
  - [Layout Data](#layout-data)
290
291
  - [Canvas Shape DSL](#canvas-shape-dsl)
292
+ - [Canvas Transform DSL](#canvas-transform-dsl)
291
293
  - [Canvas Animation DSL](#canvas-animation-dsl)
292
294
  - [Data-Binding](#data-binding)
293
295
  - [General Examples](#general-examples)
@@ -364,6 +366,7 @@ If you see anything that needs to be improved, please do not hesitate to contact
364
366
  - [Hello, Dialog!](#hello-dialog)
365
367
  - [Hello, Canvas!](#hello-canvas)
366
368
  - [Hello, Canvas Animation!](#hello-canvas-animation)
369
+ - [Hello, Canvas Transform!](#hello-canvas-transform)
367
370
  - [Elaborate Samples](#elaborate-samples)
368
371
  - [User Profile](#user-profile)
369
372
  - [Login](#login)
@@ -403,7 +406,39 @@ If you see anything that needs to be improved, please do not hesitate to contact
403
406
 
404
407
  ## Background
405
408
 
406
- Ruby is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the Ruby on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as SWT, JFace, and RCP can help fill the gap of desktop application development with Ruby.
409
+ [Ruby](https://www.ruby-lang.org) is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the [Ruby](https://www.ruby-lang.org) on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as [SWT](https://www.eclipse.org/swt/), JFace, and RCP can help fill the gap of desktop application development with Ruby.
410
+
411
+ ## Software Architecture
412
+
413
+ There are several requirements for building enterprise-level/consumer-level desktop GUI applications:
414
+ - Cross-Platform Support (Mac, Windows, Linux) without compilation/recompilation
415
+ - OS Native Look & Feel
416
+ - High Performance
417
+ - Productivity
418
+ - Maintainability
419
+ - Extensibility
420
+ - Native Executable Packaging
421
+ - Multi-Threading / Parallel Programming
422
+ - Arbitrary Graphics Painting
423
+ - Audio Support
424
+
425
+ Glimmer provides cross-platform support that does not require Ruby compilation (like Tk does), thanks to JRuby, a JVM (Java Virtual Machine) faster OS-threaded version of Ruby.
426
+
427
+ Glimmer leverages SWT (Standard Widget Toolkit), which provides cross-platform widgets that automatically use the native GUI libraries under each operating system, such as Win32 on Windows, Cocoa on Mac, and GTK on Linux.
428
+
429
+ Furthermore, what is special about SWT regarding "High Performance" is that it does all the GUI painting natively outside of Java, thus producing GUI that runs at maximum performance even in Ruby. As such, you do not need to worry about Ruby dynamic typing getting in the way of GUI performance. It has ZERO effect on it and since SWT supports making asynchronous calls for GUI rendering, you could avoid blocking the GUI completely with any computations happening in Ruby no matter how complex, thus never affecting the responsiveness of GUI of applications while taking full advantage of the productivity benefits of Ruby dynamic typing.
430
+
431
+ Glimmer takes this further by providing a very programmer friendly DSL (Domain Specific Language) that visually maps lightweight Ruby syntax to the containment hierarchy of GUI widgets (meaning Ruby blocks nested within each other map to GUI widgets nested within each other). This provides maximum productivity and maintainability.
432
+
433
+ Extensibility has never been simpler in desktop GUI application development than with Glimmer, which provides the ability to support any new custom keywords through custom widgets and custom shells (windows). Basically, you map a keyword by declaring a view class matching its name by convention with a GUI body that simply consists of reusable Glimmer GUI syntax. They can be passive views or smart views with additional logic. This provides the ultimate realization of Object Oriented Programming and micro-level MVC pattern.
434
+
435
+ Thanks to Java and JRuby, Glimmer apps can be packaged as cross-platform JAR files (with JRuby Warbler) and native executables (with Java Packager) as Mac APP/DMG/PACKAGE or Windows EXE/MSI.
436
+
437
+ The Java Virtual Machine already supports OS-native threads, so Glimmer apps can have multiple things running in parallel with no problem.
438
+
439
+ SWT supports Canvas graphics drawing, and Glimmer takes that further by provding a Canvas Shape/Transform/Animation DSL, making it very simple to decorate any existing widgets or add new widgets with a completely custom look and feel if needed for branding or entertainment (gaming) purposes.
440
+
441
+ Audio is supported via the Java Sound library in a cross-platform approach and video is supported via a Glimmer custom widget, so any Glimmer app can be enhanced with audio and video where needed.
407
442
 
408
443
  ## Platform Support
409
444
 
@@ -458,7 +493,7 @@ jgem install glimmer-dsl-swt
458
493
 
459
494
  Or this command if you want a specific version:
460
495
  ```
461
- jgem install glimmer-dsl-swt -v 4.18.2.5
496
+ jgem install glimmer-dsl-swt -v 4.18.3.4
462
497
 
463
498
 
464
499
  ```
@@ -478,7 +513,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
478
513
 
479
514
  Add the following to `Gemfile`:
480
515
  ```
481
- gem 'glimmer-dsl-swt', '~> 4.18.2.5
516
+ gem 'glimmer-dsl-swt', '~> 4.18.3.4
482
517
  '
483
518
  ```
484
519
 
@@ -537,7 +572,7 @@ bin/glimmer samples
537
572
  Below are the full usage instructions that come up when running `glimmer` without args.
538
573
 
539
574
  ```
540
- Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.2.5
575
+ Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.3.4
541
576
 
542
577
 
543
578
 
@@ -813,7 +848,7 @@ glimmer run
813
848
 
814
849
  #### Custom Shell
815
850
 
816
- To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
851
+ To scaffold a Glimmer [custom shell](#custom-shells) (full window view) for an existing Glimmer app, run the following command:
817
852
 
818
853
  ```
819
854
  glimmer scaffold:customshell[name]
@@ -827,7 +862,7 @@ glimmer scaffold:cs[name]
827
862
 
828
863
  #### Custom Widget
829
864
 
830
- To scaffold a Glimmer custom widget (part of a view) for an existing Glimmer app, run the following command:
865
+ To scaffold a Glimmer [custom widget](#custom-widgets) (part of a view) for an existing Glimmer app, run the following command:
831
866
 
832
867
  ```
833
868
  glimmer scaffold:customwidget[name]
@@ -841,7 +876,7 @@ glimmer scaffold:cw[name]
841
876
 
842
877
  #### Custom Shell Gem
843
878
 
844
- Custom shell gems are self-contained Glimmer apps as well as reusable custom shells.
879
+ Custom shell gems are self-contained Glimmer apps as well as reusable [custom shells](#custom-shells).
845
880
  They have everything scaffolded Glimmer apps come with in addition to gem content like a [Juwelier](https://rubygems.org/gems/juwelier) Rakefile that can build gemspec and release gems.
846
881
  Unlike scaffolded Glimmer apps, custom shell gem content lives under the `lib` directory (not `app`).
847
882
  They can be packaged as both a native executable (e.g. Mac DMG/PKG/APP) and a Ruby gem.
@@ -876,7 +911,7 @@ Examples:
876
911
 
877
912
  #### Custom Widget Gem
878
913
 
879
- To scaffold a Glimmer custom widget gem (part of a view distributed as a Ruby gem), run the following command:
914
+ To scaffold a Glimmer [custom widget](#custom-widgets) gem (part of a view distributed as a Ruby gem), run the following command:
880
915
 
881
916
  ```
882
917
  glimmer scaffold:gem:customwidget[name,namespace]
@@ -902,7 +937,7 @@ Examples:
902
937
 
903
938
  ### Gem Listing
904
939
 
905
- The `glimmer` command comes with tasks for listing Glimmer related gems to make it easy to find Glimmer Custom Shells, Custom Widgets, and DSLs published by others in the Glimmer community on [rubygems.org](http://www.rubygems.org).
940
+ The `glimmer` command comes with tasks for listing Glimmer related gems to make it easy to find Glimmer [Custom Shells](#custom-shells), [Custom Widgets](#custom-widgets), and DSLs published by others in the Glimmer community on [rubygems.org](http://www.rubygems.org).
906
941
 
907
942
  #### Listing Custom Shell Gems
908
943
 
@@ -1018,7 +1053,7 @@ Output:
1018
1053
 
1019
1054
  Css glimmer-dsl-css 1.1.0 AndyMaleh Glimmer DSL for CSS
1020
1055
  Opal glimmer-dsl-opal 0.10.2 AndyMaleh Glimmer DSL for Opal
1021
- Swt glimmer-dsl-swt 4.18.2.5
1056
+ Swt glimmer-dsl-swt 4.18.3.4
1022
1057
 
1023
1058
  AndyMaleh Glimmer DSL for SWT
1024
1059
  Tk glimmer-dsl-tk 0.0.6 AndyMaleh Glimmer DSL for Tk
@@ -1096,7 +1131,12 @@ bin/girb
1096
1131
 
1097
1132
  Watch out for hands-on examples in this README indicated by "you may copy/paste in [`girb`](#girb-glimmer-irb-command)"
1098
1133
 
1099
- Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
1134
+ Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt/samples](https://github.com/AndyObtiva/glimmer-dsl-swt/samples)
1135
+
1136
+ If you need a more GUI interactive option to experiement with Glimmer GUI DSL Syntax, you may try:
1137
+ - [Glimmer Meta-Sample (The Sample of Samples)](#samples): allows launching Glimmer samples and viewing/editing code to learn/experiment too.
1138
+ - ["Ugliest Editor Ever"](https://github.com/AndyObtiva/glimmer-cs-gladiator)
1139
+ - Just build your own GUI editor using the [Glimmer DSL for SWT Ruby Gem](https://rubygems.org/gems/glimmer-dsl-swt).
1100
1140
 
1101
1141
  ## Glimmer GUI DSL Syntax
1102
1142
 
@@ -1507,7 +1547,7 @@ Although SWT Display is not technically a widget, it has similar APIs and DSL su
1507
1547
 
1508
1548
  #### Multi-Threading
1509
1549
 
1510
- [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.
1550
+ [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.
1511
1551
 
1512
1552
  ##### async_exec
1513
1553
 
@@ -1938,7 +1978,7 @@ style = swt(:shell_trim, :max!) # creates a shell trim style without the maximiz
1938
1978
 
1939
1979
  SWT Shell widget by default is resizable. To make it non-resizable, one must pass a complicated style bit concoction like `swt(:shell_trim, :resize!, :max!)`.
1940
1980
 
1941
- Glimmer makes this easier by alternatively offering a `:no_resize` extra SWT style, added for convenience.
1981
+ Glimmer makes this easier by alternatively ing a `:no_resize` extra SWT style, added for convenience.
1942
1982
  This makes declaring a non-resizable window as easy as:
1943
1983
 
1944
1984
  ```ruby
@@ -2317,7 +2357,7 @@ Shape keywords and their args (including defaults) are listed below (they basica
2317
2357
  - `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
2318
2358
  - `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))
2319
2359
 
2320
- Shape keywords that can be filled with color can take an keyword argument `fill: true` (defaults to false when not specified)
2360
+ 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.
2321
2361
 
2322
2362
  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.
2323
2363
 
@@ -2339,6 +2379,7 @@ Here is a list of supported attributes nestable within a block under shapes:
2339
2379
  - `line_style` line join style (SWT style value of `:line_solid`, `:line_dash`, `:line_dot`, `:line_dashdot`, or `:line_dashdotdot`)
2340
2380
  - `line_width` line width in integer (used in draw operations)
2341
2381
  - `text_anti_alias` enables text antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
2382
+ - `transform` sets transform object using [Canvas Transform DSL](#canvas-transform-dsl) syntax
2342
2383
 
2343
2384
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
2344
2385
 
@@ -2354,10 +2395,10 @@ shell {
2354
2395
 
2355
2396
  canvas {
2356
2397
  background :dark_yellow
2357
- rectangle(0, 0, 220, 400, fill: true) {
2398
+ rectangle(0, 0, 220, 400) {
2358
2399
  background :dark_red
2359
2400
  }
2360
- rectangle(50, 20, 300, 150, 30, 50, round: true, fill: true) {
2401
+ rectangle(50, 20, 300, 150, 30, 50, round: true) {
2361
2402
  background :yellow
2362
2403
  }
2363
2404
  rectangle(150, 200, 100, 70, true, gradient: true) {
@@ -2387,6 +2428,8 @@ If you get extremely stuck, remember that you could always default to direct [SW
2387
2428
  Example of manually doing the same things as in the above example without relying on the declarative Glimmer Shape DSL:
2388
2429
 
2389
2430
  ```ruby
2431
+ image_object = image(File.expand_path('./icons/scaffold_app.png'), width: 100)
2432
+
2390
2433
  include Glimmer
2391
2434
 
2392
2435
  shell {
@@ -2397,17 +2440,23 @@ shell {
2397
2440
  background :yellow
2398
2441
 
2399
2442
  on_paint_control { |event|
2400
- event.gc.setBackground(color(:red).swt_color)
2401
- event.gc.fillRectangle(0, 0, 220, 400)
2443
+ event.gc.set_background(color(:red).swt_color)
2444
+ event.gc.fill_rectangle(0, 0, 220, 400)
2445
+
2446
+ event.gc.set_background(color(:magenta).swt_color)
2447
+ event.gc.fill_roundRectangle(50, 20, 300, 150, 30, 50)
2402
2448
 
2403
- event.gc.setBackground(color(:magenta).swt_color)
2404
- event.gc.fillRoundRectangle(50, 20, 300, 150, 30, 50)
2449
+ event.gc.set_background(color(:dark_magenta).swt_color)
2450
+ event.gc.fill_gradientRectangle(150, 200, 100, 70, true)
2405
2451
 
2406
- event.gc.setBackground(color(:dark_magenta).swt_color)
2407
- event.gc.fillGradientRectangle(150, 200, 100, 70, true)
2452
+ event.gc.set_foreground(color(:dark_blue).swt_color)
2453
+ event.gc.draw_rectangle(200, 80, 108, 36)
2408
2454
 
2409
- event.gc.setForeground(color(:dark_blue).swt_color)
2410
- event.gc.drawRectangle(200, 80, 108, 36)
2455
+ event.gc.set_foreground(color(:black).swt_color)
2456
+ event.gc.set_lineWidth(3)
2457
+ event.gc.draw_rectangle(200, 80, 108, 36)
2458
+
2459
+ event.gc.draw_image(image_object.swt_image, 70, 50)
2411
2460
  }
2412
2461
  }
2413
2462
  }.open
@@ -2419,6 +2468,185 @@ In any case, if there is anything missing you would like added to the Glimmer Sh
2419
2468
 
2420
2469
  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`.
2421
2470
 
2471
+ #### Shapes inside an Image
2472
+
2473
+ You can build an image using the Canvas Shape DSL (including setting the icon of the application).
2474
+
2475
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
2476
+
2477
+ ```
2478
+ include Glimmer
2479
+
2480
+ shell {
2481
+ text 'Image Shape DSL Example'
2482
+ label {
2483
+ bevel_constant = 20
2484
+ icon_block_size = 64
2485
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
2486
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
2487
+ icon_size = 8
2488
+ icon_pixel_size = icon_block_size * icon_size
2489
+ image(icon_pixel_size, icon_pixel_size) {
2490
+ icon_size.times { |row|
2491
+ icon_size.times { |column|
2492
+ colored = row >= 1 && column.between?(1, 6)
2493
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
2494
+ x = column * icon_block_size
2495
+ y = row * icon_block_size
2496
+ rectangle(x, y, icon_block_size, icon_block_size) {
2497
+ background color
2498
+ }
2499
+ 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) {
2500
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
2501
+ }
2502
+ 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) {
2503
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
2504
+ }
2505
+ 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) {
2506
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
2507
+ }
2508
+ 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) {
2509
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
2510
+ }
2511
+ }
2512
+ }
2513
+ }
2514
+ }
2515
+ }.open
2516
+ ```
2517
+
2518
+ ![Image Shape DSL](images/glimmer-example-image-shape-dsl.png)
2519
+
2520
+ Example setting the icon of the application (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
2521
+
2522
+ ```
2523
+ include Glimmer
2524
+
2525
+ shell {
2526
+ text 'Image Shape DSL Example'
2527
+ label {
2528
+ text 'Image Shape DSL Example'
2529
+ font height: 30
2530
+ }
2531
+ bevel_constant = 20
2532
+ icon_block_size = 64
2533
+ icon_bevel_size = icon_block_size.to_f / 25.to_f
2534
+ icon_bevel_pixel_size = 0.16*icon_block_size.to_f
2535
+ icon_size = 8
2536
+ icon_pixel_size = icon_block_size * icon_size
2537
+ image(icon_pixel_size, icon_pixel_size) {
2538
+ icon_size.times { |row|
2539
+ icon_size.times { |column|
2540
+ colored = row >= 1 && column.between?(1, 6)
2541
+ color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
2542
+ x = column * icon_block_size
2543
+ y = row * icon_block_size
2544
+ rectangle(x, y, icon_block_size, icon_block_size) {
2545
+ background color
2546
+ }
2547
+ 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) {
2548
+ background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
2549
+ }
2550
+ 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) {
2551
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
2552
+ }
2553
+ 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) {
2554
+ background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
2555
+ }
2556
+ 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) {
2557
+ background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
2558
+ }
2559
+ }
2560
+ }
2561
+ }
2562
+ }.open
2563
+ ```
2564
+
2565
+ ![Image Shape DSL](images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
2566
+
2567
+
2568
+ ### Canvas Transform DSL
2569
+
2570
+ The transform DSL builds [org.eclipse.swt.graphics.Transform](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Transform.html) objects with a nice declarative syntax.
2571
+
2572
+ `transform` keyword builds a `Transform` object. It optionally takes the transformation matrix elements: (m11, m12, m21, m22, dx, dy)
2573
+
2574
+ The first 2 values represent the 1st row, the second 2 values represent the 2nd row, and the last 2 values represent translation on the x and y axes
2575
+
2576
+ Additionally, Transform operation keywords may be nested within the `transform` keyword to set its properties:
2577
+ - `identity` resets transform to identity (no transformation)
2578
+ - `invert` inverts a transform
2579
+ - `multiply(&block)` multiplies by another transform (takes a block representing properties of another transform, no need for using the word transform again)
2580
+ - `rotate(angle)` rotates by angle degrees
2581
+ - `scale(x, y)` scales a shape (stretch)
2582
+ - `shear(x, y)` shear effect
2583
+ - `translate(x, y)` translate x and y coordinates (move)
2584
+ - `elements(m11, m12, m21, m22, dx, dy)` resets all values of the transform matrix (first 2 values represent the 1st row, second 2 values represent the 2nd row, the last 2 values represent translation on x and y axes)
2585
+
2586
+ Also, setting `transform` to `nil` after a previous `transform` has been set is like calling `identity`. It resets the transform.
2587
+
2588
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
2589
+
2590
+ ```ruby
2591
+ include Glimmer
2592
+
2593
+ shell {
2594
+ text 'Canvas Transform Example'
2595
+ minimum_size 330, 352
2596
+
2597
+ canvas { |canvas_proxy|
2598
+ background :white
2599
+
2600
+ text('glimmer', 0, 0) {
2601
+ foreground :red
2602
+ transform {
2603
+ translate 220, 100
2604
+ scale 2.5, 2.5
2605
+ rotate 90
2606
+ }
2607
+ }
2608
+ text('glimmer', 0, 0) {
2609
+ foreground :dark_green
2610
+ transform {
2611
+ translate 0, 0
2612
+ shear 2, 3
2613
+ scale 2, 2
2614
+ }
2615
+ }
2616
+ text('glimmer', 0, 0) {
2617
+ foreground :blue
2618
+ transform {
2619
+ translate 0, 220
2620
+ scale 3, 3
2621
+ }
2622
+ }
2623
+ }
2624
+ }.open
2625
+ ```
2626
+
2627
+ ![Canvas Transform Example](images/glimmer-example-canvas-transform.png)
2628
+
2629
+ #### Top-Level Transform Fluent Interface
2630
+
2631
+ When using a transform at the top-level (outside of shell), you get a fluent interface to faciliate manual constructioni and use.
2632
+
2633
+ Example:
2634
+
2635
+ ```ruby
2636
+ include Glimmer # make sure it is included in your class/module before using the fluent interface
2637
+
2638
+ transform(1, 1, 4, 2, 2, 4).
2639
+ multiply(1, 2, 3, 4,3,4).
2640
+ scale(1, 2, 3, 4, 5, 6).
2641
+ rotate(45).
2642
+ scale(2, 4).
2643
+ invert.
2644
+ shear(2, 4).
2645
+ translate(3, 7)
2646
+ ```
2647
+
2648
+ Learn more at the [Hello, Canvas Transform! Sample](#hello-canvas-transform).
2649
+
2422
2650
  ### Canvas Animation DSL
2423
2651
 
2424
2652
  (note: this is a very new feature of Glimmer. It may change a bit while getting battle tested. As always, you could default to basic SWT usage if needed.)
@@ -2442,7 +2670,7 @@ shell {
2442
2670
 
2443
2671
  frame { |index|
2444
2672
  background rgb(index%100, index%100 + 100, index%55 + 200)
2445
- rectangle(index, index, 20, 20, fill: true) {
2673
+ rectangle(index, index, 20, 20) {
2446
2674
  background :red
2447
2675
  }
2448
2676
  }
@@ -2843,7 +3071,7 @@ Glimmer automatic table sorting supports `String`, `Integer`, and `Float` column
2843
3071
 
2844
3072
  In cases where data is nil, depending on the data-type, it is automatically converted to `Float` with `to_f`, `Integer` with `to_i`, or `String` with `to_s`.
2845
3073
 
2846
- Should you have a special data type that could not be compared automatically, Glimmer offers the following 3 alternatives for custom sorting:
3074
+ Should you have a special data type that could not be compared automatically, Glimmer s the following 3 alternatives for custom sorting:
2847
3075
  - `sort_property`: this may be set to an alternative property to the one data-bound to the table column. For example, a table column called 'adult', which returns `true` or `false` may be sorted with `sort_property :dob` instead. This also support multi-property (aka multi-column) sorting (e.g. `sort_property :dob, :name`).
2848
3076
  - `sort_by(&block)`: this works just like Ruby `Enumerable` `sort_by`. The block receives the table column data as argument.
2849
3077
  - `sort(&comparator)`: this works just like Ruby `Enumerable` `sort`. The comparator block receives two objects from the table column data.
@@ -2894,6 +3122,7 @@ Here is an explanation of the example above:
2894
3122
  - Task Start Date table column has a custom sort comparator block
2895
3123
  - Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
2896
3124
 
3125
+ `bind(model, :property, read_only_sort: true)` could be used with items to make sorting not propagate sorting changes to model.
2897
3126
 
2898
3127
  #### Tree
2899
3128
 
@@ -2938,7 +3167,7 @@ a text widget to the user to change the selected or passed tree item text into s
2938
3167
 
2939
3168
  `date_time` represents the SWT DateTime widget.
2940
3169
 
2941
- Glimmer offers the following alias keywords for it for convenience:
3170
+ Glimmer s the following alias keywords for it for convenience:
2942
3171
  - `date`: `date_time(:date)`
2943
3172
  - `date_drop_down`: `date_time(:date, :drop_down)`
2944
3173
  - `time`: `date_time(:time)`
@@ -3143,7 +3372,7 @@ Approach #1 is a casual Ruby-based approach. Approach #2 is the official Glimmer
3143
3372
 
3144
3373
  A developer might start with approach #1 to eliminate duplication in a view and later upgrade it to approach #2 when needing to export a custom widget to make it available in many views.
3145
3374
 
3146
- Class-based Custom Widgets offer a number of benefits over method-based custom widgets, such as built-in support for passing SWT style, nested block of extra widgets and properties, and `before_body`/`after_body` hooks.
3375
+ Class-based Custom Widgets a number of benefits over method-based custom widgets, such as built-in support for passing SWT style, nested block of extra widgets and properties, and `before_body`/`after_body` hooks.
3147
3376
 
3148
3377
  #### Simple Example
3149
3378
 
@@ -3401,11 +3630,13 @@ shell { |app_shell|
3401
3630
  }.open
3402
3631
  ```
3403
3632
 
3633
+ 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`)
3634
+
3404
3635
  You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
3405
3636
 
3406
3637
  ### Drag and Drop
3407
3638
 
3408
- Glimmer offers Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
3639
+ Glimmer s Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
3409
3640
 
3410
3641
  You may learn more about SWT Drag and Drop support over here: [https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html](https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
3411
3642
 
@@ -3681,6 +3912,41 @@ shell(:no_resize) {
3681
3912
 
3682
3913
  Also, you may invoke `Display.app_version = '1.0.0'` if needed for OS app version identification reasons during development, replacing `'1.0.0'` with your application version.
3683
3914
 
3915
+ #### Performance Profiling
3916
+
3917
+ JRuby comes with built-in support for performance profiling via the `--profile` option (with some code shown below), which can be accepted by the `glimmer` command too:
3918
+
3919
+ `glimmer --profile path_to_glimmer_app.rb`
3920
+
3921
+ Additionally, add this code to monitor Glimmer app performance around its launch method:
3922
+
3923
+ ```ruby
3924
+ require 'jruby/profiler'
3925
+ profile_data = JRuby::Profiler.profile do
3926
+ SomeGlimmerApp.launch
3927
+ end
3928
+
3929
+ profile_printer = JRuby::Profiler::HtmlProfilePrinter.new(profile_data)
3930
+ ps = java.io.PrintStream.new(STDOUT.to_outputstream)
3931
+ ```
3932
+
3933
+ When monitoring app startup time performance, make sure to add a hook to the top-level `shell` `on_swt_show` event that exits the app as soon as the shell shows up to end performance profiling and get the results.
3934
+
3935
+ Example:
3936
+
3937
+ ```ruby
3938
+ shell {
3939
+ # some code
3940
+ on_swt_show {
3941
+ exit(0)
3942
+ }
3943
+ }
3944
+ ```
3945
+
3946
+ You may run `glimmer` with the `--profile.graph` instead for a more detailed output.
3947
+
3948
+ Learn more at the [JRuby Performance Profile WIKI page](https://github.com/jruby/jruby/wiki/Profiling-JRuby).
3949
+
3684
3950
  #### Checkbox Group Widget
3685
3951
 
3686
3952
  `checkbox_group` (or alias `check_group`) is a Glimmer built-in custom widget that displays a list of `checkbox` buttons (`button(:check)`) based on its `items` property.
@@ -4017,8 +4283,18 @@ end
4017
4283
 
4018
4284
  ### log_excluded_keywords
4019
4285
 
4286
+ (default = false)
4287
+
4020
4288
  This just tells Glimmer whether to log excluded keywords or not (at the debug level). It is off by default.
4021
4289
 
4290
+ ### auto_sync_exec
4291
+
4292
+ (default = false)
4293
+
4294
+ 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.
4295
+
4296
+ 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.
4297
+
4022
4298
  ## Glimmer Style Guide
4023
4299
 
4024
4300
  - Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
@@ -4094,6 +4370,12 @@ This brings up the [Glimmer Meta-Sample (The Sample of Samples)](samples/elabora
4094
4370
 
4095
4371
  You may edit the code of any sample before launching it by clicking on the "Launch" button. This helps you learn by experimenting with Glimmer GUI DSL syntax. To go back to original code, simply hit the "Reset" button.
4096
4372
 
4373
+ Note that if you fail to run any sample through the Glimmer Meta-Sample for whatever reason, you could always run directly by cloning the project, running `bundle`, and then this command (drop the "bin" if you install the glimmer-dsl-swt gem instead):
4374
+
4375
+ ```ruby
4376
+ bin/glimmer samples/hello/hello_canvas_transform.rb
4377
+ ```
4378
+
4097
4379
  ### Hello Samples
4098
4380
 
4099
4381
  For hello-type simple samples, check the following.
@@ -4581,6 +4863,19 @@ Hello, Canvas Animation Another Frame!
4581
4863
 
4582
4864
  ![Hello Canvas Animation Frame 2](images/glimmer-hello-canvas-animation-frame2.png)
4583
4865
 
4866
+ #### Hello, Canvas Transform!
4867
+
4868
+ This sample demonstrates the use of the `transform` keyword as part of the [Transform DSL](#canvas-transform-dsl) within the [Shape DSL](#canvas-shape-dsl).
4869
+
4870
+ Code:
4871
+
4872
+ [samples/hello/hello_canvas_transform.rb](samples/hello/hello_canvas_transform.rb)
4873
+
4874
+ Hello, Canvas Transform!
4875
+
4876
+ ![Hello Canvas Transform](images/glimmer-hello-canvas-transform.png)
4877
+
4878
+
4584
4879
  ### Elaborate Samples
4585
4880
 
4586
4881
  For more elaborate samples, check the following:
@@ -4653,16 +4948,30 @@ Contact Manager - Edit Done
4653
4948
 
4654
4949
  #### Tetris
4655
4950
 
4656
- This sample demonstrates how to build an interactive animated game with MVC architecture, custom-shell/custom-widgets, multi-threading, asynchronous programming, data-binding, canvas shape graphic decorations, and keyboard events.
4951
+ This sample demonstrates how to build an interactive animated game with MVC architecture, custom-shell/custom-widgets, multi-threading, asynchronous programming, data-binding, canvas shape graphic decorations, canvas shape icon image generation, and keyboard events/shortcuts.
4657
4952
 
4658
4953
  Code:
4659
4954
 
4660
4955
  [samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)
4661
4956
 
4957
+ ![Tetris Icon](images/glimmer-tetris-icon.png)
4958
+
4662
4959
  ![Tetris](images/glimmer-tetris.png)
4663
4960
 
4664
4961
  ![Tetris Game Over](images/glimmer-tetris-game-over.png)
4665
4962
 
4963
+ ![Tetris Game Over](images/glimmer-tetris-game-over-sorted-by-score.png)
4964
+
4965
+ ![Tetris High Scores](images/glimmer-tetris-high-score-dialog.png)
4966
+
4967
+ ![Tetris Game Menu](images/glimmer-tetris-game-menu.png)
4968
+
4969
+ ![Tetris View Menu](images/glimmer-tetris-view-menu.png)
4970
+
4971
+ ![Tetris Options Menu](images/glimmer-tetris-options-menu.png)
4972
+
4973
+ ![Tetris Help Menu](images/glimmer-tetris-help-menu.png)
4974
+
4666
4975
  ### External Samples
4667
4976
 
4668
4977
  #### Glimmer Calculator
@@ -4824,7 +5133,7 @@ Pass `-v` to javapackager in `Glimmer::RakeTask::Package.javapackager_extra_args
4824
5133
 
4825
5134
  ### Windows Application Packaging
4826
5135
 
4827
- Windows offers two options for setup packaging:
5136
+ Windows s two options for setup packaging:
4828
5137
  - `msi` (recommended): simpler packaging option. Requires [WiX Toolset](https://wixtoolset.org/) and [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework). Simply run `glimmer package[msi]` (or `glimmer package:native[msi]` if it's not your first time) and it will give you more details on the pre-requisites you need to install (e.g. [WiX Toolset](https://wixtoolset.org/) and [.NET Framework 3.5 SP1](https://dotnet.microsoft.com/download/dotnet-framework/net35-sp1)).
4829
5138
  - `exe`: more advanced packaging option. Requires [Inno Setup](https://jrsoftware.org/isinfo.php). Simply run `glimmer package[exe]` (or `glimmer package:native[exe]` if it's not your first time) and it will tell you what you need to install.
4830
5139