glimmer 0.9.0 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +844 -187
- data/VERSION +1 -1
- data/lib/glimmer.rb +38 -4
- data/lib/glimmer/config.rb +8 -0
- data/lib/glimmer/data_binding/model_binding.rb +248 -0
- data/lib/glimmer/data_binding/observable.rb +21 -0
- data/lib/glimmer/data_binding/observable_array.rb +86 -0
- data/lib/glimmer/data_binding/observable_model.rb +104 -0
- data/lib/glimmer/data_binding/observer.rb +127 -0
- data/lib/glimmer/dsl/engine.rb +31 -15
- data/lib/glimmer/excluded_keyword_error.rb +5 -0
- metadata +50 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c22f962213e82b271d67b69d910604e73ab8a257e8a797fa58feb2d97d6c199e
|
4
|
+
data.tar.gz: eee60acdf118d572196ef4a2c1eca7705093ea9d3db2fcea1a05bb612710f05b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 360edce8ae04be32396a272ad947897d256c171759f3304ed4f3b521a208540a2834e05a3140fe61de166337858bbd85c13655d02b92b1cd13e60b44b78cb0d6
|
7
|
+
data.tar.gz: 482df9f676948f24f68e665899c15e7e14b78f40f100580771a4af943fd524b676ae140f19cf1d7b370d2ef1fb5e3c4bff9f0e2eb4a8cb1cb95884c74be6ef37
|
data/README.md
CHANGED
@@ -1,12 +1,24 @@
|
|
1
|
-
#
|
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
|
-
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer)
|
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
|
+
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
6
|
+
|
7
|
+
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
8
|
+
|
9
|
+
(The Original Glimmer Library Since 2007. Beware of Imitators!)
|
4
10
|
|
5
11
|
Glimmer is a native-GUI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the GUI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models test-first afterwards.
|
6
12
|
|
7
13
|
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
8
14
|
Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
|
9
15
|
|
16
|
+
Glimmer DSL gems:
|
17
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
18
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
19
|
+
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
20
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
21
|
+
|
10
22
|
## Examples
|
11
23
|
|
12
24
|
### Hello, World!
|
@@ -67,15 +79,13 @@ glimmer samples/elaborate/tic_tac_toe.rb
|
|
67
79
|
|
68
80
|
Glimmer app:
|
69
81
|
|
70
|
-
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
82
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
|
71
83
|
|
72
84
|
NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contributing), adopting for small or low risk projects, and providing feedback.
|
73
85
|
|
74
|
-
Ruby is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the Ruby on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as SWT, JFace, and RCP can help fill the gap of desktop application development with Ruby.
|
75
|
-
|
76
86
|
## Table of contents
|
77
87
|
|
78
|
-
- [Glimmer
|
88
|
+
- [Glimmer (Ruby Desktop Development GUI Library)](#-glimmer-ruby-desktop-development-gui-library)
|
79
89
|
- [Examples](#examples)
|
80
90
|
- [Hello, World!](#hello-world)
|
81
91
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -94,6 +104,13 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
94
104
|
- [Custom Widget](#custom-widget)
|
95
105
|
- [Custom Shell Gem](#custom-shell-gem)
|
96
106
|
- [Custom Widget Gem](#custom-widget-gem)
|
107
|
+
- [Gem Listing](#gem-listing)
|
108
|
+
- [Listing Custom Shell Gems](#listing-custom-shell-gems)
|
109
|
+
- [Listing Custom Widget Gems](#listing-custom-widget-gems)
|
110
|
+
- [Listing DSL Gems](#listing-dsl-gems)
|
111
|
+
- [Packaging](#packaging)
|
112
|
+
- [Raw JRuby Command](#raw-jruby-command)
|
113
|
+
- [Mac Support](#mac-support)
|
97
114
|
- [Girb (Glimmer irb) Command](#girb-glimmer-irb-command)
|
98
115
|
- [Glimmer DSL Syntax](#glimmer-dsl-syntax)
|
99
116
|
- [Widgets](#widgets)
|
@@ -101,6 +118,7 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
101
118
|
- [SWT Proxies](#swt-proxies)
|
102
119
|
- [Dialog](#dialog)
|
103
120
|
- [Menus](#menus)
|
121
|
+
- [ScrolledComposite](#scrolledcomposite)
|
104
122
|
- [Widget Styles](#widget-styles)
|
105
123
|
- [Explicit SWT Style Bit](#explicit-swt-style-bit)
|
106
124
|
- [Negative SWT Style Bits](#negative-swt-style-bits)
|
@@ -121,29 +139,49 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
121
139
|
- [Observing Models](#observing-models)
|
122
140
|
- [Custom Widgets](#custom-widgets)
|
123
141
|
- [Simple Example](#simple-example)
|
124
|
-
- [Hook Example](#hook-example)
|
142
|
+
- [Lifecycle Hook Example](#lifecycle-hook-example)
|
143
|
+
- [Custom Widget API](#custom-widget-api)
|
125
144
|
- [Content/Options Example](#contentoptions-example)
|
145
|
+
- [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
|
126
146
|
- [Gotcha](#gotcha)
|
147
|
+
- [Final Notes](#final-notes)
|
127
148
|
- [Custom Shells](#custom-shells)
|
149
|
+
- [Drag and Drop](#drag-and-drop)
|
128
150
|
- [Miscellaneous](#miscellaneous)
|
129
151
|
- [Multi-DSL Support](#multi-dsl-support)
|
130
152
|
- [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
|
131
153
|
- [App Name and Version](#app-name-and-version)
|
132
154
|
- [Video Widget](#video-widget)
|
133
155
|
- [Browser Widget](#browser-widget)
|
156
|
+
- [Glimmer Configuration](#glimmer-configuration)
|
157
|
+
- [logger](#logger)
|
158
|
+
- [import_swt_packages](#importswtpackages)
|
159
|
+
- [loop_max_count](#loopmaxcount)
|
134
160
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
161
|
+
- [SWT Reference](#swt-reference)
|
135
162
|
- [Samples](#samples)
|
136
163
|
- [Hello Samples](#hello-samples)
|
164
|
+
- [Hello, World! Sample](#hello-world-sample)
|
165
|
+
- [Hello, Tab!](#hello-tab)
|
166
|
+
- [Hello, Combo!](#hello-combo)
|
167
|
+
- [Hello, List Single Selection!](#hello-list-single-selection)
|
168
|
+
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
169
|
+
- [Hello, Computed!](#hello-computed)
|
170
|
+
- [Hello, Message Box!](#hello-message-box)
|
171
|
+
- [Hello, Browser!](#hello-browser)
|
172
|
+
- [Hello, Drag and Drop!](#hello-drag-and-drop)
|
173
|
+
- [Hello, Menu Bar!](#hello-menu-bar)
|
174
|
+
- [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
|
137
175
|
- [Elaborate Samples](#elaborate-samples)
|
176
|
+
- [Login](#login)
|
177
|
+
- [Tic Tac Toe Sample](#tic-tac-toe-sample)
|
178
|
+
- [Contact Manager](#contact-manager)
|
138
179
|
- [External Samples](#external-samples)
|
139
180
|
- [Glimmer Calculator](#glimmer-calculator)
|
140
181
|
- [Gladiator](#gladiator)
|
141
182
|
- [In Production](#in-production)
|
142
|
-
|
143
|
-
|
144
|
-
- [Logging](#logging)
|
145
|
-
- [Raw JRuby Command](#raw-jruby-command)
|
146
|
-
- [Mac Support](#mac-support)
|
183
|
+
- [Math Bowling](#math-bowling)
|
184
|
+
- [Are We There Yet?](#are-we-there-yet)
|
147
185
|
- [Packaging & Distribution](#packaging--distribution)
|
148
186
|
- [Packaging Defaults](#packaging-defaults)
|
149
187
|
- [Packaging Configuration](#packaging-configuration)
|
@@ -154,11 +192,12 @@ Ruby is a dynamically-typed object-oriented language, which provides great produ
|
|
154
192
|
- [Resources](#resources)
|
155
193
|
- [Help](#help)
|
156
194
|
- [Issues](#issues)
|
157
|
-
- [
|
195
|
+
- [Chat](#chat)
|
158
196
|
- [Feature Suggestions](#feature-suggestions)
|
159
197
|
- [Change Log](#change-log)
|
160
198
|
- [Contributing](#contributing)
|
161
199
|
- [Contributors](#contributors)
|
200
|
+
- [Hire Me](#hire-me)
|
162
201
|
- [License](#license)
|
163
202
|
|
164
203
|
## Background
|
@@ -185,38 +224,52 @@ https://www.eclipse.org/swt/faq.php
|
|
185
224
|
## Pre-requisites
|
186
225
|
|
187
226
|
- SWT 4.15 (comes included in Glimmer gem)
|
188
|
-
- JRuby 9.2.
|
227
|
+
- JRuby 9.2.12.0 (supporting Ruby 2.5.x syntax) (find at [https://www.jruby.org/download](https://www.jruby.org/download))
|
189
228
|
- JDK 8 - 10 (find at [https://www.oracle.com/java/technologies/javase-downloads.html](https://www.oracle.com/java/technologies/javase-downloads.html))
|
190
229
|
- (Optional) RVM is needed for [Scaffolding](#scaffolding) only (find at [https://rvm.io/](https://rvm.io/))
|
191
230
|
|
192
231
|
On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
|
193
232
|
|
194
233
|
```bash
|
195
|
-
rvm install jruby-9.2.
|
234
|
+
rvm install jruby-9.2.12.0
|
196
235
|
```
|
197
236
|
|
198
237
|
Glimmer might still work on lower versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
|
199
238
|
|
200
239
|
## Setup
|
201
240
|
|
202
|
-
Please follow these instructions to make the `glimmer` command available on your system.
|
241
|
+
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.
|
203
242
|
|
204
|
-
|
243
|
+
If you intend to learn the basics of Glimmer but are not ready to build a Glimmer app yet, pick Option 1 ([Direct Install](#option-1-direct-install)).
|
244
|
+
|
245
|
+
If you intend to build a Glimmer app from scratch on the Mac, pick Option 1 ([Direct Install](#option-1-direct-install)) to leverage [Glimmer Scaffolding](#scaffolding) (only available on the Mac).
|
246
|
+
|
247
|
+
Otherwise, Option 2 ([Bundler](#option-2-bundler)) is recommended for building Glimmer apps on other platforms (Windows and Linux).
|
248
|
+
|
249
|
+
### Option 1: Direct Install
|
250
|
+
(Use for [Scaffolding](#scaffolding) on the Mac)
|
205
251
|
|
206
252
|
Run this command to install directly:
|
207
253
|
```
|
208
|
-
jgem install glimmer-dsl-swt -v 0.
|
254
|
+
jgem install glimmer-dsl-swt -v 0.3.0
|
209
255
|
```
|
210
256
|
|
211
257
|
`jgem` is JRuby's version of `gem` command.
|
212
258
|
RVM allows running `gem` as an alias.
|
213
259
|
Otherwise, you may also run `jruby -S gem install ...`
|
214
260
|
|
215
|
-
|
261
|
+
If you are new to Glimmer and would like to continue learning the basics, you may continue to the [Glimmer Command](https://github.com/AndyObtiva/glimmer#glimmer-command) section.
|
262
|
+
|
263
|
+
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.
|
264
|
+
|
265
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
266
|
+
|
267
|
+
### Option 2: Bundler
|
268
|
+
(Use for Manual App Creation)
|
216
269
|
|
217
270
|
Add the following to `Gemfile`:
|
218
271
|
```
|
219
|
-
gem 'glimmer-dsl-swt', '~> 0.
|
272
|
+
gem 'glimmer-dsl-swt', '~> 0.3.0'
|
220
273
|
```
|
221
274
|
|
222
275
|
And, then run:
|
@@ -224,10 +277,16 @@ And, then run:
|
|
224
277
|
jruby -S bundle install
|
225
278
|
```
|
226
279
|
|
227
|
-
|
280
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
281
|
+
|
282
|
+
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)
|
228
283
|
|
229
284
|
## Glimmer Command
|
230
285
|
|
286
|
+
The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
|
287
|
+
|
288
|
+
If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer DSL Syntax](#glimmer-dsl-syntax), and [Samples](#samples).
|
289
|
+
|
231
290
|
### Basic Usage
|
232
291
|
|
233
292
|
```
|
@@ -264,7 +323,11 @@ Either a single task or one or more applications may be specified.
|
|
264
323
|
When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
|
265
324
|
|
266
325
|
Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
|
326
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
327
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
328
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
267
329
|
glimmer package # Package app for distribution (generating config, jar, and native files)
|
330
|
+
glimmer package:clean # Clean by removing "dist" and "packages" directories
|
268
331
|
glimmer package:config # Generate JAR config file
|
269
332
|
glimmer package:jar # Generate JAR file
|
270
333
|
glimmer package:native # Generate Native files (DMG/PKG/APP on the Mac)
|
@@ -362,6 +425,10 @@ Eventually, it will launch an advanced "Hello, World!" app window having the tit
|
|
362
425
|
|
363
426
|
![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
|
364
427
|
|
428
|
+
On the Mac, it also comes with a boilerplate Preferences dialog.
|
429
|
+
|
430
|
+
![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
|
431
|
+
|
365
432
|
#### Custom Shell
|
366
433
|
|
367
434
|
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
|
@@ -419,9 +486,128 @@ Only official Glimmer gems created by the Glimmer project committers will have n
|
|
419
486
|
|
420
487
|
Example: [https://github.com/AndyObtiva/glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video)
|
421
488
|
|
489
|
+
### Gem Listing
|
490
|
+
|
491
|
+
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).
|
492
|
+
|
493
|
+
#### Listing Custom Shell Gems
|
494
|
+
|
495
|
+
The following command lists available Glimmer [Custom Shell Gems](#custom-shell-gem) (prefixed with "glimmer-cs-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
496
|
+
|
497
|
+
```
|
498
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
499
|
+
```
|
500
|
+
|
501
|
+
Example:
|
502
|
+
|
503
|
+
```
|
504
|
+
glimmer list:custom_shell_gems
|
505
|
+
```
|
506
|
+
|
507
|
+
Output:
|
508
|
+
|
509
|
+
```
|
510
|
+
|
511
|
+
Glimmer Custom Shell Gems at rubygems.org:
|
512
|
+
|
513
|
+
Name Gem Version Author Description
|
514
|
+
|
515
|
+
Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
|
516
|
+
Gladiator glimmer-cs-gladiator 0.2.0 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
|
517
|
+
|
518
|
+
```
|
519
|
+
|
520
|
+
#### Listing Custom Widget Gems
|
521
|
+
|
522
|
+
The following command lists available Glimmer [Custom Widget Gems](#custom-widget-gem) (prefixed with "glimmer-cw-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
523
|
+
|
524
|
+
```
|
525
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
526
|
+
```
|
527
|
+
|
528
|
+
Example:
|
529
|
+
|
530
|
+
Check if there is a custom video widget for Glimmer.
|
531
|
+
|
532
|
+
```
|
533
|
+
glimmer list:custom_widget_gems[video]
|
534
|
+
```
|
535
|
+
|
536
|
+
Output:
|
537
|
+
|
538
|
+
```
|
539
|
+
|
540
|
+
Glimmer Custom Widget Gems matching [video] at rubygems.org:
|
541
|
+
|
542
|
+
Name Gem Version Author Description
|
543
|
+
|
544
|
+
Video glimmer-cw-video 0.1.1 Andy Maleh Glimmer Custom Widget - Video
|
545
|
+
|
546
|
+
```
|
547
|
+
|
548
|
+
#### Listing DSL Gems
|
549
|
+
|
550
|
+
The following command lists available Glimmer [DSL Gems](#multi-dsl-support) (prefixed with "glimmer-dsl-" by convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
551
|
+
|
552
|
+
```
|
553
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
554
|
+
```
|
555
|
+
|
556
|
+
Example:
|
557
|
+
|
558
|
+
```
|
559
|
+
glimmer list:dsl_gems
|
560
|
+
```
|
561
|
+
|
562
|
+
Output:
|
563
|
+
|
564
|
+
```
|
565
|
+
|
566
|
+
Glimmer DSL Gems at rubygems.org:
|
567
|
+
|
568
|
+
Name Gem Version Author Description
|
569
|
+
|
570
|
+
Css glimmer-dsl-css 0.1.0 AndyMaleh Glimmer DSL for CSS
|
571
|
+
Opal glimmer-dsl-opal 0.0.9 AndyMaleh Glimmer DSL for Opal
|
572
|
+
Swt glimmer-dsl-swt 0.3.0 AndyMaleh Glimmer DSL for SWT
|
573
|
+
Xml glimmer-dsl-xml 0.1.0 AndyMaleh Glimmer DSL for XML
|
574
|
+
|
575
|
+
```
|
576
|
+
|
577
|
+
### Packaging
|
578
|
+
|
579
|
+
Glimmer packaging tasks are detailed under [Packaging & Distribution](#packaging--distribution).
|
580
|
+
|
581
|
+
### Raw JRuby Command
|
582
|
+
|
583
|
+
If there is a need to run Glimmer directly via the `jruby` command, you
|
584
|
+
may run the following:
|
585
|
+
|
586
|
+
```
|
587
|
+
jruby -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
588
|
+
```
|
589
|
+
|
590
|
+
The `-J-classpath` option specifies the `swt.jar` file path, which can be a
|
591
|
+
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.
|
592
|
+
|
593
|
+
The `-r` option preloads (requires) the `glimmer` library in Ruby.
|
594
|
+
|
595
|
+
The `-S` option specifies a script to run.
|
596
|
+
|
597
|
+
#### Mac Support
|
598
|
+
|
599
|
+
The Mac is well supported with the `glimmer` command. The advice below is not needed if you are using it.
|
600
|
+
|
601
|
+
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).
|
602
|
+
|
603
|
+
Example:
|
604
|
+
```
|
605
|
+
jruby -J-XstartOnFirstThread -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
606
|
+
```
|
607
|
+
|
422
608
|
## Girb (Glimmer irb) Command
|
423
609
|
|
424
|
-
With
|
610
|
+
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.
|
425
611
|
|
426
612
|
```
|
427
613
|
girb
|
@@ -441,13 +627,13 @@ Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-
|
|
441
627
|
|
442
628
|
Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
|
443
629
|
|
444
|
-
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `
|
630
|
+
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `message_box`, `async_exec`, and `bind`.
|
445
631
|
|
446
|
-
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `
|
632
|
+
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `list`.
|
447
633
|
|
448
|
-
The only reason to distinguish between
|
634
|
+
The only reason to distinguish between the two types of Glimmer DSL keywords is to realize that importing new Glimmer [custom widgets](#custom-widgets) and Java SWT custom widget libraries automatically expands Glimmer's DSL vocabulary via new dynamic keywords.
|
449
635
|
|
450
|
-
For example, if a project adds this custom SWT library:
|
636
|
+
For example, if a project adds this custom Java SWT library:
|
451
637
|
|
452
638
|
https://www.eclipse.org/nebula/widgets/cdatetime/cdatetime.php?page=operation
|
453
639
|
|
@@ -540,22 +726,22 @@ Check out the [samples](samples) directory for more examples.
|
|
540
726
|
|
541
727
|
Example from [hello_tab.rb](samples/hello/hello_tab.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
542
728
|
|
543
|
-
![Hello Tab
|
729
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
544
730
|
|
545
|
-
![Hello Tab
|
731
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
546
732
|
|
547
733
|
```ruby
|
548
734
|
shell {
|
549
|
-
text "
|
735
|
+
text "Hello, Tab!"
|
550
736
|
tab_folder {
|
551
737
|
tab_item {
|
552
|
-
text "
|
738
|
+
text "English"
|
553
739
|
label {
|
554
740
|
text "Hello, World!"
|
555
741
|
}
|
556
742
|
}
|
557
743
|
tab_item {
|
558
|
-
text "
|
744
|
+
text "French"
|
559
745
|
label {
|
560
746
|
text "Bonjour Univers!"
|
561
747
|
}
|
@@ -627,27 +813,34 @@ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
627
813
|
@shell.open
|
628
814
|
```
|
629
815
|
|
630
|
-
#####
|
816
|
+
##### `message_box`
|
631
817
|
|
632
|
-
Glimmer
|
818
|
+
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.
|
633
819
|
|
634
820
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
635
821
|
|
636
822
|
```ruby
|
823
|
+
include Glimmer
|
824
|
+
|
637
825
|
@shell = shell {
|
826
|
+
text 'Hello, Message Box!'
|
638
827
|
button {
|
639
|
-
text
|
828
|
+
text 'Please Click To Win a Surprise'
|
640
829
|
on_widget_selected {
|
641
|
-
message_box
|
642
|
-
|
643
|
-
|
644
|
-
|
830
|
+
message_box(@shell) {
|
831
|
+
text 'Surprise'
|
832
|
+
message "Congratulations!\n\nYou have won $1,000,000!"
|
833
|
+
}.open
|
645
834
|
}
|
646
835
|
}
|
647
836
|
}
|
648
837
|
@shell.open
|
649
838
|
```
|
650
839
|
|
840
|
+
##### `#swt_widget`
|
841
|
+
|
842
|
+
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.
|
843
|
+
|
651
844
|
##### Shell widget proxy methods
|
652
845
|
|
653
846
|
Shell widget proxy has extra methods specific to SWT Shell:
|
@@ -675,7 +868,7 @@ Glimmer DSL provides support for SWT Menu and MenuItem widgets.
|
|
675
868
|
|
676
869
|
There are 2 main types of menus in SWT:
|
677
870
|
- Menu Bar (shows up on top)
|
678
|
-
- Pop Up Menu (shows up when right-clicking a widget)
|
871
|
+
- Pop Up Context Menu (shows up when right-clicking a widget)
|
679
872
|
|
680
873
|
Underneath both types, there can be a 3rd menu type called Drop Down.
|
681
874
|
|
@@ -683,39 +876,63 @@ Glimmer provides special support for Drop Down menus as it automatically instant
|
|
683
876
|
|
684
877
|
The ampersand symbol indicates the keyboard shortcut key for the menu item (e.g. '&Help' can be triggered on Windows by hitting ALT+H)
|
685
878
|
|
686
|
-
Example
|
879
|
+
Example of a Menu Bar (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
687
880
|
|
688
881
|
```ruby
|
689
|
-
shell {
|
882
|
+
shell { |shell_proxy|
|
883
|
+
text 'Hello, Menu Bar!'
|
884
|
+
grid_layout
|
885
|
+
label(:center) {
|
886
|
+
font height: 16
|
887
|
+
text 'Check Out The File Menu and History Menu in The Menu Bar Above!'
|
888
|
+
}
|
690
889
|
menu_bar {
|
691
890
|
menu {
|
692
|
-
text
|
891
|
+
text '&File'
|
693
892
|
menu_item {
|
694
|
-
text
|
893
|
+
text 'E&xit'
|
695
894
|
}
|
696
895
|
menu_item(0) {
|
697
|
-
text
|
896
|
+
text '&New'
|
897
|
+
on_widget_selected {
|
898
|
+
message_box(shell_proxy) {
|
899
|
+
text 'New File'
|
900
|
+
message 'New File Contents'
|
901
|
+
}.open
|
902
|
+
}
|
698
903
|
}
|
699
904
|
menu(1) {
|
700
|
-
text
|
905
|
+
text '&Options'
|
701
906
|
menu_item(:radio) {
|
702
|
-
text
|
907
|
+
text 'Option 1'
|
703
908
|
}
|
704
909
|
menu_item(:separator)
|
705
910
|
menu_item(:check) {
|
706
|
-
text
|
911
|
+
text 'Option 3'
|
707
912
|
}
|
708
913
|
}
|
709
914
|
}
|
710
915
|
menu {
|
711
|
-
text
|
916
|
+
text '&History'
|
712
917
|
menu {
|
713
|
-
text
|
918
|
+
text '&Recent'
|
714
919
|
menu_item {
|
715
|
-
text
|
920
|
+
text 'File 1'
|
921
|
+
on_widget_selected {
|
922
|
+
message_box(shell_proxy) {
|
923
|
+
text 'File 1'
|
924
|
+
message 'File 1 Contents'
|
925
|
+
}.open
|
926
|
+
}
|
716
927
|
}
|
717
928
|
menu_item {
|
718
|
-
text
|
929
|
+
text 'File 2'
|
930
|
+
on_widget_selected {
|
931
|
+
message_box(shell_proxy) {
|
932
|
+
text 'File 2'
|
933
|
+
message 'File 2 Contents'
|
934
|
+
}.open
|
935
|
+
}
|
719
936
|
}
|
720
937
|
}
|
721
938
|
}
|
@@ -723,22 +940,37 @@ shell {
|
|
723
940
|
}.open
|
724
941
|
```
|
725
942
|
|
726
|
-
Example
|
943
|
+
Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
727
944
|
|
728
945
|
```ruby
|
729
|
-
shell {
|
946
|
+
shell { |shell_proxy|
|
947
|
+
text 'Hello, Pop Up Context Menu!'
|
948
|
+
grid_layout
|
730
949
|
label {
|
731
|
-
|
950
|
+
font height: 16
|
951
|
+
text 'Right-Click To Pop Up a Context Menu'
|
732
952
|
menu {
|
733
953
|
menu {
|
734
954
|
text '&History'
|
735
955
|
menu {
|
736
|
-
text
|
956
|
+
text '&Recent'
|
737
957
|
menu_item {
|
738
|
-
text
|
958
|
+
text 'File 1'
|
959
|
+
on_widget_selected {
|
960
|
+
message_box(shell_proxy) {
|
961
|
+
text 'File 1'
|
962
|
+
message 'File 1 Contents'
|
963
|
+
}.open
|
964
|
+
}
|
739
965
|
}
|
740
966
|
menu_item {
|
741
|
-
text
|
967
|
+
text 'File 2'
|
968
|
+
on_widget_selected {
|
969
|
+
message_box(shell_proxy) {
|
970
|
+
text 'File 2'
|
971
|
+
message 'File 2 Contents'
|
972
|
+
}.open
|
973
|
+
}
|
742
974
|
}
|
743
975
|
}
|
744
976
|
}
|
@@ -747,6 +979,13 @@ shell {
|
|
747
979
|
}.open
|
748
980
|
```
|
749
981
|
|
982
|
+
#### ScrolledComposite
|
983
|
+
|
984
|
+
Glimmer provides smart defaults for the `scrolled_composite` widget by:
|
985
|
+
- Automatically setting the nested widget as its content (meaning use can just like a plain old `composite` to add scrolling)
|
986
|
+
- 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 )
|
987
|
+
- Automatically setting the expand horizontal and expand vertical SWT properties to `true`
|
988
|
+
|
750
989
|
### Widget Styles
|
751
990
|
|
752
991
|
SWT widgets receive `SWT` styles in their constructor as per this guide:
|
@@ -992,9 +1231,12 @@ composite {
|
|
992
1231
|
```
|
993
1232
|
|
994
1233
|
Here is a more sophisticated example taken from [hello_computed.rb](samples/hello/hello_computed.rb) sample:
|
1234
|
+
|
1235
|
+
![Hello Computed](images/glimmer-hello-computed.png)
|
1236
|
+
|
995
1237
|
```ruby
|
996
1238
|
shell {
|
997
|
-
text
|
1239
|
+
text 'Hello, Computed!'
|
998
1240
|
composite {
|
999
1241
|
grid_layout {
|
1000
1242
|
num_columns 2
|
@@ -1002,44 +1244,44 @@ shell {
|
|
1002
1244
|
horizontal_spacing 20
|
1003
1245
|
vertical_spacing 10
|
1004
1246
|
}
|
1005
|
-
label {text
|
1247
|
+
label {text 'First &Name: '}
|
1006
1248
|
text {
|
1007
1249
|
text bind(@contact, :first_name)
|
1008
1250
|
layout_data {
|
1009
|
-
|
1010
|
-
|
1251
|
+
horizontal_alignment :fill
|
1252
|
+
grab_excess_horizontal_space true
|
1011
1253
|
}
|
1012
1254
|
}
|
1013
|
-
label {text
|
1255
|
+
label {text '&Last Name: '}
|
1014
1256
|
text {
|
1015
1257
|
text bind(@contact, :last_name)
|
1016
1258
|
layout_data {
|
1017
|
-
|
1018
|
-
|
1259
|
+
horizontal_alignment :fill
|
1260
|
+
grab_excess_horizontal_space true
|
1019
1261
|
}
|
1020
1262
|
}
|
1021
|
-
label {text
|
1263
|
+
label {text '&Year of Birth: '}
|
1022
1264
|
text {
|
1023
1265
|
text bind(@contact, :year_of_birth)
|
1024
1266
|
layout_data {
|
1025
|
-
|
1026
|
-
|
1267
|
+
horizontal_alignment :fill
|
1268
|
+
grab_excess_horizontal_space true
|
1027
1269
|
}
|
1028
1270
|
}
|
1029
|
-
label {text
|
1271
|
+
label {text 'Name: '}
|
1030
1272
|
label {
|
1031
1273
|
text bind(@contact, :name, computed_by: [:first_name, :last_name])
|
1032
1274
|
layout_data {
|
1033
|
-
|
1034
|
-
|
1275
|
+
horizontal_alignment :fill
|
1276
|
+
grab_excess_horizontal_space true
|
1035
1277
|
}
|
1036
1278
|
}
|
1037
|
-
label {text
|
1279
|
+
label {text 'Age: '}
|
1038
1280
|
label {
|
1039
1281
|
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
|
1040
1282
|
layout_data {
|
1041
|
-
|
1042
|
-
|
1283
|
+
horizontal_alignment :fill
|
1284
|
+
grab_excess_horizontal_space true
|
1043
1285
|
}
|
1044
1286
|
}
|
1045
1287
|
}
|
@@ -1182,6 +1424,10 @@ Example from [samples/hello/hello_combo.rb](samples/hello_combo.rb) sample (you
|
|
1182
1424
|
|
1183
1425
|
#### Combo
|
1184
1426
|
|
1427
|
+
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.
|
1428
|
+
|
1429
|
+
When data-binding a `combo` widget, Glimmer can automatically deduce available options from data-bound model by convention: `{attribute_name}_options` method.
|
1430
|
+
|
1185
1431
|
![Hello Combo](images/glimmer-hello-combo.png)
|
1186
1432
|
|
1187
1433
|
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
@@ -1223,7 +1469,7 @@ end
|
|
1223
1469
|
HelloCombo.new.launch
|
1224
1470
|
```
|
1225
1471
|
|
1226
|
-
`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.
|
1472
|
+
`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.
|
1227
1473
|
|
1228
1474
|
#### List
|
1229
1475
|
|
@@ -1337,6 +1583,9 @@ shell {
|
|
1337
1583
|
}
|
1338
1584
|
items bind(group, :people), column_properties(:name, :age, :adult)
|
1339
1585
|
selection bind(group, :selected_person)
|
1586
|
+
on_mouse_up { |event|
|
1587
|
+
@table.edit_table_item(event.table_item, event.column_index)
|
1588
|
+
}
|
1340
1589
|
}
|
1341
1590
|
}
|
1342
1591
|
```
|
@@ -1344,6 +1593,7 @@ shell {
|
|
1344
1593
|
The code above includes two data-bindings:
|
1345
1594
|
- 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.
|
1346
1595
|
- 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)
|
1596
|
+
- 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.)
|
1347
1597
|
|
1348
1598
|
Additionally, Table `items` data-binding automatically stores each node model unto the SWT TableItem object via `setData` method. This enables things like searchability.
|
1349
1599
|
|
@@ -1363,6 +1613,67 @@ This automatically leverages the SWT TableEditor custom class behind the scenes,
|
|
1363
1613
|
passed table item text into something else.
|
1364
1614
|
It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
1365
1615
|
|
1616
|
+
##### Table Sorting
|
1617
|
+
|
1618
|
+
Glimmer automatically adds sorting support to the SWT `Table` widget.
|
1619
|
+
|
1620
|
+
Check out the [Contact Manager](#contact-manager) sample for an example.
|
1621
|
+
You may click on any column and it will sort by ascending order first and descending if you click again.
|
1622
|
+
|
1623
|
+
Glimmer automatic table sorting supports `String`, `Integer`, and `Float` columns out of the box as well as any column data that is comparable.
|
1624
|
+
|
1625
|
+
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`.
|
1626
|
+
|
1627
|
+
Should you have a special data type that could not be compared automatically, Glimmer offers the following 3 alternatives for custom sorting:
|
1628
|
+
- `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`).
|
1629
|
+
- `sort_by(&block)`: this works just like Ruby `Enumerable` `sort_by`. The block receives the table column data as argument.
|
1630
|
+
- `sort(&comparator)`: this works just like Ruby `Enumerable` `sort`. The comparator block receives two objects from the table column data.
|
1631
|
+
|
1632
|
+
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)
|
1633
|
+
|
1634
|
+
Example:
|
1635
|
+
|
1636
|
+
```ruby
|
1637
|
+
# ...
|
1638
|
+
table {
|
1639
|
+
table_column {
|
1640
|
+
text 'Task'
|
1641
|
+
width 120
|
1642
|
+
}
|
1643
|
+
table_column {
|
1644
|
+
text 'Project'
|
1645
|
+
width 120
|
1646
|
+
}
|
1647
|
+
table_column {
|
1648
|
+
text 'Duration (hours)'
|
1649
|
+
width 120
|
1650
|
+
sort_property :duration_in_hours
|
1651
|
+
}
|
1652
|
+
table_column {
|
1653
|
+
text 'Priority'
|
1654
|
+
width 120
|
1655
|
+
sort_by { |value| ['High', 'Medium', 'Low'].index(value) }
|
1656
|
+
}
|
1657
|
+
table_column {
|
1658
|
+
text 'Start Date'
|
1659
|
+
width 120
|
1660
|
+
sort { |d1, d2| d1.to_date <=> d2.to_date }
|
1661
|
+
}
|
1662
|
+
additional_sort_properties :project_name, :duration_in_hours, :name
|
1663
|
+
items bind(Task, :list), column_properties(:name, :project_name, :duration, :priority, :start_date)
|
1664
|
+
# ...
|
1665
|
+
}
|
1666
|
+
# ...
|
1667
|
+
```
|
1668
|
+
|
1669
|
+
Here is an explanation of the example above:
|
1670
|
+
- Task and Project table columns are data-bound to the `:name` and `:project_name` properties and sorted through them automatically
|
1671
|
+
- Task Duration table column is data-bound to the `:duration` property, but sorted via the `:duration_in_hours` property instead
|
1672
|
+
- Task Priority table column has a custom sort_by block
|
1673
|
+
- Task Start Date table column has a custom sort comparator block
|
1674
|
+
- Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
|
1675
|
+
|
1676
|
+
|
1366
1677
|
#### Tree
|
1367
1678
|
|
1368
1679
|
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
@@ -1535,7 +1846,7 @@ class TicTacToe
|
|
1535
1846
|
end
|
1536
1847
|
```
|
1537
1848
|
|
1538
|
-
Observers can be a good mechanism for displaying dialog messages in Glimmer (using SWT's `MessageBox`).
|
1849
|
+
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).
|
1539
1850
|
|
1540
1851
|
Look at [`samples/elaborate/tictactoe/tic_tac_toe.rb`](samples/tictactoe/tic_tac_toe.rb) for more details starting with the code included below.
|
1541
1852
|
|
@@ -1561,10 +1872,10 @@ class TicTacToe
|
|
1561
1872
|
end
|
1562
1873
|
|
1563
1874
|
def display_game_over_message(message)
|
1564
|
-
message_box
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1875
|
+
message_box(@shell) {
|
1876
|
+
text 'Game Over'
|
1877
|
+
message message_text
|
1878
|
+
}.open
|
1568
1879
|
@tic_tac_toe_board.reset
|
1569
1880
|
end
|
1570
1881
|
# ...
|
@@ -1605,7 +1916,7 @@ shell {
|
|
1605
1916
|
|
1606
1917
|
As you can see, `RedLabel` became Glimmer DSL keyword: `red_label`
|
1607
1918
|
|
1608
|
-
#### Hook Example
|
1919
|
+
#### Lifecycle Hook Example
|
1609
1920
|
|
1610
1921
|
(you may copy/paste in [`girb`](#girb-glimmer-irb-command))
|
1611
1922
|
|
@@ -1640,10 +1951,12 @@ shell {
|
|
1640
1951
|
}.open
|
1641
1952
|
```
|
1642
1953
|
|
1643
|
-
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`.
|
1954
|
+
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`.
|
1644
1955
|
|
1645
1956
|
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.
|
1646
1957
|
|
1958
|
+
#### Custom Widget API
|
1959
|
+
|
1647
1960
|
Custom Widgets have the following attributes available to call from inside the `#body` method:
|
1648
1961
|
- `#parent`: Glimmer object parenting custom widget
|
1649
1962
|
- `#swt_style`: SWT style integer. Can be useful if you want to allow consumers to customize a widget inside the custom widget body
|
@@ -1698,7 +2011,9 @@ shell {
|
|
1698
2011
|
|
1699
2012
|
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'`
|
1700
2013
|
|
1701
|
-
|
2014
|
+
#### Custom Widget Lifecycle Hooks
|
2015
|
+
|
2016
|
+
Last but not least, these are the available lifecycle hooks:
|
1702
2017
|
- `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`
|
1703
2018
|
- `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.
|
1704
2019
|
|
@@ -1732,6 +2047,11 @@ body {
|
|
1732
2047
|
|
1733
2048
|
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`.
|
1734
2049
|
|
2050
|
+
#### Final Notes
|
2051
|
+
|
2052
|
+
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:
|
2053
|
+
[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)
|
2054
|
+
|
1735
2055
|
### Custom Shells
|
1736
2056
|
|
1737
2057
|
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.
|
@@ -1797,6 +2117,62 @@ shell { |app_shell|
|
|
1797
2117
|
}.open
|
1798
2118
|
```
|
1799
2119
|
|
2120
|
+
### Drag and Drop
|
2121
|
+
|
2122
|
+
Glimmer offers Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
|
2123
|
+
|
2124
|
+
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)
|
2125
|
+
|
2126
|
+
To get started, simply follow these steps:
|
2127
|
+
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)
|
2128
|
+
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)
|
2129
|
+
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)
|
2130
|
+
1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
|
2131
|
+
|
2132
|
+
Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2133
|
+
|
2134
|
+
```ruby
|
2135
|
+
class Location
|
2136
|
+
attr_accessor :country
|
2137
|
+
|
2138
|
+
def country_options
|
2139
|
+
%w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
2140
|
+
end
|
2141
|
+
end
|
2142
|
+
|
2143
|
+
@location = Location.new
|
2144
|
+
|
2145
|
+
include Glimmer
|
2146
|
+
|
2147
|
+
shell {
|
2148
|
+
text 'Hello, Drag and Drop!'
|
2149
|
+
list {
|
2150
|
+
selection bind(@location, :country)
|
2151
|
+
on_drag_set_data { |event|
|
2152
|
+
list = event.widget.getControl
|
2153
|
+
event.data = list.getSelection.first
|
2154
|
+
}
|
2155
|
+
}
|
2156
|
+
label(:center) {
|
2157
|
+
text 'Drag a country here!'
|
2158
|
+
font height: 20
|
2159
|
+
on_drop { |event|
|
2160
|
+
event.widget.getControl.setText(event.data)
|
2161
|
+
}
|
2162
|
+
}
|
2163
|
+
}.open
|
2164
|
+
```
|
2165
|
+
|
2166
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2167
|
+
|
2168
|
+
Optional steps:
|
2169
|
+
- 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.
|
2170
|
+
- Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2171
|
+
- 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)
|
2172
|
+
- Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2173
|
+
- 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)
|
2174
|
+
- Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
|
2175
|
+
|
1800
2176
|
### Miscellaneous
|
1801
2177
|
|
1802
2178
|
#### Multi-DSL Support
|
@@ -1952,10 +2328,10 @@ class Example
|
|
1952
2328
|
def initialize
|
1953
2329
|
display {
|
1954
2330
|
on_about {
|
1955
|
-
message_box
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
2331
|
+
message_box(@shell_proxy) {
|
2332
|
+
text 'About'
|
2333
|
+
message 'About Application'
|
2334
|
+
}.open
|
1959
2335
|
}
|
1960
2336
|
on_preferences {
|
1961
2337
|
preferences_dialog = dialog {
|
@@ -2029,7 +2405,9 @@ You may obtain via `glimmer-cw-video` gem.
|
|
2029
2405
|
|
2030
2406
|
#### Browser Widget
|
2031
2407
|
|
2032
|
-
|
2408
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2409
|
+
|
2410
|
+
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).
|
2033
2411
|
|
2034
2412
|
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2035
2413
|
|
@@ -2065,6 +2443,101 @@ shell {
|
|
2065
2443
|
|
2066
2444
|
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).
|
2067
2445
|
|
2446
|
+
## Glimmer Configuration
|
2447
|
+
|
2448
|
+
Glimmer configuration may be done via the `Glimmer::Config` module.
|
2449
|
+
|
2450
|
+
### logger
|
2451
|
+
|
2452
|
+
Glimmer supports logging via a Ruby Logger configurable with the `Glimmer::Config.logger` config option.
|
2453
|
+
It is disabled by default to ensure not affecting desktop app performance.
|
2454
|
+
It may be enabled via `Glimmer::Config.enable_logging`
|
2455
|
+
When enabled, the Glimmer logger level defaults to `:warn` (aka `Logger::WARN`)
|
2456
|
+
It may be configured to show a different level of logging via `Glimmer::Config.logger.level` just ike with any Ruby Logger.
|
2457
|
+
|
2458
|
+
Example:
|
2459
|
+
|
2460
|
+
```ruby
|
2461
|
+
Glimmer::Config.enable_logging
|
2462
|
+
Glimmer::Config.logger.level = Logger::DEBUG
|
2463
|
+
```
|
2464
|
+
This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
|
2465
|
+
|
2466
|
+
Example log:
|
2467
|
+
```
|
2468
|
+
D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
|
2469
|
+
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2470
|
+
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2471
|
+
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2472
|
+
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2473
|
+
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2474
|
+
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2475
|
+
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2476
|
+
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2477
|
+
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2478
|
+
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2479
|
+
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2480
|
+
```
|
2481
|
+
|
2482
|
+
### import_swt_packages
|
2483
|
+
|
2484
|
+
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.
|
2485
|
+
|
2486
|
+
As a result, you may call SWT Java classes from Glimmer Ruby code without mentioning Java package references explicitly.
|
2487
|
+
|
2488
|
+
For example, `org.eclipse.swt.graphics.Color` can be referenced as just `Color`
|
2489
|
+
|
2490
|
+
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:
|
2491
|
+
```
|
2492
|
+
org.eclipse.swt.*
|
2493
|
+
org.eclipse.swt.widgets.*
|
2494
|
+
org.eclipse.swt.layout.*
|
2495
|
+
org.eclipse.swt.graphics.*
|
2496
|
+
org.eclipse.swt.browser.*
|
2497
|
+
org.eclipse.swt.custom.*
|
2498
|
+
org.eclipse.swt.dnd.*
|
2499
|
+
```
|
2500
|
+
|
2501
|
+
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).
|
2502
|
+
|
2503
|
+
Example:
|
2504
|
+
|
2505
|
+
```ruby
|
2506
|
+
Glimmer::Config.import_swt_packages += [
|
2507
|
+
'org.eclipse.nebula.widgets.ganttchart'
|
2508
|
+
]
|
2509
|
+
```
|
2510
|
+
|
2511
|
+
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)
|
2512
|
+
|
2513
|
+
Nonetheless, you can disable automatic Java package import if needed via this Glimmer configuration option:
|
2514
|
+
|
2515
|
+
```ruby
|
2516
|
+
Glimmer::Config.import_swt_packages = false
|
2517
|
+
```
|
2518
|
+
|
2519
|
+
Once disabled, to import SWT Java packages manually, you may simply:
|
2520
|
+
|
2521
|
+
1. `include Glimmer::SWT::Packages`: lazily imports all SWT Java packages to your class, lazy-loading SWT Java class constants on first reference.
|
2522
|
+
|
2523
|
+
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'`)
|
2524
|
+
|
2525
|
+
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.
|
2526
|
+
|
2527
|
+
You can learn more about importing Java packages into Ruby code at this JRuby WIKI page:
|
2528
|
+
|
2529
|
+
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
|
2530
|
+
|
2531
|
+
### loop_max_count
|
2532
|
+
|
2533
|
+
Glimmer has infinite loop detection support.
|
2534
|
+
It can detect when an infinite loop is about to occur in method_missing and stops it.
|
2535
|
+
It detects potential infinite loops when the same keyword and args repeat more than 100 times, which is unusual in a GUI app.
|
2536
|
+
|
2537
|
+
The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` config option.
|
2538
|
+
|
2539
|
+
Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
|
2540
|
+
|
2068
2541
|
## Glimmer Style Guide
|
2069
2542
|
|
2070
2543
|
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
@@ -2080,11 +2553,43 @@ This relies on Glimmer's [Multi-DSL Support](#multi-dsl-support) for building th
|
|
2080
2553
|
- Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
|
2081
2554
|
- 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.
|
2082
2555
|
|
2556
|
+
## SWT Reference
|
2557
|
+
|
2558
|
+
https://www.eclipse.org/swt/docs.php
|
2559
|
+
|
2560
|
+
Here is the SWT API:
|
2561
|
+
|
2562
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html
|
2563
|
+
|
2564
|
+
Here is a visual list of SWT widgets:
|
2565
|
+
|
2566
|
+
https://www.eclipse.org/swt/widgets/
|
2567
|
+
|
2568
|
+
Here is a textual list of SWT widgets:
|
2569
|
+
|
2570
|
+
https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
|
2571
|
+
|
2572
|
+
Here is a list of SWT style bits as used in widget declaration:
|
2573
|
+
|
2574
|
+
https://wiki.eclipse.org/SWT_Widget_Style_Bits
|
2575
|
+
|
2576
|
+
Here is a SWT style bit constant reference:
|
2577
|
+
|
2578
|
+
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
2579
|
+
|
2580
|
+
Here is an SWT Drag and Drop guide:
|
2581
|
+
|
2582
|
+
https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
|
2583
|
+
|
2584
|
+
Here is an SWT Custom Widget guide:
|
2585
|
+
|
2586
|
+
https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
|
2587
|
+
|
2083
2588
|
## Samples
|
2084
2589
|
|
2085
|
-
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`).
|
2590
|
+
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`).
|
2086
2591
|
|
2087
|
-
If you cloned the project and followed [CONTRIBUTING.md](CONTRIBUTING.md) instructions, you may run all samples at once via `samples/launch` command:
|
2592
|
+
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:
|
2088
2593
|
|
2089
2594
|
```
|
2090
2595
|
samples/launch
|
@@ -2092,168 +2597,306 @@ samples/launch
|
|
2092
2597
|
|
2093
2598
|
### Hello Samples
|
2094
2599
|
|
2095
|
-
For
|
2600
|
+
For hello-type simple samples, check the following.
|
2601
|
+
|
2602
|
+
#### Hello, World! Sample
|
2603
|
+
|
2604
|
+
Code:
|
2605
|
+
|
2606
|
+
[samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)
|
2607
|
+
|
2608
|
+
Run:
|
2096
2609
|
|
2097
2610
|
```
|
2098
2611
|
glimmer samples/hello/hello_world.rb
|
2099
|
-
glimmer samples/hello/hello_browser.rb # demonstrates browser widget
|
2100
|
-
glimmer samples/hello/hello_tab.rb # demonstrates tabs
|
2101
|
-
glimmer samples/hello/hello_combo.rb # demonstrates combo data-binding
|
2102
|
-
glimmer samples/hello/hello_list_single_selection.rb # demonstrates list single-selection data-binding
|
2103
|
-
glimmer samples/hello/hello_list_multi_selection.rb # demonstrates list multi-selection data-binding
|
2104
|
-
glimmer samples/hello/hello_computed.rb # demonstrates computed data-binding
|
2105
2612
|
```
|
2106
2613
|
|
2107
|
-
|
2614
|
+
![Hello World](images/glimmer-hello-world.png)
|
2108
2615
|
|
2109
|
-
|
2616
|
+
#### Hello, Tab!
|
2617
|
+
|
2618
|
+
Code:
|
2619
|
+
|
2620
|
+
[samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_tab.rb)
|
2621
|
+
|
2622
|
+
Run:
|
2110
2623
|
|
2111
2624
|
```
|
2112
|
-
glimmer samples/
|
2113
|
-
glimmer samples/elaborate/contact_manager.rb # demonstrates table data-binding
|
2114
|
-
glimmer samples/elaborate/tic_tac_toe.rb # demonstrates a full MVC application
|
2625
|
+
glimmer samples/hello/hello_tab.rb
|
2115
2626
|
```
|
2116
2627
|
|
2117
|
-
|
2628
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
2629
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
2118
2630
|
|
2119
|
-
####
|
2631
|
+
#### Hello, Combo!
|
2120
2632
|
|
2121
|
-
|
2633
|
+
This sample demonstrates combo data-binding.
|
2122
2634
|
|
2123
|
-
|
2635
|
+
Code:
|
2124
2636
|
|
2125
|
-
|
2637
|
+
[samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_combo.rb)
|
2126
2638
|
|
2127
|
-
|
2639
|
+
Run:
|
2128
2640
|
|
2129
|
-
|
2130
|
-
|
2641
|
+
```
|
2642
|
+
glimmer samples/hello/hello_combo.rb
|
2643
|
+
```
|
2131
2644
|
|
2132
|
-
|
2645
|
+
![Hello Combo](images/glimmer-hello-combo.png)
|
2646
|
+
![Hello Combo Expanded](images/glimmer-hello-combo-expanded.png)
|
2133
2647
|
|
2134
|
-
|
2648
|
+
#### Hello, List Single Selection!
|
2135
2649
|
|
2136
|
-
|
2650
|
+
This sample demonstrates list single-selection data-binding.
|
2137
2651
|
|
2138
|
-
|
2652
|
+
Code:
|
2139
2653
|
|
2140
|
-
https://
|
2654
|
+
[samples/hello/hello_list_single_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_single_selection.rb)
|
2141
2655
|
|
2142
|
-
|
2656
|
+
Run:
|
2143
2657
|
|
2144
|
-
|
2658
|
+
```
|
2659
|
+
glimmer samples/hello/hello_list_single_selection.rb
|
2660
|
+
```
|
2145
2661
|
|
2146
|
-
|
2662
|
+
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
2147
2663
|
|
2148
|
-
|
2664
|
+
#### Hello, List Multi Selection!
|
2149
2665
|
|
2150
|
-
|
2666
|
+
This sample demonstrates list multi-selection data-binding.
|
2151
2667
|
|
2152
|
-
|
2668
|
+
Code:
|
2153
2669
|
|
2154
|
-
|
2670
|
+
[samples/hello/hello_list_multi_selection.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_list_multi_selection.rb)
|
2155
2671
|
|
2156
|
-
|
2672
|
+
Run:
|
2157
2673
|
|
2158
|
-
|
2674
|
+
```
|
2675
|
+
glimmer samples/hello/hello_list_multi_selection.rb
|
2676
|
+
```
|
2159
2677
|
|
2160
|
-
|
2678
|
+
![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
|
2679
|
+
|
2680
|
+
#### Hello, Computed!
|
2681
|
+
|
2682
|
+
This sample demonstrates computed data-binding.
|
2161
2683
|
|
2162
|
-
|
2684
|
+
Code:
|
2163
2685
|
|
2164
|
-
|
2686
|
+
[samples/hello/hello_computed.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_computed.rb)
|
2687
|
+
|
2688
|
+
Run:
|
2165
2689
|
|
2166
|
-
Here are the Java packages imported:
|
2167
2690
|
```
|
2168
|
-
|
2169
|
-
org.eclipse.swt.widgets.*
|
2170
|
-
org.eclipse.swt.layout.*
|
2171
|
-
org.eclipse.swt.graphics.*
|
2172
|
-
org.eclipse.swt.browser.*
|
2173
|
-
org.eclipse.swt.custom.*
|
2691
|
+
glimmer samples/hello/hello_computed.rb
|
2174
2692
|
```
|
2175
2693
|
|
2176
|
-
|
2694
|
+
![Hello Browser](images/glimmer-hello-computed.png)
|
2177
2695
|
|
2178
|
-
|
2696
|
+
#### Hello, Message Box!
|
2179
2697
|
|
2180
|
-
|
2698
|
+
This sample demonstrates a `message_box` dialog.
|
2699
|
+
|
2700
|
+
Code:
|
2701
|
+
|
2702
|
+
[samples/hello/hello_message_box.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_message_box.rb)
|
2703
|
+
|
2704
|
+
Run:
|
2181
2705
|
|
2182
|
-
```
|
2183
|
-
|
2706
|
+
```
|
2707
|
+
glimmer samples/hello/hello_message_box.rb
|
2184
2708
|
```
|
2185
2709
|
|
2186
|
-
|
2710
|
+
![Hello Message Box](images/glimmer-hello-message-box.png)
|
2711
|
+
![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
|
2187
2712
|
|
2188
|
-
|
2713
|
+
#### Hello, Browser!
|
2189
2714
|
|
2190
|
-
|
2715
|
+
This sample demonstrates the `browser` widget.
|
2191
2716
|
|
2192
|
-
|
2717
|
+
Code:
|
2193
2718
|
|
2194
|
-
|
2719
|
+
[samples/hello/hello_browser.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_browser.rb)
|
2195
2720
|
|
2196
|
-
|
2721
|
+
Run:
|
2197
2722
|
|
2198
|
-
|
2723
|
+
```
|
2724
|
+
glimmer samples/hello/hello_browser.rb
|
2725
|
+
```
|
2726
|
+
|
2727
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2728
|
+
|
2729
|
+
#### Hello, Drag and Drop!
|
2730
|
+
|
2731
|
+
This sample demonstrates drag and drop in Glimmer.
|
2732
|
+
|
2733
|
+
Code:
|
2734
|
+
|
2735
|
+
[samples/hello/hello_drag_and_drop.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_drag_and_drop.rb)
|
2736
|
+
|
2737
|
+
Run:
|
2199
2738
|
|
2200
|
-
Glimmer comes with a Ruby Logger accessible via `Glimmer::Config.logger`
|
2201
|
-
Its level of logging defaults to `Logger::WARN`
|
2202
|
-
It may be configured to show a different level of logging as follows:
|
2203
|
-
```ruby
|
2204
|
-
Glimmer::Config.enable_logging
|
2205
|
-
Glimmer::Config.logger.level = Logger::DEBUG
|
2206
2739
|
```
|
2207
|
-
|
2740
|
+
glimmer samples/hello/hello_drag_and_drop.rb
|
2741
|
+
```
|
2742
|
+
|
2743
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2744
|
+
|
2745
|
+
#### Hello, Menu Bar!
|
2746
|
+
|
2747
|
+
This sample demonstrates menus in Glimmer.
|
2748
|
+
|
2749
|
+
Code:
|
2750
|
+
|
2751
|
+
[samples/hello/hello_menu_bar.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_menu_bar.rb)
|
2752
|
+
|
2753
|
+
Run:
|
2208
2754
|
|
2209
|
-
Example log:
|
2210
2755
|
```
|
2211
|
-
|
2212
|
-
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2213
|
-
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2214
|
-
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2215
|
-
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2216
|
-
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2217
|
-
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2218
|
-
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2219
|
-
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2220
|
-
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2221
|
-
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2222
|
-
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2756
|
+
glimmer samples/hello/hello_menu_bar.rb
|
2223
2757
|
```
|
2224
2758
|
|
2225
|
-
|
2759
|
+
![Hello Menu Bar](images/glimmer-hello-menu-bar.png)
|
2760
|
+
![Hello Menu Bar File Menu](images/glimmer-hello-menu-bar-file-menu.png)
|
2761
|
+
![Hello Menu Bar History Menu](images/glimmer-hello-menu-bar-history-menu.png)
|
2226
2762
|
|
2227
|
-
|
2228
|
-
|
2763
|
+
#### Hello, Pop Up Context Menu!
|
2764
|
+
|
2765
|
+
This sample demonstrates pop up context menus in Glimmer.
|
2766
|
+
|
2767
|
+
Code:
|
2768
|
+
|
2769
|
+
[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)
|
2770
|
+
|
2771
|
+
Run:
|
2229
2772
|
|
2230
2773
|
```
|
2231
|
-
|
2774
|
+
glimmer samples/hello/hello_pop_up_context_menu.rb
|
2232
2775
|
```
|
2233
2776
|
|
2234
|
-
|
2235
|
-
|
2777
|
+
![Hello Pop Up Context Menu](images/glimmer-hello-pop-up-context-menu.png)
|
2778
|
+
![Hello Pop Up Context Menu Popped Up](images/glimmer-hello-pop-up-context-menu-popped-up.png)
|
2236
2779
|
|
2237
|
-
|
2780
|
+
### Elaborate Samples
|
2238
2781
|
|
2239
|
-
|
2782
|
+
For more elaborate samples, check the following:
|
2240
2783
|
|
2241
|
-
|
2784
|
+
#### Login
|
2242
2785
|
|
2243
|
-
|
2786
|
+
This sample demonstrates basic data-binding, password and text fields, and field enablement data-binding.
|
2787
|
+
|
2788
|
+
Code:
|
2789
|
+
|
2790
|
+
[samples/elaborate/login.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/login.rb)
|
2791
|
+
|
2792
|
+
Run:
|
2244
2793
|
|
2245
|
-
Example:
|
2246
2794
|
```
|
2247
|
-
|
2795
|
+
glimmer samples/elaborate/login.rb
|
2248
2796
|
```
|
2249
2797
|
|
2798
|
+
![Login](images/glimmer-login.png)
|
2799
|
+
![Login Filled In](images/glimmer-login-filled-in.png)
|
2800
|
+
![Login Logged In](images/glimmer-login-logged-in.png)
|
2801
|
+
|
2802
|
+
#### Tic Tac Toe Sample
|
2803
|
+
|
2804
|
+
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)).
|
2805
|
+
|
2806
|
+
Code:
|
2807
|
+
|
2808
|
+
[samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)
|
2809
|
+
|
2810
|
+
Run:
|
2811
|
+
|
2812
|
+
```
|
2813
|
+
glimmer samples/elaborate/tic_tac_toe.rb
|
2814
|
+
```
|
2815
|
+
|
2816
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
2817
|
+
![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
|
2818
|
+
![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
|
2819
|
+
|
2820
|
+
#### Contact Manager
|
2821
|
+
|
2822
|
+
This sample demonstrates table data-binding, sorting, filtering, GUI layout, MVP pattern, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/contact_manager/contact_manager_presenter_spec.rb)).
|
2823
|
+
|
2824
|
+
Code:
|
2825
|
+
|
2826
|
+
[samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)
|
2827
|
+
|
2828
|
+
Run:
|
2829
|
+
|
2830
|
+
```
|
2831
|
+
glimmer samples/elaborate/contact_manager.rb
|
2832
|
+
```
|
2833
|
+
|
2834
|
+
Contact Manager
|
2835
|
+
|
2836
|
+
![Contact Manager](images/glimmer-contact-manager.png)
|
2837
|
+
|
2838
|
+
Contact Manager - Find
|
2839
|
+
|
2840
|
+
![Contact Manager](images/glimmer-contact-manager-find.png)
|
2841
|
+
|
2842
|
+
Contact Manager - Edit Started
|
2843
|
+
|
2844
|
+
![Contact Manager](images/glimmer-contact-manager-edit-started.png)
|
2845
|
+
|
2846
|
+
Contact Manager - Edit In Progress
|
2847
|
+
|
2848
|
+
![Contact Manager](images/glimmer-contact-manager-edit-in-progress.png)
|
2849
|
+
|
2850
|
+
Contact Manager - Edit Done
|
2851
|
+
|
2852
|
+
![Contact Manager](images/glimmer-contact-manager-edit-done.png)
|
2853
|
+
|
2854
|
+
### External Samples
|
2855
|
+
|
2856
|
+
#### Glimmer Calculator
|
2857
|
+
|
2858
|
+
[<img alt="Glimmer Calculator Icon" src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-icon.png" height=40 /> Glimmer Calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) is a basic calculator sample project demonstrating data-binding and TDD (test-driven-development) with Glimmer following the MVP pattern (Model-View-Presenter).
|
2859
|
+
|
2860
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
|
2861
|
+
|
2862
|
+
#### Gladiator
|
2863
|
+
|
2864
|
+
[<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.
|
2865
|
+
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
2866
|
+
|
2867
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
|
2868
|
+
|
2869
|
+
Gladiator is a good demonstration of:
|
2870
|
+
- MVP Pattern
|
2871
|
+
- Tree data-binding
|
2872
|
+
- List data-binding
|
2873
|
+
- Text selection data-binding
|
2874
|
+
- Tabs
|
2875
|
+
- Context menus
|
2876
|
+
- Custom Shell
|
2877
|
+
- Custom widget
|
2878
|
+
|
2879
|
+
## In Production
|
2880
|
+
|
2881
|
+
The following production apps have been built with Glimmer.
|
2882
|
+
|
2883
|
+
### Math Bowling
|
2884
|
+
|
2885
|
+
[<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
|
2886
|
+
|
2887
|
+
### Are We There Yet?
|
2888
|
+
|
2889
|
+
[<img alt="Are We There Yet Logo" src="https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-logo.svg" width="40" />Are We There Yet?](https://github.com/AndyObtiva/are-we-there-yet): A tool that helps you learn when your small projects will finish
|
2890
|
+
|
2891
|
+
If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
|
2892
|
+
|
2250
2893
|
## Packaging & Distribution
|
2251
2894
|
|
2252
2895
|
Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
|
2253
2896
|
- Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
|
2254
2897
|
- javapackager (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html): Enables packaging a JAR file as a DMG file on Mac, EXE on Windows, and multiple Linux supported formats on Linux.
|
2255
2898
|
|
2256
|
-
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](
|
2899
|
+
Glimmer simplifies the process of Mac packaging via the `glimmer package` command. It works out of the box for any application generated by [Glimmer Scaffolding](#scaffolding):
|
2257
2900
|
|
2258
2901
|
```
|
2259
2902
|
glimmer package
|
@@ -2391,10 +3034,6 @@ By the way, keep in mind that during normal operation, it does also indicate a f
|
|
2391
3034
|
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
|
2392
3035
|
```
|
2393
3036
|
|
2394
|
-
## Limitations
|
2395
|
-
|
2396
|
-
- Glimmer apps have a long startup up time and can take anywhere between 12 and 30 seconds to start depending on the app and the machine. Once started, Glimmer apps run very fast and perform very responsively since Ruby is more than fast and capable for handling desktop GUIs. In any case, one idea to address this limitation is to include a background service (daemon) that can launch Glimmer apps instantly or near instantly by keeping a JRuby runtime started and ready at all times.
|
2397
|
-
|
2398
3037
|
## Resources
|
2399
3038
|
|
2400
3039
|
* [Code Master Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
|
@@ -2412,17 +3051,19 @@ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub
|
|
2412
3051
|
|
2413
3052
|
[Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
|
2414
3053
|
|
2415
|
-
###
|
2416
|
-
|
2417
|
-
If you need live help, try the [#glimmer](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer) IRC channel on [irc.mibbit.net](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer). If no one was available, you may [leave a GitHub issue](https://github.com/AndyObtiva/glimmer/issues) to schedule a meetup on IRC.
|
3054
|
+
### Chat
|
2418
3055
|
|
2419
|
-
|
3056
|
+
If you need live help, try to [![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)
|
2420
3057
|
|
2421
3058
|
## Feature Suggestions
|
2422
3059
|
|
2423
3060
|
These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
|
2424
3061
|
|
2425
|
-
[TODO.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md)
|
3062
|
+
[glimmer-dsl-swt/TODO.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md)
|
3063
|
+
|
3064
|
+
Glimmer DSL Engine specific tasks are at:
|
3065
|
+
|
3066
|
+
[TODO.md](TODO.md)
|
2426
3067
|
|
2427
3068
|
## Change Log
|
2428
3069
|
|
@@ -2430,6 +3071,16 @@ These features have been suggested. You might see them in a future version of Gl
|
|
2430
3071
|
|
2431
3072
|
## Contributing
|
2432
3073
|
|
3074
|
+
**Contributors Wanted!**
|
3075
|
+
|
3076
|
+
If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](#swt-reference), run all Glimmer [samples](#samples), and build a small sample app to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
|
3077
|
+
|
3078
|
+
You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
|
3079
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
3080
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
3081
|
+
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
3082
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
3083
|
+
|
2433
3084
|
[CONTRIBUTING.md](CONTRIBUTING.md)
|
2434
3085
|
|
2435
3086
|
## Contributors
|
@@ -2439,7 +3090,13 @@ These features have been suggested. You might see them in a future version of Gl
|
|
2439
3090
|
|
2440
3091
|
[Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer/graphs/contributors)
|
2441
3092
|
|
3093
|
+
## Hire Me
|
3094
|
+
|
3095
|
+
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/).
|
3096
|
+
|
2442
3097
|
## License
|
2443
3098
|
|
2444
3099
|
Copyright (c) 2007-2020 Andy Maleh.
|
2445
3100
|
See LICENSE.txt for further details.
|
3101
|
+
|
3102
|
+
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>
|