glimmer 0.9.3 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1185 -287
- data/VERSION +1 -1
- data/lib/glimmer.rb +7 -12
- data/lib/glimmer/config.rb +24 -12
- data/lib/glimmer/data_binding/observable_array.rb +225 -22
- data/lib/glimmer/data_binding/observable_model.rb +8 -6
- data/lib/glimmer/data_binding/observer.rb +4 -6
- data/lib/glimmer/dsl/engine.rb +35 -43
- data/lib/glimmer/dsl/expression_handler.rb +2 -3
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5296edf57183b7bffa288342e5c3c4ab14713dbd70af643bf8117f608314d2a
|
4
|
+
data.tar.gz: 5a9285de28140f0f7a94ed80ec9c6c597ae163a5fdce4f4ad8a060f5ad341775
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef36cf024e59cc0111d8f3a283c6d89134eea01390574962ef0b36ef89c75d482d6912b83fd1bfc609f40f262f72156df9ab8d8481ac41118bb799b1a718e473
|
7
|
+
data.tar.gz: 65c0d12d30f2ea846766d98bb91aa0b3ae86eaac11697532d6b3ed55a139816d0be797a94584297c40c949f8cff436dfa15cbc0176cbb652207bab452c148071
|
data/README.md
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
# <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 /> 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
|
+
[![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)
|
4
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)
|
5
7
|
|
6
|
-
**[Contributors Wanted!](#contributing)**
|
8
|
+
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
7
9
|
|
8
10
|
(The Original Glimmer Library Since 2007. Beware of Imitators!)
|
9
11
|
|
10
|
-
Glimmer is a native-GUI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a
|
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.
|
11
15
|
|
12
16
|
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
13
17
|
Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
|
@@ -16,13 +20,13 @@ Glimmer DSL gems:
|
|
16
20
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
17
21
|
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
18
22
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
19
|
-
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
23
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
20
24
|
|
21
25
|
## Examples
|
22
26
|
|
23
27
|
### Hello, World!
|
24
28
|
|
25
|
-
Glimmer code (from
|
29
|
+
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
|
26
30
|
```ruby
|
27
31
|
include Glimmer
|
28
32
|
|
@@ -45,28 +49,28 @@ Glimmer app:
|
|
45
49
|
|
46
50
|
### Tic Tac Toe
|
47
51
|
|
48
|
-
Glimmer code (from
|
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)):
|
49
53
|
|
50
54
|
```ruby
|
51
55
|
# ...
|
52
|
-
shell {
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
+
}
|
64
70
|
}
|
65
71
|
}
|
66
72
|
}
|
67
73
|
}
|
68
|
-
}
|
69
|
-
}
|
70
74
|
# ...
|
71
75
|
```
|
72
76
|
|
@@ -80,11 +84,99 @@ Glimmer app:
|
|
80
84
|
|
81
85
|
![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
|
82
86
|
|
83
|
-
|
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)
|
84
176
|
|
85
177
|
## Table of contents
|
86
178
|
|
87
|
-
- [Glimmer
|
179
|
+
- [Glimmer (Ruby Desktop Development GUI Library)](#-glimmer-ruby-desktop-development-gui-library)
|
88
180
|
- [Examples](#examples)
|
89
181
|
- [Hello, World!](#hello-world)
|
90
182
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -103,13 +195,21 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
103
195
|
- [Custom Widget](#custom-widget)
|
104
196
|
- [Custom Shell Gem](#custom-shell-gem)
|
105
197
|
- [Custom Widget Gem](#custom-widget-gem)
|
198
|
+
- [Gem Listing](#gem-listing)
|
199
|
+
- [Listing Custom Shell Gems](#listing-custom-shell-gems)
|
200
|
+
- [Listing Custom Widget Gems](#listing-custom-widget-gems)
|
201
|
+
- [Listing DSL Gems](#listing-dsl-gems)
|
202
|
+
- [Packaging](#packaging)
|
203
|
+
- [Raw JRuby Command](#raw-jruby-command)
|
204
|
+
- [Mac Support](#mac-support)
|
106
205
|
- [Girb (Glimmer irb) Command](#girb-glimmer-irb-command)
|
107
|
-
- [Glimmer DSL Syntax](#glimmer-dsl-syntax)
|
206
|
+
- [Glimmer GUI DSL Syntax](#glimmer-gui-dsl-syntax)
|
108
207
|
- [Widgets](#widgets)
|
109
208
|
- [Display](#display)
|
110
209
|
- [SWT Proxies](#swt-proxies)
|
111
210
|
- [Dialog](#dialog)
|
112
211
|
- [Menus](#menus)
|
212
|
+
- [ScrolledComposite](#scrolledcomposite)
|
113
213
|
- [Widget Styles](#widget-styles)
|
114
214
|
- [Explicit SWT Style Bit](#explicit-swt-style-bit)
|
115
215
|
- [Negative SWT Style Bits](#negative-swt-style-bits)
|
@@ -135,26 +235,45 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
135
235
|
- [Content/Options Example](#contentoptions-example)
|
136
236
|
- [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
|
137
237
|
- [Gotcha](#gotcha)
|
238
|
+
- [Final Notes](#final-notes)
|
138
239
|
- [Custom Shells](#custom-shells)
|
240
|
+
- [Drag and Drop](#drag-and-drop)
|
139
241
|
- [Miscellaneous](#miscellaneous)
|
140
242
|
- [Multi-DSL Support](#multi-dsl-support)
|
141
243
|
- [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
|
142
244
|
- [App Name and Version](#app-name-and-version)
|
143
245
|
- [Video Widget](#video-widget)
|
144
246
|
- [Browser Widget](#browser-widget)
|
247
|
+
- [Glimmer Configuration](#glimmer-configuration)
|
248
|
+
- [logger](#logger)
|
249
|
+
- [import_swt_packages](#importswtpackages)
|
250
|
+
- [loop_max_count](#loopmaxcount)
|
145
251
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
252
|
+
- [SWT Reference](#swt-reference)
|
146
253
|
- [Samples](#samples)
|
147
254
|
- [Hello Samples](#hello-samples)
|
255
|
+
- [Hello, World! Sample](#hello-world-sample)
|
256
|
+
- [Hello, Tab!](#hello-tab)
|
257
|
+
- [Hello, Combo!](#hello-combo)
|
258
|
+
- [Hello, List Single Selection!](#hello-list-single-selection)
|
259
|
+
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
260
|
+
- [Hello, Computed!](#hello-computed)
|
261
|
+
- [Hello, Message Box!](#hello-message-box)
|
262
|
+
- [Hello, Browser!](#hello-browser)
|
263
|
+
- [Hello, Drag and Drop!](#hello-drag-and-drop)
|
264
|
+
- [Hello, Menu Bar!](#hello-menu-bar)
|
265
|
+
- [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
|
148
266
|
- [Elaborate Samples](#elaborate-samples)
|
267
|
+
- [Login](#login)
|
268
|
+
- [Tic Tac Toe Sample](#tic-tac-toe-sample)
|
269
|
+
- [Contact Manager](#contact-manager-sample)
|
149
270
|
- [External Samples](#external-samples)
|
150
271
|
- [Glimmer Calculator](#glimmer-calculator)
|
151
272
|
- [Gladiator](#gladiator)
|
152
273
|
- [In Production](#in-production)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
- [Raw JRuby Command](#raw-jruby-command)
|
157
|
-
- [Mac Support](#mac-support)
|
274
|
+
- [Math Bowling](#math-bowling)
|
275
|
+
- [Are We There Yet?](#are-we-there-yet)
|
276
|
+
- [Garderie Rainbow Daily Agenda](#garderie-rainbow-daily-agenda)
|
158
277
|
- [Packaging & Distribution](#packaging--distribution)
|
159
278
|
- [Packaging Defaults](#packaging-defaults)
|
160
279
|
- [Packaging Configuration](#packaging-configuration)
|
@@ -162,6 +281,7 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
162
281
|
- [Mac Application Distribution](#mac-application-distribution)
|
163
282
|
- [Self Signed Certificate](#self-signed-certificate)
|
164
283
|
- [Gotchas](#gotchas)
|
284
|
+
- [App Updates](#app-updates)
|
165
285
|
- [Resources](#resources)
|
166
286
|
- [Help](#help)
|
167
287
|
- [Issues](#issues)
|
@@ -170,6 +290,7 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
170
290
|
- [Change Log](#change-log)
|
171
291
|
- [Contributing](#contributing)
|
172
292
|
- [Contributors](#contributors)
|
293
|
+
- [Hire Me](#hire-me)
|
173
294
|
- [License](#license)
|
174
295
|
|
175
296
|
## Background
|
@@ -195,39 +316,52 @@ https://www.eclipse.org/swt/faq.php
|
|
195
316
|
|
196
317
|
## Pre-requisites
|
197
318
|
|
198
|
-
- SWT 4.
|
199
|
-
- JRuby 9.2.
|
200
|
-
- JDK 8
|
201
|
-
- (Optional) RVM is needed for [Scaffolding](#scaffolding) only (find at [https://rvm.io/](https://rvm.io/))
|
319
|
+
- SWT 4.16 (comes included in Glimmer gem)
|
320
|
+
- 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)
|
321
|
+
- JDK 8 (find at https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html)
|
202
322
|
|
203
|
-
|
323
|
+
To obtain JRuby through [RVM](http://rvm.io), you may run:
|
204
324
|
|
205
325
|
```bash
|
206
|
-
rvm install jruby-9.2.
|
326
|
+
rvm install jruby-9.2.13.0
|
207
327
|
```
|
208
328
|
|
209
|
-
Glimmer might still work on
|
329
|
+
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.
|
210
330
|
|
211
331
|
## Setup
|
212
332
|
|
213
333
|
Please follow these instructions to make the `glimmer` command available on your system via the [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem.
|
214
334
|
|
215
|
-
|
335
|
+
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)).
|
336
|
+
|
337
|
+
If you intend to build a Glimmer app from scratch with [scaffolding](#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
|
338
|
+
|
339
|
+
Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](#scaffolding).
|
340
|
+
|
341
|
+
### Option 1: Direct Install
|
342
|
+
(Use for [Scaffolding](#scaffolding))
|
216
343
|
|
217
344
|
Run this command to install directly:
|
218
345
|
```
|
219
|
-
jgem install glimmer-dsl-swt -v 0.1
|
346
|
+
jgem install glimmer-dsl-swt -v 0.6.1
|
220
347
|
```
|
221
348
|
|
222
349
|
`jgem` is JRuby's version of `gem` command.
|
223
350
|
RVM allows running `gem` as an alias.
|
224
351
|
Otherwise, you may also run `jruby -S gem install ...`
|
225
352
|
|
226
|
-
|
353
|
+
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.
|
354
|
+
|
355
|
+
Otherwise, if you are ready to build a Glimmer app on the Mac, you can jump to the [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer#scaffolding) section next.
|
356
|
+
|
357
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
358
|
+
|
359
|
+
### Option 2: Bundler
|
360
|
+
(Use for Manual App Creation)
|
227
361
|
|
228
362
|
Add the following to `Gemfile`:
|
229
363
|
```
|
230
|
-
gem 'glimmer-dsl-swt', '~> 0.1
|
364
|
+
gem 'glimmer-dsl-swt', '~> 0.6.1'
|
231
365
|
```
|
232
366
|
|
233
367
|
And, then run:
|
@@ -235,10 +369,16 @@ And, then run:
|
|
235
369
|
jruby -S bundle install
|
236
370
|
```
|
237
371
|
|
372
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
373
|
+
|
238
374
|
You may learn more about other Glimmer related gems ([`glimmer-dsl-opal`](https://github.com/AndyObtiva/glimmer-dsl-opal), [`glimmer-dsl-xml`](https://github.com/AndyObtiva/glimmer-dsl-xml), and [`glimmer-dsl-css`](https://github.com/AndyObtiva/glimmer-dsl-css)) at [Multi-DSL Support](#multi-dsl-support)
|
239
375
|
|
240
376
|
## Glimmer Command
|
241
377
|
|
378
|
+
The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
|
379
|
+
|
380
|
+
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).
|
381
|
+
|
242
382
|
### Basic Usage
|
243
383
|
|
244
384
|
```
|
@@ -275,15 +415,20 @@ Either a single task or one or more applications may be specified.
|
|
275
415
|
When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
|
276
416
|
|
277
417
|
Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
|
278
|
-
glimmer
|
279
|
-
glimmer
|
280
|
-
glimmer
|
281
|
-
glimmer package
|
282
|
-
glimmer
|
283
|
-
glimmer
|
284
|
-
glimmer
|
285
|
-
glimmer
|
286
|
-
glimmer
|
418
|
+
glimmer list:gems:customshell[query] # List Glimmer custom shell gems available at rubygems.org (query is optional) [alt: list:gems:cs]
|
419
|
+
glimmer list:gems:customwidget[query] # List Glimmer custom widget gems available at rubygems.org (query is optional) [alt: list:gems:cw]
|
420
|
+
glimmer list:gems:dsl[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
421
|
+
glimmer package[type] # Package app for distribution (generating config, jar, and native files) (type is optional)
|
422
|
+
glimmer package:clean # Clean by removing "dist" and "packages" directories
|
423
|
+
glimmer package:config # Generate JAR config file
|
424
|
+
glimmer package:jar # Generate JAR file
|
425
|
+
glimmer package:lock_jars # Lock JARs
|
426
|
+
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)
|
427
|
+
glimmer scaffold[app_name] # Scaffold Glimmer application directory structure to build a new app
|
428
|
+
glimmer scaffold:customshell[name,namespace] # Scaffold Glimmer::UI::CustomShell subclass (full window view) under app/views (namespace is optional) [alt: scaffold:cs]
|
429
|
+
glimmer scaffold:customwidget[name,namespace] # Scaffold Glimmer::UI::CustomWidget subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cw]
|
430
|
+
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]
|
431
|
+
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]
|
287
432
|
|
288
433
|
When applications are specified, they are run using JRuby,
|
289
434
|
automatically preloading the glimmer Ruby gem and SWT jar dependency.
|
@@ -325,7 +470,7 @@ getting you to a running and delivered state of an advanced "Hello, World!" Glim
|
|
325
470
|
This should greatly facilitate building a new Glimmer app by helping you be productive and focus on app details while
|
326
471
|
letting Glimmer scaffolding take care of initial app file structure concerns, such as adding:
|
327
472
|
- Main application class that includes Glimmer
|
328
|
-
- Main application view that houses main window content, about dialog, and preferences dialog
|
473
|
+
- Main application view that houses main window content, menu, about dialog, and preferences dialog
|
329
474
|
- View and Model directories
|
330
475
|
- Rakefile including Glimmer tasks
|
331
476
|
- Version
|
@@ -333,7 +478,7 @@ letting Glimmer scaffolding take care of initial app file structure concerns, su
|
|
333
478
|
- Icon
|
334
479
|
- Bin file for starting application
|
335
480
|
|
336
|
-
NOTE: Scaffolding
|
481
|
+
NOTE: Scaffolding supports Mac and Windows packaging at the moment.
|
337
482
|
|
338
483
|
#### App
|
339
484
|
|
@@ -369,16 +514,35 @@ Created CarMaker/bin/car_maker
|
|
369
514
|
...
|
370
515
|
```
|
371
516
|
|
372
|
-
Eventually, it will launch an advanced "Hello, World!" app window having the title of your application
|
517
|
+
Eventually, it will launch an advanced "Hello, World!" app window having the title of your application.
|
373
518
|
|
374
519
|
![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
|
375
520
|
|
521
|
+
It also comes with a boilerplate Preferences dialog.
|
522
|
+
|
523
|
+
![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
|
524
|
+
|
525
|
+
Here is a Windows scaffolded app called Greeter:
|
526
|
+
|
527
|
+
![Glimmer Scaffold App Windows](images/glimmer-scaffolding-app-windows.png)
|
528
|
+
|
529
|
+
Here is the Windows version of the boilerplate Preferences dialog.
|
530
|
+
|
531
|
+
![Glimmer Scaffold App Windows Preferences](images/glimmer-scaffolding-app-windows-preferences.png)
|
532
|
+
|
533
|
+
|
376
534
|
#### Custom Shell
|
377
535
|
|
378
536
|
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
|
379
537
|
|
380
538
|
```
|
381
|
-
glimmer scaffold:
|
539
|
+
glimmer scaffold:customshell[name]
|
540
|
+
```
|
541
|
+
|
542
|
+
Or the following alternative abbreviation:
|
543
|
+
|
544
|
+
```
|
545
|
+
glimmer scaffold:cs[name]
|
382
546
|
```
|
383
547
|
|
384
548
|
#### Custom Widget
|
@@ -386,13 +550,19 @@ glimmer scaffold:custom_shell[custom_shell_name]
|
|
386
550
|
To scaffold a Glimmer custom widget (part of a view) for an existing Glimmer app, run the following command:
|
387
551
|
|
388
552
|
```
|
389
|
-
glimmer scaffold:
|
553
|
+
glimmer scaffold:customwidget[name]
|
554
|
+
```
|
555
|
+
|
556
|
+
Or the following alternative abbreviation:
|
557
|
+
|
558
|
+
```
|
559
|
+
glimmer scaffold:cw[name]
|
390
560
|
```
|
391
561
|
|
392
562
|
#### Custom Shell Gem
|
393
563
|
|
394
564
|
Custom shell gems are self-contained Glimmer apps as well as reusable custom shells.
|
395
|
-
They have everything scaffolded Glimmer apps come with in addition to gem content like a
|
565
|
+
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.
|
396
566
|
Unlike scaffolded Glimmer apps, custom shell gem content lives under the `lib` directory (not `app`).
|
397
567
|
They can be packaged as both a native executable (e.g. Mac DMG/PKG/APP) and a Ruby gem.
|
398
568
|
Of course, you can just build a Ruby gem and disregard native executable packaging if you do not need it.
|
@@ -400,7 +570,13 @@ Of course, you can just build a Ruby gem and disregard native executable packagi
|
|
400
570
|
To scaffold a Glimmer custom shell gem (full window view distributed as a Ruby gem), run the following command:
|
401
571
|
|
402
572
|
```
|
403
|
-
glimmer scaffold:
|
573
|
+
glimmer scaffold:gem:customshell[name,namespace]
|
574
|
+
```
|
575
|
+
|
576
|
+
Or the following alternative abbreviation:
|
577
|
+
|
578
|
+
```
|
579
|
+
glimmer scaffold:gem:cs[name,namespace]
|
404
580
|
```
|
405
581
|
|
406
582
|
It is important to specify a namespace to avoid having your gem clash with existing gems.
|
@@ -419,16 +595,157 @@ Examples:
|
|
419
595
|
To scaffold a Glimmer custom widget gem (part of a view distributed as a Ruby gem), run the following command:
|
420
596
|
|
421
597
|
```
|
422
|
-
glimmer scaffold:
|
598
|
+
glimmer scaffold:gem:customwidget[name,namespace]
|
599
|
+
```
|
600
|
+
|
601
|
+
Or the following alternative abbreviation:
|
602
|
+
|
603
|
+
```
|
604
|
+
glimmer scaffold:gem:cw[name,namespace]
|
423
605
|
```
|
424
606
|
|
607
|
+
|
425
608
|
It is important to specify a namespace to avoid having your gem clash with existing gems.
|
426
609
|
|
427
610
|
The Ruby gem name will follow the convention "glimmer-cw-customwidgetname-namespace" (the 'cw' is for Custom Widget)
|
428
611
|
|
429
612
|
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)
|
430
613
|
|
431
|
-
|
614
|
+
Examples:
|
615
|
+
|
616
|
+
- [glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video): Video Widget
|
617
|
+
- [glimmer-cw-cdatetime-nebula](https://github.com/AndyObtiva/glimmer-cw-cdatetime-nebula): Nebula CDateTime Widget
|
618
|
+
|
619
|
+
### Gem Listing
|
620
|
+
|
621
|
+
The `glimmer` command comes with tasks for listing Glimmer related gems to make it easy to find Glimmer Custom Shells, Custom Widgets, and DSLs published by others in the Glimmer community on [rubygems.org](http://www.rubygems.org).
|
622
|
+
|
623
|
+
#### Listing Custom Shell Gems
|
624
|
+
|
625
|
+
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):
|
626
|
+
|
627
|
+
```
|
628
|
+
glimmer list:gems:customshell[query]
|
629
|
+
```
|
630
|
+
|
631
|
+
Or the following alternative abbreviation:
|
632
|
+
|
633
|
+
```
|
634
|
+
glimmer list:gems:cs[query]
|
635
|
+
```
|
636
|
+
|
637
|
+
Example:
|
638
|
+
|
639
|
+
```
|
640
|
+
glimmer list:gems:cs
|
641
|
+
```
|
642
|
+
|
643
|
+
Output:
|
644
|
+
|
645
|
+
```
|
646
|
+
|
647
|
+
Glimmer Custom Shell Gems at rubygems.org:
|
648
|
+
|
649
|
+
Name Gem Version Author Description
|
650
|
+
|
651
|
+
Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
|
652
|
+
Gladiator glimmer-cs-gladiator 0.2.3 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
|
653
|
+
|
654
|
+
```
|
655
|
+
|
656
|
+
#### Listing Custom Widget Gems
|
657
|
+
|
658
|
+
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):
|
659
|
+
|
660
|
+
```
|
661
|
+
glimmer list:gems:customwidget[query]
|
662
|
+
```
|
663
|
+
|
664
|
+
Or the following alternative abbreviation:
|
665
|
+
|
666
|
+
```
|
667
|
+
glimmer list:gems:cw[query]
|
668
|
+
```
|
669
|
+
|
670
|
+
Example:
|
671
|
+
|
672
|
+
Check if there is a custom video widget for Glimmer.
|
673
|
+
|
674
|
+
```
|
675
|
+
glimmer list:gems:cw[video]
|
676
|
+
```
|
677
|
+
|
678
|
+
Output:
|
679
|
+
|
680
|
+
```
|
681
|
+
|
682
|
+
Glimmer Custom Widget Gems matching [video] at rubygems.org:
|
683
|
+
|
684
|
+
Name Gem Version Author Description
|
685
|
+
|
686
|
+
Video glimmer-cw-video 0.1.3 Andy Maleh Glimmer Custom Widget - Video
|
687
|
+
|
688
|
+
```
|
689
|
+
|
690
|
+
#### Listing DSL Gems
|
691
|
+
|
692
|
+
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):
|
693
|
+
|
694
|
+
```
|
695
|
+
glimmer list:gems:dsl[query]
|
696
|
+
```
|
697
|
+
|
698
|
+
Example:
|
699
|
+
|
700
|
+
```
|
701
|
+
glimmer list:gems:dsl
|
702
|
+
```
|
703
|
+
|
704
|
+
Output:
|
705
|
+
|
706
|
+
```
|
707
|
+
|
708
|
+
Glimmer DSL Gems at rubygems.org:
|
709
|
+
|
710
|
+
Name Gem Version Author Description
|
711
|
+
|
712
|
+
Css glimmer-dsl-css 0.2.0 AndyMaleh Glimmer DSL for CSS
|
713
|
+
Opal glimmer-dsl-opal 0.1.0 AndyMaleh Glimmer DSL for Opal
|
714
|
+
Swt glimmer-dsl-swt 0.6.1 AndyMaleh Glimmer DSL for SWT
|
715
|
+
Xml glimmer-dsl-xml 0.2.0 AndyMaleh Glimmer DSL for XML
|
716
|
+
|
717
|
+
```
|
718
|
+
|
719
|
+
### Packaging
|
720
|
+
|
721
|
+
Glimmer packaging tasks are detailed under [Packaging & Distribution](#packaging--distribution).
|
722
|
+
|
723
|
+
### Raw JRuby Command
|
724
|
+
|
725
|
+
If there is a need to run Glimmer directly via the `jruby` command, you
|
726
|
+
may run the following:
|
727
|
+
|
728
|
+
```
|
729
|
+
jruby -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
730
|
+
```
|
731
|
+
|
732
|
+
The `-J-classpath` option specifies the `swt.jar` file path, which can be a
|
733
|
+
manually downloaded version of SWT, or otherwise the one included in the gem. You can lookup the one included in the gem by running `jgem which glimmer` to find the gem path and then look through the `vendor` directory.
|
734
|
+
|
735
|
+
The `-r` option preloads (requires) the `glimmer` library in Ruby.
|
736
|
+
|
737
|
+
The `-S` option specifies a script to run.
|
738
|
+
|
739
|
+
#### Mac Support
|
740
|
+
|
741
|
+
The Mac is well supported with the `glimmer` command. The advice below is not needed if you are using it.
|
742
|
+
|
743
|
+
However, if there is a reason to use the raw `jruby` command directly instead of the `glimmer` command, you need to pass an extra option (`-J-XstartOnFirstThread`) to JRuby on the Mac (Glimmer automatically passes it for you when using the `glimmer` command).
|
744
|
+
|
745
|
+
Example:
|
746
|
+
```
|
747
|
+
jruby -J-XstartOnFirstThread -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
748
|
+
```
|
432
749
|
|
433
750
|
## Girb (Glimmer irb) Command
|
434
751
|
|
@@ -448,17 +765,28 @@ Watch out for hands-on examples in this README indicated by "you may copy/paste
|
|
448
765
|
|
449
766
|
Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
|
450
767
|
|
451
|
-
## Glimmer DSL Syntax
|
768
|
+
## Glimmer GUI DSL Syntax
|
452
769
|
|
453
|
-
Glimmer DSL
|
770
|
+
Glimmer is mainly a GUI DSL with a lightweight visual syntax that makes it easy to visualize the nesting of widgets in the GUI hierarchy tree.
|
454
771
|
|
455
|
-
|
772
|
+
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.
|
456
773
|
|
457
|
-
|
774
|
+
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)
|
458
775
|
|
459
|
-
|
776
|
+
Glimmer DSL syntax consists mainly of:
|
777
|
+
- keywords (e.g. `table` for a table widget)
|
778
|
+
- style/args (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
|
779
|
+
- 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)
|
460
780
|
|
461
|
-
|
781
|
+
Glimmer keywords may be static or dynamic.
|
782
|
+
|
783
|
+
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `display`, `message_box`, `async_exec`, `sync_exec`, and `bind`.
|
784
|
+
|
785
|
+
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.
|
786
|
+
|
787
|
+
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.
|
788
|
+
|
789
|
+
For example, if a project adds this custom Java SWT library:
|
462
790
|
|
463
791
|
https://www.eclipse.org/nebula/widgets/cdatetime/cdatetime.php?page=operation
|
464
792
|
|
@@ -474,9 +802,9 @@ https://www.eclipse.org/swt/widgets/
|
|
474
802
|
|
475
803
|
This screenshot taken from the link above should give a glimpse of how SWT widgets look and feel:
|
476
804
|
|
477
|
-
![SWT Widgets](images/glimmer-swt-widgets.png)
|
805
|
+
[![SWT Widgets](images/glimmer-swt-widgets.png)](https://www.eclipse.org/swt/widgets/)
|
478
806
|
|
479
|
-
In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name:
|
807
|
+
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:
|
480
808
|
|
481
809
|
- `shell` instantiates `org.eclipse.swt.widgets.Shell`
|
482
810
|
- `text` instantiates `org.eclipse.swt.widgets.Text`
|
@@ -492,8 +820,8 @@ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring
|
|
492
820
|
- `list` instantiates `org.eclipse.swt.widgets.List`
|
493
821
|
|
494
822
|
Every **widget** is sufficiently declared by name, but may optionally be accompanied with:
|
495
|
-
- SWT **style
|
496
|
-
- Ruby block containing **properties** (
|
823
|
+
- SWT **style**/***arguments*** wrapped by parenthesis according to [Glimmer Style Guide](#glimmer-style-guide) (see [next section](#widget-styles) for details).
|
824
|
+
- Ruby block containing **content**, which may be **properties** (e.g. `enabled false`) or nested **widgets** (e.g. `table_column` nested inside `table`)
|
497
825
|
|
498
826
|
For example, if we were to revisit `samples/hello/hello_world.rb` above (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
499
827
|
|
@@ -575,6 +903,8 @@ shell {
|
|
575
903
|
}.open
|
576
904
|
```
|
577
905
|
|
906
|
+
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.
|
907
|
+
|
578
908
|
#### Display
|
579
909
|
|
580
910
|
SWT Display is a singleton in Glimmer. It is used in SWT to represent your display device, allowing you to manage GUI globally
|
@@ -586,7 +916,7 @@ automatically uses the display created earlier without having to explicitly hook
|
|
586
916
|
```ruby
|
587
917
|
@display = display {
|
588
918
|
cursor_location 300, 300
|
589
|
-
|
919
|
+
on_swt_keydown {
|
590
920
|
# ...
|
591
921
|
}
|
592
922
|
# ...
|
@@ -638,27 +968,49 @@ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
638
968
|
@shell.open
|
639
969
|
```
|
640
970
|
|
641
|
-
#####
|
971
|
+
##### `message_box`
|
642
972
|
|
643
|
-
Glimmer
|
973
|
+
The Glimmer DSL `message_box` keyword is similar to `shell`, but renders a modal dialog with a title `text` property and main body `message` property. It may also be opened via the `#open` method.
|
644
974
|
|
645
975
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
646
976
|
|
647
977
|
```ruby
|
978
|
+
include Glimmer
|
979
|
+
|
648
980
|
@shell = shell {
|
981
|
+
text 'Hello, Message Box!'
|
649
982
|
button {
|
650
|
-
text
|
983
|
+
text 'Please Click To Win a Surprise'
|
651
984
|
on_widget_selected {
|
652
|
-
message_box
|
653
|
-
|
654
|
-
|
655
|
-
|
985
|
+
message_box(@shell) {
|
986
|
+
text 'Surprise'
|
987
|
+
message "Congratulations!\n\nYou have won $1,000,000!"
|
988
|
+
}.open
|
656
989
|
}
|
657
990
|
}
|
658
991
|
}
|
659
992
|
@shell.open
|
660
993
|
```
|
661
994
|
|
995
|
+
![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
|
996
|
+
|
997
|
+
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):
|
998
|
+
|
999
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1000
|
+
|
1001
|
+
```ruby
|
1002
|
+
include Glimmer
|
1003
|
+
|
1004
|
+
message_box {
|
1005
|
+
text 'Greeting'
|
1006
|
+
message "Hello, World!"
|
1007
|
+
}.open
|
1008
|
+
```
|
1009
|
+
|
1010
|
+
##### `#swt_widget`
|
1011
|
+
|
1012
|
+
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.
|
1013
|
+
|
662
1014
|
##### Shell widget proxy methods
|
663
1015
|
|
664
1016
|
Shell widget proxy has extra methods specific to SWT Shell:
|
@@ -674,6 +1026,24 @@ Shell widget proxy has extra methods specific to SWT Shell:
|
|
674
1026
|
- `#pack`: Packs contained widgets using SWT's `Shell#pack` method
|
675
1027
|
- `#pack_same_size`: Packs contained widgets without changing shell's size when widget sizes change
|
676
1028
|
|
1029
|
+
##### Shell Icon
|
1030
|
+
|
1031
|
+
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)
|
1032
|
+
|
1033
|
+
Example:
|
1034
|
+
|
1035
|
+
```ruby
|
1036
|
+
shell {
|
1037
|
+
# ...
|
1038
|
+
image 'path/to/image.png'
|
1039
|
+
# ...
|
1040
|
+
}
|
1041
|
+
```
|
1042
|
+
|
1043
|
+
###### Shell Icon Tip for Packaging on Windows
|
1044
|
+
|
1045
|
+
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'`)
|
1046
|
+
|
677
1047
|
#### Dialog
|
678
1048
|
|
679
1049
|
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.
|
@@ -686,7 +1056,7 @@ Glimmer DSL provides support for SWT Menu and MenuItem widgets.
|
|
686
1056
|
|
687
1057
|
There are 2 main types of menus in SWT:
|
688
1058
|
- Menu Bar (shows up on top)
|
689
|
-
- Pop Up Menu (shows up when right-clicking a widget)
|
1059
|
+
- Pop Up Context Menu (shows up when right-clicking a widget)
|
690
1060
|
|
691
1061
|
Underneath both types, there can be a 3rd menu type called Drop Down.
|
692
1062
|
|
@@ -694,39 +1064,63 @@ Glimmer provides special support for Drop Down menus as it automatically instant
|
|
694
1064
|
|
695
1065
|
The ampersand symbol indicates the keyboard shortcut key for the menu item (e.g. '&Help' can be triggered on Windows by hitting ALT+H)
|
696
1066
|
|
697
|
-
Example
|
1067
|
+
Example of a Menu Bar (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
698
1068
|
|
699
1069
|
```ruby
|
700
|
-
shell {
|
1070
|
+
shell { |shell_proxy|
|
1071
|
+
text 'Hello, Menu Bar!'
|
1072
|
+
grid_layout
|
1073
|
+
label(:center) {
|
1074
|
+
font height: 16
|
1075
|
+
text 'Check Out The File Menu and History Menu in The Menu Bar Above!'
|
1076
|
+
}
|
701
1077
|
menu_bar {
|
702
1078
|
menu {
|
703
|
-
text
|
1079
|
+
text '&File'
|
704
1080
|
menu_item {
|
705
|
-
text
|
1081
|
+
text 'E&xit'
|
706
1082
|
}
|
707
1083
|
menu_item(0) {
|
708
|
-
text
|
1084
|
+
text '&New'
|
1085
|
+
on_widget_selected {
|
1086
|
+
message_box(shell_proxy) {
|
1087
|
+
text 'New File'
|
1088
|
+
message 'New File Contents'
|
1089
|
+
}.open
|
1090
|
+
}
|
709
1091
|
}
|
710
1092
|
menu(1) {
|
711
|
-
text
|
1093
|
+
text '&Options'
|
712
1094
|
menu_item(:radio) {
|
713
|
-
text
|
1095
|
+
text 'Option 1'
|
714
1096
|
}
|
715
1097
|
menu_item(:separator)
|
716
1098
|
menu_item(:check) {
|
717
|
-
text
|
1099
|
+
text 'Option 3'
|
718
1100
|
}
|
719
1101
|
}
|
720
1102
|
}
|
721
1103
|
menu {
|
722
|
-
text
|
1104
|
+
text '&History'
|
723
1105
|
menu {
|
724
|
-
text
|
1106
|
+
text '&Recent'
|
725
1107
|
menu_item {
|
726
|
-
text
|
1108
|
+
text 'File 1'
|
1109
|
+
on_widget_selected {
|
1110
|
+
message_box(shell_proxy) {
|
1111
|
+
text 'File 1'
|
1112
|
+
message 'File 1 Contents'
|
1113
|
+
}.open
|
1114
|
+
}
|
727
1115
|
}
|
728
1116
|
menu_item {
|
729
|
-
text
|
1117
|
+
text 'File 2'
|
1118
|
+
on_widget_selected {
|
1119
|
+
message_box(shell_proxy) {
|
1120
|
+
text 'File 2'
|
1121
|
+
message 'File 2 Contents'
|
1122
|
+
}.open
|
1123
|
+
}
|
730
1124
|
}
|
731
1125
|
}
|
732
1126
|
}
|
@@ -734,22 +1128,37 @@ shell {
|
|
734
1128
|
}.open
|
735
1129
|
```
|
736
1130
|
|
737
|
-
Example
|
1131
|
+
Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
738
1132
|
|
739
1133
|
```ruby
|
740
|
-
shell {
|
1134
|
+
shell { |shell_proxy|
|
1135
|
+
text 'Hello, Pop Up Context Menu!'
|
1136
|
+
grid_layout
|
741
1137
|
label {
|
742
|
-
|
1138
|
+
font height: 16
|
1139
|
+
text 'Right-Click To Pop Up a Context Menu'
|
743
1140
|
menu {
|
744
1141
|
menu {
|
745
1142
|
text '&History'
|
746
1143
|
menu {
|
747
|
-
text
|
1144
|
+
text '&Recent'
|
748
1145
|
menu_item {
|
749
|
-
text
|
1146
|
+
text 'File 1'
|
1147
|
+
on_widget_selected {
|
1148
|
+
message_box(shell_proxy) {
|
1149
|
+
text 'File 1'
|
1150
|
+
message 'File 1 Contents'
|
1151
|
+
}.open
|
1152
|
+
}
|
750
1153
|
}
|
751
1154
|
menu_item {
|
752
|
-
text
|
1155
|
+
text 'File 2'
|
1156
|
+
on_widget_selected {
|
1157
|
+
message_box(shell_proxy) {
|
1158
|
+
text 'File 2'
|
1159
|
+
message 'File 2 Contents'
|
1160
|
+
}.open
|
1161
|
+
}
|
753
1162
|
}
|
754
1163
|
}
|
755
1164
|
}
|
@@ -758,6 +1167,13 @@ shell {
|
|
758
1167
|
}.open
|
759
1168
|
```
|
760
1169
|
|
1170
|
+
#### ScrolledComposite
|
1171
|
+
|
1172
|
+
Glimmer provides smart defaults for the `scrolled_composite` widget by:
|
1173
|
+
- Automatically setting the nested widget as its content (meaning use can just like a plain old `composite` to add scrolling)
|
1174
|
+
- 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 )
|
1175
|
+
- Automatically setting the expand horizontal and expand vertical SWT properties to `true`
|
1176
|
+
|
761
1177
|
### Widget Styles
|
762
1178
|
|
763
1179
|
SWT widgets receive `SWT` styles in their constructor as per this guide:
|
@@ -803,7 +1219,7 @@ text(:center, :border) { # Multiple SWT styles separated by comma
|
|
803
1219
|
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):
|
804
1220
|
|
805
1221
|
- `text(:border)`
|
806
|
-
- `table(:border)`
|
1222
|
+
- `table(:border, :virtual, :full_selection)`
|
807
1223
|
- `tree(:border, :virtual, :v_scroll, :h_scroll)`
|
808
1224
|
- `spinner(:border)`
|
809
1225
|
- `list(:border, :v_scroll)`
|
@@ -879,7 +1295,7 @@ button {
|
|
879
1295
|
|
880
1296
|
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)
|
881
1297
|
|
882
|
-
####
|
1298
|
+
#### Color
|
883
1299
|
|
884
1300
|
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.
|
885
1301
|
|
@@ -928,7 +1344,7 @@ Example:
|
|
928
1344
|
color(:black).swt_color # returns SWT Color object
|
929
1345
|
```
|
930
1346
|
|
931
|
-
####
|
1347
|
+
#### Font
|
932
1348
|
|
933
1349
|
Fonts are represented in Glimmer as a hash of name, height, and style keys.
|
934
1350
|
|
@@ -957,7 +1373,34 @@ label {
|
|
957
1373
|
# ...
|
958
1374
|
```
|
959
1375
|
|
960
|
-
|
1376
|
+
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.
|
1377
|
+
|
1378
|
+
Example:
|
1379
|
+
|
1380
|
+
```ruby
|
1381
|
+
@font = font(name: 'Arial', height: 36, style: :normal)
|
1382
|
+
```
|
1383
|
+
|
1384
|
+
### Cursor
|
1385
|
+
|
1386
|
+
SWT widget `cursor` property represents the mouse cursor you see on the screen when you hover over that widget.
|
1387
|
+
|
1388
|
+
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)
|
1389
|
+
|
1390
|
+
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.
|
1391
|
+
|
1392
|
+
Example:
|
1393
|
+
|
1394
|
+
```ruby
|
1395
|
+
shell {
|
1396
|
+
minimum_size 128, 128
|
1397
|
+
cursor :appstarting
|
1398
|
+
}
|
1399
|
+
```
|
1400
|
+
|
1401
|
+
This sets the shell `cursor` to that of `SWT::CURSOR_APPSTARTING`
|
1402
|
+
|
1403
|
+
### Layout
|
961
1404
|
|
962
1405
|
Glimmer lays widgets out visually using SWT layouts, which can only be set on composite widget and subclasses.
|
963
1406
|
|
@@ -1008,7 +1451,7 @@ Here is a more sophisticated example taken from [hello_computed.rb](samples/hell
|
|
1008
1451
|
|
1009
1452
|
```ruby
|
1010
1453
|
shell {
|
1011
|
-
text
|
1454
|
+
text 'Hello, Computed!'
|
1012
1455
|
composite {
|
1013
1456
|
grid_layout {
|
1014
1457
|
num_columns 2
|
@@ -1016,44 +1459,44 @@ shell {
|
|
1016
1459
|
horizontal_spacing 20
|
1017
1460
|
vertical_spacing 10
|
1018
1461
|
}
|
1019
|
-
label {text
|
1462
|
+
label {text 'First &Name: '}
|
1020
1463
|
text {
|
1021
1464
|
text bind(@contact, :first_name)
|
1022
1465
|
layout_data {
|
1023
|
-
|
1024
|
-
|
1466
|
+
horizontal_alignment :fill
|
1467
|
+
grab_excess_horizontal_space true
|
1025
1468
|
}
|
1026
1469
|
}
|
1027
|
-
label {text
|
1470
|
+
label {text '&Last Name: '}
|
1028
1471
|
text {
|
1029
1472
|
text bind(@contact, :last_name)
|
1030
1473
|
layout_data {
|
1031
|
-
|
1032
|
-
|
1474
|
+
horizontal_alignment :fill
|
1475
|
+
grab_excess_horizontal_space true
|
1033
1476
|
}
|
1034
1477
|
}
|
1035
|
-
label {text
|
1478
|
+
label {text '&Year of Birth: '}
|
1036
1479
|
text {
|
1037
1480
|
text bind(@contact, :year_of_birth)
|
1038
1481
|
layout_data {
|
1039
|
-
|
1040
|
-
|
1482
|
+
horizontal_alignment :fill
|
1483
|
+
grab_excess_horizontal_space true
|
1041
1484
|
}
|
1042
1485
|
}
|
1043
|
-
label {text
|
1486
|
+
label {text 'Name: '}
|
1044
1487
|
label {
|
1045
1488
|
text bind(@contact, :name, computed_by: [:first_name, :last_name])
|
1046
1489
|
layout_data {
|
1047
|
-
|
1048
|
-
|
1490
|
+
horizontal_alignment :fill
|
1491
|
+
grab_excess_horizontal_space true
|
1049
1492
|
}
|
1050
1493
|
}
|
1051
|
-
label {text
|
1494
|
+
label {text 'Age: '}
|
1052
1495
|
label {
|
1053
1496
|
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
|
1054
1497
|
layout_data {
|
1055
|
-
|
1056
|
-
|
1498
|
+
horizontal_alignment :fill
|
1499
|
+
grab_excess_horizontal_space true
|
1057
1500
|
}
|
1058
1501
|
}
|
1059
1502
|
}
|
@@ -1196,6 +1639,10 @@ Example from [samples/hello/hello_combo.rb](samples/hello_combo.rb) sample (you
|
|
1196
1639
|
|
1197
1640
|
#### Combo
|
1198
1641
|
|
1642
|
+
The `combo` widget provides a dropdown of options. By default, it also allows typing in a new option. To disable that behavior, you may use with the `:read_only` SWT style.
|
1643
|
+
|
1644
|
+
When data-binding a `combo` widget, Glimmer can automatically deduce available options from data-bound model by convention: `{attribute_name}_options` method.
|
1645
|
+
|
1199
1646
|
![Hello Combo](images/glimmer-hello-combo.png)
|
1200
1647
|
|
1201
1648
|
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
@@ -1237,7 +1684,7 @@ end
|
|
1237
1684
|
HelloCombo.new.launch
|
1238
1685
|
```
|
1239
1686
|
|
1240
|
-
`combo` widget is data-bound to the country of a person. Note that it expects `person` object to have `:country` attribute and `:country_options` attribute containing all available countries.
|
1687
|
+
`combo` widget is data-bound to the country of a person. Note that it expects the `person` object to have the `:country` attribute and `:country_options` attribute containing all available countries (aka options). Glimmer reads these attributes by convention.
|
1241
1688
|
|
1242
1689
|
#### List
|
1243
1690
|
|
@@ -1351,6 +1798,9 @@ shell {
|
|
1351
1798
|
}
|
1352
1799
|
items bind(group, :people), column_properties(:name, :age, :adult)
|
1353
1800
|
selection bind(group, :selected_person)
|
1801
|
+
on_mouse_up { |event|
|
1802
|
+
@table.edit_table_item(event.table_item, event.column_index)
|
1803
|
+
}
|
1354
1804
|
}
|
1355
1805
|
}
|
1356
1806
|
```
|
@@ -1358,6 +1808,7 @@ shell {
|
|
1358
1808
|
The code above includes two data-bindings:
|
1359
1809
|
- 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.
|
1360
1810
|
- 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)
|
1811
|
+
- 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.)
|
1361
1812
|
|
1362
1813
|
Additionally, Table `items` data-binding automatically stores each node model unto the SWT TableItem object via `setData` method. This enables things like searchability.
|
1363
1814
|
|
@@ -1377,38 +1828,99 @@ This automatically leverages the SWT TableEditor custom class behind the scenes,
|
|
1377
1828
|
passed table item text into something else.
|
1378
1829
|
It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
1379
1830
|
|
1380
|
-
|
1381
|
-
|
1382
|
-
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
1383
|
-
|
1384
|
-
To data-bind a Tree, you need the root model, the children querying method, and the text display attribute on each child.
|
1831
|
+
##### Table Sorting
|
1385
1832
|
|
1386
|
-
|
1833
|
+
Glimmer automatically adds sorting support to the SWT `Table` widget.
|
1387
1834
|
|
1388
|
-
|
1835
|
+
Check out the [Contact Manager](#contact-manager) sample for an example.
|
1836
|
+
You may click on any column and it will sort by ascending order first and descending if you click again.
|
1389
1837
|
|
1390
|
-
|
1391
|
-
shell {
|
1392
|
-
@tree = tree {
|
1393
|
-
items bind(company, :owner), tree_properties(children: :coworkers, text: :name)
|
1394
|
-
selection bind(company, :selected_coworker)
|
1395
|
-
}
|
1396
|
-
}
|
1397
|
-
```
|
1838
|
+
Glimmer automatic table sorting supports `String`, `Integer`, and `Float` columns out of the box as well as any column data that is comparable.
|
1398
1839
|
|
1399
|
-
|
1400
|
-
- Tree `items`, which first bind to the root node (company.owner), and then dig down via `coworkers` `children` method, using the `name` `text` attribute for displaying each tree item.
|
1401
|
-
- Tree `selection`, which binds the single tree item selected by the user to the attribute denoted by the `bind` keyword
|
1840
|
+
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`.
|
1402
1841
|
|
1403
|
-
|
1842
|
+
Should you have a special data type that could not be compared automatically, Glimmer offers the following 3 alternatives for custom sorting:
|
1843
|
+
- `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`).
|
1844
|
+
- `sort_by(&block)`: this works just like Ruby `Enumerable` `sort_by`. The block receives the table column data as argument.
|
1845
|
+
- `sort(&comparator)`: this works just like Ruby `Enumerable` `sort`. The comparator block receives two objects from the table column data.
|
1404
1846
|
|
1405
|
-
|
1406
|
-
TreeProxy includes a `depth_first_search` method that takes a block to look for a tree item.
|
1847
|
+
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)
|
1407
1848
|
|
1408
1849
|
Example:
|
1409
1850
|
|
1410
1851
|
```ruby
|
1411
|
-
|
1852
|
+
# ...
|
1853
|
+
table {
|
1854
|
+
table_column {
|
1855
|
+
text 'Task'
|
1856
|
+
width 120
|
1857
|
+
}
|
1858
|
+
table_column {
|
1859
|
+
text 'Project'
|
1860
|
+
width 120
|
1861
|
+
}
|
1862
|
+
table_column {
|
1863
|
+
text 'Duration (hours)'
|
1864
|
+
width 120
|
1865
|
+
sort_property :duration_in_hours
|
1866
|
+
}
|
1867
|
+
table_column {
|
1868
|
+
text 'Priority'
|
1869
|
+
width 120
|
1870
|
+
sort_by { |value| ['High', 'Medium', 'Low'].index(value) }
|
1871
|
+
}
|
1872
|
+
table_column {
|
1873
|
+
text 'Start Date'
|
1874
|
+
width 120
|
1875
|
+
sort { |d1, d2| d1.to_date <=> d2.to_date }
|
1876
|
+
}
|
1877
|
+
additional_sort_properties :project_name, :duration_in_hours, :name
|
1878
|
+
items bind(Task, :list), column_properties(:name, :project_name, :duration, :priority, :start_date)
|
1879
|
+
# ...
|
1880
|
+
}
|
1881
|
+
# ...
|
1882
|
+
```
|
1883
|
+
|
1884
|
+
Here is an explanation of the example above:
|
1885
|
+
- Task and Project table columns are data-bound to the `:name` and `:project_name` properties and sorted through them automatically
|
1886
|
+
- Task Duration table column is data-bound to the `:duration` property, but sorted via the `:duration_in_hours` property instead
|
1887
|
+
- Task Priority table column has a custom sort_by block
|
1888
|
+
- Task Start Date table column has a custom sort comparator block
|
1889
|
+
- Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
|
1890
|
+
|
1891
|
+
|
1892
|
+
#### Tree
|
1893
|
+
|
1894
|
+
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
1895
|
+
|
1896
|
+
To data-bind a Tree, you need the root model, the children querying method, and the text display attribute on each child.
|
1897
|
+
|
1898
|
+
This involves using the `bind` keyword mentioned above in addition to a special `tree_properties` keyword that takes the children and text attribute methods.
|
1899
|
+
|
1900
|
+
Example:
|
1901
|
+
|
1902
|
+
```ruby
|
1903
|
+
shell {
|
1904
|
+
@tree = tree {
|
1905
|
+
items bind(company, :owner), tree_properties(children: :coworkers, text: :name)
|
1906
|
+
selection bind(company, :selected_coworker)
|
1907
|
+
}
|
1908
|
+
}
|
1909
|
+
```
|
1910
|
+
|
1911
|
+
The code above includes two data-bindings:
|
1912
|
+
- Tree `items`, which first bind to the root node (company.owner), and then dig down via `coworkers` `children` method, using the `name` `text` attribute for displaying each tree item.
|
1913
|
+
- Tree `selection`, which binds the single tree item selected by the user to the attribute denoted by the `bind` keyword
|
1914
|
+
|
1915
|
+
Additionally, Tree `items` data-binding automatically stores each node model unto the SWT TreeItem object via `setData` method. This enables things like searchability.
|
1916
|
+
|
1917
|
+
The tree widget in Glimmer is represented by a subclass of `WidgetProxy` called `TreeProxy`.
|
1918
|
+
TreeProxy includes a `depth_first_search` method that takes a block to look for a tree item.
|
1919
|
+
|
1920
|
+
Example:
|
1921
|
+
|
1922
|
+
```ruby
|
1923
|
+
found_array = @tree.depth_first_search { |tree_item| tree_item.getData == company.owner }
|
1412
1924
|
```
|
1413
1925
|
|
1414
1926
|
This finds the root node. The array is a Java array. This enables easy passing of it to SWT `Tree#setSelection` method, which expects a Java array of `TreeItem` objects.
|
@@ -1424,10 +1936,10 @@ Glimmer comes with `Observer` module, which is used internally for data-binding,
|
|
1424
1936
|
|
1425
1937
|
Glimmer supports observing widgets with two main types of events:
|
1426
1938
|
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`).
|
1427
|
-
2. `
|
1939
|
+
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)
|
1428
1940
|
|
1429
1941
|
Additionally, there are two more types of events:
|
1430
|
-
- SWT `display` supports global listeners called filters that run on any widget. They are hooked via `
|
1942
|
+
- SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_swt_{swt-event-constant}`
|
1431
1943
|
- SWT `display` supports Mac application menu item observers (`on_about` and `on_preferences`), which you can read about under [Miscellaneous](#miscellaneous).
|
1432
1944
|
|
1433
1945
|
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.
|
@@ -1450,7 +1962,8 @@ Let's revisit the Tic Tac Toe example shown near the beginning of the page:
|
|
1450
1962
|
```ruby
|
1451
1963
|
shell {
|
1452
1964
|
text "Tic-Tac-Toe"
|
1453
|
-
|
1965
|
+
minimum_size 150, 178
|
1966
|
+
composite {
|
1454
1967
|
grid_layout 3, true
|
1455
1968
|
(1..3).each { |row|
|
1456
1969
|
(1..3).each { |column|
|
@@ -1472,21 +1985,21 @@ Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties da
|
|
1472
1985
|
|
1473
1986
|
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.
|
1474
1987
|
|
1475
|
-
**Regarding number 2**, you can figure out all available events by looking at the `org.eclipse.swt.SWT` API:
|
1988
|
+
**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:
|
1476
1989
|
|
1477
1990
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
1478
1991
|
|
1479
1992
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1480
1993
|
|
1481
|
-
`SWT.Show` - hooks a listener for showing a widget (using `
|
1482
|
-
`SWT.Hide` - hooks a listener for hiding a widget (using `
|
1994
|
+
`SWT.Show` - hooks a listener for showing a widget (using `on_swt_show` in Glimmer)
|
1995
|
+
`SWT.Hide` - hooks a listener for hiding a widget (using `on_swt_hide` in Glimmer)
|
1483
1996
|
|
1484
1997
|
```ruby
|
1485
1998
|
shell {
|
1486
1999
|
@button1 = button {
|
1487
2000
|
text "Show 2nd Button"
|
1488
2001
|
visible true
|
1489
|
-
|
2002
|
+
on_swt_show {
|
1490
2003
|
@button2.swt_widget.setVisible(false)
|
1491
2004
|
}
|
1492
2005
|
on_widget_selected {
|
@@ -1496,7 +2009,7 @@ shell {
|
|
1496
2009
|
@button2 = button {
|
1497
2010
|
text "Show 1st Button"
|
1498
2011
|
visible false
|
1499
|
-
|
2012
|
+
on_swt_show {
|
1500
2013
|
@button1.swt_widget.setVisible(false)
|
1501
2014
|
}
|
1502
2015
|
on_widget_selected {
|
@@ -1506,7 +2019,7 @@ shell {
|
|
1506
2019
|
}.open
|
1507
2020
|
```
|
1508
2021
|
|
1509
|
-
**Gotcha:** SWT.Resize event needs to be hooked using **`
|
2022
|
+
**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`
|
1510
2023
|
|
1511
2024
|
##### Alternative Syntax
|
1512
2025
|
|
@@ -1549,7 +2062,7 @@ class TicTacToe
|
|
1549
2062
|
end
|
1550
2063
|
```
|
1551
2064
|
|
1552
|
-
Observers can be a good mechanism for displaying dialog messages in Glimmer (using SWT's `MessageBox`).
|
2065
|
+
Observers can be a good mechanism for displaying dialog messages in Glimmer (using SWT's [`MessageBox`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/MessageBox.html) class).
|
1553
2066
|
|
1554
2067
|
Look at [`samples/elaborate/tictactoe/tic_tac_toe.rb`](samples/tictactoe/tic_tac_toe.rb) for more details starting with the code included below.
|
1555
2068
|
|
@@ -1575,10 +2088,10 @@ class TicTacToe
|
|
1575
2088
|
end
|
1576
2089
|
|
1577
2090
|
def display_game_over_message(message)
|
1578
|
-
message_box
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
2091
|
+
message_box(@shell) {
|
2092
|
+
text 'Game Over'
|
2093
|
+
message message_text
|
2094
|
+
}.open
|
1582
2095
|
@tic_tac_toe_board.reset
|
1583
2096
|
end
|
1584
2097
|
# ...
|
@@ -1750,6 +2263,11 @@ body {
|
|
1750
2263
|
|
1751
2264
|
The `text` method invoked in the custom widget body will call the one you defined above it. To avoid this gotcha, simply name the text property above something else, like `custom_text`.
|
1752
2265
|
|
2266
|
+
#### Final Notes
|
2267
|
+
|
2268
|
+
This [Eclipse guide](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm) for how to write custom SWT widgets is also applicable to Glimmer Custom Widgets written in Ruby. I recommend reading it:
|
2269
|
+
[https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm)
|
2270
|
+
|
1753
2271
|
### Custom Shells
|
1754
2272
|
|
1755
2273
|
Custom shells are a kind of custom widgets that have shells only as the body root. They can be self-contained applications that may be opened and hidden/closed independently of the main app.
|
@@ -1795,7 +2313,7 @@ shell { |app_shell|
|
|
1795
2313
|
@current_step_number = 1
|
1796
2314
|
@wizard_steps = 5.times.map { |n|
|
1797
2315
|
wizard_step(number: n+1, step_count: 5) {
|
1798
|
-
|
2316
|
+
on_swt_hide {
|
1799
2317
|
if @current_step_number < 5
|
1800
2318
|
@current_step_number += 1
|
1801
2319
|
app_shell.hide
|
@@ -1815,6 +2333,62 @@ shell { |app_shell|
|
|
1815
2333
|
}.open
|
1816
2334
|
```
|
1817
2335
|
|
2336
|
+
### Drag and Drop
|
2337
|
+
|
2338
|
+
Glimmer offers Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
|
2339
|
+
|
2340
|
+
You may learn more about SWT Drag and Drop support over here: [https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html](https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
|
2341
|
+
|
2342
|
+
To get started, simply follow these steps:
|
2343
|
+
1. On the drag source widget, add `on_drag_set_data` [DragSourceListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceListener.html) event handler block at minimum (you may also add `on_drag_start` and `on_drag_finished` if needed)
|
2344
|
+
1. Set `event.data` to transfer via drag and drop inside the `on_drag_set_data` event handler block (defaults to `transfer` type of `:text`, as in a Ruby String)
|
2345
|
+
1. On the drop target widget, add `on_drop` [DropTargetListener](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetListener.html) event handler block at minimum (you may also add `on_drag_enter` [must set [`event.detail`](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEvent.html#detail) if added], `on_drag_over`, `on_drag_leave`, `on_drag_operation_changed` and `on_drop_accept` if needed)
|
2346
|
+
1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
|
2347
|
+
|
2348
|
+
Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2349
|
+
|
2350
|
+
```ruby
|
2351
|
+
class Location
|
2352
|
+
attr_accessor :country
|
2353
|
+
|
2354
|
+
def country_options
|
2355
|
+
%w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
2356
|
+
end
|
2357
|
+
end
|
2358
|
+
|
2359
|
+
@location = Location.new
|
2360
|
+
|
2361
|
+
include Glimmer
|
2362
|
+
|
2363
|
+
shell {
|
2364
|
+
text 'Hello, Drag and Drop!'
|
2365
|
+
list {
|
2366
|
+
selection bind(@location, :country)
|
2367
|
+
on_drag_set_data { |event|
|
2368
|
+
list = event.widget.getControl
|
2369
|
+
event.data = list.getSelection.first
|
2370
|
+
}
|
2371
|
+
}
|
2372
|
+
label(:center) {
|
2373
|
+
text 'Drag a country here!'
|
2374
|
+
font height: 20
|
2375
|
+
on_drop { |event|
|
2376
|
+
event.widget.getControl.setText(event.data)
|
2377
|
+
}
|
2378
|
+
}
|
2379
|
+
}.open
|
2380
|
+
```
|
2381
|
+
|
2382
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2383
|
+
|
2384
|
+
Optional steps:
|
2385
|
+
- Set a `transfer` property (defaults to `:text`). Values may be: :text (default), :html :image, :rtf, :url, and :file, or an array of multiple values. The `transfer` property will automatically convert your option into a [Transfer](https://help.eclipse.org/2020-03/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/Transfer.html) object as per the SWT API.
|
2386
|
+
- Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2387
|
+
- Specify `drag_source_effect` (Check [DragSourceEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DragSourceEffect.html) SWT API for details)
|
2388
|
+
- Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2389
|
+
- Specify `drop_target_effect` (Check [DropTargetEffect](https://help.eclipse.org/2020-06/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/dnd/DropTargetEffect.html) SWT API for details)
|
2390
|
+
- Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
|
2391
|
+
|
1818
2392
|
### Miscellaneous
|
1819
2393
|
|
1820
2394
|
#### Multi-DSL Support
|
@@ -1970,10 +2544,10 @@ class Example
|
|
1970
2544
|
def initialize
|
1971
2545
|
display {
|
1972
2546
|
on_about {
|
1973
|
-
message_box
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
2547
|
+
message_box(@shell_proxy) {
|
2548
|
+
text 'About'
|
2549
|
+
message 'About Application'
|
2550
|
+
}.open
|
1977
2551
|
}
|
1978
2552
|
on_preferences {
|
1979
2553
|
preferences_dialog = dialog {
|
@@ -2039,7 +2613,7 @@ Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app versi
|
|
2039
2613
|
|
2040
2614
|
#### Video Widget
|
2041
2615
|
|
2042
|
-
![Video Widget](images/glimmer-video-widget.png)
|
2616
|
+
[![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
|
2043
2617
|
|
2044
2618
|
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
|
2045
2619
|
|
@@ -2049,7 +2623,7 @@ You may obtain via `glimmer-cw-video` gem.
|
|
2049
2623
|
|
2050
2624
|
![Hello Browser](images/glimmer-hello-browser.png)
|
2051
2625
|
|
2052
|
-
Glimmer supports SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged
|
2626
|
+
Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
|
2053
2627
|
|
2054
2628
|
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2055
2629
|
|
@@ -2085,6 +2659,170 @@ shell {
|
|
2085
2659
|
|
2086
2660
|
This relies on Glimmer's [Multi-DSL Support](#multi-dsl-support) for building the HTML text using [Glimmer XML DSL](https://github.com/AndyObtiva/glimmer-dsl-xml).
|
2087
2661
|
|
2662
|
+
## Glimmer Configuration
|
2663
|
+
|
2664
|
+
Glimmer configuration may be done via the `Glimmer::Config` module.
|
2665
|
+
|
2666
|
+
### logger
|
2667
|
+
|
2668
|
+
The Glimmer DSL engine supports logging via a standard `STDOUT` Ruby `Logger` configured in the `Glimmer::Config.logger` config option.
|
2669
|
+
It is set to level Logger::ERROR by default.
|
2670
|
+
Log level may be adjusted via `Glimmer::Config.logger.level` just like any other Ruby Logger.
|
2671
|
+
|
2672
|
+
Example:
|
2673
|
+
|
2674
|
+
```ruby
|
2675
|
+
Glimmer::Config.logger.level = :debug
|
2676
|
+
```
|
2677
|
+
This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
|
2678
|
+
|
2679
|
+
Example log:
|
2680
|
+
```
|
2681
|
+
D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
|
2682
|
+
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2683
|
+
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2684
|
+
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2685
|
+
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2686
|
+
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2687
|
+
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2688
|
+
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2689
|
+
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2690
|
+
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2691
|
+
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2692
|
+
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2693
|
+
```
|
2694
|
+
|
2695
|
+
The `logger` instance may be replaced with a custom logger via `Glimmer::Config.logger = custom_logger`
|
2696
|
+
|
2697
|
+
To reset `logger` to the default instance, you may call `Glimmer::Config.reset_logger!`
|
2698
|
+
|
2699
|
+
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.
|
2700
|
+
|
2701
|
+
[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.
|
2702
|
+
|
2703
|
+
Other config options related to the [`logging`](https://github.com/TwP/logging) gem are mentioned below.
|
2704
|
+
|
2705
|
+
#### logging_devices
|
2706
|
+
|
2707
|
+
This is an array of these possible values: `:stdout` (default), `:stderr`, `:file`, `:syslog` (default), `:stringio`
|
2708
|
+
|
2709
|
+
It defaults to `[:stdout, :syslog]`
|
2710
|
+
|
2711
|
+
When `:file` is included, Glimmer creates a 'log' directory directly below the Glimmer app local directory.
|
2712
|
+
It may also be customized further via the `logging_device_file_options` option.
|
2713
|
+
This is useful on Windows as an alternative to `syslog`, which is not available on Windows by default.
|
2714
|
+
|
2715
|
+
#### logging_device_file_options
|
2716
|
+
|
2717
|
+
This is a hash of [`logging`](https://github.com/TwP/logging) gem options for the `:file` logging device.
|
2718
|
+
|
2719
|
+
Default: `{size: 1_000_000, age: 'daily', roll_by: 'number'}`
|
2720
|
+
|
2721
|
+
That ensures splitting log files at the 1MB size and daily, rolling them by unique number.
|
2722
|
+
|
2723
|
+
#### logging_appender_options
|
2724
|
+
|
2725
|
+
Appender options is a hash passed as options to every appender (logging device) used in the [`logging`](https://github.com/TwP/logging) gem.
|
2726
|
+
|
2727
|
+
Default: `{async: true, auto_flushing: 500, write_size: 500, flush_period: 60, immediate_at: [:error, :fatal], layout: logging_layout}`
|
2728
|
+
|
2729
|
+
That ensures asynchronous buffered logging that is flushed every 500 messages and 60 seconds, or immediately at error and fatal log levels
|
2730
|
+
|
2731
|
+
#### logging_layout
|
2732
|
+
|
2733
|
+
This is a [`logging`](https://github.com/TwP/logging) gem layout that formats the logging output.
|
2734
|
+
|
2735
|
+
Default:
|
2736
|
+
|
2737
|
+
```
|
2738
|
+
Logging.layouts.pattern(
|
2739
|
+
pattern: '[%d] %-5l %c: %m\n',
|
2740
|
+
date_pattern: '%Y-%m-%d %H:%M:%S'
|
2741
|
+
)
|
2742
|
+
```
|
2743
|
+
|
2744
|
+
### import_swt_packages
|
2745
|
+
|
2746
|
+
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.
|
2747
|
+
|
2748
|
+
As a result, you may call SWT Java classes from Glimmer Ruby code without mentioning Java package references explicitly.
|
2749
|
+
|
2750
|
+
For example, `org.eclipse.swt.graphics.Color` can be referenced as just `Color`
|
2751
|
+
|
2752
|
+
The Java packages imported come from the [`Glimmer::Config.import_swt_packages`](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/lib/ext/glimmer/config.rb) config option, which defaults to `Glimmer::Config::DEFAULT_IMPORT_SWT_PACKAGES`, importing the following Java packages:
|
2753
|
+
```
|
2754
|
+
org.eclipse.swt.*
|
2755
|
+
org.eclipse.swt.widgets.*
|
2756
|
+
org.eclipse.swt.layout.*
|
2757
|
+
org.eclipse.swt.graphics.*
|
2758
|
+
org.eclipse.swt.browser.*
|
2759
|
+
org.eclipse.swt.custom.*
|
2760
|
+
org.eclipse.swt.dnd.*
|
2761
|
+
```
|
2762
|
+
|
2763
|
+
If you need to import additional Java packages as extra Glimmer widgets, you may add more packages to [`Glimmer::Config.import_swt_packages`](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/lib/ext/glimmer/config.rb) by using the `+=` operator (or alternatively limit to certain packages via `=` operator).
|
2764
|
+
|
2765
|
+
Example:
|
2766
|
+
|
2767
|
+
```ruby
|
2768
|
+
Glimmer::Config.import_swt_packages += [
|
2769
|
+
'org.eclipse.nebula.widgets.ganttchart'
|
2770
|
+
]
|
2771
|
+
```
|
2772
|
+
|
2773
|
+
Another alternative is to simply add a `java_import` call to your code (e.g. `java_import 'org.eclipse.nebula.widgets.ganttchart.GanttChart'`). Glimmer will automatically take advantage of it (e.g. when invoking `gantt_chart` keyword)
|
2774
|
+
|
2775
|
+
Nonetheless, you can disable automatic Java package import if needed via this Glimmer configuration option:
|
2776
|
+
|
2777
|
+
```ruby
|
2778
|
+
Glimmer::Config.import_swt_packages = false
|
2779
|
+
```
|
2780
|
+
|
2781
|
+
Once disabled, to import SWT Java packages manually, you may simply:
|
2782
|
+
|
2783
|
+
1. `include Glimmer::SWT::Packages`: lazily imports all SWT Java packages to your class, lazy-loading SWT Java class constants on first reference.
|
2784
|
+
|
2785
|
+
2. `java_import swt_package_class_string`: immediately imports a specific Java class where `swt_package_class_string` is the Java full package reference of a Java class (e.g. `java_import 'org.eclipse.swt.SWT'`)
|
2786
|
+
|
2787
|
+
Note: Glimmer relies on [`nested_imported_jruby_include_package`](https://github.com/AndyObtiva/nested_inherited_jruby_include_package), which automatically brings packages to nested-modules/nested-classes and sub-modules/sub-classes.
|
2788
|
+
|
2789
|
+
You can learn more about importing Java packages into Ruby code at this JRuby WIKI page:
|
2790
|
+
|
2791
|
+
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
|
2792
|
+
|
2793
|
+
### loop_max_count
|
2794
|
+
|
2795
|
+
Glimmer has infinite loop detection support.
|
2796
|
+
It can detect when an infinite loop is about to occur in method_missing and stops it.
|
2797
|
+
It detects potential infinite loops when the same keyword and args repeat more than 100 times, which is unusual in a GUI app.
|
2798
|
+
|
2799
|
+
The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` config option.
|
2800
|
+
|
2801
|
+
Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
|
2802
|
+
|
2803
|
+
### excluded_keyword_checkers
|
2804
|
+
|
2805
|
+
Glimmer permits consumers to exclude keywords from DSL processing by its engine via the `excluded_keyword_checkers` config option.
|
2806
|
+
|
2807
|
+
To do so, add a proc to it that returns a boolean indicating if a keyword is excluded or not.
|
2808
|
+
|
2809
|
+
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.
|
2810
|
+
|
2811
|
+
Example of keywords excluded by [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt):
|
2812
|
+
|
2813
|
+
```ruby
|
2814
|
+
Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
2815
|
+
method = method_symbol.to_s
|
2816
|
+
result = false
|
2817
|
+
result ||= method.start_with?('on_swt_') && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
|
2818
|
+
result ||= method == 'dispose' && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
|
2819
|
+
result ||= ['drag_source_proxy', 'drop_target_proxy'].include?(method) && is_a?(Glimmer::UI::CustomWidget)
|
2820
|
+
result ||= method == 'post_initialize_child'
|
2821
|
+
result ||= method.end_with?('=')
|
2822
|
+
result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
|
2823
|
+
end
|
2824
|
+
```
|
2825
|
+
|
2088
2826
|
## Glimmer Style Guide
|
2089
2827
|
|
2090
2828
|
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
@@ -2100,6 +2838,38 @@ This relies on Glimmer's [Multi-DSL Support](#multi-dsl-support) for building th
|
|
2100
2838
|
- Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
|
2101
2839
|
- Custom widgets receive additional arguments to SWT style called options. These are passed as the last argument inside the parentheses, a hash of option names pointing to values.
|
2102
2840
|
|
2841
|
+
## SWT Reference
|
2842
|
+
|
2843
|
+
https://www.eclipse.org/swt/docs.php
|
2844
|
+
|
2845
|
+
Here is the SWT API:
|
2846
|
+
|
2847
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
|
2848
|
+
|
2849
|
+
Here is a visual list of SWT widgets:
|
2850
|
+
|
2851
|
+
https://www.eclipse.org/swt/widgets/
|
2852
|
+
|
2853
|
+
Here is a textual list of SWT widgets:
|
2854
|
+
|
2855
|
+
https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
|
2856
|
+
|
2857
|
+
Here is a list of SWT style bits as used in widget declaration:
|
2858
|
+
|
2859
|
+
https://wiki.eclipse.org/SWT_Widget_Style_Bits
|
2860
|
+
|
2861
|
+
Here is a SWT style bit constant reference:
|
2862
|
+
|
2863
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
2864
|
+
|
2865
|
+
Here is an SWT Drag and Drop guide:
|
2866
|
+
|
2867
|
+
https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
|
2868
|
+
|
2869
|
+
Here is an SWT Custom Widget guide:
|
2870
|
+
|
2871
|
+
https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
|
2872
|
+
|
2103
2873
|
## Samples
|
2104
2874
|
|
2105
2875
|
Check the [samples](samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`).
|
@@ -2112,233 +2882,325 @@ samples/launch
|
|
2112
2882
|
|
2113
2883
|
### Hello Samples
|
2114
2884
|
|
2115
|
-
For
|
2885
|
+
For hello-type simple samples, check the following.
|
2886
|
+
|
2887
|
+
#### Hello, World! Sample
|
2888
|
+
|
2889
|
+
Code:
|
2890
|
+
|
2891
|
+
[samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)
|
2892
|
+
|
2893
|
+
Run:
|
2116
2894
|
|
2117
2895
|
```
|
2118
2896
|
glimmer samples/hello/hello_world.rb
|
2119
|
-
glimmer samples/hello/hello_browser.rb # demonstrates browser widget
|
2120
|
-
glimmer samples/hello/hello_tab.rb # demonstrates tabs
|
2121
|
-
glimmer samples/hello/hello_combo.rb # demonstrates combo data-binding
|
2122
|
-
glimmer samples/hello/hello_list_single_selection.rb # demonstrates list single-selection data-binding
|
2123
|
-
glimmer samples/hello/hello_list_multi_selection.rb # demonstrates list multi-selection data-binding
|
2124
|
-
glimmer samples/hello/hello_computed.rb # demonstrates computed data-binding
|
2125
2897
|
```
|
2126
2898
|
|
2127
|
-
|
2899
|
+
![Hello World](images/glimmer-hello-world.png)
|
2128
2900
|
|
2129
|
-
|
2901
|
+
#### Hello, Tab!
|
2130
2902
|
|
2131
|
-
|
2903
|
+
Code:
|
2904
|
+
|
2905
|
+
[samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_tab.rb)
|
2906
|
+
|
2907
|
+
Run:
|
2132
2908
|
|
2133
2909
|
```
|
2134
|
-
glimmer samples/
|
2910
|
+
glimmer samples/hello/hello_tab.rb
|
2135
2911
|
```
|
2136
2912
|
|
2137
|
-
![
|
2138
|
-
![
|
2139
|
-
|
2913
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
2914
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
2915
|
+
|
2916
|
+
#### Hello, Combo!
|
2917
|
+
|
2918
|
+
This sample demonstrates combo data-binding.
|
2919
|
+
|
2920
|
+
Code:
|
2140
2921
|
|
2141
|
-
|
2922
|
+
[samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_combo.rb)
|
2923
|
+
|
2924
|
+
Run:
|
2142
2925
|
|
2143
2926
|
```
|
2144
|
-
glimmer samples/
|
2927
|
+
glimmer samples/hello/hello_combo.rb
|
2145
2928
|
```
|
2146
2929
|
|
2147
|
-
![
|
2148
|
-
![
|
2149
|
-
|
2930
|
+
![Hello Combo](images/glimmer-hello-combo.png)
|
2931
|
+
![Hello Combo Expanded](images/glimmer-hello-combo-expanded.png)
|
2932
|
+
|
2933
|
+
#### Hello, List Single Selection!
|
2150
2934
|
|
2151
|
-
|
2935
|
+
This sample demonstrates list single-selection data-binding.
|
2936
|
+
|
2937
|
+
Code:
|
2938
|
+
|
2939
|
+
[samples/hello/hello_list_single_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_single_selection.rb)
|
2940
|
+
|
2941
|
+
Run:
|
2152
2942
|
|
2153
2943
|
```
|
2154
|
-
glimmer samples/
|
2944
|
+
glimmer samples/hello/hello_list_single_selection.rb
|
2155
2945
|
```
|
2156
2946
|
|
2157
|
-
|
2947
|
+
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
2158
2948
|
|
2159
|
-
!
|
2949
|
+
#### Hello, List Multi Selection!
|
2160
2950
|
|
2161
|
-
|
2951
|
+
This sample demonstrates list multi-selection data-binding.
|
2162
2952
|
|
2163
|
-
|
2953
|
+
Code:
|
2164
2954
|
|
2165
|
-
|
2955
|
+
[samples/hello/hello_list_multi_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_multi_selection.rb)
|
2166
2956
|
|
2167
|
-
|
2957
|
+
Run:
|
2168
2958
|
|
2169
|
-
|
2959
|
+
```
|
2960
|
+
glimmer samples/hello/hello_list_multi_selection.rb
|
2961
|
+
```
|
2170
2962
|
|
2171
|
-
![
|
2963
|
+
![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
|
2172
2964
|
|
2173
|
-
|
2965
|
+
#### Hello, Computed!
|
2174
2966
|
|
2175
|
-
|
2967
|
+
This sample demonstrates computed data-binding.
|
2176
2968
|
|
2177
|
-
|
2969
|
+
Code:
|
2178
2970
|
|
2179
|
-
|
2971
|
+
[samples/hello/hello_computed.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_computed.rb)
|
2180
2972
|
|
2181
|
-
|
2973
|
+
Run:
|
2182
2974
|
|
2183
|
-
|
2975
|
+
```
|
2976
|
+
glimmer samples/hello/hello_computed.rb
|
2977
|
+
```
|
2184
2978
|
|
2185
|
-
|
2979
|
+
![Hello Browser](images/glimmer-hello-computed.png)
|
2186
2980
|
|
2187
|
-
|
2981
|
+
#### Hello, Message Box!
|
2188
2982
|
|
2189
|
-
|
2190
|
-
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
2983
|
+
This sample demonstrates a `message_box` dialog.
|
2191
2984
|
|
2192
|
-
|
2193
|
-
- MVP Pattern
|
2194
|
-
- Tree data-binding
|
2195
|
-
- List data-binding
|
2196
|
-
- Text selection data-binding
|
2197
|
-
- Tabs
|
2198
|
-
- Context menus
|
2199
|
-
- Custom Shell
|
2200
|
-
- Custom widget
|
2985
|
+
Code:
|
2201
2986
|
|
2202
|
-
|
2987
|
+
[samples/hello/hello_message_box.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_message_box.rb)
|
2203
2988
|
|
2204
|
-
|
2989
|
+
Run:
|
2205
2990
|
|
2206
|
-
|
2991
|
+
```
|
2992
|
+
glimmer samples/hello/hello_message_box.rb
|
2993
|
+
```
|
2207
2994
|
|
2208
|
-
|
2995
|
+
![Hello Message Box](images/glimmer-hello-message-box.png)
|
2996
|
+
![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
|
2209
2997
|
|
2210
|
-
|
2998
|
+
#### Hello, Browser!
|
2211
2999
|
|
2212
|
-
|
3000
|
+
This sample demonstrates the `browser` widget.
|
2213
3001
|
|
2214
|
-
|
3002
|
+
Code:
|
2215
3003
|
|
2216
|
-
https://
|
3004
|
+
[samples/hello/hello_browser.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_browser.rb)
|
2217
3005
|
|
2218
|
-
|
3006
|
+
Run:
|
2219
3007
|
|
2220
|
-
|
3008
|
+
```
|
3009
|
+
glimmer samples/hello/hello_browser.rb
|
3010
|
+
```
|
2221
3011
|
|
2222
|
-
|
3012
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2223
3013
|
|
2224
|
-
|
3014
|
+
#### Hello, Drag and Drop!
|
2225
3015
|
|
2226
|
-
|
3016
|
+
This sample demonstrates drag and drop in Glimmer.
|
2227
3017
|
|
2228
|
-
|
3018
|
+
Code:
|
2229
3019
|
|
2230
|
-
|
3020
|
+
[samples/hello/hello_drag_and_drop.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_drag_and_drop.rb)
|
2231
3021
|
|
2232
|
-
|
3022
|
+
Run:
|
3023
|
+
|
3024
|
+
```
|
3025
|
+
glimmer samples/hello/hello_drag_and_drop.rb
|
3026
|
+
```
|
3027
|
+
|
3028
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2233
3029
|
|
2234
|
-
|
3030
|
+
#### Hello, Menu Bar!
|
2235
3031
|
|
2236
|
-
|
3032
|
+
This sample demonstrates menus in Glimmer.
|
3033
|
+
|
3034
|
+
Code:
|
3035
|
+
|
3036
|
+
[samples/hello/hello_menu_bar.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_menu_bar.rb)
|
3037
|
+
|
3038
|
+
Run:
|
2237
3039
|
|
2238
|
-
Here are the Java packages imported:
|
2239
3040
|
```
|
2240
|
-
|
2241
|
-
org.eclipse.swt.widgets.*
|
2242
|
-
org.eclipse.swt.layout.*
|
2243
|
-
org.eclipse.swt.graphics.*
|
2244
|
-
org.eclipse.swt.browser.*
|
2245
|
-
org.eclipse.swt.custom.*
|
3041
|
+
glimmer samples/hello/hello_menu_bar.rb
|
2246
3042
|
```
|
2247
3043
|
|
2248
|
-
|
3044
|
+
![Hello Menu Bar](images/glimmer-hello-menu-bar.png)
|
3045
|
+
![Hello Menu Bar File Menu](images/glimmer-hello-menu-bar-file-menu.png)
|
3046
|
+
![Hello Menu Bar History Menu](images/glimmer-hello-menu-bar-history-menu.png)
|
2249
3047
|
|
2250
|
-
|
3048
|
+
#### Hello, Pop Up Context Menu!
|
2251
3049
|
|
2252
|
-
|
3050
|
+
This sample demonstrates pop up context menus in Glimmer.
|
2253
3051
|
|
2254
|
-
|
2255
|
-
Glimmer::Config.import_swt_packages = false
|
2256
|
-
```
|
3052
|
+
Code:
|
2257
3053
|
|
2258
|
-
|
3054
|
+
[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)
|
2259
3055
|
|
2260
|
-
|
3056
|
+
Run:
|
2261
3057
|
|
2262
|
-
|
3058
|
+
```
|
3059
|
+
glimmer samples/hello/hello_pop_up_context_menu.rb
|
3060
|
+
```
|
2263
3061
|
|
2264
|
-
|
3062
|
+
![Hello Pop Up Context Menu](images/glimmer-hello-pop-up-context-menu.png)
|
3063
|
+
![Hello Pop Up Context Menu Popped Up](images/glimmer-hello-pop-up-context-menu-popped-up.png)
|
2265
3064
|
|
2266
|
-
|
3065
|
+
### Elaborate Samples
|
2267
3066
|
|
2268
|
-
|
3067
|
+
For more elaborate samples, check the following:
|
2269
3068
|
|
2270
|
-
|
3069
|
+
#### Login
|
2271
3070
|
|
2272
|
-
|
3071
|
+
This sample demonstrates basic data-binding, password and text fields, and field enablement data-binding.
|
2273
3072
|
|
2274
|
-
|
3073
|
+
Code:
|
2275
3074
|
|
2276
|
-
|
3075
|
+
[samples/elaborate/login.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/login.rb)
|
2277
3076
|
|
2278
|
-
|
3077
|
+
Run:
|
2279
3078
|
|
2280
|
-
Glimmer comes with a Ruby Logger accessible via `Glimmer::Config.logger`
|
2281
|
-
Its level of logging defaults to `Logger::WARN`
|
2282
|
-
It may be configured to show a different level of logging as follows:
|
2283
|
-
```ruby
|
2284
|
-
Glimmer::Config.enable_logging
|
2285
|
-
Glimmer::Config.logger.level = Logger::DEBUG
|
2286
3079
|
```
|
2287
|
-
|
2288
|
-
|
2289
|
-
Example log:
|
2290
|
-
```
|
2291
|
-
D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
|
2292
|
-
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2293
|
-
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2294
|
-
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2295
|
-
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2296
|
-
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2297
|
-
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2298
|
-
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2299
|
-
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2300
|
-
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2301
|
-
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2302
|
-
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
3080
|
+
glimmer samples/elaborate/login.rb
|
2303
3081
|
```
|
2304
3082
|
|
2305
|
-
|
3083
|
+
![Login](images/glimmer-login.png)
|
3084
|
+
![Login Filled In](images/glimmer-login-filled-in.png)
|
3085
|
+
![Login Logged In](images/glimmer-login-logged-in.png)
|
3086
|
+
|
3087
|
+
#### Tic Tac Toe Sample
|
2306
3088
|
|
2307
|
-
|
2308
|
-
|
3089
|
+
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)).
|
3090
|
+
|
3091
|
+
Code:
|
3092
|
+
|
3093
|
+
(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`)
|
3094
|
+
|
3095
|
+
[samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)
|
3096
|
+
|
3097
|
+
Run:
|
2309
3098
|
|
2310
3099
|
```
|
2311
|
-
|
3100
|
+
glimmer samples/elaborate/tic_tac_toe.rb
|
2312
3101
|
```
|
2313
3102
|
|
2314
|
-
|
2315
|
-
|
3103
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
3104
|
+
![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
|
3105
|
+
![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
|
2316
3106
|
|
2317
|
-
|
3107
|
+
#### Contact Manager Sample
|
2318
3108
|
|
2319
|
-
|
3109
|
+
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)).
|
2320
3110
|
|
2321
|
-
|
3111
|
+
Code:
|
2322
3112
|
|
2323
|
-
|
3113
|
+
[samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)
|
3114
|
+
|
3115
|
+
Run:
|
2324
3116
|
|
2325
|
-
Example:
|
2326
3117
|
```
|
2327
|
-
|
3118
|
+
glimmer samples/elaborate/contact_manager.rb
|
2328
3119
|
```
|
2329
3120
|
|
3121
|
+
Contact Manager
|
3122
|
+
|
3123
|
+
![Contact Manager](images/glimmer-contact-manager.png)
|
3124
|
+
|
3125
|
+
Contact Manager - Find
|
3126
|
+
|
3127
|
+
![Contact Manager](images/glimmer-contact-manager-find.png)
|
3128
|
+
|
3129
|
+
Contact Manager - Edit Started
|
3130
|
+
|
3131
|
+
![Contact Manager](images/glimmer-contact-manager-edit-started.png)
|
3132
|
+
|
3133
|
+
Contact Manager - Edit In Progress
|
3134
|
+
|
3135
|
+
![Contact Manager](images/glimmer-contact-manager-edit-in-progress.png)
|
3136
|
+
|
3137
|
+
Contact Manager - Edit Done
|
3138
|
+
|
3139
|
+
![Contact Manager](images/glimmer-contact-manager-edit-done.png)
|
3140
|
+
|
3141
|
+
### External Samples
|
3142
|
+
|
3143
|
+
#### Glimmer Calculator
|
3144
|
+
|
3145
|
+
[<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).
|
3146
|
+
|
3147
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
|
3148
|
+
|
3149
|
+
#### Gladiator
|
3150
|
+
|
3151
|
+
[<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.
|
3152
|
+
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
3153
|
+
|
3154
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
|
3155
|
+
|
3156
|
+
Gladiator is a good demonstration of:
|
3157
|
+
- MVP Pattern
|
3158
|
+
- Tree data-binding
|
3159
|
+
- List data-binding
|
3160
|
+
- Text selection data-binding
|
3161
|
+
- Tabs
|
3162
|
+
- Context menus
|
3163
|
+
- Custom Shell
|
3164
|
+
- Custom widget
|
3165
|
+
|
3166
|
+
## In Production
|
3167
|
+
|
3168
|
+
The following production apps have been built with Glimmer.
|
3169
|
+
|
3170
|
+
If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
|
3171
|
+
|
3172
|
+
### Math Bowling
|
3173
|
+
|
3174
|
+
[<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
|
3175
|
+
|
3176
|
+
### Are We There Yet?
|
3177
|
+
|
3178
|
+
[<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
|
3179
|
+
|
3180
|
+
### Garderie Rainbow Daily Agenda
|
3181
|
+
|
3182
|
+
[<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
|
3183
|
+
|
2330
3184
|
## Packaging & Distribution
|
2331
3185
|
|
2332
3186
|
Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
|
2333
3187
|
- Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
|
2334
|
-
- 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
|
3188
|
+
- javapackager (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html): Enables packaging a JAR file as a DMG/PKG/APP file on Mac, MSI/EXE on Windows, and DEB/RPM on Linux.
|
2335
3189
|
|
2336
|
-
Glimmer simplifies the process of Mac packaging via the `glimmer package` command
|
3190
|
+
Glimmer simplifies the process of Mac and Windows packaging via the `glimmer package` command:
|
2337
3191
|
|
2338
3192
|
```
|
2339
3193
|
glimmer package
|
2340
3194
|
```
|
2341
3195
|
|
3196
|
+
It works out of the box for any application generated by [Glimmer Scaffolding](#scaffolding).
|
3197
|
+
|
3198
|
+
Otherwise, if you are using Glimmer manually, to make the `glimmer package` command available, you must add the following line to your application `Rakefile`:
|
3199
|
+
|
3200
|
+
```ruby
|
3201
|
+
require 'glimmer/rake_task'
|
3202
|
+
```
|
3203
|
+
|
2342
3204
|
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`.
|
2343
3205
|
JAR file name will match your application local directory name (e.g. `MathBowling.jar` for `~/code/MathBowling`)
|
2344
3206
|
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)
|
@@ -2346,6 +3208,14 @@ DMG file name will match the humanized local directory name + dash + application
|
|
2346
3208
|
The `glimmer package` command will automatically set "mac.CFBundleIdentifier" to ="org.#{project_name}.application.#{project_name}".
|
2347
3209
|
You may override by configuring as an extra argument for javapackger (e.g. Glimmer::Package.javapackager_extra_args = " -Bmac.CFBundleIdentifier=org.andymaleh.application.MathBowling")
|
2348
3210
|
|
3211
|
+
You may choose to generate a specific type of packaging by passing the `[type]` option:
|
3212
|
+
|
3213
|
+
```
|
3214
|
+
glimmer package[msi]
|
3215
|
+
```
|
3216
|
+
|
3217
|
+
That generates an MSI file on Windows (could specify exe or image as alternatives on Windows).
|
3218
|
+
|
2349
3219
|
### Packaging Defaults
|
2350
3220
|
|
2351
3221
|
Glimmer employs smart defaults in packaging.
|
@@ -2406,6 +3276,14 @@ JAVAPACKAGER_EXTRA_ARGS='-Bmac.CFBundleName="Math Bowling Game"' glimmer package
|
|
2406
3276
|
|
2407
3277
|
That overrides the default application display name.
|
2408
3278
|
|
3279
|
+
### Windows Application Packaging
|
3280
|
+
|
3281
|
+
Windows offers two options for setup packaging:
|
3282
|
+
- `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 tell you what you need to install including which version of .NET Framework it needs.
|
3283
|
+
- `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.
|
3284
|
+
|
3285
|
+
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.
|
3286
|
+
|
2409
3287
|
### Mac Application Distribution
|
2410
3288
|
|
2411
3289
|
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.
|
@@ -2471,6 +3349,10 @@ By the way, keep in mind that during normal operation, it does also indicate a f
|
|
2471
3349
|
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
|
2472
3350
|
```
|
2473
3351
|
|
3352
|
+
## App Updates
|
3353
|
+
|
3354
|
+
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.
|
3355
|
+
|
2474
3356
|
## Resources
|
2475
3357
|
|
2476
3358
|
* [Code Master Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
|
@@ -2504,13 +3386,21 @@ Glimmer DSL Engine specific tasks are at:
|
|
2504
3386
|
|
2505
3387
|
## Change Log
|
2506
3388
|
|
3389
|
+
[glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
|
3390
|
+
|
2507
3391
|
[CHANGELOG.md](CHANGELOG.md)
|
2508
3392
|
|
2509
3393
|
## Contributing
|
2510
3394
|
|
2511
3395
|
**Contributors Wanted!**
|
2512
3396
|
|
2513
|
-
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).
|
3397
|
+
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).
|
3398
|
+
|
3399
|
+
You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
|
3400
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
3401
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
3402
|
+
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
3403
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
2514
3404
|
|
2515
3405
|
[CONTRIBUTING.md](CONTRIBUTING.md)
|
2516
3406
|
|
@@ -2521,9 +3411,17 @@ If you would like to contribute to Glimmer, please study up on Glimmer and [SWT]
|
|
2521
3411
|
|
2522
3412
|
[Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer/graphs/contributors)
|
2523
3413
|
|
3414
|
+
## Hire Me
|
3415
|
+
|
3416
|
+
If your company would like to invest fulltime in further development of the Glimmer open-source project, [hire me](https://www.linkedin.com/in/andymaleh/).
|
3417
|
+
|
2524
3418
|
## License
|
2525
3419
|
|
2526
|
-
|
2527
|
-
|
3420
|
+
[MIT](https://opensource.org/licenses/MIT)
|
3421
|
+
|
3422
|
+
Copyright (c) 2007-2020 - Andy Maleh.
|
3423
|
+
See [LICENSE.txt](LICENSE.txt) for further details.
|
3424
|
+
|
3425
|
+
--
|
2528
3426
|
|
2529
3427
|
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>
|