glimmer 0.9.4 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11d28368bdf3ae26dcee4ddc661bdeee07fdf932f7c7c8fb45c27de98d4f43dc
4
- data.tar.gz: b30a42a8f18f74fca414937f068ebcaeee31ba4f76c3afb1be866b9958647426
3
+ metadata.gz: 9c1c9758088604c5d7369a6cabaf6b80e8ff7ff18036e55e397c472014d5dd3d
4
+ data.tar.gz: a4f41a4f54df4a2ba9fb52557879132e9c473db57a150597fc8c974c81e4eb28
5
5
  SHA512:
6
- metadata.gz: 5f0728a1a263ff3c8c841a508d3b250910d2ddf548284029dcea23364522d436f408fe49b10683981241144d4e2bf6a20ab718ce75ed04244c6f9dc0ca51be07
7
- data.tar.gz: 411965a314069222d27aaddfdbcbe129665725e73d082d6c15805adb188e1a1fc89d62578dc2712972684d8f5f59313b6868667b245cfdfee66f06ad6ef521e9
6
+ metadata.gz: a5551a3822e3743a4d38e228351bb06fb067ed50e42eeb9a1846fd326ea93319efc68b8294ecf589269f276600077d5023de057c35f10309ce312bc76c345e42
7
+ data.tar.gz: 7d85be1c6744e2fcee830ba228142d62d72c75b8f270e57bc4f132174e0dad676a4603c49f21a1efb89194f0d5b734be0c8228576edca86a4d625f497cd82e50
data/README.md CHANGED
@@ -1,14 +1,17 @@
1
- # <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" /> Glimmer (Ruby Desktop Development GUI Library)
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" />](https://rubygems.org/gems/glimmer) Glimmer (Ruby Desktop Development GUI Library)
2
2
  [![Gem Version](https://badge.fury.io/rb/glimmer.svg)](http://badge.fury.io/rb/glimmer)
3
3
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/38fbc278022862794414/maintainability)](https://codeclimate.com/github/AndyObtiva/glimmer/maintainability)
5
6
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6
7
 
7
8
  **[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
8
9
 
9
10
  (The Original Glimmer Library Since 2007. Beware of Imitators!)
10
11
 
11
- Glimmer is a native-GUI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the GUI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models test-first afterwards.
12
+ [**Glimmer**](https://rubygems.org/gems/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://rubygems.org/gems/glimmer)'s main innovation is a declarative [Ruby DSL](#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces while 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. 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/) and MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows). Unlike libraries like TK, [Glimmer](https://rubygems.org/gems/glimmer) does not require recompilation of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://rubygems.org/gems/glimmer) runs native GUI out of the box on every platform thanks to the [JVM](https://java.com/en/download/faq/whatis_java.xml), [JRuby](https://www.jruby.org/), and the [Eclipse SWT library](https://www.eclipse.org/swt/).
13
+
14
+ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contributing), adopting for small or low risk projects, and providing feedback. While a lot of hard work has gone into it, it is by no means polished, and definitely has bugs waiting to be reported. The more feedback and issues you report the better.
12
15
 
13
16
  [<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
14
17
  Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
@@ -17,13 +20,13 @@ Glimmer DSL gems:
17
20
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
18
21
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
19
22
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
20
- - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
23
+ - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
21
24
 
22
25
  ## Examples
23
26
 
24
27
  ### Hello, World!
25
28
 
26
- Glimmer code (from `samples/hello/hello_world.rb`):
29
+ Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
27
30
  ```ruby
28
31
  include Glimmer
29
32
 
@@ -46,28 +49,28 @@ Glimmer app:
46
49
 
47
50
  ### Tic Tac Toe
48
51
 
49
- Glimmer code (from `samples/elaborate/tic_tac_toe.rb`):
52
+ Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
50
53
 
51
54
  ```ruby
52
55
  # ...
53
- shell {
54
- text "Tic-Tac-Toe"
55
- composite {
56
- grid_layout 3, true
57
- (1..3).each { |row|
58
- (1..3).each { |column|
59
- button {
60
- layout_data :fill, :fill, true, true
61
- text bind(@tic_tac_toe_board[row, column], :sign)
62
- enabled bind(@tic_tac_toe_board[row, column], :empty)
63
- on_widget_selected {
64
- @tic_tac_toe_board.mark(row, column)
56
+ @shell = shell {
57
+ text "Tic-Tac-Toe"
58
+ composite {
59
+ grid_layout 3, true
60
+ (1..3).each { |row|
61
+ (1..3).each { |column|
62
+ button {
63
+ layout_data :fill, :fill, true, true
64
+ text bind(@tic_tac_toe_board[row, column], :sign)
65
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
66
+ on_widget_selected {
67
+ @tic_tac_toe_board.mark(row, column)
68
+ }
69
+ }
65
70
  }
66
71
  }
67
72
  }
68
73
  }
69
- }
70
- }
71
74
  # ...
72
75
  ```
73
76
 
@@ -81,7 +84,95 @@ Glimmer app:
81
84
 
82
85
  ![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
83
86
 
84
- NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contributing), adopting for small or low risk projects, and providing feedback.
87
+ ### Contact Manager
88
+
89
+ Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
90
+
91
+ ```ruby
92
+ # ...
93
+ shell {
94
+ text "Contact Manager"
95
+ composite {
96
+ composite {
97
+ grid_layout 2, false
98
+ label {text "First &Name: "}
99
+ text {
100
+ text bind(@contact_manager_presenter, :first_name)
101
+ on_key_pressed {|key_event|
102
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
103
+ }
104
+ }
105
+ label {text "&Last Name: "}
106
+ text {
107
+ text bind(@contact_manager_presenter, :last_name)
108
+ on_key_pressed {|key_event|
109
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
110
+ }
111
+ }
112
+ label {text "&Email: "}
113
+ text {
114
+ text bind(@contact_manager_presenter, :email)
115
+ on_key_pressed {|key_event|
116
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
117
+ }
118
+ }
119
+ composite {
120
+ grid_layout 2, false
121
+ button {
122
+ text "&Find"
123
+ on_widget_selected {
124
+ @contact_manager_presenter.find
125
+ }
126
+ }
127
+ button {
128
+ text "&List All"
129
+ on_widget_selected {
130
+ @contact_manager_presenter.list
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ table(:multi) { |table_proxy|
137
+ layout_data {
138
+ horizontal_alignment :fill
139
+ vertical_alignment :fill
140
+ grab_excess_horizontal_space true
141
+ grab_excess_vertical_space true
142
+ height_hint 200
143
+ }
144
+ table_column {
145
+ text "First Name"
146
+ width 80
147
+ }
148
+ table_column {
149
+ text "Last Name"
150
+ width 80
151
+ }
152
+ table_column {
153
+ text "Email"
154
+ width 200
155
+ }
156
+ items bind(@contact_manager_presenter, :results),
157
+ column_properties(:first_name, :last_name, :email)
158
+ on_mouse_up { |event|
159
+ table_proxy.edit_table_item(event.table_item, event.column_index)
160
+ }
161
+ }
162
+ }
163
+ }.open
164
+ # ...
165
+ ```
166
+
167
+ Run:
168
+
169
+ ```
170
+ glimmer samples/elaborate/contact_manager.rb
171
+ ```
172
+
173
+ Glimmer App:
174
+
175
+ ![Contact Manager](images/glimmer-contact-manager.png)
85
176
 
86
177
  ## Table of contents
87
178
 
@@ -112,12 +203,14 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
112
203
  - [Raw JRuby Command](#raw-jruby-command)
113
204
  - [Mac Support](#mac-support)
114
205
  - [Girb (Glimmer irb) Command](#girb-glimmer-irb-command)
115
- - [Glimmer DSL Syntax](#glimmer-dsl-syntax)
206
+ - [Glimmer GUI DSL Syntax](#glimmer-gui-dsl-syntax)
207
+ - [DSL Auto-Expansion](#dsl-auto-expansion)
116
208
  - [Widgets](#widgets)
117
209
  - [Display](#display)
118
210
  - [SWT Proxies](#swt-proxies)
119
211
  - [Dialog](#dialog)
120
212
  - [Menus](#menus)
213
+ - [ScrolledComposite](#scrolledcomposite)
121
214
  - [Widget Styles](#widget-styles)
122
215
  - [Explicit SWT Style Bit](#explicit-swt-style-bit)
123
216
  - [Negative SWT Style Bits](#negative-swt-style-bits)
@@ -143,6 +236,7 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
143
236
  - [Content/Options Example](#contentoptions-example)
144
237
  - [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
145
238
  - [Gotcha](#gotcha)
239
+ - [Final Notes](#final-notes)
146
240
  - [Custom Shells](#custom-shells)
147
241
  - [Drag and Drop](#drag-and-drop)
148
242
  - [Miscellaneous](#miscellaneous)
@@ -153,13 +247,13 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
153
247
  - [Browser Widget](#browser-widget)
154
248
  - [Glimmer Configuration](#glimmer-configuration)
155
249
  - [logger](#logger)
156
- - [import_swt_packages](#import_swt_packages)
157
- - [loop_max_count](#loop_max_count)
250
+ - [import_swt_packages](#importswtpackages)
251
+ - [loop_max_count](#loopmaxcount)
158
252
  - [Glimmer Style Guide](#glimmer-style-guide)
159
253
  - [SWT Reference](#swt-reference)
160
254
  - [Samples](#samples)
161
255
  - [Hello Samples](#hello-samples)
162
- - [Hello, World!](#hello-world-sample)
256
+ - [Hello, World! Sample](#hello-world-sample)
163
257
  - [Hello, Tab!](#hello-tab)
164
258
  - [Hello, Combo!](#hello-combo)
165
259
  - [Hello, List Single Selection!](#hello-list-single-selection)
@@ -168,14 +262,20 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
168
262
  - [Hello, Message Box!](#hello-message-box)
169
263
  - [Hello, Browser!](#hello-browser)
170
264
  - [Hello, Drag and Drop!](#hello-drag-and-drop)
265
+ - [Hello, Menu Bar!](#hello-menu-bar)
266
+ - [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
171
267
  - [Elaborate Samples](#elaborate-samples)
172
268
  - [Login](#login)
173
- - [Tic Tac Toe](#tic-tac-toe-sample)
174
- - [Contact Manager](#contact-manager)
269
+ - [Tic Tac Toe Sample](#tic-tac-toe-sample)
270
+ - [Contact Manager](#contact-manager-sample)
175
271
  - [External Samples](#external-samples)
176
272
  - [Glimmer Calculator](#glimmer-calculator)
177
273
  - [Gladiator](#gladiator)
274
+ - [Timer](#timer)
178
275
  - [In Production](#in-production)
276
+ - [Math Bowling](#math-bowling)
277
+ - [Are We There Yet?](#are-we-there-yet)
278
+ - [Garderie Rainbow Daily Agenda](#garderie-rainbow-daily-agenda)
179
279
  - [Packaging & Distribution](#packaging--distribution)
180
280
  - [Packaging Defaults](#packaging-defaults)
181
281
  - [Packaging Configuration](#packaging-configuration)
@@ -183,6 +283,9 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
183
283
  - [Mac Application Distribution](#mac-application-distribution)
184
284
  - [Self Signed Certificate](#self-signed-certificate)
185
285
  - [Gotchas](#gotchas)
286
+ - [App Updates](#app-updates)
287
+ - [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
288
+ - [Glimmer Process](#glimmer-process)
186
289
  - [Resources](#resources)
187
290
  - [Help](#help)
188
291
  - [Issues](#issues)
@@ -191,6 +294,7 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
191
294
  - [Change Log](#change-log)
192
295
  - [Contributing](#contributing)
193
296
  - [Contributors](#contributors)
297
+ - [Hire Me](#hire-me)
194
298
  - [License](#license)
195
299
 
196
300
  ## Background
@@ -216,18 +320,17 @@ https://www.eclipse.org/swt/faq.php
216
320
 
217
321
  ## Pre-requisites
218
322
 
219
- - SWT 4.15 (comes included in Glimmer gem)
220
- - JRuby 9.2.12.0 (supporting Ruby 2.5.x syntax) (find at [https://www.jruby.org/download](https://www.jruby.org/download))
221
- - JDK 8 - 10 (find at [https://www.oracle.com/java/technologies/javase-downloads.html](https://www.oracle.com/java/technologies/javase-downloads.html))
222
- - (Optional) RVM is needed for [Scaffolding](#scaffolding) only (find at [https://rvm.io/](https://rvm.io/))
323
+ - JDK 8u241 (1.8.0_241) (find at https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html)
324
+ - JRuby 9.2.13.0 (supporting Ruby 2.5.x syntax) (get via [RVM](http://rvm.io) on Mac and Linux or find at [https://www.jruby.org/download](https://www.jruby.org/download) for Windows)
325
+ - SWT 4.16 (already included in the [glimmer-dsl-swt](https://rubygems.org/gems/glimmer-dsl-swt) gem)
223
326
 
224
- On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
327
+ To obtain JRuby through [RVM](http://rvm.io), you may run:
225
328
 
226
329
  ```bash
227
- rvm install jruby-9.2.12.0
330
+ rvm install jruby-9.2.13.0
228
331
  ```
229
332
 
230
- Glimmer might still work on lower versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
333
+ Glimmer might still work on other versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
231
334
 
232
335
  ## Setup
233
336
 
@@ -235,20 +338,25 @@ Please follow these instructions to make the `glimmer` command available on your
235
338
 
236
339
  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)).
237
340
 
238
- If you intend to build a Glimmer app from scratch on the Mac, pick Option 1 ([Direct Install](#option-1-direct-install)) to leverage [Glimmer Scaffolding](#scaffolding) (only available on the Mac).
341
+ If you intend to build a Glimmer app from scratch with [scaffolding](#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
239
342
 
240
- Otherwise, Option 2 ([Bundler](#option-2-bundler)) is recommended for building Glimmer apps on other platforms (Windows and Linux).
343
+ Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](#scaffolding).
241
344
 
242
345
  ### Option 1: Direct Install
243
- (Use for [Scaffolding](#scaffolding) on the Mac)
346
+ (Use for [Scaffolding](#scaffolding))
244
347
 
245
348
  Run this command to install directly:
246
349
  ```
247
- jgem install glimmer-dsl-swt -v 0.2.2
350
+ jgem install glimmer-dsl-swt
351
+ ```
352
+
353
+ Or this command if you want a specific version:
354
+ ```
355
+ jgem install glimmer-dsl-swt -v 0.6.3
248
356
  ```
249
357
 
250
358
  `jgem` is JRuby's version of `gem` command.
251
- RVM allows running `gem` as an alias.
359
+ RVM allows running `gem install` directly as an alias.
252
360
  Otherwise, you may also run `jruby -S gem install ...`
253
361
 
254
362
  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.
@@ -262,7 +370,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
262
370
 
263
371
  Add the following to `Gemfile`:
264
372
  ```
265
- gem 'glimmer-dsl-swt', '~> 0.2.2'
373
+ gem 'glimmer-dsl-swt', '~> 0.6.3'
266
374
  ```
267
375
 
268
376
  And, then run:
@@ -278,7 +386,7 @@ You may learn more about other Glimmer related gems ([`glimmer-dsl-opal`](https:
278
386
 
279
387
  The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
280
388
 
281
- If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer DSL Syntax](#glimmer-dsl-syntax), and [Samples](#samples).
389
+ If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer GUI DSL Syntax](#glimmer-gui-dsl-syntax), and [Samples](#samples).
282
390
 
283
391
  ### Basic Usage
284
392
 
@@ -316,18 +424,20 @@ Either a single task or one or more applications may be specified.
316
424
  When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
317
425
 
318
426
  Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
319
- glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
320
- glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
321
- glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
322
- glimmer package # Package app for distribution (generating config, jar, and native files)
323
- glimmer package:config # Generate JAR config file
324
- glimmer package:jar # Generate JAR file
325
- glimmer package:native # Generate Native files (DMG/PKG/APP on the Mac)
326
- glimmer scaffold[app_name] # Scaffold a Glimmer application directory structure to begin building a new app
327
- glimmer scaffold:custom_shell[custom_shell_name,namespace] # Scaffold a Glimmer::UI::CustomShell subclass (represents a full window view) under app/views (namespace is optional)
328
- glimmer scaffold:custom_shell_gem[custom_shell_name,namespace] # Scaffold a Glimmer::UI::CustomShell subclass (represents a full window view) under its own Ruby gem + app project (namespace is required)
329
- glimmer scaffold:custom_widget[custom_widget_name,namespace] # Scaffold a Glimmer::UI::CustomWidget subclass (represents a part of a view) under app/views (namespace is optional)
330
- glimmer scaffold:custom_widget_gem[custom_widget_name,namespace] # Scaffold a Glimmer::UI::CustomWidget subclass (represents a part of a view) under its own Ruby gem project (namespace is required)
427
+ glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
428
+ glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
429
+ glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
430
+ glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
431
+ glimmer package:clean # Clean by removing "dist" and "packages" directories
432
+ glimmer package:config # Generate JAR config file
433
+ glimmer package:jar # Generate JAR file
434
+ glimmer package:lock_jars # Lock JARs
435
+ glimmer package:native[type] # Generate Native files (DMG/PKG/APP on the Mac, MSI/EXE/IMAGE on Windows, RPM/DEB on Linux) (type is optional)
436
+ glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
437
+ glimmer scaffold:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cs]
438
+ glimmer scaffold:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cw]
439
+ glimmer scaffold:gem:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under its own Ruby gem + app project (namespace is required) [alt: scaffold:gem:cs]
440
+ glimmer scaffold:gem:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cw]
331
441
 
332
442
  When applications are specified, they are run using JRuby,
333
443
  automatically preloading the glimmer Ruby gem and SWT jar dependency.
@@ -368,16 +478,16 @@ getting you to a running and delivered state of an advanced "Hello, World!" Glim
368
478
 
369
479
  This should greatly facilitate building a new Glimmer app by helping you be productive and focus on app details while
370
480
  letting Glimmer scaffolding take care of initial app file structure concerns, such as adding:
371
- - Main application class that includes Glimmer
372
- - Main application view that houses main window content, about dialog, and preferences dialog
373
- - View and Model directories
374
- - Rakefile including Glimmer tasks
375
- - Version
376
- - License
377
- - Icon
378
- - Bin file for starting application
481
+ - Main application class that includes Glimmer (`app/{app_name}.rb`)
482
+ - Main application view that houses main window content, menu, about dialog, and preferences dialog
483
+ - View and Model directories (`app/views` and `app/models`)
484
+ - Rakefile including Glimmer tasks (`Rakefile`)
485
+ - Version (`VERSION`)
486
+ - License (`LICENSE.txt`)
487
+ - Icon (under `package/{platform}/{App Name}.{icon_extension}` for `macosx` .icns, `windows` .ico, and `linux` .png)
488
+ - Bin file for starting application (`bin/{app_name}.rb`)
379
489
 
380
- NOTE: Scaffolding requires RVM and currently supports Mac packaging only at the moment.
490
+ NOTE: Scaffolding supports Mac and Windows packaging at the moment.
381
491
 
382
492
  #### App
383
493
 
@@ -394,39 +504,72 @@ This will generate an advanced "Hello, World!" app, package it as a Mac native f
394
504
  Suppose you run:
395
505
 
396
506
  ```
397
- glimmer scaffold[CarMaker]
507
+ glimmer scaffold[greeter]
398
508
  ```
399
509
 
400
510
  You should see output like the following:
401
511
 
402
512
  ```
403
- Created CarMaker/.ruby-version
404
- Created CarMaker/.ruby-gemset
405
- Created CarMaker/VERSION
406
- Created CarMaker/LICENSE.txt
407
- Created CarMaker/Gemfile
408
- Created CarMaker/Rakefile
409
- Created CarMaker/app/car_maker.rb
410
- Created CarMaker/app/views/car_maker/app_view.rb
411
- Created CarMaker/package/macosx/Car Maker.icns
412
- Created CarMaker/bin/car_maker
513
+ $ glimmer scaffold[greeter]
514
+ create .gitignore
515
+ create Rakefile
516
+ create Gemfile
517
+ create LICENSE.txt
518
+ create README.rdoc
519
+ create .document
520
+ create lib
521
+ create lib/greeter.rb
522
+ create spec
523
+ create spec/spec_helper.rb
524
+ create spec/greeter_spec.rb
525
+ create .rspec
526
+ Jeweler has prepared your gem in ./greeter
527
+ Created greeter/.gitignore
528
+ Created greeter/.ruby-version
529
+ Created greeter/.ruby-gemset
530
+ Created greeter/VERSION
531
+ Created greeter/LICENSE.txt
532
+ Created greeter/Gemfile
533
+ Created greeter/Rakefile
534
+ Created greeter/app/greeter.rb
535
+ Created greeter/app/views/greeter/app_view.rb
536
+ Created greeter/package/windows/Greeter.ico
537
+ Created greeter/package/macosx/Greeter.icns
538
+ Created greeter/package/linux/Greeter.png
539
+ Created greeter/bin/greeter
540
+ Created greeter/spec/spec_helper.rb
413
541
  ...
414
542
  ```
415
543
 
416
- Eventually, it will launch an advanced "Hello, World!" app window having the title of your application and a Mac icon.
544
+ Eventually, it will launch an advanced "Hello, World!" app window having the title of your application.
417
545
 
418
546
  ![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
419
547
 
420
- On the Mac, it also comes with a boilerplate Preferences dialog.
548
+ It also comes with a boilerplate Preferences dialog.
421
549
 
422
550
  ![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
423
551
 
552
+ Here is a Windows scaffolded app called Greeter:
553
+
554
+ ![Glimmer Scaffold App Windows](images/glimmer-scaffolding-app-windows.png)
555
+
556
+ Here is the Windows version of the boilerplate Preferences dialog.
557
+
558
+ ![Glimmer Scaffold App Windows Preferences](images/glimmer-scaffolding-app-windows-preferences.png)
559
+
560
+
424
561
  #### Custom Shell
425
562
 
426
563
  To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
427
564
 
428
565
  ```
429
- glimmer scaffold:custom_shell[custom_shell_name]
566
+ glimmer scaffold:customshell[name]
567
+ ```
568
+
569
+ Or the following alternative abbreviation:
570
+
571
+ ```
572
+ glimmer scaffold:cs[name]
430
573
  ```
431
574
 
432
575
  #### Custom Widget
@@ -434,13 +577,19 @@ glimmer scaffold:custom_shell[custom_shell_name]
434
577
  To scaffold a Glimmer custom widget (part of a view) for an existing Glimmer app, run the following command:
435
578
 
436
579
  ```
437
- glimmer scaffold:custom_widget[custom_widget_name]
580
+ glimmer scaffold:customwidget[name]
581
+ ```
582
+
583
+ Or the following alternative abbreviation:
584
+
585
+ ```
586
+ glimmer scaffold:cw[name]
438
587
  ```
439
588
 
440
589
  #### Custom Shell Gem
441
590
 
442
591
  Custom shell gems are self-contained Glimmer apps as well as reusable custom shells.
443
- They have everything scaffolded Glimmer apps come with in addition to gem content like a Jeweler Rakefile that can build gemspec and release gems.
592
+ They have everything scaffolded Glimmer apps come with in addition to gem content like a [jeweler](https://github.com/technicalpickles/jeweler) Rakefile that can build gemspec and release gems.
444
593
  Unlike scaffolded Glimmer apps, custom shell gem content lives under the `lib` directory (not `app`).
445
594
  They can be packaged as both a native executable (e.g. Mac DMG/PKG/APP) and a Ruby gem.
446
595
  Of course, you can just build a Ruby gem and disregard native executable packaging if you do not need it.
@@ -448,7 +597,13 @@ Of course, you can just build a Ruby gem and disregard native executable packagi
448
597
  To scaffold a Glimmer custom shell gem (full window view distributed as a Ruby gem), run the following command:
449
598
 
450
599
  ```
451
- glimmer scaffold:custom_shell_gem[custom_shell_name, namespace]
600
+ glimmer scaffold:gem:customshell[name,namespace]
601
+ ```
602
+
603
+ Or the following alternative abbreviation:
604
+
605
+ ```
606
+ glimmer scaffold:gem:cs[name,namespace]
452
607
  ```
453
608
 
454
609
  It is important to specify a namespace to avoid having your gem clash with existing gems.
@@ -467,16 +622,26 @@ Examples:
467
622
  To scaffold a Glimmer custom widget gem (part of a view distributed as a Ruby gem), run the following command:
468
623
 
469
624
  ```
470
- glimmer scaffold:custom_widget_gem[custom_widget_name, namespace]
625
+ glimmer scaffold:gem:customwidget[name,namespace]
626
+ ```
627
+
628
+ Or the following alternative abbreviation:
629
+
630
+ ```
631
+ glimmer scaffold:gem:cw[name,namespace]
471
632
  ```
472
633
 
634
+
473
635
  It is important to specify a namespace to avoid having your gem clash with existing gems.
474
636
 
475
637
  The Ruby gem name will follow the convention "glimmer-cw-customwidgetname-namespace" (the 'cw' is for Custom Widget)
476
638
 
477
639
  Only official Glimmer gems created by the Glimmer project committers will have no namespace (e.g. [glimmer-cw-video](https://rubygems.org/gems/glimmer-cw-video) Ruby gem)
478
640
 
479
- Example: [https://github.com/AndyObtiva/glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video)
641
+ Examples:
642
+
643
+ - [glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video): Video Widget
644
+ - [glimmer-cw-cdatetime-nebula](https://github.com/AndyObtiva/glimmer-cw-cdatetime-nebula): Nebula CDateTime Widget
480
645
 
481
646
  ### Gem Listing
482
647
 
@@ -487,13 +652,19 @@ The `glimmer` command comes with tasks for listing Glimmer related gems to make
487
652
  The following command lists available Glimmer [Custom Shell Gems](#custom-shell-gem) (prefixed with "glimmer-cs-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
488
653
 
489
654
  ```
490
- glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
655
+ glimmer list:gems:customshell[query]
656
+ ```
657
+
658
+ Or the following alternative abbreviation:
659
+
660
+ ```
661
+ glimmer list:gems:cs[query]
491
662
  ```
492
663
 
493
664
  Example:
494
665
 
495
666
  ```
496
- glimmer list:custom_shell_gems
667
+ glimmer list:gems:cs
497
668
  ```
498
669
 
499
670
  Output:
@@ -504,8 +675,9 @@ Output:
504
675
 
505
676
  Name Gem Version Author Description
506
677
 
507
- Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
508
- Gladiator glimmer-cs-gladiator 0.2.0 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
678
+ Calculator glimmer-cs-calculator 1.0.2 Andy Maleh Calculator - Glimmer Custom Shell
679
+ Gladiator glimmer-cs-gladiator 0.2.4 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
680
+ Timer glimmer-cs-timer 1.0.0 Andy Maleh Timer - Glimmer Custom Shell
509
681
 
510
682
  ```
511
683
 
@@ -514,7 +686,13 @@ Output:
514
686
  The following command lists available Glimmer [Custom Widget Gems](#custom-widget-gem) (prefixed with "glimmer-cw-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
515
687
 
516
688
  ```
517
- glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
689
+ glimmer list:gems:customwidget[query]
690
+ ```
691
+
692
+ Or the following alternative abbreviation:
693
+
694
+ ```
695
+ glimmer list:gems:cw[query]
518
696
  ```
519
697
 
520
698
  Example:
@@ -522,7 +700,7 @@ Example:
522
700
  Check if there is a custom video widget for Glimmer.
523
701
 
524
702
  ```
525
- glimmer list:custom_widget_gems[video]
703
+ glimmer list:gems:cw[video]
526
704
  ```
527
705
 
528
706
  Output:
@@ -533,7 +711,7 @@ Output:
533
711
 
534
712
  Name Gem Version Author Description
535
713
 
536
- Video glimmer-cw-video 0.1.1 Andy Maleh Glimmer Custom Widget - Video
714
+ Video glimmer-cw-video 0.1.3 Andy Maleh Glimmer Custom Widget - Video
537
715
 
538
716
  ```
539
717
 
@@ -542,13 +720,13 @@ Output:
542
720
  The following command lists available Glimmer [DSL Gems](#multi-dsl-support) (prefixed with "glimmer-dsl-" by convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
543
721
 
544
722
  ```
545
- glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
723
+ glimmer list:gems:dsl[query]
546
724
  ```
547
725
 
548
726
  Example:
549
727
 
550
728
  ```
551
- glimmer list:dsl_gems
729
+ glimmer list:gems:dsl
552
730
  ```
553
731
 
554
732
  Output:
@@ -559,10 +737,10 @@ Output:
559
737
 
560
738
  Name Gem Version Author Description
561
739
 
562
- Css glimmer-dsl-css 0.1.0 AndyMaleh Glimmer DSL for CSS
563
- Opal glimmer-dsl-opal 0.0.9 AndyMaleh Glimmer DSL for Opal
564
- Swt glimmer-dsl-swt 0.2.2 AndyMaleh Glimmer DSL for SWT
565
- Xml glimmer-dsl-xml 0.1.0 AndyMaleh Glimmer DSL for XML
740
+ Css glimmer-dsl-css 0.2.0 AndyMaleh Glimmer DSL for CSS
741
+ Opal glimmer-dsl-opal 0.1.0 AndyMaleh Glimmer DSL for Opal
742
+ Swt glimmer-dsl-swt 0.6.3 AndyMaleh Glimmer DSL for SWT
743
+ Xml glimmer-dsl-xml 0.2.0 AndyMaleh Glimmer DSL for XML
566
744
 
567
745
  ```
568
746
 
@@ -615,15 +793,76 @@ Watch out for hands-on examples in this README indicated by "you may copy/paste
615
793
 
616
794
  Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
617
795
 
618
- ## Glimmer DSL Syntax
796
+ ## Glimmer GUI DSL Syntax
797
+
798
+ 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.
799
+
800
+ It is available through mixing in the `Glimmer` module, which makes Glimmer GUI DSL keywords available to both the instance scope and class scope:
801
+
802
+ ```ruby
803
+ include Glimmer
804
+ ```
805
+
806
+ For example, here is the basic "Hello, World!" sample code (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
807
+
808
+ ```ruby
809
+ include Glimmer
810
+
811
+ shell {
812
+ text "Glimmer"
813
+ label {
814
+ text "Hello, World!"
815
+ }
816
+ }.open
817
+ ```
818
+
819
+ The `include Glimmer` declaration on top mixed the `Glimmer` module into the Ruby global main object making the Glimmer GUI DSL available at the top-level global scope.
820
+
821
+ While this works well enough for mini-samples, it is better to isolate Glimmer in a class or module during production application development to create a clean separation between view code (GUI) and model code (business domain). Here is the "Hello, World!" sample re-written in a class to illustrate how mixing in the `Glimmer` module (via `include Glimmer`) makes the Glimmer GUI DSL available in both the instance scope and class scope. That is clearly demonstrated by pre-initializing a color constant in the class scope and building the GUI in the `#open` instance method (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
822
+
823
+ ```ruby
824
+ class HelloWorld
825
+ include Glimmer # makes the GUI DSL available in both the class scope and instance scope
826
+
827
+ COLOR_FOREGROUND_DEFAULT = rgb(255, 0, 0) # rgb is a GUI DSL keyword used in the class scope
828
+
829
+ def open
830
+ # the following are GUI DSL keywords (shell, text, and label) used in the instance scope
831
+ shell {
832
+ text "Glimmer"
833
+ label {
834
+ text "Hello, World!"
835
+ foreground COLOR_FOREGROUND_DEFAULT
836
+ }
837
+ }.open
838
+ end
839
+ end
619
840
 
620
- Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
841
+ HelloWorld.new.open
842
+ ```
621
843
 
622
- Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `message_box`, `async_exec`, and `bind`.
844
+ This renders "Hello, World!" with a red foreground color:
623
845
 
624
- Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `list`.
846
+ ![Hello World Red Foreground Color](images/glimmer-hello-world-red-foreground-color.png)
625
847
 
626
- The only reason to distinguish between the two types of Glimmer DSL keywords is to realize that importing new Glimmer [custom widgets](#custom-widgets) and Java SWT custom widget libraries automatically expands Glimmer's DSL vocabulary via new dynamic keywords.
848
+ The GUI DSL intentionally avoids overly verbose syntax, requiring as little declarative code as possible to describe what GUI to render, how to style it, and what properties to data-bind to the Models.
849
+
850
+ As such, it breaks off from Ruby's convention of using `do end` for multi-line blocks, opting instead for the lightweight and visual `{ }` curly brace blocks everywhere inside the GUI DSL. More details about Glimmer's syntax conventions may be found in the [Glimmer Style Guide](#glimmer-style-guide)
851
+
852
+ Glimmer DSL syntax consists mainly of:
853
+ - keywords (e.g. `table` for a table widget)
854
+ - style/args (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
855
+ - content (e.g. `{ table_column { text 'Name'} }` as in `table(:multi) { table_column { text 'name'} }` for a multi-line selection table widget with a table column having header text property `'Name'` as content)
856
+
857
+ ### DSL Auto-Expansion
858
+
859
+ Glimmer supports a new and radical Ruby DSL concept called DSL Auto-Expansion. It is explained by first mentioning the two types of Glimmer GUI DSL keywords: static and dynamic.
860
+
861
+ Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `display`, `message_box`, `async_exec`, `sync_exec`, and `bind`.
862
+
863
+ Dynamic keywords are dynamically figured out from currently imported (aka required/loaded) SWT widgets, custom widgets, and widget properties. Examples are: `label`, `combo`, and `list` for widgets and `enabled`, `text`, and `selection` for properties.
864
+
865
+ The only reason to distinguish between the two types of Glimmer DSL keywords is to realize that importing new Glimmer [custom widgets](#custom-widgets) and Java SWT custom widget libraries automatically expands Glimmer's DSL vocabulary via new dynamic keywords.
627
866
 
628
867
  For example, if a project adds this custom Java SWT library:
629
868
 
@@ -641,9 +880,9 @@ https://www.eclipse.org/swt/widgets/
641
880
 
642
881
  This screenshot taken from the link above should give a glimpse of how SWT widgets look and feel:
643
882
 
644
- ![SWT Widgets](images/glimmer-swt-widgets.png)
883
+ [![SWT Widgets](images/glimmer-swt-widgets.png)](https://www.eclipse.org/swt/widgets/)
645
884
 
646
- In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name:
885
+ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name. For example, here are some Glimmer widgets and their SWT counterparts:
647
886
 
648
887
  - `shell` instantiates `org.eclipse.swt.widgets.Shell`
649
888
  - `text` instantiates `org.eclipse.swt.widgets.Text`
@@ -659,8 +898,8 @@ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring
659
898
  - `list` instantiates `org.eclipse.swt.widgets.List`
660
899
 
661
900
  Every **widget** is sufficiently declared by name, but may optionally be accompanied with:
662
- - SWT **style** ***argument*** wrapped by parenthesis according to [Glimmer Style Guide](#glimmer-style-guide) (see [next section](#widget-styles) for details).
663
- - Ruby block containing **properties** (widget attributes) and **content** (nested widgets)
901
+ - SWT **style**/***arguments*** wrapped by parenthesis according to [Glimmer Style Guide](#glimmer-style-guide) (see [next section](#widget-styles) for details).
902
+ - Ruby block containing **content**, which may be **properties** (e.g. `enabled false`) or nested **widgets** (e.g. `table_column` nested inside `table`)
664
903
 
665
904
  For example, if we were to revisit `samples/hello/hello_world.rb` above (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
666
905
 
@@ -742,6 +981,8 @@ shell {
742
981
  }.open
743
982
  ```
744
983
 
984
+ If you are new to Glimmer, you have learned enough to start running some [samples](#samples). Go ahead and run all Glimmer [samples](#samples), and come back to read the rest in any order you like since this material is more organized like a reference.
985
+
745
986
  #### Display
746
987
 
747
988
  SWT Display is a singleton in Glimmer. It is used in SWT to represent your display device, allowing you to manage GUI globally
@@ -753,7 +994,7 @@ automatically uses the display created earlier without having to explicitly hook
753
994
  ```ruby
754
995
  @display = display {
755
996
  cursor_location 300, 300
756
- on_event_keydown {
997
+ on_swt_keydown {
757
998
  # ...
758
999
  }
759
1000
  # ...
@@ -829,6 +1070,21 @@ include Glimmer
829
1070
  @shell.open
830
1071
  ```
831
1072
 
1073
+ ![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
1074
+
1075
+ It is also possible to use `message_box` even before instantiating the first `shell` ([Glimmer](https://rubygems.org/gems/glimmer) builds a throwaway `shell` parent automatically for it):
1076
+
1077
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1078
+
1079
+ ```ruby
1080
+ include Glimmer
1081
+
1082
+ message_box {
1083
+ text 'Greeting'
1084
+ message "Hello, World!"
1085
+ }.open
1086
+ ```
1087
+
832
1088
  ##### `#swt_widget`
833
1089
 
834
1090
  Glimmer widget objects come with an instance method `#swt_widget` that returns the actual SWT `Widget` object wrapped by the Glimmer widget object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
@@ -848,6 +1104,24 @@ Shell widget proxy has extra methods specific to SWT Shell:
848
1104
  - `#pack`: Packs contained widgets using SWT's `Shell#pack` method
849
1105
  - `#pack_same_size`: Packs contained widgets without changing shell's size when widget sizes change
850
1106
 
1107
+ ##### Shell Icon
1108
+
1109
+ To set the shell icon, simply set the `image` property under the `shell` widget. This shows up in the operating system toolbar and app-switcher (e.g. CMD+TAB) (and application window top-left corner in Windows)
1110
+
1111
+ Example:
1112
+
1113
+ ```ruby
1114
+ shell {
1115
+ # ...
1116
+ image 'path/to/image.png'
1117
+ # ...
1118
+ }
1119
+ ```
1120
+
1121
+ ###### Shell Icon Tip for Packaging on Windows
1122
+
1123
+ 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'`)
1124
+
851
1125
  #### Dialog
852
1126
 
853
1127
  Dialog is a variation on Shell. It is basically a shell that is modal (blocks what's behind it) and belongs to another shell. It only has a close button.
@@ -935,7 +1209,7 @@ shell { |shell_proxy|
935
1209
  Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
936
1210
 
937
1211
  ```ruby
938
- shell { |shell_proxy|
1212
+ shell { |shell_proxy|
939
1213
  text 'Hello, Pop Up Context Menu!'
940
1214
  grid_layout
941
1215
  label {
@@ -971,6 +1245,13 @@ Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-i
971
1245
  }.open
972
1246
  ```
973
1247
 
1248
+ #### ScrolledComposite
1249
+
1250
+ Glimmer provides smart defaults for the `scrolled_composite` widget by:
1251
+ - Automatically setting the nested widget as its content (meaning use can just like a plain old `composite` to add scrolling)
1252
+ - Automatically setting the :h_scroll and :v_scroll SWT styles (can be set manually if only one of either :h_scroll or :v_scroll is desired )
1253
+ - Automatically setting the expand horizontal and expand vertical SWT properties to `true`
1254
+
974
1255
  ### Widget Styles
975
1256
 
976
1257
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -1016,7 +1297,7 @@ text(:center, :border) { # Multiple SWT styles separated by comma
1016
1297
  Glimmer ships with SWT style **smart defaults** so you wouldn't have to set them yourself most of the time (albeit you can always override them):
1017
1298
 
1018
1299
  - `text(:border)`
1019
- - `table(:border)`
1300
+ - `table(:border, :virtual, :full_selection)`
1020
1301
  - `tree(:border, :virtual, :v_scroll, :h_scroll)`
1021
1302
  - `spinner(:border)`
1022
1303
  - `list(:border, :v_scroll)`
@@ -1092,7 +1373,7 @@ button {
1092
1373
 
1093
1374
  In the above example, the `text` widget `enabled` property was data-bound to `#empty` method on `@tic_tac_toe_board.box(row, column)` (learn more about data-binding below)
1094
1375
 
1095
- #### Colors
1376
+ #### Color
1096
1377
 
1097
1378
  Colors make up a subset of widget properties. SWT accepts color objects created with RGB (Red Green Blue) or RGBA (Red Green Blue Alpha). Glimmer supports constructing color objects using the `rgb` and `rgba` DSL keywords.
1098
1379
 
@@ -1141,7 +1422,7 @@ Example:
1141
1422
  color(:black).swt_color # returns SWT Color object
1142
1423
  ```
1143
1424
 
1144
- #### Fonts
1425
+ #### Font
1145
1426
 
1146
1427
  Fonts are represented in Glimmer as a hash of name, height, and style keys.
1147
1428
 
@@ -1170,6 +1451,33 @@ label {
1170
1451
  # ...
1171
1452
  ```
1172
1453
 
1454
+ You may simply use the standalone `font` keyword without nesting in a parent if there is a need to build a Font object to use in manual SWT programming outside of widget font property setting.
1455
+
1456
+ Example:
1457
+
1458
+ ```ruby
1459
+ @font = font(name: 'Arial', height: 36, style: :normal)
1460
+ ```
1461
+
1462
+ ### Cursor
1463
+
1464
+ SWT widget `cursor` property represents the mouse cursor you see on the screen when you hover over that widget.
1465
+
1466
+ The `Display` class provides a way to obtain standard system cursors matching of the SWT style constants starting with prefix `CURSOR_` (e.g. `SWT::CURSOR_HELP` shows a question mark mouse cursor)
1467
+
1468
+ Glimmer provides an easier way to obtain and set `cursor` property on a widget by simply mentioning the SWT style constant as an abbreviated symbol excluding the "CURSOR_" suffix.
1469
+
1470
+ Example:
1471
+
1472
+ ```ruby
1473
+ shell {
1474
+ minimum_size 128, 128
1475
+ cursor :appstarting
1476
+ }
1477
+ ```
1478
+
1479
+ This sets the shell `cursor` to that of `SWT::CURSOR_APPSTARTING`
1480
+
1173
1481
  ### Layouts
1174
1482
 
1175
1483
  Glimmer lays widgets out visually using SWT layouts, which can only be set on composite widget and subclasses.
@@ -1568,6 +1876,9 @@ shell {
1568
1876
  }
1569
1877
  items bind(group, :people), column_properties(:name, :age, :adult)
1570
1878
  selection bind(group, :selected_person)
1879
+ on_mouse_up { |event|
1880
+ @table.edit_table_item(event.table_item, event.column_index)
1881
+ }
1571
1882
  }
1572
1883
  }
1573
1884
  ```
@@ -1575,6 +1886,7 @@ shell {
1575
1886
  The code above includes two data-bindings:
1576
1887
  - Table `items`, which first bind to the model collection property (group.people), and then maps each column property (name, age, adult) for displaying each table item column.
1577
1888
  - Table `selection`, which binds the single table item selected by the user to the attribute denoted by the `bind` keyword (or binds multiple table items selected for a table with `:multi` SWT style)
1889
+ - The `on_mouse_up` event handler invokes `@table.edit_table_item(event.table_item, event.column_index)` to start edit mode on the clicked table item cell, and then saves or cancel depending on whether the user hits ENTER or ESC once done editing (or focus-out after either making a change or not making any changes.)
1578
1890
 
1579
1891
  Additionally, Table `items` data-binding automatically stores each node model unto the SWT TableItem object via `setData` method. This enables things like searchability.
1580
1892
 
@@ -1594,6 +1906,67 @@ This automatically leverages the SWT TableEditor custom class behind the scenes,
1594
1906
  passed table item text into something else.
1595
1907
  It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
1596
1908
 
1909
+ ##### Table Sorting
1910
+
1911
+ Glimmer automatically adds sorting support to the SWT `Table` widget.
1912
+
1913
+ Check out the [Contact Manager](#contact-manager) sample for an example.
1914
+ You may click on any column and it will sort by ascending order first and descending if you click again.
1915
+
1916
+ Glimmer automatic table sorting supports `String`, `Integer`, and `Float` columns out of the box as well as any column data that is comparable.
1917
+
1918
+ 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`.
1919
+
1920
+ Should you have a special data type that could not be compared automatically, Glimmer offers the following 3 alternatives for custom sorting:
1921
+ - `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`).
1922
+ - `sort_by(&block)`: this works just like Ruby `Enumerable` `sort_by`. The block receives the table column data as argument.
1923
+ - `sort(&comparator)`: this works just like Ruby `Enumerable` `sort`. The comparator block receives two objects from the table column data.
1924
+
1925
+ You may also set `additional_sort_properties` on the parent `table` widget to have secondary sorting applied. For example, if you set `additional_sort_properties :name, :project_name`, then whenever you sort by `:name`, it additionally sorts by `:project_name` afterwards, and vice versa. This only works for columns that either have no custom sort set or have a `sort_property` with one property only (but no sort or sort_by block)
1926
+
1927
+ Example:
1928
+
1929
+ ```ruby
1930
+ # ...
1931
+ table {
1932
+ table_column {
1933
+ text 'Task'
1934
+ width 120
1935
+ }
1936
+ table_column {
1937
+ text 'Project'
1938
+ width 120
1939
+ }
1940
+ table_column {
1941
+ text 'Duration (hours)'
1942
+ width 120
1943
+ sort_property :duration_in_hours
1944
+ }
1945
+ table_column {
1946
+ text 'Priority'
1947
+ width 120
1948
+ sort_by { |value| ['High', 'Medium', 'Low'].index(value) }
1949
+ }
1950
+ table_column {
1951
+ text 'Start Date'
1952
+ width 120
1953
+ sort { |d1, d2| d1.to_date <=> d2.to_date }
1954
+ }
1955
+ additional_sort_properties :project_name, :duration_in_hours, :name
1956
+ items bind(Task, :list), column_properties(:name, :project_name, :duration, :priority, :start_date)
1957
+ # ...
1958
+ }
1959
+ # ...
1960
+ ```
1961
+
1962
+ Here is an explanation of the example above:
1963
+ - Task and Project table columns are data-bound to the `:name` and `:project_name` properties and sorted through them automatically
1964
+ - Task Duration table column is data-bound to the `:duration` property, but sorted via the `:duration_in_hours` property instead
1965
+ - Task Priority table column has a custom sort_by block
1966
+ - Task Start Date table column has a custom sort comparator block
1967
+ - Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
1968
+
1969
+
1597
1970
  #### Tree
1598
1971
 
1599
1972
  The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
@@ -1641,10 +2014,10 @@ Glimmer comes with `Observer` module, which is used internally for data-binding,
1641
2014
 
1642
2015
  Glimmer supports observing widgets with two main types of events:
1643
2016
  1. `on_{swt-listener-method-name}`: where {swt-listener-method-name} is replaced with the lowercase underscored event method name on an SWT listener class (e.g. `on_verify_text` for `org.eclipse.swt.events.VerifyListener#verifyText`).
1644
- 2. `on_event_{swt-event-constant}`: where {swt-event-constant} is replaced with an `org.eclipse.swt.SWT` event constant (e.g. `on_event_show` for `SWT.Show` to observe when widget becomes visible)
2017
+ 2. `on_swt_{swt-event-constant}`: where {swt-event-constant} is replaced with an [`org.eclipse.swt.SWT`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html) event constant (e.g. `on_swt_show` for `SWT.Show` to observe when widget becomes visible)
1645
2018
 
1646
2019
  Additionally, there are two more types of events:
1647
- - SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_event_{swt-event-constant}`
2020
+ - SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_swt_{swt-event-constant}`
1648
2021
  - SWT `display` supports Mac application menu item observers (`on_about` and `on_preferences`), which you can read about under [Miscellaneous](#miscellaneous).
1649
2022
 
1650
2023
  Number 1 is more commonly used in SWT applications, so make it your starting point. Number 2 covers events not found in number 1, so look into it if you don't find an SWT listener you need in number 1.
@@ -1667,7 +2040,8 @@ Let's revisit the Tic Tac Toe example shown near the beginning of the page:
1667
2040
  ```ruby
1668
2041
  shell {
1669
2042
  text "Tic-Tac-Toe"
1670
- composite {
2043
+ minimum_size 150, 178
2044
+ composite {
1671
2045
  grid_layout 3, true
1672
2046
  (1..3).each { |row|
1673
2047
  (1..3).each { |column|
@@ -1689,21 +2063,21 @@ Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties da
1689
2063
 
1690
2064
  Next however, each of these Tic Tac Toe grid cells, which are clickable buttons, have an `on_widget_selected` observer, which once triggered, marks the cell on the `TicTacToe::Board` to make a move.
1691
2065
 
1692
- **Regarding number 2**, you can figure out all available events by looking at the `org.eclipse.swt.SWT` API:
2066
+ **Regarding number 2**, you can figure out all available events by looking at the [`org.eclipse.swt.SWT`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html) API:
1693
2067
 
1694
2068
  https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
1695
2069
 
1696
2070
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1697
2071
 
1698
- `SWT.Show` - hooks a listener for showing a widget (using `on_event_show` in Glimmer)
1699
- `SWT.Hide` - hooks a listener for hiding a widget (using `on_event_hide` in Glimmer)
2072
+ `SWT.Show` - hooks a listener for showing a widget (using `on_swt_show` in Glimmer)
2073
+ `SWT.Hide` - hooks a listener for hiding a widget (using `on_swt_hide` in Glimmer)
1700
2074
 
1701
2075
  ```ruby
1702
2076
  shell {
1703
2077
  @button1 = button {
1704
2078
  text "Show 2nd Button"
1705
2079
  visible true
1706
- on_event_show {
2080
+ on_swt_show {
1707
2081
  @button2.swt_widget.setVisible(false)
1708
2082
  }
1709
2083
  on_widget_selected {
@@ -1713,7 +2087,7 @@ shell {
1713
2087
  @button2 = button {
1714
2088
  text "Show 1st Button"
1715
2089
  visible false
1716
- on_event_show {
2090
+ on_swt_show {
1717
2091
  @button1.swt_widget.setVisible(false)
1718
2092
  }
1719
2093
  on_widget_selected {
@@ -1723,7 +2097,7 @@ shell {
1723
2097
  }.open
1724
2098
  ```
1725
2099
 
1726
- **Gotcha:** SWT.Resize event needs to be hooked using **`on_event_Resize`** because `org.eclipse.swt.SWT` has 2 constants for resize: `RESIZE` and `Resize`, so it cannot infer the right one automatically from the underscored version `on_event_resize`
2100
+ **Gotcha:** SWT.Resize event needs to be hooked using **`on_swt_Resize`** because [`org.eclipse.swt.SWT`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html) has 2 constants for resize: `RESIZE` and `Resize`, so it cannot infer the right one automatically from the underscored version `on_swt_resize`
1727
2101
 
1728
2102
  ##### Alternative Syntax
1729
2103
 
@@ -2017,7 +2391,7 @@ shell { |app_shell|
2017
2391
  @current_step_number = 1
2018
2392
  @wizard_steps = 5.times.map { |n|
2019
2393
  wizard_step(number: n+1, step_count: 5) {
2020
- on_event_hide {
2394
+ on_swt_hide {
2021
2395
  if @current_step_number < 5
2022
2396
  @current_step_number += 1
2023
2397
  app_shell.hide
@@ -2317,7 +2691,7 @@ Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app versi
2317
2691
 
2318
2692
  #### Video Widget
2319
2693
 
2320
- ![Video Widget](images/glimmer-video-widget.png)
2694
+ [![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
2321
2695
 
2322
2696
  Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
2323
2697
 
@@ -2369,17 +2743,14 @@ Glimmer configuration may be done via the `Glimmer::Config` module.
2369
2743
 
2370
2744
  ### logger
2371
2745
 
2372
- Glimmer supports logging via a Ruby Logger configurable with the `Glimmer::Config.logger` config option.
2373
- It is disabled by default to ensure not affecting desktop app performance.
2374
- It may be enabled via `Glimmer::Config.enable_logging`
2375
- When enabled, the Glimmer logger level defaults to `:warn` (aka `Logger::WARN`)
2376
- It may be configured to show a different level of logging via `Glimmer::Config.logger.level` just ike with any Ruby Logger.
2746
+ The Glimmer DSL engine supports logging via a standard `STDOUT` Ruby `Logger` configured in the `Glimmer::Config.logger` config option.
2747
+ It is set to level Logger::ERROR by default.
2748
+ Log level may be adjusted via `Glimmer::Config.logger.level` just like any other Ruby Logger.
2377
2749
 
2378
2750
  Example:
2379
2751
 
2380
2752
  ```ruby
2381
- Glimmer::Config.enable_logging
2382
- Glimmer::Config.logger.level = Logger::DEBUG
2753
+ Glimmer::Config.logger.level = :debug
2383
2754
  ```
2384
2755
  This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
2385
2756
 
@@ -2399,6 +2770,55 @@ D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will hand
2399
2770
  D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
2400
2771
  ```
2401
2772
 
2773
+ The `logger` instance may be replaced with a custom logger via `Glimmer::Config.logger = custom_logger`
2774
+
2775
+ To reset `logger` to the default instance, you may call `Glimmer::Config.reset_logger!`
2776
+
2777
+ All logging is done lazily via blocks (e.g. `logger.debug {message}`) to avoid affecting app performance with logging when below the configured logging level threshold.
2778
+
2779
+ [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) enhances Glimmer default logging support via the Ruby [`logging`](https://github.com/TwP/logging) gem, enabling buffered asynchronous logging in a separate thread, thus completely unhindering normal desktop app performance.
2780
+
2781
+ Other config options related to the [`logging`](https://github.com/TwP/logging) gem are mentioned below.
2782
+
2783
+ #### logging_devices
2784
+
2785
+ This is an array of these possible values: `:stdout` (default), `:stderr`, `:file`, `:syslog` (default), `:stringio`
2786
+
2787
+ It defaults to `[:stdout, :syslog]`
2788
+
2789
+ When `:file` is included, Glimmer creates a 'log' directory directly below the Glimmer app local directory.
2790
+ It may also be customized further via the `logging_device_file_options` option.
2791
+ This is useful on Windows as an alternative to `syslog`, which is not available on Windows by default.
2792
+
2793
+ #### logging_device_file_options
2794
+
2795
+ This is a hash of [`logging`](https://github.com/TwP/logging) gem options for the `:file` logging device.
2796
+
2797
+ Default: `{size: 1_000_000, age: 'daily', roll_by: 'number'}`
2798
+
2799
+ That ensures splitting log files at the 1MB size and daily, rolling them by unique number.
2800
+
2801
+ #### logging_appender_options
2802
+
2803
+ Appender options is a hash passed as options to every appender (logging device) used in the [`logging`](https://github.com/TwP/logging) gem.
2804
+
2805
+ Default: `{async: true, auto_flushing: 500, write_size: 500, flush_period: 60, immediate_at: [:error, :fatal], layout: logging_layout}`
2806
+
2807
+ That ensures asynchronous buffered logging that is flushed every 500 messages and 60 seconds, or immediately at error and fatal log levels
2808
+
2809
+ #### logging_layout
2810
+
2811
+ This is a [`logging`](https://github.com/TwP/logging) gem layout that formats the logging output.
2812
+
2813
+ Default:
2814
+
2815
+ ```
2816
+ Logging.layouts.pattern(
2817
+ pattern: '[%d] %-5l %c: %m\n',
2818
+ date_pattern: '%Y-%m-%d %H:%M:%S'
2819
+ )
2820
+ ```
2821
+
2402
2822
  ### import_swt_packages
2403
2823
 
2404
2824
  Glimmer automatically imports all SWT Java packages upon adding `include Glimmer`, `include Glimmer::UI::CustomWidget`, or `include Glimmer::UI::CustomShell` to a class or module. It relies on JRuby's `include_package` for lazy-importing upon first reference of a Java class.
@@ -2458,6 +2878,29 @@ The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` c
2458
2878
 
2459
2879
  Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
2460
2880
 
2881
+ ### excluded_keyword_checkers
2882
+
2883
+ Glimmer permits consumers to exclude keywords from DSL processing by its engine via the `excluded_keyword_checkers` config option.
2884
+
2885
+ To do so, add a proc to it that returns a boolean indicating if a keyword is excluded or not.
2886
+
2887
+ Note that this proc runs within the context of the Glimmer object (as in the object mixing in the Glimmer module), so checker can can pretend to run there with its `self` object assumption.
2888
+
2889
+ Example of keywords excluded by [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt):
2890
+
2891
+ ```ruby
2892
+ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
2893
+ method = method_symbol.to_s
2894
+ result = false
2895
+ result ||= method.start_with?('on_swt_') && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
2896
+ result ||= method == 'dispose' && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
2897
+ result ||= ['drag_source_proxy', 'drop_target_proxy'].include?(method) && is_a?(Glimmer::UI::CustomWidget)
2898
+ result ||= method == 'post_initialize_child'
2899
+ result ||= method.end_with?('=')
2900
+ result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
2901
+ end
2902
+ ```
2903
+
2461
2904
  ## Glimmer Style Guide
2462
2905
 
2463
2906
  - Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
@@ -2521,6 +2964,10 @@ For hello-type simple samples, check the following.
2521
2964
 
2522
2965
  #### Hello, World! Sample
2523
2966
 
2967
+ Code:
2968
+
2969
+ [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)
2970
+
2524
2971
  Run:
2525
2972
 
2526
2973
  ```
@@ -2531,6 +2978,10 @@ glimmer samples/hello/hello_world.rb
2531
2978
 
2532
2979
  #### Hello, Tab!
2533
2980
 
2981
+ Code:
2982
+
2983
+ [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_tab.rb)
2984
+
2534
2985
  Run:
2535
2986
 
2536
2987
  ```
@@ -2544,6 +2995,10 @@ glimmer samples/hello/hello_tab.rb
2544
2995
 
2545
2996
  This sample demonstrates combo data-binding.
2546
2997
 
2998
+ Code:
2999
+
3000
+ [samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_combo.rb)
3001
+
2547
3002
  Run:
2548
3003
 
2549
3004
  ```
@@ -2557,6 +3012,10 @@ glimmer samples/hello/hello_combo.rb
2557
3012
 
2558
3013
  This sample demonstrates list single-selection data-binding.
2559
3014
 
3015
+ Code:
3016
+
3017
+ [samples/hello/hello_list_single_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_single_selection.rb)
3018
+
2560
3019
  Run:
2561
3020
 
2562
3021
  ```
@@ -2569,6 +3028,10 @@ glimmer samples/hello/hello_list_single_selection.rb
2569
3028
 
2570
3029
  This sample demonstrates list multi-selection data-binding.
2571
3030
 
3031
+ Code:
3032
+
3033
+ [samples/hello/hello_list_multi_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_multi_selection.rb)
3034
+
2572
3035
  Run:
2573
3036
 
2574
3037
  ```
@@ -2581,6 +3044,10 @@ glimmer samples/hello/hello_list_multi_selection.rb
2581
3044
 
2582
3045
  This sample demonstrates computed data-binding.
2583
3046
 
3047
+ Code:
3048
+
3049
+ [samples/hello/hello_computed.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_computed.rb)
3050
+
2584
3051
  Run:
2585
3052
 
2586
3053
  ```
@@ -2593,6 +3060,10 @@ glimmer samples/hello/hello_computed.rb
2593
3060
 
2594
3061
  This sample demonstrates a `message_box` dialog.
2595
3062
 
3063
+ Code:
3064
+
3065
+ [samples/hello/hello_message_box.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_message_box.rb)
3066
+
2596
3067
  Run:
2597
3068
 
2598
3069
  ```
@@ -2606,6 +3077,10 @@ glimmer samples/hello/hello_message_box.rb
2606
3077
 
2607
3078
  This sample demonstrates the `browser` widget.
2608
3079
 
3080
+ Code:
3081
+
3082
+ [samples/hello/hello_browser.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_browser.rb)
3083
+
2609
3084
  Run:
2610
3085
 
2611
3086
  ```
@@ -2618,6 +3093,10 @@ glimmer samples/hello/hello_browser.rb
2618
3093
 
2619
3094
  This sample demonstrates drag and drop in Glimmer.
2620
3095
 
3096
+ Code:
3097
+
3098
+ [samples/hello/hello_drag_and_drop.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_drag_and_drop.rb)
3099
+
2621
3100
  Run:
2622
3101
 
2623
3102
  ```
@@ -2630,6 +3109,10 @@ glimmer samples/hello/hello_drag_and_drop.rb
2630
3109
 
2631
3110
  This sample demonstrates menus in Glimmer.
2632
3111
 
3112
+ Code:
3113
+
3114
+ [samples/hello/hello_menu_bar.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_menu_bar.rb)
3115
+
2633
3116
  Run:
2634
3117
 
2635
3118
  ```
@@ -2644,6 +3127,10 @@ glimmer samples/hello/hello_menu_bar.rb
2644
3127
 
2645
3128
  This sample demonstrates pop up context menus in Glimmer.
2646
3129
 
3130
+ Code:
3131
+
3132
+ [samples/hello/hello_pop_up_context_menu.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_pop_up_context_menu.rb)
3133
+
2647
3134
  Run:
2648
3135
 
2649
3136
  ```
@@ -2659,8 +3146,16 @@ For more elaborate samples, check the following:
2659
3146
 
2660
3147
  #### Login
2661
3148
 
3149
+ This sample demonstrates basic data-binding, password and text fields, and field enablement data-binding.
3150
+
3151
+ Code:
3152
+
3153
+ [samples/elaborate/login.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/login.rb)
3154
+
3155
+ Run:
3156
+
2662
3157
  ```
2663
- glimmer samples/elaborate/login.rb # demonstrates basic data-binding
3158
+ glimmer samples/elaborate/login.rb
2664
3159
  ```
2665
3160
 
2666
3161
  ![Login](images/glimmer-login.png)
@@ -2669,18 +3164,36 @@ glimmer samples/elaborate/login.rb # demonstrates basic data-binding
2669
3164
 
2670
3165
  #### Tic Tac Toe Sample
2671
3166
 
3167
+ This sample demonstrates a full MVC application, including GUI layout, text and enablement data-binding, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/tic_tac_toe/board_spec.rb)).
3168
+
3169
+ Code:
3170
+
3171
+ (Please note that on some Linux instances where the display x-axis is set to double-scale, you need to set the `shell` `minimum_size` to `300, 178` instead of `150, 178`)
3172
+
3173
+ [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)
3174
+
3175
+ Run:
3176
+
2672
3177
  ```
2673
- glimmer samples/elaborate/tic_tac_toe.rb # demonstrates a full MVC application
3178
+ glimmer samples/elaborate/tic_tac_toe.rb
2674
3179
  ```
2675
3180
 
2676
3181
  ![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
2677
3182
  ![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
2678
3183
  ![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
2679
3184
 
2680
- #### Contact Manager
3185
+ #### Contact Manager Sample
3186
+
3187
+ This sample demonstrates table data-binding, sorting, filtering, GUI layout, MVP pattern, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/contact_manager/contact_manager_presenter_spec.rb)).
3188
+
3189
+ Code:
3190
+
3191
+ [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)
3192
+
3193
+ Run:
2681
3194
 
2682
3195
  ```
2683
- glimmer samples/elaborate/contact_manager.rb # demonstrates table data-binding
3196
+ glimmer samples/elaborate/contact_manager.rb
2684
3197
  ```
2685
3198
 
2686
3199
  Contact Manager
@@ -2707,17 +3220,17 @@ Contact Manager - Edit Done
2707
3220
 
2708
3221
  #### Glimmer Calculator
2709
3222
 
2710
- [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/v1.0.0/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
3223
+ [<img alt="Glimmer Calculator Icon" src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-icon.png" height=40 /> Glimmer Calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) is a basic calculator sample app demonstrating data-binding and TDD (test-driven-development) with Glimmer following the MVP pattern (Model-View-Presenter).
2711
3224
 
2712
- [Glimmer Calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) is a basic calculator sample project demonstrating data-binding and TDD (test-driven-development) with Glimmer following the MVP pattern (Model-View-Presenter).
3225
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
2713
3226
 
2714
3227
  #### Gladiator
2715
3228
 
2716
- [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
2717
-
2718
- [Gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator) (short for Glimmer Editor) is a Glimmer sample project under on-going development.
3229
+ [<img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=40 /> Gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator) (short for Glimmer Editor) is a Glimmer sample project under on-going development.
2719
3230
  You may check it out to learn how to build a Glimmer Custom Shell gem.
2720
3231
 
3232
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
3233
+
2721
3234
  Gladiator is a good demonstration of:
2722
3235
  - MVP Pattern
2723
3236
  - Tree data-binding
@@ -2728,31 +3241,65 @@ Gladiator is a good demonstration of:
2728
3241
  - Custom Shell
2729
3242
  - Custom widget
2730
3243
 
3244
+ #### Timer
3245
+
3246
+ [<img alt="Glimmer Timer Icon" src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-timer/master/images/glimmer-timer-logo.png" height=40 /> Timer](https://github.com/AndyObtiva/glimmer-cs-timer) is a sample app demonstrating data-binding and multi-threading in a desktop application.
3247
+
3248
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-timer/master/glimmer-timer-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-timer)
3249
+
2731
3250
  ## In Production
2732
3251
 
2733
- The following production apps have been built with Glimmer:
3252
+ The following production apps have been built with Glimmer.
3253
+
3254
+ If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
3255
+
3256
+ ### Math Bowling
2734
3257
 
2735
3258
  [<img alt="Math Bowling Logo" src="https://raw.githubusercontent.com/AndyObtiva/MathBowling/master/images/math-bowling-logo.png" width="40" />Math Bowling](https://github.com/AndyObtiva/MathBowling): an educational math game for elementary level kids
2736
3259
 
3260
+ ### Are We There Yet?
3261
+
2737
3262
  [<img alt="Are We There Yet Logo" src="https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-logo.svg" width="40" />Are We There Yet?](https://github.com/AndyObtiva/are-we-there-yet): A tool that helps you learn when your small projects will finish
2738
3263
 
2739
- If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
3264
+ ### Garderie Rainbow Daily Agenda
2740
3265
 
2741
- ## Packaging & Distribution
3266
+ [<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
2742
3267
 
2743
- Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
2744
- - Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
2745
- - javapackager (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html): Enables packaging a JAR file as a DMG file on Mac, EXE on Windows, and multiple Linux supported formats on Linux.
3268
+ ## Packaging & Distribution
2746
3269
 
2747
- Glimmer simplifies the process of Mac packaging via the `glimmer package` command. It works out of the box for any application generated by [Glimmer Scaffolding](#scaffolding):
3270
+ Glimmer simplifies the process of native-executable packaging and distribution on Mac and Windows via a single `glimmer package` command:
2748
3271
 
2749
3272
  ```
2750
3273
  glimmer package
2751
3274
  ```
2752
3275
 
2753
- This will automatically generate a JAR file under `./dist` directory using Warbler, which is then used to automatically generate a DMG file (and pkg/app) under `./packages/bundles` using `javapackager`.
2754
- JAR file name will match your application local directory name (e.g. `MathBowling.jar` for `~/code/MathBowling`)
2755
- DMG file name will match the humanized local directory name + dash + application version (e.g. `Math Bowling-1.0.dmg` for `~/code/MathBowling` with version 1.0 or unspecified)
3276
+ It works out of the box for any application scaffolded by [Glimmer Scaffolding](#scaffolding), generating all available packaging types on the current platform (e.g. `DMG`, `PKG`, `APP` on the Mac) and displaying a message indicating what pre-requisite setup tools are needed if not installed already (e.g. [Wix Toolset](https://wixtoolset.org/) to generate MSI files on Windows)
3277
+
3278
+ You may choose to generate a specific type of packaging instead by addionally passing in the `[type]` option. For example, this generates an MSI setup file on Windows:
3279
+
3280
+ ```
3281
+ glimmer package[msi]
3282
+ ```
3283
+
3284
+ - Available Mac packaging types are `dmg`, `pkg`, and `image` (image means a pure Mac `app` without a setup program)
3285
+ - Available Windows packaging types are `msi`, `exe`, and `image` (image means a Windows application directory without a setup program). Learn more about Windows packaging are [over here](#windows-application-packaging).
3286
+
3287
+ Note: if you are using Glimmer manually, to make the `glimmer package` command available, you must add the following line to your application `Rakefile` (automatically done for you if you scaffold an app or gem with `glimmer scaffold[AppName]` or `glimmer scaffold:gem:customshell[GemName]`):
3288
+
3289
+ ```ruby
3290
+ require 'glimmer/rake_task'
3291
+ ```
3292
+
3293
+ The Glimmer packaging process done in the `glimmer package` command consists of the following steps:
3294
+ 1. Generate gemspec via Jeweler (`rake gemspec:generate`): Having a gemspec is required by the [`jar-dependencies`](https://github.com/mkristian/jar-dependencies) JRuby gem, used by JRuby libraries to declare JAR dependencies.
3295
+ 1. Lock JAR versions (`glimmer package:lock_jars`): This locks versions of JAR dependencies leveraged by the `jar-dependencies` JRuby gem, downloading them into the `./vendor` directory so they would get inside the top-level Glimmer app/gem JAR file.
3296
+ 1. Generate [Warbler](https://github.com/jruby/warbler) config (`glimmer package:config`): Generates initial Warbler config file (under `./config/warble.rb`) to use for generating JAR file.
3297
+ 1. Generate JAR file using [Warbler](https://github.com/jruby/warbler) (`glimmer package:jar`): Enables bundling a Glimmer app into a JAR file under the `./dist` directory
3298
+ 1. Generate native executable using [javapackager](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html) (`glimmer package:native`): Enables packaging a JAR file as a DMG/PKG/APP file on Mac, MSI/EXE/APP on Windows, and DEB/RPM/APP on Linux (Glimmer does not officially support Linux with the `glimmer package` command yet, but it generates the JAR file successfully, and you could use `javapackager` manually afterwards if needed).
3299
+
3300
+ Those steps automatically ensure generating a JAR file under the `./dist` directory using [Warbler](https://github.com/jruby/warbler), which is then used to automatically generate a DMG/MSI file (and other executables) under the `./packages/bundles` directory using `javapackager`.
3301
+ The JAR file name will match your application local directory name (e.g. `MathBowling.jar` for `~/code/MathBowling`)
3302
+ The DMG file name will match the humanized local directory name + dash + application version (e.g. `Math Bowling-1.0.dmg` for `~/code/MathBowling` with version 1.0 or unspecified)
2756
3303
 
2757
3304
  The `glimmer package` command will automatically set "mac.CFBundleIdentifier" to ="org.#{project_name}.application.#{project_name}".
2758
3305
  You may override by configuring as an extra argument for javapackger (e.g. Glimmer::Package.javapackager_extra_args = " -Bmac.CFBundleIdentifier=org.andymaleh.application.MathBowling")
@@ -2817,6 +3364,14 @@ JAVAPACKAGER_EXTRA_ARGS='-Bmac.CFBundleName="Math Bowling Game"' glimmer package
2817
3364
 
2818
3365
  That overrides the default application display name.
2819
3366
 
3367
+ ### Windows Application Packaging
3368
+
3369
+ Windows offers two options for setup packaging:
3370
+ - `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)).
3371
+ - `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.
3372
+
3373
+ If you just want to test out packaging into a native Windows app that is not packaged for Windows setup, just pass `image` to generate a native Windows app only.
3374
+
2820
3375
  ### Mac Application Distribution
2821
3376
 
2822
3377
  Recent macOS versions (starting with Catalina) have very stringent security requirements requiring all applications to be signed before running (unless the user goes to System Preferences -> Privacy -> General tab and clicks "Open Anyway" after failing to open application the first time they run it). So, to release a desktop application on the Mac, it is recommended to enroll in the [Apple Developer Program](https://developer.apple.com/programs/) to distribute on the [Mac App Store](https://developer.apple.com/distribute/) or otherwise request [app notarization from Apple](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) to distribute independently.
@@ -2882,6 +3437,29 @@ By the way, keep in mind that during normal operation, it does also indicate a f
2882
3437
  Exec failed with code 2 command [[/usr/bin/SetFile, -c, icnC, /var/folders/4_/g1sw__tx6mjdgyh3mky7vydc0000gp/T/fxbundler4076750801763032201/images/MathBowling/.VolumeIcon.icns] in unspecified directory
2883
3438
  ```
2884
3439
 
3440
+ ## App Updates
3441
+
3442
+ Glimmer already supports automatic (and manual) app updates via the Mac App Store for Mac apps. Simply run the `glimmer package` command with the Mac App Store keys configured as per [Mac Application Distribution](mac-application-distribution) instructions and you get automatic (and manual) app update support courtesy of the Mac App Store.
3443
+
3444
+ ## Glimmer Supporting Libraries
3445
+
3446
+ Here is a list of notable 3rd party gems used by Glimmer:
3447
+ - [jeweler](https://github.com/technicalpickles/jeweler): generates app gems during [Glimmer Scaffolding](#scaffolding)
3448
+ - [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)
3449
+ - [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
3450
+ - [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
3451
+ - [puts_debuggerer](https://github.com/AndyObtiva/puts_debuggerer): helps in troubleshooting when adding `require 'pd'` and using the `pd` command instead of `puts` or `p` (also `#pd_inspect` or `#pdi` instead of `#inspect`)
3452
+ - [rake](https://github.com/ruby/rake): used to implement and execute `glimmer` commands
3453
+ - [super_module](https://github.com/AndyObtiva/super_module): used to cleanly write the Glimmer::UI:CustomWidget and Glimmer::UI::CustomShell modules
3454
+ - [text-table](https://github.com/aptinio/text-table): renders textual data in a textual table for the command-line interface of Glimmer
3455
+ - [warbler](https://github.com/jruby/warbler): converts a Glimmer app into a Java JAR file during packaging
3456
+
3457
+ ## Glimmer Process
3458
+
3459
+ [Glimmer Process](PROCESS.md) is the lightweight software development process used for building Glimmer libraries and Glimmer apps, which goes beyond Agile, rendering all Agile processes obsolete. [Glimmer Process](PROCESS.md) is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied.
3460
+
3461
+ Learn more by reading the [GPG](PROCESS.md) (Glimmer Process Guidelines)
3462
+
2885
3463
  ## Resources
2886
3464
 
2887
3465
  * [Code Master Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
@@ -2915,13 +3493,15 @@ Glimmer DSL Engine specific tasks are at:
2915
3493
 
2916
3494
  ## Change Log
2917
3495
 
3496
+ [glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
3497
+
2918
3498
  [CHANGELOG.md](CHANGELOG.md)
2919
3499
 
2920
3500
  ## Contributing
2921
3501
 
2922
3502
  **Contributors Wanted!**
2923
3503
 
2924
- If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](#swt-reference), run all Glimmer [samples](#samples), and build a small sample app to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
3504
+ If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](#swt-reference), run all Glimmer [samples](#samples), and build a small sample app (perhaps from [this TODO list](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md#samples)) to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
2925
3505
 
2926
3506
  You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
2927
3507
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
@@ -2944,7 +3524,11 @@ If your company would like to invest fulltime in further development of the Glim
2944
3524
 
2945
3525
  ## License
2946
3526
 
2947
- Copyright (c) 2007-2020 Andy Maleh.
2948
- See LICENSE.txt for further details.
3527
+ [MIT](https://opensource.org/licenses/MIT)
3528
+
3529
+ Copyright (c) 2007-2020 - Andy Maleh.
3530
+ See [LICENSE.txt](LICENSE.txt) for further details.
3531
+
3532
+ --
2949
3533
 
2950
3534
  Glimmer logo was made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon"> www.flaticon.com</a>