glimmer 0.9.2 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +986 -209
- data/VERSION +1 -1
- data/lib/glimmer.rb +39 -12
- data/lib/glimmer/config.rb +33 -7
- data/lib/glimmer/data_binding/observable_array.rb +1 -1
- data/lib/glimmer/data_binding/observable_model.rb +7 -5
- data/lib/glimmer/data_binding/observer.rb +3 -6
- data/lib/glimmer/dsl/engine.rb +27 -19
- data/lib/glimmer/dsl/expression_handler.rb +2 -3
- data/lib/glimmer/excluded_keyword_error.rb +5 -0
- metadata +45 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e5e05e1e5ce6544e9c0286a46f5436c82ff92e8659044b31794d3f4d9db40f2
|
4
|
+
data.tar.gz: 3ad9c659f81fed05328533f1af05713939d44297693af78d78799006009cad71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 674f6f7ea6cf2908261b83ce3580b770bb39ac47c1069c2b26651c897d109863516349d7b09d94199c928b2efceb19719d41123453caa7fde187127bb0c3b16a
|
7
|
+
data.tar.gz: c5d22e44fa047b35f5aadb232f446cc074873dbb4b8638b2f83038208ae0e32535e0668cd19419994d76d1aac95e7a917b711cc8853d589ac3757e9ca90e350c
|
data/README.md
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
# <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=
|
1
|
+
# <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" /> Glimmer (Ruby Desktop Development GUI Library)
|
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)
|
4
5
|
[![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
6
|
|
6
|
-
|
7
|
+
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
8
|
+
|
9
|
+
(The Original Glimmer Library Since 2007. Beware of Imitators!)
|
10
|
+
|
11
|
+
[**Glimmer**](https://rubygems.org/gems/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), a highly portable 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. This achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about GUI concerns or alternatively drive development GUI-first and then write clean business models test-first afterwards. 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). Last but not least, [Glimmer](https://rubygems.org/gems/glimmer) includes native-executable [packaging](#packaging--distribution) support, sorely lacking in competing libraries, thus enabling 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). Given that [JRuby](https://www.jruby.org/) runs on the [JVM](https://java.com/en/download/faq/whatis_java.xml) (Java Virtual Machine), unlike competing libraries like TK, it does not require recompilation of [Ruby](https://www.ruby-lang.org/en/) to use native GUI libraries on every platform. [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) and [Eclipse SWT library](https://www.eclipse.org/swt/).
|
7
12
|
|
8
13
|
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
9
14
|
Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
|
@@ -12,13 +17,13 @@ Glimmer DSL gems:
|
|
12
17
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
13
18
|
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
14
19
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
15
|
-
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
20
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
16
21
|
|
17
22
|
## Examples
|
18
23
|
|
19
24
|
### Hello, World!
|
20
25
|
|
21
|
-
Glimmer code (from
|
26
|
+
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
|
22
27
|
```ruby
|
23
28
|
include Glimmer
|
24
29
|
|
@@ -41,28 +46,28 @@ Glimmer app:
|
|
41
46
|
|
42
47
|
### Tic Tac Toe
|
43
48
|
|
44
|
-
Glimmer code (from
|
49
|
+
Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
|
45
50
|
|
46
51
|
```ruby
|
47
52
|
# ...
|
48
|
-
shell {
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
@shell = shell {
|
54
|
+
text "Tic-Tac-Toe"
|
55
|
+
composite {
|
56
|
+
grid_layout 3, true
|
57
|
+
(1..3).each { |row|
|
58
|
+
(1..3).each { |column|
|
59
|
+
button {
|
60
|
+
layout_data :fill, :fill, true, true
|
61
|
+
text bind(@tic_tac_toe_board[row, column], :sign)
|
62
|
+
enabled bind(@tic_tac_toe_board[row, column], :empty)
|
63
|
+
on_widget_selected {
|
64
|
+
@tic_tac_toe_board.mark(row, column)
|
65
|
+
}
|
66
|
+
}
|
60
67
|
}
|
61
68
|
}
|
62
69
|
}
|
63
70
|
}
|
64
|
-
}
|
65
|
-
}
|
66
71
|
# ...
|
67
72
|
```
|
68
73
|
|
@@ -74,15 +79,103 @@ glimmer samples/elaborate/tic_tac_toe.rb
|
|
74
79
|
|
75
80
|
Glimmer app:
|
76
81
|
|
77
|
-
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
82
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
|
78
83
|
|
79
|
-
|
84
|
+
### Contact Manager
|
80
85
|
|
81
|
-
|
86
|
+
Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
# ...
|
90
|
+
shell {
|
91
|
+
text "Contact Manager"
|
92
|
+
composite {
|
93
|
+
composite {
|
94
|
+
grid_layout 2, false
|
95
|
+
label {text "First &Name: "}
|
96
|
+
text {
|
97
|
+
text bind(@contact_manager_presenter, :first_name)
|
98
|
+
on_key_pressed {|key_event|
|
99
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
100
|
+
}
|
101
|
+
}
|
102
|
+
label {text "&Last Name: "}
|
103
|
+
text {
|
104
|
+
text bind(@contact_manager_presenter, :last_name)
|
105
|
+
on_key_pressed {|key_event|
|
106
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
107
|
+
}
|
108
|
+
}
|
109
|
+
label {text "&Email: "}
|
110
|
+
text {
|
111
|
+
text bind(@contact_manager_presenter, :email)
|
112
|
+
on_key_pressed {|key_event|
|
113
|
+
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
114
|
+
}
|
115
|
+
}
|
116
|
+
composite {
|
117
|
+
grid_layout 2, false
|
118
|
+
button {
|
119
|
+
text "&Find"
|
120
|
+
on_widget_selected {
|
121
|
+
@contact_manager_presenter.find
|
122
|
+
}
|
123
|
+
}
|
124
|
+
button {
|
125
|
+
text "&List All"
|
126
|
+
on_widget_selected {
|
127
|
+
@contact_manager_presenter.list
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
table(:multi) { |table_proxy|
|
134
|
+
layout_data {
|
135
|
+
horizontal_alignment :fill
|
136
|
+
vertical_alignment :fill
|
137
|
+
grab_excess_horizontal_space true
|
138
|
+
grab_excess_vertical_space true
|
139
|
+
height_hint 200
|
140
|
+
}
|
141
|
+
table_column {
|
142
|
+
text "First Name"
|
143
|
+
width 80
|
144
|
+
}
|
145
|
+
table_column {
|
146
|
+
text "Last Name"
|
147
|
+
width 80
|
148
|
+
}
|
149
|
+
table_column {
|
150
|
+
text "Email"
|
151
|
+
width 200
|
152
|
+
}
|
153
|
+
items bind(@contact_manager_presenter, :results),
|
154
|
+
column_properties(:first_name, :last_name, :email)
|
155
|
+
on_mouse_up { |event|
|
156
|
+
table_proxy.edit_table_item(event.table_item, event.column_index)
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}.open
|
161
|
+
# ...
|
162
|
+
```
|
163
|
+
|
164
|
+
Run:
|
165
|
+
|
166
|
+
```
|
167
|
+
glimmer samples/elaborate/contact_manager.rb
|
168
|
+
```
|
169
|
+
|
170
|
+
Glimmer App:
|
171
|
+
|
172
|
+
![Contact Manager](images/glimmer-contact-manager.png)
|
173
|
+
|
174
|
+
NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contributing), adopting for small or low risk projects, and providing feedback.
|
82
175
|
|
83
176
|
## Table of contents
|
84
177
|
|
85
|
-
- [Glimmer
|
178
|
+
- [Glimmer (Ruby Desktop Development GUI Library)](#-glimmer-ruby-desktop-development-gui-library)
|
86
179
|
- [Examples](#examples)
|
87
180
|
- [Hello, World!](#hello-world)
|
88
181
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -101,6 +194,13 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
101
194
|
- [Custom Widget](#custom-widget)
|
102
195
|
- [Custom Shell Gem](#custom-shell-gem)
|
103
196
|
- [Custom Widget Gem](#custom-widget-gem)
|
197
|
+
- [Gem Listing](#gem-listing)
|
198
|
+
- [Listing Custom Shell Gems](#listing-custom-shell-gems)
|
199
|
+
- [Listing Custom Widget Gems](#listing-custom-widget-gems)
|
200
|
+
- [Listing DSL Gems](#listing-dsl-gems)
|
201
|
+
- [Packaging](#packaging)
|
202
|
+
- [Raw JRuby Command](#raw-jruby-command)
|
203
|
+
- [Mac Support](#mac-support)
|
104
204
|
- [Girb (Glimmer irb) Command](#girb-glimmer-irb-command)
|
105
205
|
- [Glimmer DSL Syntax](#glimmer-dsl-syntax)
|
106
206
|
- [Widgets](#widgets)
|
@@ -108,6 +208,7 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
108
208
|
- [SWT Proxies](#swt-proxies)
|
109
209
|
- [Dialog](#dialog)
|
110
210
|
- [Menus](#menus)
|
211
|
+
- [ScrolledComposite](#scrolledcomposite)
|
111
212
|
- [Widget Styles](#widget-styles)
|
112
213
|
- [Explicit SWT Style Bit](#explicit-swt-style-bit)
|
113
214
|
- [Negative SWT Style Bits](#negative-swt-style-bits)
|
@@ -128,29 +229,49 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
128
229
|
- [Observing Models](#observing-models)
|
129
230
|
- [Custom Widgets](#custom-widgets)
|
130
231
|
- [Simple Example](#simple-example)
|
131
|
-
- [Hook Example](#hook-example)
|
232
|
+
- [Lifecycle Hook Example](#lifecycle-hook-example)
|
233
|
+
- [Custom Widget API](#custom-widget-api)
|
132
234
|
- [Content/Options Example](#contentoptions-example)
|
235
|
+
- [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
|
133
236
|
- [Gotcha](#gotcha)
|
237
|
+
- [Final Notes](#final-notes)
|
134
238
|
- [Custom Shells](#custom-shells)
|
239
|
+
- [Drag and Drop](#drag-and-drop)
|
135
240
|
- [Miscellaneous](#miscellaneous)
|
136
241
|
- [Multi-DSL Support](#multi-dsl-support)
|
137
242
|
- [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
|
138
243
|
- [App Name and Version](#app-name-and-version)
|
139
244
|
- [Video Widget](#video-widget)
|
140
245
|
- [Browser Widget](#browser-widget)
|
246
|
+
- [Glimmer Configuration](#glimmer-configuration)
|
247
|
+
- [logger](#logger)
|
248
|
+
- [import_swt_packages](#importswtpackages)
|
249
|
+
- [loop_max_count](#loopmaxcount)
|
141
250
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
251
|
+
- [SWT Reference](#swt-reference)
|
142
252
|
- [Samples](#samples)
|
143
253
|
- [Hello Samples](#hello-samples)
|
254
|
+
- [Hello, World! Sample](#hello-world-sample)
|
255
|
+
- [Hello, Tab!](#hello-tab)
|
256
|
+
- [Hello, Combo!](#hello-combo)
|
257
|
+
- [Hello, List Single Selection!](#hello-list-single-selection)
|
258
|
+
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
259
|
+
- [Hello, Computed!](#hello-computed)
|
260
|
+
- [Hello, Message Box!](#hello-message-box)
|
261
|
+
- [Hello, Browser!](#hello-browser)
|
262
|
+
- [Hello, Drag and Drop!](#hello-drag-and-drop)
|
263
|
+
- [Hello, Menu Bar!](#hello-menu-bar)
|
264
|
+
- [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
|
144
265
|
- [Elaborate Samples](#elaborate-samples)
|
266
|
+
- [Login](#login)
|
267
|
+
- [Tic Tac Toe Sample](#tic-tac-toe-sample)
|
268
|
+
- [Contact Manager](#contact-manager-sample)
|
145
269
|
- [External Samples](#external-samples)
|
146
270
|
- [Glimmer Calculator](#glimmer-calculator)
|
147
271
|
- [Gladiator](#gladiator)
|
148
272
|
- [In Production](#in-production)
|
149
|
-
|
150
|
-
|
151
|
-
- [Logging](#logging)
|
152
|
-
- [Raw JRuby Command](#raw-jruby-command)
|
153
|
-
- [Mac Support](#mac-support)
|
273
|
+
- [Math Bowling](#math-bowling)
|
274
|
+
- [Are We There Yet?](#are-we-there-yet)
|
154
275
|
- [Packaging & Distribution](#packaging--distribution)
|
155
276
|
- [Packaging Defaults](#packaging-defaults)
|
156
277
|
- [Packaging Configuration](#packaging-configuration)
|
@@ -161,11 +282,12 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
161
282
|
- [Resources](#resources)
|
162
283
|
- [Help](#help)
|
163
284
|
- [Issues](#issues)
|
164
|
-
- [
|
285
|
+
- [Chat](#chat)
|
165
286
|
- [Feature Suggestions](#feature-suggestions)
|
166
287
|
- [Change Log](#change-log)
|
167
288
|
- [Contributing](#contributing)
|
168
289
|
- [Contributors](#contributors)
|
290
|
+
- [Hire Me](#hire-me)
|
169
291
|
- [License](#license)
|
170
292
|
|
171
293
|
## Background
|
@@ -192,14 +314,14 @@ https://www.eclipse.org/swt/faq.php
|
|
192
314
|
## Pre-requisites
|
193
315
|
|
194
316
|
- SWT 4.15 (comes included in Glimmer gem)
|
195
|
-
- JRuby 9.2.
|
196
|
-
- JDK 8
|
317
|
+
- JRuby 9.2.12.0 (supporting Ruby 2.5.x syntax) (find at [https://www.jruby.org/download](https://www.jruby.org/download))
|
318
|
+
- JDK 8 (find at [https://www.oracle.com/java/technologies/javase-downloads.html](https://www.oracle.com/java/technologies/javase-downloads.html))
|
197
319
|
- (Optional) RVM is needed for [Scaffolding](#scaffolding) only (find at [https://rvm.io/](https://rvm.io/))
|
198
320
|
|
199
321
|
On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
|
200
322
|
|
201
323
|
```bash
|
202
|
-
rvm install jruby-9.2.
|
324
|
+
rvm install jruby-9.2.12.0
|
203
325
|
```
|
204
326
|
|
205
327
|
Glimmer might still work on lower versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
|
@@ -208,22 +330,36 @@ Glimmer might still work on lower versions of Java, JRuby and SWT, but there are
|
|
208
330
|
|
209
331
|
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.
|
210
332
|
|
211
|
-
|
333
|
+
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)).
|
334
|
+
|
335
|
+
If you intend to build a Glimmer app from scratch on the Mac, pick Option 1 ([Direct Install](#option-1-direct-install)) to leverage [Glimmer Scaffolding](#scaffolding) (only available on the Mac).
|
336
|
+
|
337
|
+
Otherwise, Option 2 ([Bundler](#option-2-bundler)) is recommended for building Glimmer apps on other platforms (Windows and Linux).
|
338
|
+
|
339
|
+
### Option 1: Direct Install
|
340
|
+
(Use for [Scaffolding](#scaffolding) on the Mac)
|
212
341
|
|
213
342
|
Run this command to install directly:
|
214
343
|
```
|
215
|
-
jgem install glimmer-dsl-swt -v 0.1
|
344
|
+
jgem install glimmer-dsl-swt -v 0.4.1
|
216
345
|
```
|
217
346
|
|
218
347
|
`jgem` is JRuby's version of `gem` command.
|
219
348
|
RVM allows running `gem` as an alias.
|
220
349
|
Otherwise, you may also run `jruby -S gem install ...`
|
221
350
|
|
222
|
-
|
351
|
+
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.
|
352
|
+
|
353
|
+
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.
|
354
|
+
|
355
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
356
|
+
|
357
|
+
### Option 2: Bundler
|
358
|
+
(Use for Manual App Creation)
|
223
359
|
|
224
360
|
Add the following to `Gemfile`:
|
225
361
|
```
|
226
|
-
gem 'glimmer-dsl-swt', '~> 0.1
|
362
|
+
gem 'glimmer-dsl-swt', '~> 0.4.1'
|
227
363
|
```
|
228
364
|
|
229
365
|
And, then run:
|
@@ -231,10 +367,16 @@ And, then run:
|
|
231
367
|
jruby -S bundle install
|
232
368
|
```
|
233
369
|
|
370
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
371
|
+
|
234
372
|
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)
|
235
373
|
|
236
374
|
## Glimmer Command
|
237
375
|
|
376
|
+
The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
|
377
|
+
|
378
|
+
If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer DSL Syntax](#glimmer-dsl-syntax), and [Samples](#samples).
|
379
|
+
|
238
380
|
### Basic Usage
|
239
381
|
|
240
382
|
```
|
@@ -271,7 +413,11 @@ Either a single task or one or more applications may be specified.
|
|
271
413
|
When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
|
272
414
|
|
273
415
|
Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
|
416
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
417
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
418
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
274
419
|
glimmer package # Package app for distribution (generating config, jar, and native files)
|
420
|
+
glimmer package:clean # Clean by removing "dist" and "packages" directories
|
275
421
|
glimmer package:config # Generate JAR config file
|
276
422
|
glimmer package:jar # Generate JAR file
|
277
423
|
glimmer package:native # Generate Native files (DMG/PKG/APP on the Mac)
|
@@ -369,6 +515,10 @@ Eventually, it will launch an advanced "Hello, World!" app window having the tit
|
|
369
515
|
|
370
516
|
![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
|
371
517
|
|
518
|
+
On the Mac, it also comes with a boilerplate Preferences dialog.
|
519
|
+
|
520
|
+
![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
|
521
|
+
|
372
522
|
#### Custom Shell
|
373
523
|
|
374
524
|
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
|
@@ -424,11 +574,133 @@ The Ruby gem name will follow the convention "glimmer-cw-customwidgetname-namesp
|
|
424
574
|
|
425
575
|
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)
|
426
576
|
|
427
|
-
|
577
|
+
Examples:
|
578
|
+
|
579
|
+
- [glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video): Video Widget
|
580
|
+
- [glimmer-cw-cdatetime-nebula](https://github.com/AndyObtiva/glimmer-cw-cdatetime-nebula): Nebula CDateTime Widget
|
581
|
+
|
582
|
+
### Gem Listing
|
583
|
+
|
584
|
+
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).
|
585
|
+
|
586
|
+
#### Listing Custom Shell Gems
|
587
|
+
|
588
|
+
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):
|
589
|
+
|
590
|
+
```
|
591
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
592
|
+
```
|
593
|
+
|
594
|
+
Example:
|
595
|
+
|
596
|
+
```
|
597
|
+
glimmer list:custom_shell_gems
|
598
|
+
```
|
599
|
+
|
600
|
+
Output:
|
601
|
+
|
602
|
+
```
|
603
|
+
|
604
|
+
Glimmer Custom Shell Gems at rubygems.org:
|
605
|
+
|
606
|
+
Name Gem Version Author Description
|
607
|
+
|
608
|
+
Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
|
609
|
+
Gladiator glimmer-cs-gladiator 0.2.0 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
|
610
|
+
|
611
|
+
```
|
612
|
+
|
613
|
+
#### Listing Custom Widget Gems
|
614
|
+
|
615
|
+
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):
|
616
|
+
|
617
|
+
```
|
618
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
619
|
+
```
|
620
|
+
|
621
|
+
Example:
|
622
|
+
|
623
|
+
Check if there is a custom video widget for Glimmer.
|
624
|
+
|
625
|
+
```
|
626
|
+
glimmer list:custom_widget_gems[video]
|
627
|
+
```
|
628
|
+
|
629
|
+
Output:
|
630
|
+
|
631
|
+
```
|
632
|
+
|
633
|
+
Glimmer Custom Widget Gems matching [video] at rubygems.org:
|
634
|
+
|
635
|
+
Name Gem Version Author Description
|
636
|
+
|
637
|
+
Video glimmer-cw-video 0.1.1 Andy Maleh Glimmer Custom Widget - Video
|
638
|
+
|
639
|
+
```
|
640
|
+
|
641
|
+
#### Listing DSL Gems
|
642
|
+
|
643
|
+
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):
|
644
|
+
|
645
|
+
```
|
646
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
647
|
+
```
|
648
|
+
|
649
|
+
Example:
|
650
|
+
|
651
|
+
```
|
652
|
+
glimmer list:dsl_gems
|
653
|
+
```
|
654
|
+
|
655
|
+
Output:
|
656
|
+
|
657
|
+
```
|
658
|
+
|
659
|
+
Glimmer DSL Gems at rubygems.org:
|
660
|
+
|
661
|
+
Name Gem Version Author Description
|
662
|
+
|
663
|
+
Css glimmer-dsl-css 0.1.0 AndyMaleh Glimmer DSL for CSS
|
664
|
+
Opal glimmer-dsl-opal 0.0.9 AndyMaleh Glimmer DSL for Opal
|
665
|
+
Swt glimmer-dsl-swt 0.4.1 AndyMaleh Glimmer DSL for SWT
|
666
|
+
Xml glimmer-dsl-xml 0.1.0 AndyMaleh Glimmer DSL for XML
|
667
|
+
|
668
|
+
```
|
669
|
+
|
670
|
+
### Packaging
|
671
|
+
|
672
|
+
Glimmer packaging tasks are detailed under [Packaging & Distribution](#packaging--distribution).
|
673
|
+
|
674
|
+
### Raw JRuby Command
|
675
|
+
|
676
|
+
If there is a need to run Glimmer directly via the `jruby` command, you
|
677
|
+
may run the following:
|
678
|
+
|
679
|
+
```
|
680
|
+
jruby -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
681
|
+
```
|
682
|
+
|
683
|
+
The `-J-classpath` option specifies the `swt.jar` file path, which can be a
|
684
|
+
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.
|
685
|
+
|
686
|
+
The `-r` option preloads (requires) the `glimmer` library in Ruby.
|
687
|
+
|
688
|
+
The `-S` option specifies a script to run.
|
689
|
+
|
690
|
+
#### Mac Support
|
691
|
+
|
692
|
+
The Mac is well supported with the `glimmer` command. The advice below is not needed if you are using it.
|
693
|
+
|
694
|
+
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).
|
695
|
+
|
696
|
+
Example:
|
697
|
+
```
|
698
|
+
jruby -J-XstartOnFirstThread -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
699
|
+
```
|
428
700
|
|
429
701
|
## Girb (Glimmer irb) Command
|
430
702
|
|
431
|
-
With
|
703
|
+
With `glimmer-dsl-swt` installed, you may want to run `girb` instead of standard `irb` to have SWT preloaded and the Glimmer library required and included for quick Glimmer coding/testing.
|
432
704
|
|
433
705
|
```
|
434
706
|
girb
|
@@ -448,13 +720,13 @@ Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-
|
|
448
720
|
|
449
721
|
Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
|
450
722
|
|
451
|
-
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `
|
723
|
+
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `message_box`, `async_exec`, and `bind`.
|
452
724
|
|
453
|
-
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `
|
725
|
+
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `list`.
|
454
726
|
|
455
|
-
The only reason to distinguish between
|
727
|
+
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.
|
456
728
|
|
457
|
-
For example, if a project adds this custom SWT library:
|
729
|
+
For example, if a project adds this custom Java SWT library:
|
458
730
|
|
459
731
|
https://www.eclipse.org/nebula/widgets/cdatetime/cdatetime.php?page=operation
|
460
732
|
|
@@ -547,22 +819,22 @@ Check out the [samples](samples) directory for more examples.
|
|
547
819
|
|
548
820
|
Example from [hello_tab.rb](samples/hello/hello_tab.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
549
821
|
|
550
|
-
![Hello Tab
|
822
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
551
823
|
|
552
|
-
![Hello Tab
|
824
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
553
825
|
|
554
826
|
```ruby
|
555
827
|
shell {
|
556
|
-
text "
|
828
|
+
text "Hello, Tab!"
|
557
829
|
tab_folder {
|
558
830
|
tab_item {
|
559
|
-
text "
|
831
|
+
text "English"
|
560
832
|
label {
|
561
833
|
text "Hello, World!"
|
562
834
|
}
|
563
835
|
}
|
564
836
|
tab_item {
|
565
|
-
text "
|
837
|
+
text "French"
|
566
838
|
label {
|
567
839
|
text "Bonjour Univers!"
|
568
840
|
}
|
@@ -582,7 +854,7 @@ automatically uses the display created earlier without having to explicitly hook
|
|
582
854
|
```ruby
|
583
855
|
@display = display {
|
584
856
|
cursor_location 300, 300
|
585
|
-
|
857
|
+
on_swt_keydown {
|
586
858
|
# ...
|
587
859
|
}
|
588
860
|
# ...
|
@@ -634,27 +906,34 @@ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
634
906
|
@shell.open
|
635
907
|
```
|
636
908
|
|
637
|
-
#####
|
909
|
+
##### `message_box`
|
638
910
|
|
639
|
-
Glimmer
|
911
|
+
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.
|
640
912
|
|
641
913
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
642
914
|
|
643
915
|
```ruby
|
916
|
+
include Glimmer
|
917
|
+
|
644
918
|
@shell = shell {
|
919
|
+
text 'Hello, Message Box!'
|
645
920
|
button {
|
646
|
-
text
|
921
|
+
text 'Please Click To Win a Surprise'
|
647
922
|
on_widget_selected {
|
648
|
-
message_box
|
649
|
-
|
650
|
-
|
651
|
-
|
923
|
+
message_box(@shell) {
|
924
|
+
text 'Surprise'
|
925
|
+
message "Congratulations!\n\nYou have won $1,000,000!"
|
926
|
+
}.open
|
652
927
|
}
|
653
928
|
}
|
654
929
|
}
|
655
930
|
@shell.open
|
656
931
|
```
|
657
932
|
|
933
|
+
##### `#swt_widget`
|
934
|
+
|
935
|
+
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.
|
936
|
+
|
658
937
|
##### Shell widget proxy methods
|
659
938
|
|
660
939
|
Shell widget proxy has extra methods specific to SWT Shell:
|
@@ -682,7 +961,7 @@ Glimmer DSL provides support for SWT Menu and MenuItem widgets.
|
|
682
961
|
|
683
962
|
There are 2 main types of menus in SWT:
|
684
963
|
- Menu Bar (shows up on top)
|
685
|
-
- Pop Up Menu (shows up when right-clicking a widget)
|
964
|
+
- Pop Up Context Menu (shows up when right-clicking a widget)
|
686
965
|
|
687
966
|
Underneath both types, there can be a 3rd menu type called Drop Down.
|
688
967
|
|
@@ -690,39 +969,63 @@ Glimmer provides special support for Drop Down menus as it automatically instant
|
|
690
969
|
|
691
970
|
The ampersand symbol indicates the keyboard shortcut key for the menu item (e.g. '&Help' can be triggered on Windows by hitting ALT+H)
|
692
971
|
|
693
|
-
Example
|
972
|
+
Example of a Menu Bar (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
694
973
|
|
695
974
|
```ruby
|
696
|
-
shell {
|
975
|
+
shell { |shell_proxy|
|
976
|
+
text 'Hello, Menu Bar!'
|
977
|
+
grid_layout
|
978
|
+
label(:center) {
|
979
|
+
font height: 16
|
980
|
+
text 'Check Out The File Menu and History Menu in The Menu Bar Above!'
|
981
|
+
}
|
697
982
|
menu_bar {
|
698
983
|
menu {
|
699
|
-
text
|
984
|
+
text '&File'
|
700
985
|
menu_item {
|
701
|
-
text
|
986
|
+
text 'E&xit'
|
702
987
|
}
|
703
988
|
menu_item(0) {
|
704
|
-
text
|
989
|
+
text '&New'
|
990
|
+
on_widget_selected {
|
991
|
+
message_box(shell_proxy) {
|
992
|
+
text 'New File'
|
993
|
+
message 'New File Contents'
|
994
|
+
}.open
|
995
|
+
}
|
705
996
|
}
|
706
997
|
menu(1) {
|
707
|
-
text
|
998
|
+
text '&Options'
|
708
999
|
menu_item(:radio) {
|
709
|
-
text
|
1000
|
+
text 'Option 1'
|
710
1001
|
}
|
711
1002
|
menu_item(:separator)
|
712
1003
|
menu_item(:check) {
|
713
|
-
text
|
1004
|
+
text 'Option 3'
|
714
1005
|
}
|
715
1006
|
}
|
716
1007
|
}
|
717
1008
|
menu {
|
718
|
-
text
|
1009
|
+
text '&History'
|
719
1010
|
menu {
|
720
|
-
text
|
1011
|
+
text '&Recent'
|
721
1012
|
menu_item {
|
722
|
-
text
|
1013
|
+
text 'File 1'
|
1014
|
+
on_widget_selected {
|
1015
|
+
message_box(shell_proxy) {
|
1016
|
+
text 'File 1'
|
1017
|
+
message 'File 1 Contents'
|
1018
|
+
}.open
|
1019
|
+
}
|
723
1020
|
}
|
724
1021
|
menu_item {
|
725
|
-
text
|
1022
|
+
text 'File 2'
|
1023
|
+
on_widget_selected {
|
1024
|
+
message_box(shell_proxy) {
|
1025
|
+
text 'File 2'
|
1026
|
+
message 'File 2 Contents'
|
1027
|
+
}.open
|
1028
|
+
}
|
726
1029
|
}
|
727
1030
|
}
|
728
1031
|
}
|
@@ -730,22 +1033,37 @@ shell {
|
|
730
1033
|
}.open
|
731
1034
|
```
|
732
1035
|
|
733
|
-
Example
|
1036
|
+
Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
734
1037
|
|
735
1038
|
```ruby
|
736
|
-
shell {
|
1039
|
+
shell { |shell_proxy|
|
1040
|
+
text 'Hello, Pop Up Context Menu!'
|
1041
|
+
grid_layout
|
737
1042
|
label {
|
738
|
-
|
1043
|
+
font height: 16
|
1044
|
+
text 'Right-Click To Pop Up a Context Menu'
|
739
1045
|
menu {
|
740
1046
|
menu {
|
741
1047
|
text '&History'
|
742
1048
|
menu {
|
743
|
-
text
|
1049
|
+
text '&Recent'
|
744
1050
|
menu_item {
|
745
|
-
text
|
1051
|
+
text 'File 1'
|
1052
|
+
on_widget_selected {
|
1053
|
+
message_box(shell_proxy) {
|
1054
|
+
text 'File 1'
|
1055
|
+
message 'File 1 Contents'
|
1056
|
+
}.open
|
1057
|
+
}
|
746
1058
|
}
|
747
1059
|
menu_item {
|
748
|
-
text
|
1060
|
+
text 'File 2'
|
1061
|
+
on_widget_selected {
|
1062
|
+
message_box(shell_proxy) {
|
1063
|
+
text 'File 2'
|
1064
|
+
message 'File 2 Contents'
|
1065
|
+
}.open
|
1066
|
+
}
|
749
1067
|
}
|
750
1068
|
}
|
751
1069
|
}
|
@@ -754,6 +1072,13 @@ shell {
|
|
754
1072
|
}.open
|
755
1073
|
```
|
756
1074
|
|
1075
|
+
#### ScrolledComposite
|
1076
|
+
|
1077
|
+
Glimmer provides smart defaults for the `scrolled_composite` widget by:
|
1078
|
+
- Automatically setting the nested widget as its content (meaning use can just like a plain old `composite` to add scrolling)
|
1079
|
+
- 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 )
|
1080
|
+
- Automatically setting the expand horizontal and expand vertical SWT properties to `true`
|
1081
|
+
|
757
1082
|
### Widget Styles
|
758
1083
|
|
759
1084
|
SWT widgets receive `SWT` styles in their constructor as per this guide:
|
@@ -999,9 +1324,12 @@ composite {
|
|
999
1324
|
```
|
1000
1325
|
|
1001
1326
|
Here is a more sophisticated example taken from [hello_computed.rb](samples/hello/hello_computed.rb) sample:
|
1327
|
+
|
1328
|
+
![Hello Computed](images/glimmer-hello-computed.png)
|
1329
|
+
|
1002
1330
|
```ruby
|
1003
1331
|
shell {
|
1004
|
-
text
|
1332
|
+
text 'Hello, Computed!'
|
1005
1333
|
composite {
|
1006
1334
|
grid_layout {
|
1007
1335
|
num_columns 2
|
@@ -1009,44 +1337,44 @@ shell {
|
|
1009
1337
|
horizontal_spacing 20
|
1010
1338
|
vertical_spacing 10
|
1011
1339
|
}
|
1012
|
-
label {text
|
1340
|
+
label {text 'First &Name: '}
|
1013
1341
|
text {
|
1014
1342
|
text bind(@contact, :first_name)
|
1015
1343
|
layout_data {
|
1016
|
-
|
1017
|
-
|
1344
|
+
horizontal_alignment :fill
|
1345
|
+
grab_excess_horizontal_space true
|
1018
1346
|
}
|
1019
1347
|
}
|
1020
|
-
label {text
|
1348
|
+
label {text '&Last Name: '}
|
1021
1349
|
text {
|
1022
1350
|
text bind(@contact, :last_name)
|
1023
1351
|
layout_data {
|
1024
|
-
|
1025
|
-
|
1352
|
+
horizontal_alignment :fill
|
1353
|
+
grab_excess_horizontal_space true
|
1026
1354
|
}
|
1027
1355
|
}
|
1028
|
-
label {text
|
1356
|
+
label {text '&Year of Birth: '}
|
1029
1357
|
text {
|
1030
1358
|
text bind(@contact, :year_of_birth)
|
1031
1359
|
layout_data {
|
1032
|
-
|
1033
|
-
|
1360
|
+
horizontal_alignment :fill
|
1361
|
+
grab_excess_horizontal_space true
|
1034
1362
|
}
|
1035
1363
|
}
|
1036
|
-
label {text
|
1364
|
+
label {text 'Name: '}
|
1037
1365
|
label {
|
1038
1366
|
text bind(@contact, :name, computed_by: [:first_name, :last_name])
|
1039
1367
|
layout_data {
|
1040
|
-
|
1041
|
-
|
1368
|
+
horizontal_alignment :fill
|
1369
|
+
grab_excess_horizontal_space true
|
1042
1370
|
}
|
1043
1371
|
}
|
1044
|
-
label {text
|
1372
|
+
label {text 'Age: '}
|
1045
1373
|
label {
|
1046
1374
|
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
|
1047
1375
|
layout_data {
|
1048
|
-
|
1049
|
-
|
1376
|
+
horizontal_alignment :fill
|
1377
|
+
grab_excess_horizontal_space true
|
1050
1378
|
}
|
1051
1379
|
}
|
1052
1380
|
}
|
@@ -1189,6 +1517,10 @@ Example from [samples/hello/hello_combo.rb](samples/hello_combo.rb) sample (you
|
|
1189
1517
|
|
1190
1518
|
#### Combo
|
1191
1519
|
|
1520
|
+
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.
|
1521
|
+
|
1522
|
+
When data-binding a `combo` widget, Glimmer can automatically deduce available options from data-bound model by convention: `{attribute_name}_options` method.
|
1523
|
+
|
1192
1524
|
![Hello Combo](images/glimmer-hello-combo.png)
|
1193
1525
|
|
1194
1526
|
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
@@ -1230,7 +1562,7 @@ end
|
|
1230
1562
|
HelloCombo.new.launch
|
1231
1563
|
```
|
1232
1564
|
|
1233
|
-
`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.
|
1565
|
+
`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.
|
1234
1566
|
|
1235
1567
|
#### List
|
1236
1568
|
|
@@ -1344,6 +1676,9 @@ shell {
|
|
1344
1676
|
}
|
1345
1677
|
items bind(group, :people), column_properties(:name, :age, :adult)
|
1346
1678
|
selection bind(group, :selected_person)
|
1679
|
+
on_mouse_up { |event|
|
1680
|
+
@table.edit_table_item(event.table_item, event.column_index)
|
1681
|
+
}
|
1347
1682
|
}
|
1348
1683
|
}
|
1349
1684
|
```
|
@@ -1351,6 +1686,7 @@ shell {
|
|
1351
1686
|
The code above includes two data-bindings:
|
1352
1687
|
- 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.
|
1353
1688
|
- 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)
|
1689
|
+
- 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.)
|
1354
1690
|
|
1355
1691
|
Additionally, Table `items` data-binding automatically stores each node model unto the SWT TableItem object via `setData` method. This enables things like searchability.
|
1356
1692
|
|
@@ -1370,6 +1706,67 @@ This automatically leverages the SWT TableEditor custom class behind the scenes,
|
|
1370
1706
|
passed table item text into something else.
|
1371
1707
|
It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
1372
1708
|
|
1709
|
+
##### Table Sorting
|
1710
|
+
|
1711
|
+
Glimmer automatically adds sorting support to the SWT `Table` widget.
|
1712
|
+
|
1713
|
+
Check out the [Contact Manager](#contact-manager) sample for an example.
|
1714
|
+
You may click on any column and it will sort by ascending order first and descending if you click again.
|
1715
|
+
|
1716
|
+
Glimmer automatic table sorting supports `String`, `Integer`, and `Float` columns out of the box as well as any column data that is comparable.
|
1717
|
+
|
1718
|
+
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`.
|
1719
|
+
|
1720
|
+
Should you have a special data type that could not be compared automatically, Glimmer offers the following 3 alternatives for custom sorting:
|
1721
|
+
- `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`).
|
1722
|
+
- `sort_by(&block)`: this works just like Ruby `Enumerable` `sort_by`. The block receives the table column data as argument.
|
1723
|
+
- `sort(&comparator)`: this works just like Ruby `Enumerable` `sort`. The comparator block receives two objects from the table column data.
|
1724
|
+
|
1725
|
+
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)
|
1726
|
+
|
1727
|
+
Example:
|
1728
|
+
|
1729
|
+
```ruby
|
1730
|
+
# ...
|
1731
|
+
table {
|
1732
|
+
table_column {
|
1733
|
+
text 'Task'
|
1734
|
+
width 120
|
1735
|
+
}
|
1736
|
+
table_column {
|
1737
|
+
text 'Project'
|
1738
|
+
width 120
|
1739
|
+
}
|
1740
|
+
table_column {
|
1741
|
+
text 'Duration (hours)'
|
1742
|
+
width 120
|
1743
|
+
sort_property :duration_in_hours
|
1744
|
+
}
|
1745
|
+
table_column {
|
1746
|
+
text 'Priority'
|
1747
|
+
width 120
|
1748
|
+
sort_by { |value| ['High', 'Medium', 'Low'].index(value) }
|
1749
|
+
}
|
1750
|
+
table_column {
|
1751
|
+
text 'Start Date'
|
1752
|
+
width 120
|
1753
|
+
sort { |d1, d2| d1.to_date <=> d2.to_date }
|
1754
|
+
}
|
1755
|
+
additional_sort_properties :project_name, :duration_in_hours, :name
|
1756
|
+
items bind(Task, :list), column_properties(:name, :project_name, :duration, :priority, :start_date)
|
1757
|
+
# ...
|
1758
|
+
}
|
1759
|
+
# ...
|
1760
|
+
```
|
1761
|
+
|
1762
|
+
Here is an explanation of the example above:
|
1763
|
+
- Task and Project table columns are data-bound to the `:name` and `:project_name` properties and sorted through them automatically
|
1764
|
+
- Task Duration table column is data-bound to the `:duration` property, but sorted via the `:duration_in_hours` property instead
|
1765
|
+
- Task Priority table column has a custom sort_by block
|
1766
|
+
- Task Start Date table column has a custom sort comparator block
|
1767
|
+
- Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
|
1768
|
+
|
1769
|
+
|
1373
1770
|
#### Tree
|
1374
1771
|
|
1375
1772
|
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
@@ -1417,10 +1814,10 @@ Glimmer comes with `Observer` module, which is used internally for data-binding,
|
|
1417
1814
|
|
1418
1815
|
Glimmer supports observing widgets with two main types of events:
|
1419
1816
|
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`).
|
1420
|
-
2. `
|
1817
|
+
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)
|
1421
1818
|
|
1422
1819
|
Additionally, there are two more types of events:
|
1423
|
-
- SWT `display` supports global listeners called filters that run on any widget. They are hooked via `
|
1820
|
+
- SWT `display` supports global listeners called filters that run on any widget. They are hooked via `on_swt_{swt-event-constant}`
|
1424
1821
|
- SWT `display` supports Mac application menu item observers (`on_about` and `on_preferences`), which you can read about under [Miscellaneous](#miscellaneous).
|
1425
1822
|
|
1426
1823
|
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.
|
@@ -1465,21 +1862,21 @@ Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties da
|
|
1465
1862
|
|
1466
1863
|
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.
|
1467
1864
|
|
1468
|
-
**Regarding number 2**, you can figure out all available events by looking at the `org.eclipse.swt.SWT` API:
|
1865
|
+
**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:
|
1469
1866
|
|
1470
1867
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
1471
1868
|
|
1472
1869
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1473
1870
|
|
1474
|
-
`SWT.Show` - hooks a listener for showing a widget (using `
|
1475
|
-
`SWT.Hide` - hooks a listener for hiding a widget (using `
|
1871
|
+
`SWT.Show` - hooks a listener for showing a widget (using `on_swt_show` in Glimmer)
|
1872
|
+
`SWT.Hide` - hooks a listener for hiding a widget (using `on_swt_hide` in Glimmer)
|
1476
1873
|
|
1477
1874
|
```ruby
|
1478
1875
|
shell {
|
1479
1876
|
@button1 = button {
|
1480
1877
|
text "Show 2nd Button"
|
1481
1878
|
visible true
|
1482
|
-
|
1879
|
+
on_swt_show {
|
1483
1880
|
@button2.swt_widget.setVisible(false)
|
1484
1881
|
}
|
1485
1882
|
on_widget_selected {
|
@@ -1489,7 +1886,7 @@ shell {
|
|
1489
1886
|
@button2 = button {
|
1490
1887
|
text "Show 1st Button"
|
1491
1888
|
visible false
|
1492
|
-
|
1889
|
+
on_swt_show {
|
1493
1890
|
@button1.swt_widget.setVisible(false)
|
1494
1891
|
}
|
1495
1892
|
on_widget_selected {
|
@@ -1499,7 +1896,7 @@ shell {
|
|
1499
1896
|
}.open
|
1500
1897
|
```
|
1501
1898
|
|
1502
|
-
**Gotcha:** SWT.Resize event needs to be hooked using **`
|
1899
|
+
**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`
|
1503
1900
|
|
1504
1901
|
##### Alternative Syntax
|
1505
1902
|
|
@@ -1542,7 +1939,7 @@ class TicTacToe
|
|
1542
1939
|
end
|
1543
1940
|
```
|
1544
1941
|
|
1545
|
-
Observers can be a good mechanism for displaying dialog messages in Glimmer (using SWT's `MessageBox`).
|
1942
|
+
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).
|
1546
1943
|
|
1547
1944
|
Look at [`samples/elaborate/tictactoe/tic_tac_toe.rb`](samples/tictactoe/tic_tac_toe.rb) for more details starting with the code included below.
|
1548
1945
|
|
@@ -1568,10 +1965,10 @@ class TicTacToe
|
|
1568
1965
|
end
|
1569
1966
|
|
1570
1967
|
def display_game_over_message(message)
|
1571
|
-
message_box
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1968
|
+
message_box(@shell) {
|
1969
|
+
text 'Game Over'
|
1970
|
+
message message_text
|
1971
|
+
}.open
|
1575
1972
|
@tic_tac_toe_board.reset
|
1576
1973
|
end
|
1577
1974
|
# ...
|
@@ -1612,7 +2009,7 @@ shell {
|
|
1612
2009
|
|
1613
2010
|
As you can see, `RedLabel` became Glimmer DSL keyword: `red_label`
|
1614
2011
|
|
1615
|
-
#### Hook Example
|
2012
|
+
#### Lifecycle Hook Example
|
1616
2013
|
|
1617
2014
|
(you may copy/paste in [`girb`](#girb-glimmer-irb-command))
|
1618
2015
|
|
@@ -1647,10 +2044,12 @@ shell {
|
|
1647
2044
|
}.open
|
1648
2045
|
```
|
1649
2046
|
|
1650
|
-
Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention. Additionally, `before_body` hook was utilized to set a `@color` variable and use inside the `body`.
|
2047
|
+
Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention. Additionally, the `before_body` lifecycle hook was utilized to set a `@color` variable and use inside the `body`.
|
1651
2048
|
|
1652
2049
|
Keep in mind that namespaces are not needed to be specified if the Custom Widget class has a unique name, not clashing with a basic SWT widget or another custom widget name.
|
1653
2050
|
|
2051
|
+
#### Custom Widget API
|
2052
|
+
|
1654
2053
|
Custom Widgets have the following attributes available to call from inside the `#body` method:
|
1655
2054
|
- `#parent`: Glimmer object parenting custom widget
|
1656
2055
|
- `#swt_style`: SWT style integer. Can be useful if you want to allow consumers to customize a widget inside the custom widget body
|
@@ -1705,7 +2104,9 @@ shell {
|
|
1705
2104
|
|
1706
2105
|
Notice how `:no_focus` was the `swt_style` value, followed by the `options` hash `{orientation: :horizontal, bg_color: :white}`, and finally the `content` block containing the label with `'SANDWICH CONTENT'`
|
1707
2106
|
|
1708
|
-
|
2107
|
+
#### Custom Widget Lifecycle Hooks
|
2108
|
+
|
2109
|
+
Last but not least, these are the available lifecycle hooks:
|
1709
2110
|
- `before_body`: takes a block that executes in the custom widget instance scope before calling `body`. Useful for initializing variables to later use in `body`
|
1710
2111
|
- `after_body`: takes a block that executes in the custom widget instance scope after calling `body`. Useful for setting up observers on widgets built in `body` (set in instance variables) and linking to other shells.
|
1711
2112
|
|
@@ -1739,6 +2140,11 @@ body {
|
|
1739
2140
|
|
1740
2141
|
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`.
|
1741
2142
|
|
2143
|
+
#### Final Notes
|
2144
|
+
|
2145
|
+
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:
|
2146
|
+
[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)
|
2147
|
+
|
1742
2148
|
### Custom Shells
|
1743
2149
|
|
1744
2150
|
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.
|
@@ -1784,7 +2190,7 @@ shell { |app_shell|
|
|
1784
2190
|
@current_step_number = 1
|
1785
2191
|
@wizard_steps = 5.times.map { |n|
|
1786
2192
|
wizard_step(number: n+1, step_count: 5) {
|
1787
|
-
|
2193
|
+
on_swt_hide {
|
1788
2194
|
if @current_step_number < 5
|
1789
2195
|
@current_step_number += 1
|
1790
2196
|
app_shell.hide
|
@@ -1804,6 +2210,62 @@ shell { |app_shell|
|
|
1804
2210
|
}.open
|
1805
2211
|
```
|
1806
2212
|
|
2213
|
+
### Drag and Drop
|
2214
|
+
|
2215
|
+
Glimmer offers Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
|
2216
|
+
|
2217
|
+
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)
|
2218
|
+
|
2219
|
+
To get started, simply follow these steps:
|
2220
|
+
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)
|
2221
|
+
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)
|
2222
|
+
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)
|
2223
|
+
1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
|
2224
|
+
|
2225
|
+
Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2226
|
+
|
2227
|
+
```ruby
|
2228
|
+
class Location
|
2229
|
+
attr_accessor :country
|
2230
|
+
|
2231
|
+
def country_options
|
2232
|
+
%w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
2233
|
+
end
|
2234
|
+
end
|
2235
|
+
|
2236
|
+
@location = Location.new
|
2237
|
+
|
2238
|
+
include Glimmer
|
2239
|
+
|
2240
|
+
shell {
|
2241
|
+
text 'Hello, Drag and Drop!'
|
2242
|
+
list {
|
2243
|
+
selection bind(@location, :country)
|
2244
|
+
on_drag_set_data { |event|
|
2245
|
+
list = event.widget.getControl
|
2246
|
+
event.data = list.getSelection.first
|
2247
|
+
}
|
2248
|
+
}
|
2249
|
+
label(:center) {
|
2250
|
+
text 'Drag a country here!'
|
2251
|
+
font height: 20
|
2252
|
+
on_drop { |event|
|
2253
|
+
event.widget.getControl.setText(event.data)
|
2254
|
+
}
|
2255
|
+
}
|
2256
|
+
}.open
|
2257
|
+
```
|
2258
|
+
|
2259
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2260
|
+
|
2261
|
+
Optional steps:
|
2262
|
+
- 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.
|
2263
|
+
- Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2264
|
+
- 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)
|
2265
|
+
- Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2266
|
+
- 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)
|
2267
|
+
- Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
|
2268
|
+
|
1807
2269
|
### Miscellaneous
|
1808
2270
|
|
1809
2271
|
#### Multi-DSL Support
|
@@ -1959,10 +2421,10 @@ class Example
|
|
1959
2421
|
def initialize
|
1960
2422
|
display {
|
1961
2423
|
on_about {
|
1962
|
-
message_box
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
2424
|
+
message_box(@shell_proxy) {
|
2425
|
+
text 'About'
|
2426
|
+
message 'About Application'
|
2427
|
+
}.open
|
1966
2428
|
}
|
1967
2429
|
on_preferences {
|
1968
2430
|
preferences_dialog = dialog {
|
@@ -2028,7 +2490,7 @@ Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app versi
|
|
2028
2490
|
|
2029
2491
|
#### Video Widget
|
2030
2492
|
|
2031
|
-
![Video Widget](images/glimmer-video-widget.png)
|
2493
|
+
[![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
|
2032
2494
|
|
2033
2495
|
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
|
2034
2496
|
|
@@ -2036,7 +2498,9 @@ You may obtain via `glimmer-cw-video` gem.
|
|
2036
2498
|
|
2037
2499
|
#### Browser Widget
|
2038
2500
|
|
2039
|
-
|
2501
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2502
|
+
|
2503
|
+
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).
|
2040
2504
|
|
2041
2505
|
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2042
2506
|
|
@@ -2072,6 +2536,123 @@ shell {
|
|
2072
2536
|
|
2073
2537
|
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).
|
2074
2538
|
|
2539
|
+
## Glimmer Configuration
|
2540
|
+
|
2541
|
+
Glimmer configuration may be done via the `Glimmer::Config` module.
|
2542
|
+
|
2543
|
+
### logger
|
2544
|
+
|
2545
|
+
Glimmer supports logging via a standard `STDOUT` Ruby `Logger` configured in the `Glimmer::Config.logger` config option.
|
2546
|
+
It is set to level Logger::ERROR by default.
|
2547
|
+
Log level may be adjusted via `Glimmer::Config.logger.level` just like any other Ruby Logger.
|
2548
|
+
It may be replaced with a custom logger via `Glimmer::Config.logger = custom_logger`
|
2549
|
+
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.
|
2550
|
+
|
2551
|
+
Example:
|
2552
|
+
|
2553
|
+
```ruby
|
2554
|
+
Glimmer::Config.logger.level = :debug
|
2555
|
+
```
|
2556
|
+
This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
|
2557
|
+
|
2558
|
+
Example log:
|
2559
|
+
```
|
2560
|
+
D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
|
2561
|
+
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2562
|
+
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2563
|
+
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2564
|
+
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2565
|
+
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2566
|
+
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2567
|
+
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2568
|
+
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2569
|
+
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2570
|
+
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2571
|
+
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2572
|
+
```
|
2573
|
+
|
2574
|
+
### import_swt_packages
|
2575
|
+
|
2576
|
+
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.
|
2577
|
+
|
2578
|
+
As a result, you may call SWT Java classes from Glimmer Ruby code without mentioning Java package references explicitly.
|
2579
|
+
|
2580
|
+
For example, `org.eclipse.swt.graphics.Color` can be referenced as just `Color`
|
2581
|
+
|
2582
|
+
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:
|
2583
|
+
```
|
2584
|
+
org.eclipse.swt.*
|
2585
|
+
org.eclipse.swt.widgets.*
|
2586
|
+
org.eclipse.swt.layout.*
|
2587
|
+
org.eclipse.swt.graphics.*
|
2588
|
+
org.eclipse.swt.browser.*
|
2589
|
+
org.eclipse.swt.custom.*
|
2590
|
+
org.eclipse.swt.dnd.*
|
2591
|
+
```
|
2592
|
+
|
2593
|
+
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).
|
2594
|
+
|
2595
|
+
Example:
|
2596
|
+
|
2597
|
+
```ruby
|
2598
|
+
Glimmer::Config.import_swt_packages += [
|
2599
|
+
'org.eclipse.nebula.widgets.ganttchart'
|
2600
|
+
]
|
2601
|
+
```
|
2602
|
+
|
2603
|
+
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)
|
2604
|
+
|
2605
|
+
Nonetheless, you can disable automatic Java package import if needed via this Glimmer configuration option:
|
2606
|
+
|
2607
|
+
```ruby
|
2608
|
+
Glimmer::Config.import_swt_packages = false
|
2609
|
+
```
|
2610
|
+
|
2611
|
+
Once disabled, to import SWT Java packages manually, you may simply:
|
2612
|
+
|
2613
|
+
1. `include Glimmer::SWT::Packages`: lazily imports all SWT Java packages to your class, lazy-loading SWT Java class constants on first reference.
|
2614
|
+
|
2615
|
+
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'`)
|
2616
|
+
|
2617
|
+
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.
|
2618
|
+
|
2619
|
+
You can learn more about importing Java packages into Ruby code at this JRuby WIKI page:
|
2620
|
+
|
2621
|
+
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
|
2622
|
+
|
2623
|
+
### loop_max_count
|
2624
|
+
|
2625
|
+
Glimmer has infinite loop detection support.
|
2626
|
+
It can detect when an infinite loop is about to occur in method_missing and stops it.
|
2627
|
+
It detects potential infinite loops when the same keyword and args repeat more than 100 times, which is unusual in a GUI app.
|
2628
|
+
|
2629
|
+
The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` config option.
|
2630
|
+
|
2631
|
+
Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
|
2632
|
+
|
2633
|
+
### excluded_keyword_checkers
|
2634
|
+
|
2635
|
+
Glimmer permits consumers to exclude keywords from DSL processing by its engine via the `excluded_keyword_checkers` config option.
|
2636
|
+
|
2637
|
+
To do so, add a proc to it that returns a boolean indicating if a keyword is excluded or not.
|
2638
|
+
|
2639
|
+
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.
|
2640
|
+
|
2641
|
+
Example of keywords excluded by [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt):
|
2642
|
+
|
2643
|
+
```ruby
|
2644
|
+
Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
2645
|
+
method = method_symbol.to_s
|
2646
|
+
result = false
|
2647
|
+
result ||= method.start_with?('on_swt_') && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
|
2648
|
+
result ||= method == 'dispose' && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
|
2649
|
+
result ||= ['drag_source_proxy', 'drop_target_proxy'].include?(method) && is_a?(Glimmer::UI::CustomWidget)
|
2650
|
+
result ||= method == 'post_initialize_child'
|
2651
|
+
result ||= method.end_with?('=')
|
2652
|
+
result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
|
2653
|
+
end
|
2654
|
+
```
|
2655
|
+
|
2075
2656
|
## Glimmer Style Guide
|
2076
2657
|
|
2077
2658
|
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
@@ -2087,11 +2668,43 @@ This relies on Glimmer's [Multi-DSL Support](#multi-dsl-support) for building th
|
|
2087
2668
|
- Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
|
2088
2669
|
- 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.
|
2089
2670
|
|
2671
|
+
## SWT Reference
|
2672
|
+
|
2673
|
+
https://www.eclipse.org/swt/docs.php
|
2674
|
+
|
2675
|
+
Here is the SWT API:
|
2676
|
+
|
2677
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
|
2678
|
+
|
2679
|
+
Here is a visual list of SWT widgets:
|
2680
|
+
|
2681
|
+
https://www.eclipse.org/swt/widgets/
|
2682
|
+
|
2683
|
+
Here is a textual list of SWT widgets:
|
2684
|
+
|
2685
|
+
https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
|
2686
|
+
|
2687
|
+
Here is a list of SWT style bits as used in widget declaration:
|
2688
|
+
|
2689
|
+
https://wiki.eclipse.org/SWT_Widget_Style_Bits
|
2690
|
+
|
2691
|
+
Here is a SWT style bit constant reference:
|
2692
|
+
|
2693
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
2694
|
+
|
2695
|
+
Here is an SWT Drag and Drop guide:
|
2696
|
+
|
2697
|
+
https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
|
2698
|
+
|
2699
|
+
Here is an SWT Custom Widget guide:
|
2700
|
+
|
2701
|
+
https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
|
2702
|
+
|
2090
2703
|
## Samples
|
2091
2704
|
|
2092
|
-
Check the [samples](samples) directory 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`).
|
2705
|
+
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`).
|
2093
2706
|
|
2094
|
-
If you cloned the project and followed [CONTRIBUTING.md](CONTRIBUTING.md) instructions, you may run all samples at once via `samples/launch` command:
|
2707
|
+
If you cloned the project and followed [CONTRIBUTING.md](CONTRIBUTING.md) instructions, you may run all samples in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) at once via `samples/launch` command:
|
2095
2708
|
|
2096
2709
|
```
|
2097
2710
|
samples/launch
|
@@ -2099,168 +2712,306 @@ samples/launch
|
|
2099
2712
|
|
2100
2713
|
### Hello Samples
|
2101
2714
|
|
2102
|
-
For
|
2715
|
+
For hello-type simple samples, check the following.
|
2716
|
+
|
2717
|
+
#### Hello, World! Sample
|
2718
|
+
|
2719
|
+
Code:
|
2720
|
+
|
2721
|
+
[samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)
|
2722
|
+
|
2723
|
+
Run:
|
2103
2724
|
|
2104
2725
|
```
|
2105
2726
|
glimmer samples/hello/hello_world.rb
|
2106
|
-
glimmer samples/hello/hello_browser.rb # demonstrates browser widget
|
2107
|
-
glimmer samples/hello/hello_tab.rb # demonstrates tabs
|
2108
|
-
glimmer samples/hello/hello_combo.rb # demonstrates combo data-binding
|
2109
|
-
glimmer samples/hello/hello_list_single_selection.rb # demonstrates list single-selection data-binding
|
2110
|
-
glimmer samples/hello/hello_list_multi_selection.rb # demonstrates list multi-selection data-binding
|
2111
|
-
glimmer samples/hello/hello_computed.rb # demonstrates computed data-binding
|
2112
2727
|
```
|
2113
2728
|
|
2114
|
-
|
2729
|
+
![Hello World](images/glimmer-hello-world.png)
|
2115
2730
|
|
2116
|
-
|
2731
|
+
#### Hello, Tab!
|
2732
|
+
|
2733
|
+
Code:
|
2734
|
+
|
2735
|
+
[samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_tab.rb)
|
2736
|
+
|
2737
|
+
Run:
|
2117
2738
|
|
2118
2739
|
```
|
2119
|
-
glimmer samples/
|
2120
|
-
glimmer samples/elaborate/contact_manager.rb # demonstrates table data-binding
|
2121
|
-
glimmer samples/elaborate/tic_tac_toe.rb # demonstrates a full MVC application
|
2740
|
+
glimmer samples/hello/hello_tab.rb
|
2122
2741
|
```
|
2123
2742
|
|
2124
|
-
|
2743
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
2744
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
2125
2745
|
|
2126
|
-
####
|
2746
|
+
#### Hello, Combo!
|
2127
2747
|
|
2128
|
-
|
2748
|
+
This sample demonstrates combo data-binding.
|
2129
2749
|
|
2130
|
-
|
2750
|
+
Code:
|
2131
2751
|
|
2132
|
-
|
2752
|
+
[samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_combo.rb)
|
2133
2753
|
|
2134
|
-
|
2754
|
+
Run:
|
2135
2755
|
|
2136
|
-
|
2137
|
-
|
2756
|
+
```
|
2757
|
+
glimmer samples/hello/hello_combo.rb
|
2758
|
+
```
|
2138
2759
|
|
2139
|
-
|
2760
|
+
![Hello Combo](images/glimmer-hello-combo.png)
|
2761
|
+
![Hello Combo Expanded](images/glimmer-hello-combo-expanded.png)
|
2140
2762
|
|
2141
|
-
|
2763
|
+
#### Hello, List Single Selection!
|
2142
2764
|
|
2143
|
-
|
2765
|
+
This sample demonstrates list single-selection data-binding.
|
2144
2766
|
|
2145
|
-
|
2767
|
+
Code:
|
2146
2768
|
|
2147
|
-
https://
|
2769
|
+
[samples/hello/hello_list_single_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_single_selection.rb)
|
2148
2770
|
|
2149
|
-
|
2771
|
+
Run:
|
2150
2772
|
|
2151
|
-
|
2773
|
+
```
|
2774
|
+
glimmer samples/hello/hello_list_single_selection.rb
|
2775
|
+
```
|
2152
2776
|
|
2153
|
-
|
2777
|
+
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
2154
2778
|
|
2155
|
-
|
2779
|
+
#### Hello, List Multi Selection!
|
2156
2780
|
|
2157
|
-
|
2781
|
+
This sample demonstrates list multi-selection data-binding.
|
2158
2782
|
|
2159
|
-
|
2783
|
+
Code:
|
2160
2784
|
|
2161
|
-
|
2785
|
+
[samples/hello/hello_list_multi_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_multi_selection.rb)
|
2162
2786
|
|
2163
|
-
|
2787
|
+
Run:
|
2164
2788
|
|
2165
|
-
|
2789
|
+
```
|
2790
|
+
glimmer samples/hello/hello_list_multi_selection.rb
|
2791
|
+
```
|
2166
2792
|
|
2167
|
-
|
2793
|
+
![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
|
2794
|
+
|
2795
|
+
#### Hello, Computed!
|
2796
|
+
|
2797
|
+
This sample demonstrates computed data-binding.
|
2168
2798
|
|
2169
|
-
|
2799
|
+
Code:
|
2170
2800
|
|
2171
|
-
|
2801
|
+
[samples/hello/hello_computed.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_computed.rb)
|
2802
|
+
|
2803
|
+
Run:
|
2172
2804
|
|
2173
|
-
Here are the Java packages imported:
|
2174
2805
|
```
|
2175
|
-
|
2176
|
-
org.eclipse.swt.widgets.*
|
2177
|
-
org.eclipse.swt.layout.*
|
2178
|
-
org.eclipse.swt.graphics.*
|
2179
|
-
org.eclipse.swt.browser.*
|
2180
|
-
org.eclipse.swt.custom.*
|
2806
|
+
glimmer samples/hello/hello_computed.rb
|
2181
2807
|
```
|
2182
2808
|
|
2183
|
-
|
2809
|
+
![Hello Browser](images/glimmer-hello-computed.png)
|
2184
2810
|
|
2185
|
-
|
2811
|
+
#### Hello, Message Box!
|
2186
2812
|
|
2187
|
-
|
2813
|
+
This sample demonstrates a `message_box` dialog.
|
2814
|
+
|
2815
|
+
Code:
|
2816
|
+
|
2817
|
+
[samples/hello/hello_message_box.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_message_box.rb)
|
2818
|
+
|
2819
|
+
Run:
|
2188
2820
|
|
2189
|
-
```
|
2190
|
-
|
2821
|
+
```
|
2822
|
+
glimmer samples/hello/hello_message_box.rb
|
2191
2823
|
```
|
2192
2824
|
|
2193
|
-
|
2825
|
+
![Hello Message Box](images/glimmer-hello-message-box.png)
|
2826
|
+
![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
|
2194
2827
|
|
2195
|
-
|
2828
|
+
#### Hello, Browser!
|
2196
2829
|
|
2197
|
-
|
2830
|
+
This sample demonstrates the `browser` widget.
|
2198
2831
|
|
2199
|
-
|
2832
|
+
Code:
|
2200
2833
|
|
2201
|
-
|
2834
|
+
[samples/hello/hello_browser.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_browser.rb)
|
2202
2835
|
|
2203
|
-
|
2836
|
+
Run:
|
2204
2837
|
|
2205
|
-
|
2838
|
+
```
|
2839
|
+
glimmer samples/hello/hello_browser.rb
|
2840
|
+
```
|
2841
|
+
|
2842
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2843
|
+
|
2844
|
+
#### Hello, Drag and Drop!
|
2845
|
+
|
2846
|
+
This sample demonstrates drag and drop in Glimmer.
|
2847
|
+
|
2848
|
+
Code:
|
2849
|
+
|
2850
|
+
[samples/hello/hello_drag_and_drop.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_drag_and_drop.rb)
|
2851
|
+
|
2852
|
+
Run:
|
2206
2853
|
|
2207
|
-
Glimmer comes with a Ruby Logger accessible via `Glimmer::Config.logger`
|
2208
|
-
Its level of logging defaults to `Logger::WARN`
|
2209
|
-
It may be configured to show a different level of logging as follows:
|
2210
|
-
```ruby
|
2211
|
-
Glimmer::Config.enable_logging
|
2212
|
-
Glimmer::Config.logger.level = Logger::DEBUG
|
2213
2854
|
```
|
2214
|
-
|
2855
|
+
glimmer samples/hello/hello_drag_and_drop.rb
|
2856
|
+
```
|
2857
|
+
|
2858
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2859
|
+
|
2860
|
+
#### Hello, Menu Bar!
|
2861
|
+
|
2862
|
+
This sample demonstrates menus in Glimmer.
|
2863
|
+
|
2864
|
+
Code:
|
2865
|
+
|
2866
|
+
[samples/hello/hello_menu_bar.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_menu_bar.rb)
|
2867
|
+
|
2868
|
+
Run:
|
2215
2869
|
|
2216
|
-
Example log:
|
2217
2870
|
```
|
2218
|
-
|
2219
|
-
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2220
|
-
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2221
|
-
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2222
|
-
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2223
|
-
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2224
|
-
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2225
|
-
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2226
|
-
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2227
|
-
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2228
|
-
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2229
|
-
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2871
|
+
glimmer samples/hello/hello_menu_bar.rb
|
2230
2872
|
```
|
2231
2873
|
|
2232
|
-
|
2874
|
+
![Hello Menu Bar](images/glimmer-hello-menu-bar.png)
|
2875
|
+
![Hello Menu Bar File Menu](images/glimmer-hello-menu-bar-file-menu.png)
|
2876
|
+
![Hello Menu Bar History Menu](images/glimmer-hello-menu-bar-history-menu.png)
|
2233
2877
|
|
2234
|
-
|
2235
|
-
|
2878
|
+
#### Hello, Pop Up Context Menu!
|
2879
|
+
|
2880
|
+
This sample demonstrates pop up context menus in Glimmer.
|
2881
|
+
|
2882
|
+
Code:
|
2883
|
+
|
2884
|
+
[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)
|
2885
|
+
|
2886
|
+
Run:
|
2236
2887
|
|
2237
2888
|
```
|
2238
|
-
|
2889
|
+
glimmer samples/hello/hello_pop_up_context_menu.rb
|
2239
2890
|
```
|
2240
2891
|
|
2241
|
-
|
2242
|
-
|
2892
|
+
![Hello Pop Up Context Menu](images/glimmer-hello-pop-up-context-menu.png)
|
2893
|
+
![Hello Pop Up Context Menu Popped Up](images/glimmer-hello-pop-up-context-menu-popped-up.png)
|
2243
2894
|
|
2244
|
-
|
2895
|
+
### Elaborate Samples
|
2245
2896
|
|
2246
|
-
|
2897
|
+
For more elaborate samples, check the following:
|
2247
2898
|
|
2248
|
-
|
2899
|
+
#### Login
|
2249
2900
|
|
2250
|
-
|
2901
|
+
This sample demonstrates basic data-binding, password and text fields, and field enablement data-binding.
|
2902
|
+
|
2903
|
+
Code:
|
2904
|
+
|
2905
|
+
[samples/elaborate/login.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/login.rb)
|
2906
|
+
|
2907
|
+
Run:
|
2251
2908
|
|
2252
|
-
Example:
|
2253
2909
|
```
|
2254
|
-
|
2910
|
+
glimmer samples/elaborate/login.rb
|
2255
2911
|
```
|
2256
2912
|
|
2913
|
+
![Login](images/glimmer-login.png)
|
2914
|
+
![Login Filled In](images/glimmer-login-filled-in.png)
|
2915
|
+
![Login Logged In](images/glimmer-login-logged-in.png)
|
2916
|
+
|
2917
|
+
#### Tic Tac Toe Sample
|
2918
|
+
|
2919
|
+
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)).
|
2920
|
+
|
2921
|
+
Code:
|
2922
|
+
|
2923
|
+
[samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)
|
2924
|
+
|
2925
|
+
Run:
|
2926
|
+
|
2927
|
+
```
|
2928
|
+
glimmer samples/elaborate/tic_tac_toe.rb
|
2929
|
+
```
|
2930
|
+
|
2931
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
2932
|
+
![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
|
2933
|
+
![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
|
2934
|
+
|
2935
|
+
#### Contact Manager Sample
|
2936
|
+
|
2937
|
+
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)).
|
2938
|
+
|
2939
|
+
Code:
|
2940
|
+
|
2941
|
+
[samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)
|
2942
|
+
|
2943
|
+
Run:
|
2944
|
+
|
2945
|
+
```
|
2946
|
+
glimmer samples/elaborate/contact_manager.rb
|
2947
|
+
```
|
2948
|
+
|
2949
|
+
Contact Manager
|
2950
|
+
|
2951
|
+
![Contact Manager](images/glimmer-contact-manager.png)
|
2952
|
+
|
2953
|
+
Contact Manager - Find
|
2954
|
+
|
2955
|
+
![Contact Manager](images/glimmer-contact-manager-find.png)
|
2956
|
+
|
2957
|
+
Contact Manager - Edit Started
|
2958
|
+
|
2959
|
+
![Contact Manager](images/glimmer-contact-manager-edit-started.png)
|
2960
|
+
|
2961
|
+
Contact Manager - Edit In Progress
|
2962
|
+
|
2963
|
+
![Contact Manager](images/glimmer-contact-manager-edit-in-progress.png)
|
2964
|
+
|
2965
|
+
Contact Manager - Edit Done
|
2966
|
+
|
2967
|
+
![Contact Manager](images/glimmer-contact-manager-edit-done.png)
|
2968
|
+
|
2969
|
+
### External Samples
|
2970
|
+
|
2971
|
+
#### Glimmer Calculator
|
2972
|
+
|
2973
|
+
[<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).
|
2974
|
+
|
2975
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
|
2976
|
+
|
2977
|
+
#### Gladiator
|
2978
|
+
|
2979
|
+
[<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.
|
2980
|
+
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
2981
|
+
|
2982
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
|
2983
|
+
|
2984
|
+
Gladiator is a good demonstration of:
|
2985
|
+
- MVP Pattern
|
2986
|
+
- Tree data-binding
|
2987
|
+
- List data-binding
|
2988
|
+
- Text selection data-binding
|
2989
|
+
- Tabs
|
2990
|
+
- Context menus
|
2991
|
+
- Custom Shell
|
2992
|
+
- Custom widget
|
2993
|
+
|
2994
|
+
## In Production
|
2995
|
+
|
2996
|
+
The following production apps have been built with Glimmer.
|
2997
|
+
|
2998
|
+
### Math Bowling
|
2999
|
+
|
3000
|
+
[<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
|
3001
|
+
|
3002
|
+
### Are We There Yet?
|
3003
|
+
|
3004
|
+
[<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
|
3005
|
+
|
3006
|
+
If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
|
3007
|
+
|
2257
3008
|
## Packaging & Distribution
|
2258
3009
|
|
2259
3010
|
Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
|
2260
3011
|
- Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
|
2261
3012
|
- javapackager (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html): Enables packaging a JAR file as a DMG file on Mac, EXE on Windows, and multiple Linux supported formats on Linux.
|
2262
3013
|
|
2263
|
-
Glimmer simplifies the process of Mac packaging via the `glimmer package` command. It works out of the box for any application generated by [Glimmer Scaffolding](
|
3014
|
+
Glimmer simplifies the process of Mac packaging via the `glimmer package` command. It works out of the box for any application generated by [Glimmer Scaffolding](#scaffolding):
|
2264
3015
|
|
2265
3016
|
```
|
2266
3017
|
glimmer package
|
@@ -2423,14 +3174,30 @@ If you need live help, try to [![Join the chat at https://gitter.im/AndyObtiva/g
|
|
2423
3174
|
|
2424
3175
|
These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
|
2425
3176
|
|
2426
|
-
[TODO.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md)
|
3177
|
+
[glimmer-dsl-swt/TODO.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md)
|
3178
|
+
|
3179
|
+
Glimmer DSL Engine specific tasks are at:
|
3180
|
+
|
3181
|
+
[TODO.md](TODO.md)
|
2427
3182
|
|
2428
3183
|
## Change Log
|
2429
3184
|
|
3185
|
+
[glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
|
3186
|
+
|
2430
3187
|
[CHANGELOG.md](CHANGELOG.md)
|
2431
3188
|
|
2432
3189
|
## Contributing
|
2433
3190
|
|
3191
|
+
**Contributors Wanted!**
|
3192
|
+
|
3193
|
+
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).
|
3194
|
+
|
3195
|
+
You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
|
3196
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
3197
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
3198
|
+
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
3199
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
3200
|
+
|
2434
3201
|
[CONTRIBUTING.md](CONTRIBUTING.md)
|
2435
3202
|
|
2436
3203
|
## Contributors
|
@@ -2440,7 +3207,17 @@ These features have been suggested. You might see them in a future version of Gl
|
|
2440
3207
|
|
2441
3208
|
[Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer/graphs/contributors)
|
2442
3209
|
|
3210
|
+
## Hire Me
|
3211
|
+
|
3212
|
+
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/).
|
3213
|
+
|
2443
3214
|
## License
|
2444
3215
|
|
2445
|
-
|
2446
|
-
|
3216
|
+
[MIT](https://opensource.org/licenses/MIT)
|
3217
|
+
|
3218
|
+
Copyright (c) 2007-2020 - Andy Maleh.
|
3219
|
+
See [LICENSE.txt](LICENSE.txt) for further details.
|
3220
|
+
|
3221
|
+
--
|
3222
|
+
|
3223
|
+
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>
|