glimmer 0.9.5 → 0.10.4

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: c22f962213e82b271d67b69d910604e73ab8a257e8a797fa58feb2d97d6c199e
4
- data.tar.gz: eee60acdf118d572196ef4a2c1eca7705093ea9d3db2fcea1a05bb612710f05b
3
+ metadata.gz: 4fbfd6caf79d10dbaeb2d737d68a8f028819d6172f45a8b494d1a88c34e3e04b
4
+ data.tar.gz: 9fcbc6d1948ced1b67192aeb22a25420b9a165930bc084e30534141c2f65a1fb
5
5
  SHA512:
6
- metadata.gz: 360edce8ae04be32396a272ad947897d256c171759f3304ed4f3b521a208540a2834e05a3140fe61de166337858bbd85c13655d02b92b1cd13e60b44b78cb0d6
7
- data.tar.gz: 482df9f676948f24f68e665899c15e7e14b78f40f100580771a4af943fd524b676ae140f19cf1d7b370d2ef1fb5e3c4bff9f0e2eb4a8cb1cb95884c74be6ef37
6
+ metadata.gz: b5809d0f9a9ae9536dfaf0ff74612c44a74df732d3ea7db7a8102aec6e434373104f9fba13a1aa3c1109faad754cfa390c3ac57bbd5de379f31441d9d61357d0
7
+ data.tar.gz: 4d5d53bd6881b462b2aa2ca36ddcd2e41ab61862f5162e0a888288596609271fb5e8e3130a9c99647d7226ed1373ee1b2a6477d8e5660ec13bbb615f5a853b72
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,7 +203,8 @@ 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)
@@ -175,13 +267,15 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
175
267
  - [Elaborate Samples](#elaborate-samples)
176
268
  - [Login](#login)
177
269
  - [Tic Tac Toe Sample](#tic-tac-toe-sample)
178
- - [Contact Manager](#contact-manager)
270
+ - [Contact Manager](#contact-manager-sample)
179
271
  - [External Samples](#external-samples)
180
272
  - [Glimmer Calculator](#glimmer-calculator)
181
273
  - [Gladiator](#gladiator)
274
+ - [Timer](#timer)
182
275
  - [In Production](#in-production)
183
276
  - [Math Bowling](#math-bowling)
184
277
  - [Are We There Yet?](#are-we-there-yet)
278
+ - [Garderie Rainbow Daily Agenda](#garderie-rainbow-daily-agenda)
185
279
  - [Packaging & Distribution](#packaging--distribution)
186
280
  - [Packaging Defaults](#packaging-defaults)
187
281
  - [Packaging Configuration](#packaging-configuration)
@@ -189,6 +283,9 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
189
283
  - [Mac Application Distribution](#mac-application-distribution)
190
284
  - [Self Signed Certificate](#self-signed-certificate)
191
285
  - [Gotchas](#gotchas)
286
+ - [App Updates](#app-updates)
287
+ - [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
288
+ - [Glimmer Process](#glimmer-process)
192
289
  - [Resources](#resources)
193
290
  - [Help](#help)
194
291
  - [Issues](#issues)
@@ -223,18 +320,17 @@ https://www.eclipse.org/swt/faq.php
223
320
 
224
321
  ## Pre-requisites
225
322
 
226
- - SWT 4.15 (comes included in Glimmer gem)
227
- - JRuby 9.2.12.0 (supporting Ruby 2.5.x syntax) (find at [https://www.jruby.org/download](https://www.jruby.org/download))
228
- - JDK 8 - 10 (find at [https://www.oracle.com/java/technologies/javase-downloads.html](https://www.oracle.com/java/technologies/javase-downloads.html))
229
- - (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)
230
326
 
231
- 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:
232
328
 
233
329
  ```bash
234
- rvm install jruby-9.2.12.0
330
+ rvm install jruby-9.2.13.0
235
331
  ```
236
332
 
237
- 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.
238
334
 
239
335
  ## Setup
240
336
 
@@ -242,20 +338,25 @@ Please follow these instructions to make the `glimmer` command available on your
242
338
 
243
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)).
244
340
 
245
- 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.
246
342
 
247
- 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).
248
344
 
249
345
  ### Option 1: Direct Install
250
- (Use for [Scaffolding](#scaffolding) on the Mac)
346
+ (Use for [Scaffolding](#scaffolding))
251
347
 
252
348
  Run this command to install directly:
253
349
  ```
254
- jgem install glimmer-dsl-swt -v 0.3.0
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.5
255
356
  ```
256
357
 
257
358
  `jgem` is JRuby's version of `gem` command.
258
- RVM allows running `gem` as an alias.
359
+ RVM allows running `gem install` directly as an alias.
259
360
  Otherwise, you may also run `jruby -S gem install ...`
260
361
 
261
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.
@@ -269,7 +370,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
269
370
 
270
371
  Add the following to `Gemfile`:
271
372
  ```
272
- gem 'glimmer-dsl-swt', '~> 0.3.0'
373
+ gem 'glimmer-dsl-swt', '~> 0.6.5'
273
374
  ```
274
375
 
275
376
  And, then run:
@@ -285,7 +386,17 @@ You may learn more about other Glimmer related gems ([`glimmer-dsl-opal`](https:
285
386
 
286
387
  The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
287
388
 
288
- 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
+ You can bring up usage instructions by running the `glimmer` command without arguments:
390
+
391
+ ```
392
+ glimmer
393
+ ```
394
+
395
+ On Mac and Linux, it additionally brings up a TUI (Text-based User Interface) for interactive navigation and execution of Glimmer tasks (courtesy of [rake-tui](https://github.com/AndyObtiva/rake-tui)).
396
+
397
+ On Windows, it simply lists the available Glimmer tasks at the end (courtsey of [rake](https://github.com/ruby/rake)).
398
+
399
+ 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).
289
400
 
290
401
  ### Basic Usage
291
402
 
@@ -314,42 +425,44 @@ bin/glimmer samples/hello/hello_world.rb
314
425
  Below are the full usage instructions that come up when running `glimmer` without args.
315
426
 
316
427
  ```
428
+ Glimmer (Ruby Desktop Development GUI Library) - JRuby Gem: glimmer-dsl-swt v0.6.5
429
+
317
430
  Usage: glimmer [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
318
431
 
319
- Runs Glimmer applications/tasks.
320
-
321
- Either a single task or one or more applications may be specified.
322
-
323
- When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
324
-
325
- Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
326
- glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
327
- glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
328
- glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
329
- glimmer package # Package app for distribution (generating config, jar, and native files)
330
- glimmer package:clean # Clean by removing "dist" and "packages" directories
331
- glimmer package:config # Generate JAR config file
332
- glimmer package:jar # Generate JAR file
333
- glimmer package:native # Generate Native files (DMG/PKG/APP on the Mac)
334
- glimmer scaffold[app_name] # Scaffold a Glimmer application directory structure to begin building a new app
335
- 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)
336
- 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)
337
- 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)
338
- 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)
432
+ Runs Glimmer applications and tasks.
339
433
 
340
434
  When applications are specified, they are run using JRuby,
341
435
  automatically preloading the glimmer Ruby gem and SWT jar dependency.
342
436
 
343
- Optionally, extra Glimmer options, JRuby options and environment variables may be passed in.
437
+ Optionally, extra Glimmer options, JRuby options, and/or environment variables may be passed in.
344
438
 
345
439
  Glimmer options:
346
440
  - "--quiet" : Does not announce file path of Glimmer application being launched
347
441
  - "--debug" : Displays extra debugging information, passes "--debug" to JRuby, and enables debug logging
348
442
  - "--log-level=VALUE" : Sets Glimmer's Ruby logger level ("ERROR" / "WARN" / "INFO" / "DEBUG"; default is none)
349
443
 
350
- Example: glimmer samples/hello_world.rb
351
-
352
- This runs the Glimmer application samples/hello_world.rb
444
+ Tasks are run via rake. Some tasks take arguments in square brackets.
445
+
446
+ Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
447
+
448
+ Select a Glimmer task to run: (Press ↑/↓ arrow to move, Enter to select and letters to filter)
449
+ ‣ glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
450
+ glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
451
+ glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
452
+ glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
453
+ glimmer package:clean # Clean by removing "dist" and "packages" directories
454
+ glimmer package:config # Generate JAR config file
455
+ glimmer package:jar # Generate JAR file
456
+ glimmer package:lock_jars # Lock JARs
457
+ glimmer package:native[type] # Generate Native files
458
+ glimmer sample:code[name] # Outputs code for a Glimmer internal sample [included in gem] (name is required)
459
+ glimmer sample:list[query] # Lists Glimmer internal samples [included in gem]. Filters by query if specified (query is optional)
460
+ glimmer sample:run[name] # Runs a Glimmer internal sample [included in gem]. If no name is supplied, it runs all samples
461
+ glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
462
+ glimmer scaffold:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cs]
463
+ glimmer scaffold:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cw]
464
+ 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:ge...
465
+ 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]
353
466
  ```
354
467
 
355
468
  Example (Glimmer/JRuby option specified):
@@ -366,26 +479,353 @@ glimmer samples/hello/hello_world.rb samples/hello_tab.rb
366
479
 
367
480
  Launches samples/hello/hello_world.rb and samples/hello_tab.rb at the same time, each in a separate JRuby thread.
368
481
 
482
+ ### Sample List/Run/Code
483
+
484
+ #### Sample List
485
+
486
+ You can list available Glimmer samples by running:
487
+
488
+ ```
489
+ glimmer sample:list
490
+ ```
491
+
492
+ This should output the following (providing the name of each sample, description, and command to run the sample and view its code):
493
+
494
+ ```
495
+ $ glimmer sample:list
496
+
497
+ Glimmer Hello Samples (run all via: glimmer sample:run:hello):
498
+
499
+ Name Description Run
500
+
501
+ hello_browser Hello Browser glimmer sample:run[hello_browser]
502
+ hello_combo Hello Combo glimmer sample:run[hello_combo]
503
+ hello_computed Hello Computed glimmer sample:run[hello_computed]
504
+ hello_drag_and_drop Hello Drag And Drop glimmer sample:run[hello_drag_and_drop]
505
+ hello_list_multi_selection Hello List Multi Selection glimmer sample:run[hello_list_multi_selection]
506
+ hello_list_single_selection Hello List Single Selection glimmer sample:run[hello_list_single_selection]
507
+ hello_menu_bar Hello Menu Bar glimmer sample:run[hello_menu_bar]
508
+ hello_message_box Hello Message Box glimmer sample:run[hello_message_box]
509
+ hello_pop_up_context_menu Hello Pop Up Context Menu glimmer sample:run[hello_pop_up_context_menu]
510
+ hello_tab Hello Tab glimmer sample:run[hello_tab]
511
+ hello_world Hello World glimmer sample:run[hello_world]
512
+
513
+
514
+ Glimmer Elaborate Samples (run all via: glimmer sample:run:elaborate):
515
+
516
+ Name Description Run
517
+
518
+ contact_manager Contact Manager glimmer sample:run[contact_manager]
519
+ login Login glimmer sample:run[login]
520
+ tic_tac_toe Tic Tac Toe glimmer sample:run[tic_tac_toe]
521
+ ```
522
+
523
+ #### Sample Run
524
+
525
+ A sample may be run via `glimmer sample:run[name]`. This also outputs the sample code so that you could take a look at it and compare to the GUI that launches.
526
+
527
+ If the sample name is left empty (e.g. `glimmer sample:run`), then all samples are run.
528
+
529
+ Example:
530
+
531
+ ```
532
+ glimmer sample:run[hello_tab]
533
+ ```
534
+
535
+ This will run the hello_tab sample and output its code:
536
+
537
+ ```
538
+ $ glimmer sample:run[hello_tab]
539
+
540
+ # /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/hello/hello_tab.rb
541
+
542
+ class HelloTab
543
+ include Glimmer
544
+ def launch
545
+ shell {
546
+ text "Hello, Tab!"
547
+ tab_folder {
548
+ tab_item {
549
+ text "English"
550
+ label {
551
+ text "Hello, World!"
552
+ }
553
+ }
554
+ tab_item {
555
+ text "French"
556
+ label {
557
+ text "Bonjour, Univers!"
558
+ }
559
+ }
560
+ }
561
+ }.open
562
+ end
563
+ end
564
+
565
+ HelloTab.new.launch
566
+
567
+ # # #
568
+ ```
569
+
570
+ ![Hello Tab English](images/glimmer-hello-tab-english.png)
571
+
572
+ #### Sample Code
573
+
574
+ You may output any sample code via this command: `glimmer sample:code[name]`
575
+
576
+ This is very similar to the sample run command, except the name is required.
577
+
578
+ It will not only output the main sample file, but any required supporting files as well.
579
+
580
+ Example:
581
+
582
+ ```
583
+ $ glimmer sample:code[tic_tac_toe]
584
+
585
+ # /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe.rb
586
+
587
+ require_relative "tic_tac_toe/board"
588
+
589
+ class TicTacToe
590
+ include Glimmer
591
+
592
+ def initialize
593
+ @tic_tac_toe_board = Board.new
594
+ @shell = shell {
595
+ text "Tic-Tac-Toe"
596
+ minimum_size 150, 178
597
+ composite {
598
+ grid_layout 3, true
599
+ (1..3).each { |row|
600
+ (1..3).each { |column|
601
+ button {
602
+ layout_data :fill, :fill, true, true
603
+ text bind(@tic_tac_toe_board[row, column], :sign)
604
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
605
+ font style: :bold, height: 20
606
+ on_widget_selected {
607
+ @tic_tac_toe_board.mark(row, column)
608
+ }
609
+ }
610
+ }
611
+ }
612
+ }
613
+ }
614
+ observe(@tic_tac_toe_board, :game_status) { |game_status|
615
+ display_win_message if game_status == Board::WIN
616
+ display_draw_message if game_status == Board::DRAW
617
+ }
618
+ end
619
+
620
+ def display_win_message
621
+ display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
622
+ end
623
+
624
+ def display_draw_message
625
+ display_game_over_message("Draw!")
626
+ end
627
+
628
+ def display_game_over_message(message_text)
629
+ message_box(@shell) {
630
+ text 'Game Over'
631
+ message message_text
632
+ }.open
633
+ @tic_tac_toe_board.reset
634
+ end
635
+
636
+ def open
637
+ @shell.open
638
+ end
639
+ end
640
+
641
+ TicTacToe.new.open
642
+
643
+ # # #
644
+
645
+
646
+ # /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe/cell.rb
647
+
648
+ class TicTacToe
649
+ class Cell
650
+ EMPTY = ""
651
+ attr_accessor :sign, :empty
652
+
653
+ def initialize
654
+ reset
655
+ end
656
+
657
+ def mark(sign)
658
+ self.sign = sign
659
+ end
660
+
661
+ def reset
662
+ self.sign = EMPTY
663
+ end
664
+
665
+ def sign=(sign_symbol)
666
+ @sign = sign_symbol
667
+ self.empty = sign == EMPTY
668
+ end
669
+
670
+ def marked
671
+ !empty
672
+ end
673
+ end
674
+ end
675
+
676
+ # # #
677
+
678
+
679
+ # /Users/User/.rvm/gems/jruby-9.2.13.0@glimmerapp/gems/glimmer-dsl-swt-0.6.5/samples/elaborate/tic_tac_toe/board.rb
680
+
681
+ require_relative 'cell'
682
+
683
+ class TicTacToe
684
+ class Board
685
+ DRAW = :draw
686
+ IN_PROGRESS = :in_progress
687
+ WIN = :win
688
+ attr :winning_sign
689
+ attr_accessor :game_status
690
+
691
+ def initialize
692
+ @sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
693
+ build_grid
694
+ @winning_sign = Cell::EMPTY
695
+ @game_status = IN_PROGRESS
696
+ end
697
+
698
+ #row and column numbers are 1-based
699
+ def mark(row, column)
700
+ self[row, column].mark(current_sign)
701
+ game_over? #updates winning sign
702
+ end
703
+
704
+ def current_sign
705
+ @current_sign = @sign_state_machine[@current_sign]
706
+ end
707
+
708
+ def [](row, column)
709
+ @grid[row-1][column-1]
710
+ end
711
+
712
+ def game_over?
713
+ win? or draw?
714
+ end
715
+
716
+ def win?
717
+ win = (row_win? or column_win? or diagonal_win?)
718
+ self.game_status=WIN if win
719
+ win
720
+ end
721
+
722
+ def reset
723
+ (1..3).each do |row|
724
+ (1..3).each do |column|
725
+ self[row, column].reset
726
+ end
727
+ end
728
+ @winning_sign = Cell::EMPTY
729
+ @current_sign = nil
730
+ self.game_status=IN_PROGRESS
731
+ end
732
+
733
+ private
734
+
735
+ def build_grid
736
+ @grid = []
737
+ 3.times do |row_index| #0-based
738
+ @grid << []
739
+ 3.times { @grid[row_index] << Cell.new }
740
+ end
741
+ end
742
+
743
+ def row_win?
744
+ (1..3).each do |row|
745
+ if row_has_same_sign(row)
746
+ @winning_sign = self[row, 1].sign
747
+ return true
748
+ end
749
+ end
750
+ false
751
+ end
752
+
753
+ def column_win?
754
+ (1..3).each do |column|
755
+ if column_has_same_sign(column)
756
+ @winning_sign = self[1, column].sign
757
+ return true
758
+ end
759
+ end
760
+ false
761
+ end
762
+
763
+ #needs refactoring if we ever decide to make the board size dynamic
764
+ def diagonal_win?
765
+ if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
766
+ @winning_sign = self[1, 1].sign
767
+ return true
768
+ end
769
+ if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
770
+ @winning_sign = self[3, 1].sign
771
+ return true
772
+ end
773
+ false
774
+ end
775
+
776
+ def draw?
777
+ @board_full = true
778
+ 3.times do |x|
779
+ 3.times do |y|
780
+ @board_full = false if self[x, y].empty
781
+ end
782
+ end
783
+ self.game_status = DRAW if @board_full
784
+ @board_full
785
+ end
786
+
787
+ def row_has_same_sign(number)
788
+ row_sign = self[number, 1].sign
789
+ [2, 3].each do |column|
790
+ return false unless row_sign == (self[number, column].sign)
791
+ end
792
+ true if self[number, 1].marked
793
+ end
794
+
795
+ def column_has_same_sign(number)
796
+ column_sign = self[1, number].sign
797
+ [2, 3].each do |row|
798
+ return false unless column_sign == (self[row, number].sign)
799
+ end
800
+ true if self[1, number].marked
801
+ end
802
+
803
+ end
804
+ end
805
+
806
+ # # #
807
+ ```
808
+
369
809
  ### Scaffolding
370
810
 
371
811
  Glimmer borrows from Rails the idea of Scaffolding, that is generating a structure for your app files that
372
- helps you get started just like true building scaffolding helps construction workers, civil engineers, and architects.
812
+ helps you get started just like true buildinThis g scaffolding helps construction workers, civil engineers, and architects.
373
813
 
374
814
  Glimmer scaffolding goes beyond just scaffolding the app files that Rails does. It also packages it and launches it,
375
815
  getting you to a running and delivered state of an advanced "Hello, World!" Glimmer application right off the bat.
376
816
 
377
817
  This should greatly facilitate building a new Glimmer app by helping you be productive and focus on app details while
378
818
  letting Glimmer scaffolding take care of initial app file structure concerns, such as adding:
379
- - Main application class that includes Glimmer
380
- - Main application view that houses main window content, about dialog, and preferences dialog
381
- - View and Model directories
382
- - Rakefile including Glimmer tasks
383
- - Version
384
- - License
385
- - Icon
386
- - Bin file for starting application
819
+ - Main application class that includes Glimmer (`app/{app_name}.rb`)
820
+ - Main application view that houses main window content, menu, about dialog, and preferences dialog
821
+ - View and Model directories (`app/views` and `app/models`)
822
+ - Rakefile including Glimmer tasks (`Rakefile`)
823
+ - Version (`VERSION`)
824
+ - License (`LICENSE.txt`)
825
+ - Icon (under `package/{platform}/{App Name}.{icon_extension}` for `macosx` .icns, `windows` .ico, and `linux` .png)
826
+ - Bin file for starting application (`bin/{app_name}.rb`)
387
827
 
388
- NOTE: Scaffolding requires RVM and currently supports Mac packaging only at the moment.
828
+ NOTE: Scaffolding supports Mac and Windows packaging at the moment.
389
829
 
390
830
  #### App
391
831
 
@@ -402,39 +842,77 @@ This will generate an advanced "Hello, World!" app, package it as a Mac native f
402
842
  Suppose you run:
403
843
 
404
844
  ```
405
- glimmer scaffold[CarMaker]
845
+ glimmer scaffold[greeter]
406
846
  ```
407
847
 
408
848
  You should see output like the following:
409
849
 
410
850
  ```
411
- Created CarMaker/.ruby-version
412
- Created CarMaker/.ruby-gemset
413
- Created CarMaker/VERSION
414
- Created CarMaker/LICENSE.txt
415
- Created CarMaker/Gemfile
416
- Created CarMaker/Rakefile
417
- Created CarMaker/app/car_maker.rb
418
- Created CarMaker/app/views/car_maker/app_view.rb
419
- Created CarMaker/package/macosx/Car Maker.icns
420
- Created CarMaker/bin/car_maker
851
+ $ glimmer scaffold[greeter]
852
+ create .gitignore
853
+ create Rakefile
854
+ create Gemfile
855
+ create LICENSE.txt
856
+ create README.rdoc
857
+ create .document
858
+ create lib
859
+ create lib/greeter.rb
860
+ create spec
861
+ create spec/spec_helper.rb
862
+ create spec/greeter_spec.rb
863
+ create .rspec
864
+ Jeweler has prepared your gem in ./greeter
865
+ Created greeter/.gitignore
866
+ Created greeter/.ruby-version
867
+ Created greeter/.ruby-gemset
868
+ Created greeter/VERSION
869
+ Created greeter/LICENSE.txt
870
+ Created greeter/Gemfile
871
+ Created greeter/Rakefile
872
+ Created greeter/app/greeter.rb
873
+ Created greeter/app/views/greeter/app_view.rb
874
+ Created greeter/package/windows/Greeter.ico
875
+ Created greeter/package/macosx/Greeter.icns
876
+ Created greeter/package/linux/Greeter.png
877
+ Created greeter/bin/greeter
878
+ Created greeter/spec/spec_helper.rb
421
879
  ...
422
880
  ```
423
881
 
424
- Eventually, it will launch an advanced "Hello, World!" app window having the title of your application and a Mac icon.
882
+ Eventually, it will launch an advanced "Hello, World!" app window having the title of your application ("Greeter").
425
883
 
426
884
  ![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
427
885
 
428
- On the Mac, it also comes with a boilerplate Preferences dialog.
886
+ It also comes with a boilerplate Preferences dialog.
429
887
 
430
888
  ![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
431
889
 
890
+ Here is the Windows version of the scaffolded "Greeter" app:
891
+
892
+ ![Glimmer Scaffold App Windows](images/glimmer-scaffolding-app-windows.png)
893
+
894
+ And, here is the Windows version of the boilerplate Preferences dialog.
895
+
896
+ ![Glimmer Scaffold App Windows Preferences](images/glimmer-scaffolding-app-windows-preferences.png)
897
+
898
+ In order to run the app after making changes, you must run the `glimmer` command and pass it the generated script under the `bin` directory as an argument:
899
+
900
+ ```
901
+ glimmer bin/greeter
902
+ ```
903
+
432
904
  #### Custom Shell
433
905
 
434
906
  To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
435
907
 
436
908
  ```
437
- glimmer scaffold:custom_shell[custom_shell_name]
909
+ glimmer scaffold:customshell[name]
910
+ ```
911
+
912
+ Or the following alternative abbreviation:
913
+
914
+ ```
915
+ glimmer scaffold:cs[name]
438
916
  ```
439
917
 
440
918
  #### Custom Widget
@@ -442,13 +920,19 @@ glimmer scaffold:custom_shell[custom_shell_name]
442
920
  To scaffold a Glimmer custom widget (part of a view) for an existing Glimmer app, run the following command:
443
921
 
444
922
  ```
445
- glimmer scaffold:custom_widget[custom_widget_name]
923
+ glimmer scaffold:customwidget[name]
924
+ ```
925
+
926
+ Or the following alternative abbreviation:
927
+
928
+ ```
929
+ glimmer scaffold:cw[name]
446
930
  ```
447
931
 
448
932
  #### Custom Shell Gem
449
933
 
450
934
  Custom shell gems are self-contained Glimmer apps as well as reusable custom shells.
451
- They have everything scaffolded Glimmer apps come with in addition to gem content like a Jeweler Rakefile that can build gemspec and release gems.
935
+ 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.
452
936
  Unlike scaffolded Glimmer apps, custom shell gem content lives under the `lib` directory (not `app`).
453
937
  They can be packaged as both a native executable (e.g. Mac DMG/PKG/APP) and a Ruby gem.
454
938
  Of course, you can just build a Ruby gem and disregard native executable packaging if you do not need it.
@@ -456,7 +940,13 @@ Of course, you can just build a Ruby gem and disregard native executable packagi
456
940
  To scaffold a Glimmer custom shell gem (full window view distributed as a Ruby gem), run the following command:
457
941
 
458
942
  ```
459
- glimmer scaffold:custom_shell_gem[custom_shell_name, namespace]
943
+ glimmer scaffold:gem:customshell[name,namespace]
944
+ ```
945
+
946
+ Or the following alternative abbreviation:
947
+
948
+ ```
949
+ glimmer scaffold:gem:cs[name,namespace]
460
950
  ```
461
951
 
462
952
  It is important to specify a namespace to avoid having your gem clash with existing gems.
@@ -465,6 +955,10 @@ The Ruby gem name will follow the convention "glimmer-cs-customwidgetname-namesp
465
955
 
466
956
  Only official Glimmer gems created by the Glimmer project committers will have no namespace (e.g. [glimmer-cs-gladiator](https://rubygems.org/gems/glimmer-cs-gladiator) Ruby gem)
467
957
 
958
+ Since custom shell gems are both an app and a gem, they provide two ways to run:
959
+ - Run the `glimmer` command and pass it the generated script under the `bin` directory that matches the gem name (e.g. run `glimmer bin/glimmer-cs-calculator`)
960
+ - Run the executable binary file that ships with the gem directly (without `glimmer`). It intentionally has a shorter name for convenience since it is meant to be used on the command line (not in a package), so you can leave out the `glimmer-cs-` prefix (e.g. run `bin/calculator` directly)
961
+
468
962
  Examples:
469
963
 
470
964
  - [glimmer-cs-gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator): Gladiator (Glimmer Editor)
@@ -475,16 +969,26 @@ Examples:
475
969
  To scaffold a Glimmer custom widget gem (part of a view distributed as a Ruby gem), run the following command:
476
970
 
477
971
  ```
478
- glimmer scaffold:custom_widget_gem[custom_widget_name, namespace]
972
+ glimmer scaffold:gem:customwidget[name,namespace]
479
973
  ```
480
974
 
975
+ Or the following alternative abbreviation:
976
+
977
+ ```
978
+ glimmer scaffold:gem:cw[name,namespace]
979
+ ```
980
+
981
+
481
982
  It is important to specify a namespace to avoid having your gem clash with existing gems.
482
983
 
483
984
  The Ruby gem name will follow the convention "glimmer-cw-customwidgetname-namespace" (the 'cw' is for Custom Widget)
484
985
 
485
986
  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)
486
987
 
487
- Example: [https://github.com/AndyObtiva/glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video)
988
+ Examples:
989
+
990
+ - [glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video): Video Widget
991
+ - [glimmer-cw-cdatetime-nebula](https://github.com/AndyObtiva/glimmer-cw-cdatetime-nebula): Nebula CDateTime Widget
488
992
 
489
993
  ### Gem Listing
490
994
 
@@ -495,13 +999,19 @@ The `glimmer` command comes with tasks for listing Glimmer related gems to make
495
999
  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):
496
1000
 
497
1001
  ```
498
- glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
1002
+ glimmer list:gems:customshell[query]
1003
+ ```
1004
+
1005
+ Or the following alternative abbreviation:
1006
+
1007
+ ```
1008
+ glimmer list:gems:cs[query]
499
1009
  ```
500
1010
 
501
1011
  Example:
502
1012
 
503
1013
  ```
504
- glimmer list:custom_shell_gems
1014
+ glimmer list:gems:cs
505
1015
  ```
506
1016
 
507
1017
  Output:
@@ -512,8 +1022,9 @@ Output:
512
1022
 
513
1023
  Name Gem Version Author Description
514
1024
 
515
- Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
516
- Gladiator glimmer-cs-gladiator 0.2.0 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
1025
+ Calculator glimmer-cs-calculator 1.0.2 Andy Maleh Calculator - Glimmer Custom Shell
1026
+ Gladiator glimmer-cs-gladiator 0.2.4 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
1027
+ Timer glimmer-cs-timer 1.0.0 Andy Maleh Timer - Glimmer Custom Shell
517
1028
 
518
1029
  ```
519
1030
 
@@ -522,7 +1033,13 @@ Output:
522
1033
  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):
523
1034
 
524
1035
  ```
525
- glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
1036
+ glimmer list:gems:customwidget[query]
1037
+ ```
1038
+
1039
+ Or the following alternative abbreviation:
1040
+
1041
+ ```
1042
+ glimmer list:gems:cw[query]
526
1043
  ```
527
1044
 
528
1045
  Example:
@@ -530,7 +1047,7 @@ Example:
530
1047
  Check if there is a custom video widget for Glimmer.
531
1048
 
532
1049
  ```
533
- glimmer list:custom_widget_gems[video]
1050
+ glimmer list:gems:cw[video]
534
1051
  ```
535
1052
 
536
1053
  Output:
@@ -541,7 +1058,7 @@ Output:
541
1058
 
542
1059
  Name Gem Version Author Description
543
1060
 
544
- Video glimmer-cw-video 0.1.1 Andy Maleh Glimmer Custom Widget - Video
1061
+ Video glimmer-cw-video 0.1.3 Andy Maleh Glimmer Custom Widget - Video
545
1062
 
546
1063
  ```
547
1064
 
@@ -550,13 +1067,13 @@ Output:
550
1067
  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):
551
1068
 
552
1069
  ```
553
- glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
1070
+ glimmer list:gems:dsl[query]
554
1071
  ```
555
1072
 
556
1073
  Example:
557
1074
 
558
1075
  ```
559
- glimmer list:dsl_gems
1076
+ glimmer list:gems:dsl
560
1077
  ```
561
1078
 
562
1079
  Output:
@@ -567,10 +1084,10 @@ Output:
567
1084
 
568
1085
  Name Gem Version Author Description
569
1086
 
570
- Css glimmer-dsl-css 0.1.0 AndyMaleh Glimmer DSL for CSS
571
- Opal glimmer-dsl-opal 0.0.9 AndyMaleh Glimmer DSL for Opal
572
- Swt glimmer-dsl-swt 0.3.0 AndyMaleh Glimmer DSL for SWT
573
- Xml glimmer-dsl-xml 0.1.0 AndyMaleh Glimmer DSL for XML
1087
+ Css glimmer-dsl-css 0.2.0 AndyMaleh Glimmer DSL for CSS
1088
+ Opal glimmer-dsl-opal 0.1.0 AndyMaleh Glimmer DSL for Opal
1089
+ Swt glimmer-dsl-swt 0.6.5 AndyMaleh Glimmer DSL for SWT
1090
+ Xml glimmer-dsl-xml 0.2.0 AndyMaleh Glimmer DSL for XML
574
1091
 
575
1092
  ```
576
1093
 
@@ -623,15 +1140,76 @@ Watch out for hands-on examples in this README indicated by "you may copy/paste
623
1140
 
624
1141
  Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
625
1142
 
626
- ## Glimmer DSL Syntax
1143
+ ## Glimmer GUI DSL Syntax
627
1144
 
628
- Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
1145
+ 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.
629
1146
 
630
- Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `message_box`, `async_exec`, and `bind`.
1147
+ It is available through mixing in the `Glimmer` module, which makes Glimmer GUI DSL keywords available to both the instance scope and class scope:
631
1148
 
632
- Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `list`.
1149
+ ```ruby
1150
+ include Glimmer
1151
+ ```
633
1152
 
634
- 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.
1153
+ For example, here is the basic "Hello, World!" sample code (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1154
+
1155
+ ```ruby
1156
+ include Glimmer
1157
+
1158
+ shell {
1159
+ text "Glimmer"
1160
+ label {
1161
+ text "Hello, World!"
1162
+ }
1163
+ }.open
1164
+ ```
1165
+
1166
+ 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.
1167
+
1168
+ 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)):
1169
+
1170
+ ```ruby
1171
+ class HelloWorld
1172
+ include Glimmer # makes the GUI DSL available in both the class scope and instance scope
1173
+
1174
+ COLOR_FOREGROUND_DEFAULT = rgb(255, 0, 0) # rgb is a GUI DSL keyword used in the class scope
1175
+
1176
+ def open
1177
+ # the following are GUI DSL keywords (shell, text, and label) used in the instance scope
1178
+ shell {
1179
+ text "Glimmer"
1180
+ label {
1181
+ text "Hello, World!"
1182
+ foreground COLOR_FOREGROUND_DEFAULT
1183
+ }
1184
+ }.open
1185
+ end
1186
+ end
1187
+
1188
+ HelloWorld.new.open
1189
+ ```
1190
+
1191
+ This renders "Hello, World!" with a red foreground color:
1192
+
1193
+ ![Hello World Red Foreground Color](images/glimmer-hello-world-red-foreground-color.png)
1194
+
1195
+ 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.
1196
+
1197
+ 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)
1198
+
1199
+ Glimmer DSL syntax consists mainly of:
1200
+ - keywords (e.g. `table` for a table widget)
1201
+ - style/args (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
1202
+ - 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)
1203
+
1204
+ ### DSL Auto-Expansion
1205
+
1206
+ 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.
1207
+
1208
+ Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `display`, `message_box`, `async_exec`, `sync_exec`, and `bind`.
1209
+
1210
+ 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.
1211
+
1212
+ 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.
635
1213
 
636
1214
  For example, if a project adds this custom Java SWT library:
637
1215
 
@@ -649,9 +1227,9 @@ https://www.eclipse.org/swt/widgets/
649
1227
 
650
1228
  This screenshot taken from the link above should give a glimpse of how SWT widgets look and feel:
651
1229
 
652
- ![SWT Widgets](images/glimmer-swt-widgets.png)
1230
+ [![SWT Widgets](images/glimmer-swt-widgets.png)](https://www.eclipse.org/swt/widgets/)
653
1231
 
654
- In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name:
1232
+ 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:
655
1233
 
656
1234
  - `shell` instantiates `org.eclipse.swt.widgets.Shell`
657
1235
  - `text` instantiates `org.eclipse.swt.widgets.Text`
@@ -667,8 +1245,8 @@ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring
667
1245
  - `list` instantiates `org.eclipse.swt.widgets.List`
668
1246
 
669
1247
  Every **widget** is sufficiently declared by name, but may optionally be accompanied with:
670
- - SWT **style** ***argument*** wrapped by parenthesis according to [Glimmer Style Guide](#glimmer-style-guide) (see [next section](#widget-styles) for details).
671
- - Ruby block containing **properties** (widget attributes) and **content** (nested widgets)
1248
+ - SWT **style**/***arguments*** wrapped by parenthesis according to [Glimmer Style Guide](#glimmer-style-guide) (see [next section](#widget-styles) for details).
1249
+ - Ruby block containing **content**, which may be **properties** (e.g. `enabled false`) or nested **widgets** (e.g. `table_column` nested inside `table`)
672
1250
 
673
1251
  For example, if we were to revisit `samples/hello/hello_world.rb` above (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
674
1252
 
@@ -750,6 +1328,8 @@ shell {
750
1328
  }.open
751
1329
  ```
752
1330
 
1331
+ 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.
1332
+
753
1333
  #### Display
754
1334
 
755
1335
  SWT Display is a singleton in Glimmer. It is used in SWT to represent your display device, allowing you to manage GUI globally
@@ -761,7 +1341,7 @@ automatically uses the display created earlier without having to explicitly hook
761
1341
  ```ruby
762
1342
  @display = display {
763
1343
  cursor_location 300, 300
764
- on_event_keydown {
1344
+ on_swt_keydown {
765
1345
  # ...
766
1346
  }
767
1347
  # ...
@@ -837,6 +1417,21 @@ include Glimmer
837
1417
  @shell.open
838
1418
  ```
839
1419
 
1420
+ ![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
1421
+
1422
+ 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):
1423
+
1424
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1425
+
1426
+ ```ruby
1427
+ include Glimmer
1428
+
1429
+ message_box {
1430
+ text 'Greeting'
1431
+ message "Hello, World!"
1432
+ }.open
1433
+ ```
1434
+
840
1435
  ##### `#swt_widget`
841
1436
 
842
1437
  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.
@@ -856,6 +1451,24 @@ Shell widget proxy has extra methods specific to SWT Shell:
856
1451
  - `#pack`: Packs contained widgets using SWT's `Shell#pack` method
857
1452
  - `#pack_same_size`: Packs contained widgets without changing shell's size when widget sizes change
858
1453
 
1454
+ ##### Shell Icon
1455
+
1456
+ 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)
1457
+
1458
+ Example:
1459
+
1460
+ ```ruby
1461
+ shell {
1462
+ # ...
1463
+ image 'path/to/image.png'
1464
+ # ...
1465
+ }
1466
+ ```
1467
+
1468
+ ###### Shell Icon Tip for Packaging on Windows
1469
+
1470
+ 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'`)
1471
+
859
1472
  #### Dialog
860
1473
 
861
1474
  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.
@@ -1031,7 +1644,7 @@ text(:center, :border) { # Multiple SWT styles separated by comma
1031
1644
  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):
1032
1645
 
1033
1646
  - `text(:border)`
1034
- - `table(:border)`
1647
+ - `table(:border, :virtual, :full_selection)`
1035
1648
  - `tree(:border, :virtual, :v_scroll, :h_scroll)`
1036
1649
  - `spinner(:border)`
1037
1650
  - `list(:border, :v_scroll)`
@@ -1107,7 +1720,7 @@ button {
1107
1720
 
1108
1721
  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)
1109
1722
 
1110
- #### Colors
1723
+ #### Color
1111
1724
 
1112
1725
  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.
1113
1726
 
@@ -1156,7 +1769,7 @@ Example:
1156
1769
  color(:black).swt_color # returns SWT Color object
1157
1770
  ```
1158
1771
 
1159
- #### Fonts
1772
+ #### Font
1160
1773
 
1161
1774
  Fonts are represented in Glimmer as a hash of name, height, and style keys.
1162
1775
 
@@ -1185,6 +1798,33 @@ label {
1185
1798
  # ...
1186
1799
  ```
1187
1800
 
1801
+ 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.
1802
+
1803
+ Example:
1804
+
1805
+ ```ruby
1806
+ @font = font(name: 'Arial', height: 36, style: :normal)
1807
+ ```
1808
+
1809
+ ### Cursor
1810
+
1811
+ SWT widget `cursor` property represents the mouse cursor you see on the screen when you hover over that widget.
1812
+
1813
+ 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)
1814
+
1815
+ 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.
1816
+
1817
+ Example:
1818
+
1819
+ ```ruby
1820
+ shell {
1821
+ minimum_size 128, 128
1822
+ cursor :appstarting
1823
+ }
1824
+ ```
1825
+
1826
+ This sets the shell `cursor` to that of `SWT::CURSOR_APPSTARTING`
1827
+
1188
1828
  ### Layouts
1189
1829
 
1190
1830
  Glimmer lays widgets out visually using SWT layouts, which can only be set on composite widget and subclasses.
@@ -1721,10 +2361,10 @@ Glimmer comes with `Observer` module, which is used internally for data-binding,
1721
2361
 
1722
2362
  Glimmer supports observing widgets with two main types of events:
1723
2363
  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`).
1724
- 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)
2364
+ 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)
1725
2365
 
1726
2366
  Additionally, there are two more types of events:
1727
- - SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_event_{swt-event-constant}`
2367
+ - SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_swt_{swt-event-constant}`
1728
2368
  - SWT `display` supports Mac application menu item observers (`on_about` and `on_preferences`), which you can read about under [Miscellaneous](#miscellaneous).
1729
2369
 
1730
2370
  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.
@@ -1747,7 +2387,8 @@ Let's revisit the Tic Tac Toe example shown near the beginning of the page:
1747
2387
  ```ruby
1748
2388
  shell {
1749
2389
  text "Tic-Tac-Toe"
1750
- composite {
2390
+ minimum_size 150, 178
2391
+ composite {
1751
2392
  grid_layout 3, true
1752
2393
  (1..3).each { |row|
1753
2394
  (1..3).each { |column|
@@ -1769,21 +2410,21 @@ Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties da
1769
2410
 
1770
2411
  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.
1771
2412
 
1772
- **Regarding number 2**, you can figure out all available events by looking at the `org.eclipse.swt.SWT` API:
2413
+ **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:
1773
2414
 
1774
2415
  https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
1775
2416
 
1776
2417
  Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1777
2418
 
1778
- `SWT.Show` - hooks a listener for showing a widget (using `on_event_show` in Glimmer)
1779
- `SWT.Hide` - hooks a listener for hiding a widget (using `on_event_hide` in Glimmer)
2419
+ `SWT.Show` - hooks a listener for showing a widget (using `on_swt_show` in Glimmer)
2420
+ `SWT.Hide` - hooks a listener for hiding a widget (using `on_swt_hide` in Glimmer)
1780
2421
 
1781
2422
  ```ruby
1782
2423
  shell {
1783
2424
  @button1 = button {
1784
2425
  text "Show 2nd Button"
1785
2426
  visible true
1786
- on_event_show {
2427
+ on_swt_show {
1787
2428
  @button2.swt_widget.setVisible(false)
1788
2429
  }
1789
2430
  on_widget_selected {
@@ -1793,7 +2434,7 @@ shell {
1793
2434
  @button2 = button {
1794
2435
  text "Show 1st Button"
1795
2436
  visible false
1796
- on_event_show {
2437
+ on_swt_show {
1797
2438
  @button1.swt_widget.setVisible(false)
1798
2439
  }
1799
2440
  on_widget_selected {
@@ -1803,7 +2444,7 @@ shell {
1803
2444
  }.open
1804
2445
  ```
1805
2446
 
1806
- **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`
2447
+ **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`
1807
2448
 
1808
2449
  ##### Alternative Syntax
1809
2450
 
@@ -2097,7 +2738,7 @@ shell { |app_shell|
2097
2738
  @current_step_number = 1
2098
2739
  @wizard_steps = 5.times.map { |n|
2099
2740
  wizard_step(number: n+1, step_count: 5) {
2100
- on_event_hide {
2741
+ on_swt_hide {
2101
2742
  if @current_step_number < 5
2102
2743
  @current_step_number += 1
2103
2744
  app_shell.hide
@@ -2397,7 +3038,7 @@ Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app versi
2397
3038
 
2398
3039
  #### Video Widget
2399
3040
 
2400
- ![Video Widget](images/glimmer-video-widget.png)
3041
+ [![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
2401
3042
 
2402
3043
  Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
2403
3044
 
@@ -2449,17 +3090,14 @@ Glimmer configuration may be done via the `Glimmer::Config` module.
2449
3090
 
2450
3091
  ### logger
2451
3092
 
2452
- Glimmer supports logging via a Ruby Logger configurable with the `Glimmer::Config.logger` config option.
2453
- It is disabled by default to ensure not affecting desktop app performance.
2454
- It may be enabled via `Glimmer::Config.enable_logging`
2455
- When enabled, the Glimmer logger level defaults to `:warn` (aka `Logger::WARN`)
2456
- It may be configured to show a different level of logging via `Glimmer::Config.logger.level` just ike with any Ruby Logger.
3093
+ The Glimmer DSL engine supports logging via a standard `STDOUT` Ruby `Logger` configured in the `Glimmer::Config.logger` config option.
3094
+ It is set to level Logger::ERROR by default.
3095
+ Log level may be adjusted via `Glimmer::Config.logger.level` just like any other Ruby Logger.
2457
3096
 
2458
3097
  Example:
2459
3098
 
2460
3099
  ```ruby
2461
- Glimmer::Config.enable_logging
2462
- Glimmer::Config.logger.level = Logger::DEBUG
3100
+ Glimmer::Config.logger.level = :debug
2463
3101
  ```
2464
3102
  This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
2465
3103
 
@@ -2479,6 +3117,55 @@ D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will hand
2479
3117
  D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
2480
3118
  ```
2481
3119
 
3120
+ The `logger` instance may be replaced with a custom logger via `Glimmer::Config.logger = custom_logger`
3121
+
3122
+ To reset `logger` to the default instance, you may call `Glimmer::Config.reset_logger!`
3123
+
3124
+ 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.
3125
+
3126
+ [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.
3127
+
3128
+ Other config options related to the [`logging`](https://github.com/TwP/logging) gem are mentioned below.
3129
+
3130
+ #### logging_devices
3131
+
3132
+ This is an array of these possible values: `:stdout` (default), `:stderr`, `:file`, `:syslog` (default), `:stringio`
3133
+
3134
+ It defaults to `[:stdout, :syslog]`
3135
+
3136
+ When `:file` is included, Glimmer creates a 'log' directory directly below the Glimmer app local directory.
3137
+ It may also be customized further via the `logging_device_file_options` option.
3138
+ This is useful on Windows as an alternative to `syslog`, which is not available on Windows by default.
3139
+
3140
+ #### logging_device_file_options
3141
+
3142
+ This is a hash of [`logging`](https://github.com/TwP/logging) gem options for the `:file` logging device.
3143
+
3144
+ Default: `{size: 1_000_000, age: 'daily', roll_by: 'number'}`
3145
+
3146
+ That ensures splitting log files at the 1MB size and daily, rolling them by unique number.
3147
+
3148
+ #### logging_appender_options
3149
+
3150
+ Appender options is a hash passed as options to every appender (logging device) used in the [`logging`](https://github.com/TwP/logging) gem.
3151
+
3152
+ Default: `{async: true, auto_flushing: 500, write_size: 500, flush_period: 60, immediate_at: [:error, :fatal], layout: logging_layout}`
3153
+
3154
+ That ensures asynchronous buffered logging that is flushed every 500 messages and 60 seconds, or immediately at error and fatal log levels
3155
+
3156
+ #### logging_layout
3157
+
3158
+ This is a [`logging`](https://github.com/TwP/logging) gem layout that formats the logging output.
3159
+
3160
+ Default:
3161
+
3162
+ ```
3163
+ Logging.layouts.pattern(
3164
+ pattern: '[%d] %-5l %c: %m\n',
3165
+ date_pattern: '%Y-%m-%d %H:%M:%S'
3166
+ )
3167
+ ```
3168
+
2482
3169
  ### import_swt_packages
2483
3170
 
2484
3171
  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.
@@ -2538,6 +3225,33 @@ The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` c
2538
3225
 
2539
3226
  Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
2540
3227
 
3228
+ ### excluded_keyword_checkers
3229
+
3230
+ Glimmer permits consumers to exclude keywords from DSL processing by its engine via the `excluded_keyword_checkers` config option.
3231
+
3232
+ To do so, add a proc to it that returns a boolean indicating if a keyword is excluded or not.
3233
+
3234
+ 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.
3235
+
3236
+ Example of keywords excluded by [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt):
3237
+
3238
+ ```ruby
3239
+ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
3240
+ method = method_symbol.to_s
3241
+ result = false
3242
+ result ||= method.start_with?('on_swt_') && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
3243
+ result ||= method == 'dispose' && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
3244
+ result ||= ['drag_source_proxy', 'drop_target_proxy'].include?(method) && is_a?(Glimmer::UI::CustomWidget)
3245
+ result ||= method == 'post_initialize_child'
3246
+ result ||= method.end_with?('=')
3247
+ result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
3248
+ end
3249
+ ```
3250
+
3251
+ ### log_excluded_keywords
3252
+
3253
+ This just tells Glimmer whether to log excluded keywords or not (at the debug level). It is off by default.
3254
+
2541
3255
  ## Glimmer Style Guide
2542
3256
 
2543
3257
  - Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
@@ -2805,6 +3519,8 @@ This sample demonstrates a full MVC application, including GUI layout, text and
2805
3519
 
2806
3520
  Code:
2807
3521
 
3522
+ (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`)
3523
+
2808
3524
  [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)
2809
3525
 
2810
3526
  Run:
@@ -2817,7 +3533,7 @@ glimmer samples/elaborate/tic_tac_toe.rb
2817
3533
  ![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
2818
3534
  ![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
2819
3535
 
2820
- #### Contact Manager
3536
+ #### Contact Manager Sample
2821
3537
 
2822
3538
  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)).
2823
3539
 
@@ -2855,7 +3571,7 @@ Contact Manager - Edit Done
2855
3571
 
2856
3572
  #### Glimmer Calculator
2857
3573
 
2858
- [<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 project demonstrating data-binding and TDD (test-driven-development) with Glimmer following the MVP pattern (Model-View-Presenter).
3574
+ [<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).
2859
3575
 
2860
3576
  [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
2861
3577
 
@@ -2876,10 +3592,18 @@ Gladiator is a good demonstration of:
2876
3592
  - Custom Shell
2877
3593
  - Custom widget
2878
3594
 
3595
+ #### Timer
3596
+
3597
+ [<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.
3598
+
3599
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-timer/master/glimmer-timer-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-timer)
3600
+
2879
3601
  ## In Production
2880
3602
 
2881
3603
  The following production apps have been built with Glimmer.
2882
3604
 
3605
+ If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
3606
+
2883
3607
  ### Math Bowling
2884
3608
 
2885
3609
  [<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
@@ -2888,23 +3612,45 @@ The following production apps have been built with Glimmer.
2888
3612
 
2889
3613
  [<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
2890
3614
 
2891
- If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
3615
+ ### Garderie Rainbow Daily Agenda
2892
3616
 
2893
- ## Packaging & Distribution
3617
+ [<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
2894
3618
 
2895
- Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
2896
- - Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
2897
- - 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.
3619
+ ## Packaging & Distribution
2898
3620
 
2899
- 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):
3621
+ Glimmer simplifies the process of native-executable packaging and distribution on Mac and Windows via a single `glimmer package` command:
2900
3622
 
2901
3623
  ```
2902
3624
  glimmer package
2903
3625
  ```
2904
3626
 
2905
- 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`.
2906
- JAR file name will match your application local directory name (e.g. `MathBowling.jar` for `~/code/MathBowling`)
2907
- 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)
3627
+ 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)
3628
+
3629
+ 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:
3630
+
3631
+ ```
3632
+ glimmer package[msi]
3633
+ ```
3634
+
3635
+ - Available Mac packaging types are `dmg`, `pkg`, and `image` (image means a pure Mac `app` without a setup program)
3636
+ - 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).
3637
+
3638
+ 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]`):
3639
+
3640
+ ```ruby
3641
+ require 'glimmer/rake_task'
3642
+ ```
3643
+
3644
+ The Glimmer packaging process done in the `glimmer package` command consists of the following steps:
3645
+ 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.
3646
+ 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.
3647
+ 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.
3648
+ 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
3649
+ 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).
3650
+
3651
+ 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`.
3652
+ The JAR file name will match your application local directory name (e.g. `MathBowling.jar` for `~/code/MathBowling`)
3653
+ 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)
2908
3654
 
2909
3655
  The `glimmer package` command will automatically set "mac.CFBundleIdentifier" to ="org.#{project_name}.application.#{project_name}".
2910
3656
  You may override by configuring as an extra argument for javapackger (e.g. Glimmer::Package.javapackager_extra_args = " -Bmac.CFBundleIdentifier=org.andymaleh.application.MathBowling")
@@ -2932,6 +3678,7 @@ This will generate `config/warble.rb`, which you may configure and then run `gli
2932
3678
  require_relative '../app/my_application.rb'
2933
3679
  ```
2934
3680
  - Include Icon (Optional): If you'd like to include an icon for your app (.icns format on the Mac), place it under `package/macosx` matching the humanized application local directory name (e.g. 'Math Bowling.icns' [containing space] for MathBowling or math_bowling). You may generate your Mac icon easily using tools like Image2Icon (http://www.img2icnsapp.com/) or manually using the Mac terminal command `iconutil` (iconutil guide: https://applehelpwriter.com/tag/iconutil/)
3681
+ - Include DMG Background Icon (Optional): Simply place a .png file under `package/macosx/{HumanAppName}-background.png`
2935
3682
  - Include Version (Optional): Create a `VERSION` file in your application and fill it your app version on one line (e.g. `1.1.0`)
2936
3683
  - Include License (Optional): Create a `LICENSE.txt` file in your application and fill it up with your license (e.g. MIT). It will show up to people when installing your app. Note that, you may optionally also specify license type, but you'd have to do so manually via `-BlicenseType=MIT` shown in an [example below](#javapackager-extra-arguments).
2937
3684
  - Extra args (Optional): You may optionally add the following to `Rakefile` to configure extra arguments for javapackager: `Glimmer::Packager.javapackager_extra_args = "..."` (Useful to avoid re-entering extra arguments on every run of rake task.). Read about them in [their section below](#javapackager-extra-arguments).
@@ -2969,6 +3716,18 @@ JAVAPACKAGER_EXTRA_ARGS='-Bmac.CFBundleName="Math Bowling Game"' glimmer package
2969
3716
 
2970
3717
  That overrides the default application display name.
2971
3718
 
3719
+ ### Verbose Mode
3720
+
3721
+ Pass `-v` to javapackager in `Glimmer::Package.javapackager_extra_args` or by running `glimmer package:native[type] -v` to learn more about further available customizations for the installer you are requesting to generate.
3722
+
3723
+ ### Windows Application Packaging
3724
+
3725
+ Windows offers two options for setup packaging:
3726
+ - `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)).
3727
+ - `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.
3728
+
3729
+ 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.
3730
+
2972
3731
  ### Mac Application Distribution
2973
3732
 
2974
3733
  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.
@@ -3034,6 +3793,30 @@ By the way, keep in mind that during normal operation, it does also indicate a f
3034
3793
  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
3035
3794
  ```
3036
3795
 
3796
+ ## App Updates
3797
+
3798
+ 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.
3799
+
3800
+ ## Glimmer Supporting Libraries
3801
+
3802
+ Here is a list of notable 3rd party gems used by Glimmer:
3803
+ - [jeweler](https://github.com/technicalpickles/jeweler): generates app gems during [Glimmer Scaffolding](#scaffolding)
3804
+ - [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)
3805
+ - [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
3806
+ - [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
3807
+ - [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`)
3808
+ - [rake](https://github.com/ruby/rake): used to implement and execute `glimmer` commands
3809
+ - [rake-tui](https://github.com/AndyObtiva/rake-tui): Rake Text-based User Interface. Allows navigating rake tasks with arrow keys and filtering task list by typing to quickly find an run a rake task.
3810
+ - [super_module](https://github.com/AndyObtiva/super_module): used to cleanly write the Glimmer::UI:CustomWidget and Glimmer::UI::CustomShell modules
3811
+ - [text-table](https://github.com/aptinio/text-table): renders textual data in a textual table for the command-line interface of Glimmer
3812
+ - [warbler](https://github.com/jruby/warbler): converts a Glimmer app into a Java JAR file during packaging
3813
+
3814
+ ## Glimmer Process
3815
+
3816
+ [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.
3817
+
3818
+ Learn more by reading the [GPG](PROCESS.md) (Glimmer Process Guidelines)
3819
+
3037
3820
  ## Resources
3038
3821
 
3039
3822
  * [Code Master Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
@@ -3067,13 +3850,15 @@ Glimmer DSL Engine specific tasks are at:
3067
3850
 
3068
3851
  ## Change Log
3069
3852
 
3853
+ [glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
3854
+
3070
3855
  [CHANGELOG.md](CHANGELOG.md)
3071
3856
 
3072
3857
  ## Contributing
3073
3858
 
3074
3859
  **Contributors Wanted!**
3075
3860
 
3076
- 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).
3861
+ 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).
3077
3862
 
3078
3863
  You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
3079
3864
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
@@ -3096,7 +3881,11 @@ If your company would like to invest fulltime in further development of the Glim
3096
3881
 
3097
3882
  ## License
3098
3883
 
3099
- Copyright (c) 2007-2020 Andy Maleh.
3100
- See LICENSE.txt for further details.
3884
+ [MIT](https://opensource.org/licenses/MIT)
3885
+
3886
+ Copyright (c) 2007-2020 - Andy Maleh.
3887
+ See [LICENSE.txt](LICENSE.txt) for further details.
3888
+
3889
+ --
3101
3890
 
3102
3891
  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>