glimmer 0.8.2 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +823 -297
- data/VERSION +1 -1
- data/lib/glimmer.rb +35 -21
- data/lib/glimmer/config.rb +7 -12
- data/lib/glimmer/data_binding/observable_array.rb +32 -53
- data/lib/glimmer/data_binding/observable_model.rb +12 -16
- data/lib/glimmer/data_binding/observer.rb +3 -0
- data/lib/glimmer/dsl/engine.rb +58 -27
- data/lib/glimmer/dsl/expression.rb +0 -7
- data/lib/glimmer/dsl/static_expression.rb +2 -2
- data/lib/glimmer/excluded_keyword_error.rb +5 -0
- metadata +60 -142
- data/RUBY_VERSION +0 -1
- data/bin/girb +0 -10
- data/bin/girb_runner.rb +0 -13
- data/bin/glimmer +0 -5
- data/icons/scaffold_app.icns +0 -0
- data/lib/glimmer/css/rule.rb +0 -25
- data/lib/glimmer/css/style_sheet.rb +0 -19
- data/lib/glimmer/data_binding/list_selection_binding.rb +0 -52
- data/lib/glimmer/data_binding/observable_widget.rb +0 -17
- data/lib/glimmer/data_binding/shine.rb +0 -23
- data/lib/glimmer/data_binding/table_items_binding.rb +0 -56
- data/lib/glimmer/data_binding/tree_items_binding.rb +0 -71
- data/lib/glimmer/data_binding/widget_binding.rb +0 -33
- data/lib/glimmer/dsl/css/css_expression.rb +0 -21
- data/lib/glimmer/dsl/css/dsl.rb +0 -10
- data/lib/glimmer/dsl/css/dynamic_property_expression.rb +0 -12
- data/lib/glimmer/dsl/css/property_expression.rb +0 -22
- data/lib/glimmer/dsl/css/pv_expression.rb +0 -17
- data/lib/glimmer/dsl/css/rule_expression.rb +0 -25
- data/lib/glimmer/dsl/css/s_expression.rb +0 -26
- data/lib/glimmer/dsl/swt/async_exec_expression.rb +0 -14
- data/lib/glimmer/dsl/swt/bind_expression.rb +0 -37
- data/lib/glimmer/dsl/swt/color_expression.rb +0 -19
- data/lib/glimmer/dsl/swt/column_properties_expression.rb +0 -24
- data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +0 -42
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +0 -36
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +0 -34
- data/lib/glimmer/dsl/swt/dialog_expression.rb +0 -26
- data/lib/glimmer/dsl/swt/display_expression.rb +0 -19
- data/lib/glimmer/dsl/swt/dsl.rb +0 -28
- data/lib/glimmer/dsl/swt/exec_expression.rb +0 -28
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +0 -25
- data/lib/glimmer/dsl/swt/layout_expression.rb +0 -27
- data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +0 -44
- data/lib/glimmer/dsl/swt/menu_bar_expression.rb +0 -33
- data/lib/glimmer/dsl/swt/menu_expression.rb +0 -32
- data/lib/glimmer/dsl/swt/message_box_expression.rb +0 -29
- data/lib/glimmer/dsl/swt/observe_expression.rb +0 -32
- data/lib/glimmer/dsl/swt/property_expression.rb +0 -22
- data/lib/glimmer/dsl/swt/rgb_expression.rb +0 -12
- data/lib/glimmer/dsl/swt/rgba_expression.rb +0 -12
- data/lib/glimmer/dsl/swt/shell_expression.rb +0 -25
- data/lib/glimmer/dsl/swt/swt_expression.rb +0 -25
- data/lib/glimmer/dsl/swt/sync_exec_expression.rb +0 -15
- data/lib/glimmer/dsl/swt/tab_item_expression.rb +0 -33
- data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +0 -31
- data/lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb +0 -31
- data/lib/glimmer/dsl/swt/tree_properties_expression.rb +0 -26
- data/lib/glimmer/dsl/swt/widget_expression.rb +0 -35
- data/lib/glimmer/dsl/swt/widget_listener_expression.rb +0 -32
- data/lib/glimmer/dsl/xml/dsl.rb +0 -11
- data/lib/glimmer/dsl/xml/html_expression.rb +0 -25
- data/lib/glimmer/dsl/xml/meta_expression.rb +0 -23
- data/lib/glimmer/dsl/xml/name_space_expression.rb +0 -37
- data/lib/glimmer/dsl/xml/node_parent_expression.rb +0 -33
- data/lib/glimmer/dsl/xml/tag_expression.rb +0 -29
- data/lib/glimmer/dsl/xml/text_expression.rb +0 -22
- data/lib/glimmer/dsl/xml/xml_expression.rb +0 -21
- data/lib/glimmer/launcher.rb +0 -199
- data/lib/glimmer/package.rb +0 -55
- data/lib/glimmer/rake_task.rb +0 -58
- data/lib/glimmer/scaffold.rb +0 -582
- data/lib/glimmer/swt/color_proxy.rb +0 -53
- data/lib/glimmer/swt/display_proxy.rb +0 -88
- data/lib/glimmer/swt/font_proxy.rb +0 -72
- data/lib/glimmer/swt/layout_data_proxy.rb +0 -84
- data/lib/glimmer/swt/layout_proxy.rb +0 -82
- data/lib/glimmer/swt/menu_proxy.rb +0 -101
- data/lib/glimmer/swt/message_box_proxy.rb +0 -48
- data/lib/glimmer/swt/packages.rb +0 -13
- data/lib/glimmer/swt/shell_proxy.rb +0 -152
- data/lib/glimmer/swt/swt_proxy.rb +0 -106
- data/lib/glimmer/swt/tab_item_proxy.rb +0 -65
- data/lib/glimmer/swt/table_proxy.rb +0 -150
- data/lib/glimmer/swt/tree_proxy.rb +0 -120
- data/lib/glimmer/swt/widget_listener_proxy.rb +0 -34
- data/lib/glimmer/swt/widget_proxy.rb +0 -489
- data/lib/glimmer/ui/custom_shell.rb +0 -45
- data/lib/glimmer/ui/custom_widget.rb +0 -244
- data/lib/glimmer/util/proc_tracker.rb +0 -16
- data/lib/glimmer/xml/depth_first_search_iterator.rb +0 -22
- data/lib/glimmer/xml/name_space_visitor.rb +0 -21
- data/lib/glimmer/xml/node.rb +0 -75
- data/lib/glimmer/xml/node_visitor.rb +0 -13
- data/lib/glimmer/xml/xml_visitor.rb +0 -65
- data/vendor/swt/linux/swt.jar +0 -0
- data/vendor/swt/mac/swt.jar +0 -0
- data/vendor/swt/windows/swt.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11d28368bdf3ae26dcee4ddc661bdeee07fdf932f7c7c8fb45c27de98d4f43dc
|
4
|
+
data.tar.gz: b30a42a8f18f74fca414937f068ebcaeee31ba4f76c3afb1be866b9958647426
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f0728a1a263ff3c8c841a508d3b250910d2ddf548284029dcea23364522d436f408fe49b10683981241144d4e2bf6a20ab718ce75ed04244c6f9dc0ca51be07
|
7
|
+
data.tar.gz: 411965a314069222d27aaddfdbcbe129665725e73d082d6c15805adb188e1a1fc89d62578dc2712972684d8f5f59313b6868667b245cfdfee66f06ad6ef521e9
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,13 +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)
|
4
|
-
[![
|
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!)
|
5
10
|
|
6
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.
|
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)
|
10
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
|
+
|
11
22
|
## Examples
|
12
23
|
|
13
24
|
### Hello, World!
|
@@ -68,13 +79,13 @@ glimmer samples/elaborate/tic_tac_toe.rb
|
|
68
79
|
|
69
80
|
Glimmer app:
|
70
81
|
|
71
|
-
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
82
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
|
72
83
|
|
73
84
|
NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contributing), adopting for small or low risk projects, and providing feedback.
|
74
85
|
|
75
86
|
## Table of contents
|
76
87
|
|
77
|
-
- [Glimmer
|
88
|
+
- [Glimmer (Ruby Desktop Development GUI Library)](#-glimmer-ruby-desktop-development-gui-library)
|
78
89
|
- [Examples](#examples)
|
79
90
|
- [Hello, World!](#hello-world)
|
80
91
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -93,6 +104,13 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
93
104
|
- [Custom Widget](#custom-widget)
|
94
105
|
- [Custom Shell Gem](#custom-shell-gem)
|
95
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)
|
96
114
|
- [Girb (Glimmer irb) Command](#girb-glimmer-irb-command)
|
97
115
|
- [Glimmer DSL Syntax](#glimmer-dsl-syntax)
|
98
116
|
- [Widgets](#widgets)
|
@@ -120,29 +138,44 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
120
138
|
- [Observing Models](#observing-models)
|
121
139
|
- [Custom Widgets](#custom-widgets)
|
122
140
|
- [Simple Example](#simple-example)
|
123
|
-
- [Hook Example](#hook-example)
|
141
|
+
- [Lifecycle Hook Example](#lifecycle-hook-example)
|
142
|
+
- [Custom Widget API](#custom-widget-api)
|
124
143
|
- [Content/Options Example](#contentoptions-example)
|
144
|
+
- [Custom Widget Lifecycle Hooks](#custom-widget-lifecycle-hooks)
|
125
145
|
- [Gotcha](#gotcha)
|
126
146
|
- [Custom Shells](#custom-shells)
|
147
|
+
- [Drag and Drop](#drag-and-drop)
|
127
148
|
- [Miscellaneous](#miscellaneous)
|
149
|
+
- [Multi-DSL Support](#multi-dsl-support)
|
128
150
|
- [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
|
129
151
|
- [App Name and Version](#app-name-and-version)
|
130
|
-
- [Multi-DSL Support](#multi-dsl-support)
|
131
152
|
- [Video Widget](#video-widget)
|
132
153
|
- [Browser Widget](#browser-widget)
|
154
|
+
- [Glimmer Configuration](#glimmer-configuration)
|
155
|
+
- [logger](#logger)
|
156
|
+
- [import_swt_packages](#import_swt_packages)
|
157
|
+
- [loop_max_count](#loop_max_count)
|
133
158
|
- [Glimmer Style Guide](#glimmer-style-guide)
|
159
|
+
- [SWT Reference](#swt-reference)
|
134
160
|
- [Samples](#samples)
|
135
161
|
- [Hello Samples](#hello-samples)
|
162
|
+
- [Hello, World!](#hello-world-sample)
|
163
|
+
- [Hello, Tab!](#hello-tab)
|
164
|
+
- [Hello, Combo!](#hello-combo)
|
165
|
+
- [Hello, List Single Selection!](#hello-list-single-selection)
|
166
|
+
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
167
|
+
- [Hello, Computed!](#hello-computed)
|
168
|
+
- [Hello, Message Box!](#hello-message-box)
|
169
|
+
- [Hello, Browser!](#hello-browser)
|
170
|
+
- [Hello, Drag and Drop!](#hello-drag-and-drop)
|
136
171
|
- [Elaborate Samples](#elaborate-samples)
|
172
|
+
- [Login](#login)
|
173
|
+
- [Tic Tac Toe](#tic-tac-toe-sample)
|
174
|
+
- [Contact Manager](#contact-manager)
|
137
175
|
- [External Samples](#external-samples)
|
138
176
|
- [Glimmer Calculator](#glimmer-calculator)
|
139
177
|
- [Gladiator](#gladiator)
|
140
178
|
- [In Production](#in-production)
|
141
|
-
- [SWT Reference](#swt-reference)
|
142
|
-
- [SWT Packages](#swt-packages)
|
143
|
-
- [Logging](#logging)
|
144
|
-
- [Raw JRuby Command](#raw-jruby-command)
|
145
|
-
- [Mac Support](#mac-support)
|
146
179
|
- [Packaging & Distribution](#packaging--distribution)
|
147
180
|
- [Packaging Defaults](#packaging-defaults)
|
148
181
|
- [Packaging Configuration](#packaging-configuration)
|
@@ -153,7 +186,7 @@ NOTE: Glimmer is in beta mode. Please help make better by [contributing](#contri
|
|
153
186
|
- [Resources](#resources)
|
154
187
|
- [Help](#help)
|
155
188
|
- [Issues](#issues)
|
156
|
-
- [
|
189
|
+
- [Chat](#chat)
|
157
190
|
- [Feature Suggestions](#feature-suggestions)
|
158
191
|
- [Change Log](#change-log)
|
159
192
|
- [Contributing](#contributing)
|
@@ -184,38 +217,52 @@ https://www.eclipse.org/swt/faq.php
|
|
184
217
|
## Pre-requisites
|
185
218
|
|
186
219
|
- SWT 4.15 (comes included in Glimmer gem)
|
187
|
-
- JRuby 9.2.
|
220
|
+
- JRuby 9.2.12.0 (supporting Ruby 2.5.x syntax) (find at [https://www.jruby.org/download](https://www.jruby.org/download))
|
188
221
|
- JDK 8 - 10 (find at [https://www.oracle.com/java/technologies/javase-downloads.html](https://www.oracle.com/java/technologies/javase-downloads.html))
|
189
222
|
- (Optional) RVM is needed for [Scaffolding](#scaffolding) only (find at [https://rvm.io/](https://rvm.io/))
|
190
223
|
|
191
224
|
On **Mac** and **Linux**, an easy way to obtain JRuby is through [RVM](http://rvm.io) by running:
|
192
225
|
|
193
226
|
```bash
|
194
|
-
rvm install jruby-9.2.
|
227
|
+
rvm install jruby-9.2.12.0
|
195
228
|
```
|
196
229
|
|
197
230
|
Glimmer might still work on lower versions of Java, JRuby and SWT, but there are no guarantees, so it is best to stick to the pre-requisites outlined above.
|
198
231
|
|
199
232
|
## Setup
|
200
233
|
|
201
|
-
Please follow these instructions to make the `glimmer` command available on your system.
|
234
|
+
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.
|
202
235
|
|
203
|
-
|
236
|
+
If you intend to learn the basics of Glimmer but are not ready to build a Glimmer app yet, pick Option 1 ([Direct Install](#option-1-direct-install)).
|
237
|
+
|
238
|
+
If you intend to build a Glimmer app from scratch on the Mac, pick Option 1 ([Direct Install](#option-1-direct-install)) to leverage [Glimmer Scaffolding](#scaffolding) (only available on the Mac).
|
239
|
+
|
240
|
+
Otherwise, Option 2 ([Bundler](#option-2-bundler)) is recommended for building Glimmer apps on other platforms (Windows and Linux).
|
241
|
+
|
242
|
+
### Option 1: Direct Install
|
243
|
+
(Use for [Scaffolding](#scaffolding) on the Mac)
|
204
244
|
|
205
245
|
Run this command to install directly:
|
206
246
|
```
|
207
|
-
jgem install glimmer -v 0.
|
247
|
+
jgem install glimmer-dsl-swt -v 0.2.2
|
208
248
|
```
|
209
249
|
|
210
250
|
`jgem` is JRuby's version of `gem` command.
|
211
251
|
RVM allows running `gem` as an alias.
|
212
252
|
Otherwise, you may also run `jruby -S gem install ...`
|
213
253
|
|
214
|
-
|
254
|
+
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.
|
255
|
+
|
256
|
+
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.
|
257
|
+
|
258
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
259
|
+
|
260
|
+
### Option 2: Bundler
|
261
|
+
(Use for Manual App Creation)
|
215
262
|
|
216
263
|
Add the following to `Gemfile`:
|
217
264
|
```
|
218
|
-
gem 'glimmer', '~> 0.
|
265
|
+
gem 'glimmer-dsl-swt', '~> 0.2.2'
|
219
266
|
```
|
220
267
|
|
221
268
|
And, then run:
|
@@ -223,8 +270,16 @@ And, then run:
|
|
223
270
|
jruby -S bundle install
|
224
271
|
```
|
225
272
|
|
273
|
+
Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
|
274
|
+
|
275
|
+
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)
|
276
|
+
|
226
277
|
## Glimmer Command
|
227
278
|
|
279
|
+
The `glimmer` command allows you to run, scaffold, package, and list Glimmer applications/gems.
|
280
|
+
|
281
|
+
If you are new to Glimmer, you may read the Basic Usage section and skip the rest until you have gone through [Girb (Glimmer irb) Command](#girb-glimmer-irb-command), [Glimmer DSL Syntax](#glimmer-dsl-syntax), and [Samples](#samples).
|
282
|
+
|
228
283
|
### Basic Usage
|
229
284
|
|
230
285
|
```
|
@@ -261,6 +316,9 @@ Either a single task or one or more applications may be specified.
|
|
261
316
|
When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
|
262
317
|
|
263
318
|
Available tasks are below (you may also lookup by adding `require 'glimmer/rake_task'` in Rakefile and running rake -T):
|
319
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
320
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
321
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
264
322
|
glimmer package # Package app for distribution (generating config, jar, and native files)
|
265
323
|
glimmer package:config # Generate JAR config file
|
266
324
|
glimmer package:jar # Generate JAR file
|
@@ -359,6 +417,10 @@ Eventually, it will launch an advanced "Hello, World!" app window having the tit
|
|
359
417
|
|
360
418
|
![Glimmer Scaffold App](images/glimmer-scaffolding-app.png)
|
361
419
|
|
420
|
+
On the Mac, it also comes with a boilerplate Preferences dialog.
|
421
|
+
|
422
|
+
![Glimmer Scaffold App Preferences](images/glimmer-scaffolding-app-preferences.png)
|
423
|
+
|
362
424
|
#### Custom Shell
|
363
425
|
|
364
426
|
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
|
@@ -416,15 +478,134 @@ Only official Glimmer gems created by the Glimmer project committers will have n
|
|
416
478
|
|
417
479
|
Example: [https://github.com/AndyObtiva/glimmer-cw-video](https://github.com/AndyObtiva/glimmer-cw-video)
|
418
480
|
|
481
|
+
### Gem Listing
|
482
|
+
|
483
|
+
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).
|
484
|
+
|
485
|
+
#### Listing Custom Shell Gems
|
486
|
+
|
487
|
+
The following command lists available Glimmer [Custom Shell Gems](#custom-shell-gem) (prefixed with "glimmer-cs-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
488
|
+
|
489
|
+
```
|
490
|
+
glimmer list:custom_shell_gems[query] # List Glimmer custom shell gems available at rubygems.org (query is optional)
|
491
|
+
```
|
492
|
+
|
493
|
+
Example:
|
494
|
+
|
495
|
+
```
|
496
|
+
glimmer list:custom_shell_gems
|
497
|
+
```
|
498
|
+
|
499
|
+
Output:
|
500
|
+
|
501
|
+
```
|
502
|
+
|
503
|
+
Glimmer Custom Shell Gems at rubygems.org:
|
504
|
+
|
505
|
+
Name Gem Version Author Description
|
506
|
+
|
507
|
+
Calculator glimmer-cs-calculator 1.0.1 Andy Maleh Calculator - Glimmer Custom Shell
|
508
|
+
Gladiator glimmer-cs-gladiator 0.2.0 Andy Maleh Gladiator (Glimmer Editor) - Glimmer Custom Shell
|
509
|
+
|
510
|
+
```
|
511
|
+
|
512
|
+
#### Listing Custom Widget Gems
|
513
|
+
|
514
|
+
The following command lists available Glimmer [Custom Widget Gems](#custom-widget-gem) (prefixed with "glimmer-cw-" by scaffolding convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
515
|
+
|
516
|
+
```
|
517
|
+
glimmer list:custom_widget_gems[query] # List Glimmer custom widget gems available at rubygems.org (query is optional)
|
518
|
+
```
|
519
|
+
|
520
|
+
Example:
|
521
|
+
|
522
|
+
Check if there is a custom video widget for Glimmer.
|
523
|
+
|
524
|
+
```
|
525
|
+
glimmer list:custom_widget_gems[video]
|
526
|
+
```
|
527
|
+
|
528
|
+
Output:
|
529
|
+
|
530
|
+
```
|
531
|
+
|
532
|
+
Glimmer Custom Widget Gems matching [video] at rubygems.org:
|
533
|
+
|
534
|
+
Name Gem Version Author Description
|
535
|
+
|
536
|
+
Video glimmer-cw-video 0.1.1 Andy Maleh Glimmer Custom Widget - Video
|
537
|
+
|
538
|
+
```
|
539
|
+
|
540
|
+
#### Listing DSL Gems
|
541
|
+
|
542
|
+
The following command lists available Glimmer [DSL Gems](#multi-dsl-support) (prefixed with "glimmer-dsl-" by convention) created by the the Glimmer community and published on [rubygems.org](http://www.rubygems.org):
|
543
|
+
|
544
|
+
```
|
545
|
+
glimmer list:dsl_gems[query] # List Glimmer DSL gems available at rubygems.org (query is optional)
|
546
|
+
```
|
547
|
+
|
548
|
+
Example:
|
549
|
+
|
550
|
+
```
|
551
|
+
glimmer list:dsl_gems
|
552
|
+
```
|
553
|
+
|
554
|
+
Output:
|
555
|
+
|
556
|
+
```
|
557
|
+
|
558
|
+
Glimmer DSL Gems at rubygems.org:
|
559
|
+
|
560
|
+
Name Gem Version Author Description
|
561
|
+
|
562
|
+
Css glimmer-dsl-css 0.1.0 AndyMaleh Glimmer DSL for CSS
|
563
|
+
Opal glimmer-dsl-opal 0.0.9 AndyMaleh Glimmer DSL for Opal
|
564
|
+
Swt glimmer-dsl-swt 0.2.2 AndyMaleh Glimmer DSL for SWT
|
565
|
+
Xml glimmer-dsl-xml 0.1.0 AndyMaleh Glimmer DSL for XML
|
566
|
+
|
567
|
+
```
|
568
|
+
|
569
|
+
### Packaging
|
570
|
+
|
571
|
+
Glimmer packaging tasks are detailed under [Packaging & Distribution](#packaging--distribution).
|
572
|
+
|
573
|
+
### Raw JRuby Command
|
574
|
+
|
575
|
+
If there is a need to run Glimmer directly via the `jruby` command, you
|
576
|
+
may run the following:
|
577
|
+
|
578
|
+
```
|
579
|
+
jruby -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
580
|
+
```
|
581
|
+
|
582
|
+
The `-J-classpath` option specifies the `swt.jar` file path, which can be a
|
583
|
+
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.
|
584
|
+
|
585
|
+
The `-r` option preloads (requires) the `glimmer` library in Ruby.
|
586
|
+
|
587
|
+
The `-S` option specifies a script to run.
|
588
|
+
|
589
|
+
#### Mac Support
|
590
|
+
|
591
|
+
The Mac is well supported with the `glimmer` command. The advice below is not needed if you are using it.
|
592
|
+
|
593
|
+
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).
|
594
|
+
|
595
|
+
Example:
|
596
|
+
```
|
597
|
+
jruby -J-XstartOnFirstThread -J-classpath "path_to/swt.jar" -r glimmer -S application.rb
|
598
|
+
```
|
599
|
+
|
419
600
|
## Girb (Glimmer irb) Command
|
420
601
|
|
421
|
-
With
|
602
|
+
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.
|
422
603
|
|
423
604
|
```
|
424
605
|
girb
|
425
606
|
```
|
426
607
|
|
427
|
-
If you cloned
|
608
|
+
If you cloned [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) project locally, you may run `bin/girb` instead.
|
428
609
|
|
429
610
|
```
|
430
611
|
bin/girb
|
@@ -432,17 +613,19 @@ bin/girb
|
|
432
613
|
|
433
614
|
Watch out for hands-on examples in this README indicated by "you may copy/paste in [`girb`](#girb-glimmer-irb-command)"
|
434
615
|
|
616
|
+
Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
|
617
|
+
|
435
618
|
## Glimmer DSL Syntax
|
436
619
|
|
437
620
|
Glimmer DSL syntax consists of static keywords and dynamic keywords to build and bind user-interface objects.
|
438
621
|
|
439
|
-
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `
|
622
|
+
Static keywords are pre-identified keywords in the Glimmer DSL, such as `shell`, `message_box`, `async_exec`, and `bind`.
|
440
623
|
|
441
|
-
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `
|
624
|
+
Dynamic keywords are dynamically figured out from available SWT widgets, custom widgets, and properties. Examples are: `label`, `combo`, and `list`.
|
442
625
|
|
443
|
-
The only reason to distinguish between
|
626
|
+
The only reason to distinguish between the two types of Glimmer DSL keywords is to realize that importing new Glimmer [custom widgets](#custom-widgets) and Java SWT custom widget libraries automatically expands Glimmer's DSL vocabulary via new dynamic keywords.
|
444
627
|
|
445
|
-
For example, if a project adds this custom SWT library:
|
628
|
+
For example, if a project adds this custom Java SWT library:
|
446
629
|
|
447
630
|
https://www.eclipse.org/nebula/widgets/cdatetime/cdatetime.php?page=operation
|
448
631
|
|
@@ -535,22 +718,22 @@ Check out the [samples](samples) directory for more examples.
|
|
535
718
|
|
536
719
|
Example from [hello_tab.rb](samples/hello/hello_tab.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
537
720
|
|
538
|
-
![Hello Tab
|
721
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
539
722
|
|
540
|
-
![Hello Tab
|
723
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
541
724
|
|
542
725
|
```ruby
|
543
726
|
shell {
|
544
|
-
text "
|
727
|
+
text "Hello, Tab!"
|
545
728
|
tab_folder {
|
546
729
|
tab_item {
|
547
|
-
text "
|
730
|
+
text "English"
|
548
731
|
label {
|
549
732
|
text "Hello, World!"
|
550
733
|
}
|
551
734
|
}
|
552
735
|
tab_item {
|
553
|
-
text "
|
736
|
+
text "French"
|
554
737
|
label {
|
555
738
|
text "Bonjour Univers!"
|
556
739
|
}
|
@@ -622,27 +805,34 @@ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
622
805
|
@shell.open
|
623
806
|
```
|
624
807
|
|
625
|
-
#####
|
808
|
+
##### `message_box`
|
626
809
|
|
627
|
-
Glimmer
|
810
|
+
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.
|
628
811
|
|
629
812
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
630
813
|
|
631
814
|
```ruby
|
815
|
+
include Glimmer
|
816
|
+
|
632
817
|
@shell = shell {
|
818
|
+
text 'Hello, Message Box!'
|
633
819
|
button {
|
634
|
-
text
|
820
|
+
text 'Please Click To Win a Surprise'
|
635
821
|
on_widget_selected {
|
636
|
-
message_box
|
637
|
-
|
638
|
-
|
639
|
-
|
822
|
+
message_box(@shell) {
|
823
|
+
text 'Surprise'
|
824
|
+
message "Congratulations!\n\nYou have won $1,000,000!"
|
825
|
+
}.open
|
640
826
|
}
|
641
827
|
}
|
642
828
|
}
|
643
829
|
@shell.open
|
644
830
|
```
|
645
831
|
|
832
|
+
##### `#swt_widget`
|
833
|
+
|
834
|
+
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.
|
835
|
+
|
646
836
|
##### Shell widget proxy methods
|
647
837
|
|
648
838
|
Shell widget proxy has extra methods specific to SWT Shell:
|
@@ -670,7 +860,7 @@ Glimmer DSL provides support for SWT Menu and MenuItem widgets.
|
|
670
860
|
|
671
861
|
There are 2 main types of menus in SWT:
|
672
862
|
- Menu Bar (shows up on top)
|
673
|
-
- Pop Up Menu (shows up when right-clicking a widget)
|
863
|
+
- Pop Up Context Menu (shows up when right-clicking a widget)
|
674
864
|
|
675
865
|
Underneath both types, there can be a 3rd menu type called Drop Down.
|
676
866
|
|
@@ -678,39 +868,63 @@ Glimmer provides special support for Drop Down menus as it automatically instant
|
|
678
868
|
|
679
869
|
The ampersand symbol indicates the keyboard shortcut key for the menu item (e.g. '&Help' can be triggered on Windows by hitting ALT+H)
|
680
870
|
|
681
|
-
Example
|
871
|
+
Example of a Menu Bar (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
682
872
|
|
683
873
|
```ruby
|
684
|
-
shell {
|
874
|
+
shell { |shell_proxy|
|
875
|
+
text 'Hello, Menu Bar!'
|
876
|
+
grid_layout
|
877
|
+
label(:center) {
|
878
|
+
font height: 16
|
879
|
+
text 'Check Out The File Menu and History Menu in The Menu Bar Above!'
|
880
|
+
}
|
685
881
|
menu_bar {
|
686
882
|
menu {
|
687
|
-
text
|
883
|
+
text '&File'
|
688
884
|
menu_item {
|
689
|
-
text
|
885
|
+
text 'E&xit'
|
690
886
|
}
|
691
887
|
menu_item(0) {
|
692
|
-
text
|
888
|
+
text '&New'
|
889
|
+
on_widget_selected {
|
890
|
+
message_box(shell_proxy) {
|
891
|
+
text 'New File'
|
892
|
+
message 'New File Contents'
|
893
|
+
}.open
|
894
|
+
}
|
693
895
|
}
|
694
896
|
menu(1) {
|
695
|
-
text
|
897
|
+
text '&Options'
|
696
898
|
menu_item(:radio) {
|
697
|
-
text
|
899
|
+
text 'Option 1'
|
698
900
|
}
|
699
901
|
menu_item(:separator)
|
700
902
|
menu_item(:check) {
|
701
|
-
text
|
903
|
+
text 'Option 3'
|
702
904
|
}
|
703
905
|
}
|
704
906
|
}
|
705
907
|
menu {
|
706
|
-
text
|
908
|
+
text '&History'
|
707
909
|
menu {
|
708
|
-
text
|
910
|
+
text '&Recent'
|
709
911
|
menu_item {
|
710
|
-
text
|
912
|
+
text 'File 1'
|
913
|
+
on_widget_selected {
|
914
|
+
message_box(shell_proxy) {
|
915
|
+
text 'File 1'
|
916
|
+
message 'File 1 Contents'
|
917
|
+
}.open
|
918
|
+
}
|
711
919
|
}
|
712
920
|
menu_item {
|
713
|
-
text
|
921
|
+
text 'File 2'
|
922
|
+
on_widget_selected {
|
923
|
+
message_box(shell_proxy) {
|
924
|
+
text 'File 2'
|
925
|
+
message 'File 2 Contents'
|
926
|
+
}.open
|
927
|
+
}
|
714
928
|
}
|
715
929
|
}
|
716
930
|
}
|
@@ -718,22 +932,37 @@ shell {
|
|
718
932
|
}.open
|
719
933
|
```
|
720
934
|
|
721
|
-
Example
|
935
|
+
Example of a Pop Up Context Menu (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
722
936
|
|
723
937
|
```ruby
|
724
|
-
shell {
|
938
|
+
shell { |shell_proxy|
|
939
|
+
text 'Hello, Pop Up Context Menu!'
|
940
|
+
grid_layout
|
725
941
|
label {
|
726
|
-
|
942
|
+
font height: 16
|
943
|
+
text 'Right-Click To Pop Up a Context Menu'
|
727
944
|
menu {
|
728
945
|
menu {
|
729
946
|
text '&History'
|
730
947
|
menu {
|
731
|
-
text
|
948
|
+
text '&Recent'
|
732
949
|
menu_item {
|
733
|
-
text
|
950
|
+
text 'File 1'
|
951
|
+
on_widget_selected {
|
952
|
+
message_box(shell_proxy) {
|
953
|
+
text 'File 1'
|
954
|
+
message 'File 1 Contents'
|
955
|
+
}.open
|
956
|
+
}
|
734
957
|
}
|
735
958
|
menu_item {
|
736
|
-
text
|
959
|
+
text 'File 2'
|
960
|
+
on_widget_selected {
|
961
|
+
message_box(shell_proxy) {
|
962
|
+
text 'File 2'
|
963
|
+
message 'File 2 Contents'
|
964
|
+
}.open
|
965
|
+
}
|
737
966
|
}
|
738
967
|
}
|
739
968
|
}
|
@@ -987,9 +1216,12 @@ composite {
|
|
987
1216
|
```
|
988
1217
|
|
989
1218
|
Here is a more sophisticated example taken from [hello_computed.rb](samples/hello/hello_computed.rb) sample:
|
1219
|
+
|
1220
|
+
![Hello Computed](images/glimmer-hello-computed.png)
|
1221
|
+
|
990
1222
|
```ruby
|
991
1223
|
shell {
|
992
|
-
text
|
1224
|
+
text 'Hello, Computed!'
|
993
1225
|
composite {
|
994
1226
|
grid_layout {
|
995
1227
|
num_columns 2
|
@@ -997,44 +1229,44 @@ shell {
|
|
997
1229
|
horizontal_spacing 20
|
998
1230
|
vertical_spacing 10
|
999
1231
|
}
|
1000
|
-
label {text
|
1232
|
+
label {text 'First &Name: '}
|
1001
1233
|
text {
|
1002
1234
|
text bind(@contact, :first_name)
|
1003
1235
|
layout_data {
|
1004
|
-
|
1005
|
-
|
1236
|
+
horizontal_alignment :fill
|
1237
|
+
grab_excess_horizontal_space true
|
1006
1238
|
}
|
1007
1239
|
}
|
1008
|
-
label {text
|
1240
|
+
label {text '&Last Name: '}
|
1009
1241
|
text {
|
1010
1242
|
text bind(@contact, :last_name)
|
1011
1243
|
layout_data {
|
1012
|
-
|
1013
|
-
|
1244
|
+
horizontal_alignment :fill
|
1245
|
+
grab_excess_horizontal_space true
|
1014
1246
|
}
|
1015
1247
|
}
|
1016
|
-
label {text
|
1248
|
+
label {text '&Year of Birth: '}
|
1017
1249
|
text {
|
1018
1250
|
text bind(@contact, :year_of_birth)
|
1019
1251
|
layout_data {
|
1020
|
-
|
1021
|
-
|
1252
|
+
horizontal_alignment :fill
|
1253
|
+
grab_excess_horizontal_space true
|
1022
1254
|
}
|
1023
1255
|
}
|
1024
|
-
label {text
|
1256
|
+
label {text 'Name: '}
|
1025
1257
|
label {
|
1026
1258
|
text bind(@contact, :name, computed_by: [:first_name, :last_name])
|
1027
1259
|
layout_data {
|
1028
|
-
|
1029
|
-
|
1260
|
+
horizontal_alignment :fill
|
1261
|
+
grab_excess_horizontal_space true
|
1030
1262
|
}
|
1031
1263
|
}
|
1032
|
-
label {text
|
1264
|
+
label {text 'Age: '}
|
1033
1265
|
label {
|
1034
1266
|
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
|
1035
1267
|
layout_data {
|
1036
|
-
|
1037
|
-
|
1268
|
+
horizontal_alignment :fill
|
1269
|
+
grab_excess_horizontal_space true
|
1038
1270
|
}
|
1039
1271
|
}
|
1040
1272
|
}
|
@@ -1177,6 +1409,10 @@ Example from [samples/hello/hello_combo.rb](samples/hello_combo.rb) sample (you
|
|
1177
1409
|
|
1178
1410
|
#### Combo
|
1179
1411
|
|
1412
|
+
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.
|
1413
|
+
|
1414
|
+
When data-binding a `combo` widget, Glimmer can automatically deduce available options from data-bound model by convention: `{attribute_name}_options` method.
|
1415
|
+
|
1180
1416
|
![Hello Combo](images/glimmer-hello-combo.png)
|
1181
1417
|
|
1182
1418
|
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
@@ -1218,7 +1454,7 @@ end
|
|
1218
1454
|
HelloCombo.new.launch
|
1219
1455
|
```
|
1220
1456
|
|
1221
|
-
`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.
|
1457
|
+
`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.
|
1222
1458
|
|
1223
1459
|
#### List
|
1224
1460
|
|
@@ -1530,7 +1766,7 @@ class TicTacToe
|
|
1530
1766
|
end
|
1531
1767
|
```
|
1532
1768
|
|
1533
|
-
Observers can be a good mechanism for displaying dialog messages in Glimmer (using SWT's `MessageBox`).
|
1769
|
+
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).
|
1534
1770
|
|
1535
1771
|
Look at [`samples/elaborate/tictactoe/tic_tac_toe.rb`](samples/tictactoe/tic_tac_toe.rb) for more details starting with the code included below.
|
1536
1772
|
|
@@ -1556,10 +1792,10 @@ class TicTacToe
|
|
1556
1792
|
end
|
1557
1793
|
|
1558
1794
|
def display_game_over_message(message)
|
1559
|
-
message_box
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1795
|
+
message_box(@shell) {
|
1796
|
+
text 'Game Over'
|
1797
|
+
message message_text
|
1798
|
+
}.open
|
1563
1799
|
@tic_tac_toe_board.reset
|
1564
1800
|
end
|
1565
1801
|
# ...
|
@@ -1600,7 +1836,7 @@ shell {
|
|
1600
1836
|
|
1601
1837
|
As you can see, `RedLabel` became Glimmer DSL keyword: `red_label`
|
1602
1838
|
|
1603
|
-
#### Hook Example
|
1839
|
+
#### Lifecycle Hook Example
|
1604
1840
|
|
1605
1841
|
(you may copy/paste in [`girb`](#girb-glimmer-irb-command))
|
1606
1842
|
|
@@ -1635,10 +1871,12 @@ shell {
|
|
1635
1871
|
}.open
|
1636
1872
|
```
|
1637
1873
|
|
1638
|
-
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`.
|
1874
|
+
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`.
|
1639
1875
|
|
1640
1876
|
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.
|
1641
1877
|
|
1878
|
+
#### Custom Widget API
|
1879
|
+
|
1642
1880
|
Custom Widgets have the following attributes available to call from inside the `#body` method:
|
1643
1881
|
- `#parent`: Glimmer object parenting custom widget
|
1644
1882
|
- `#swt_style`: SWT style integer. Can be useful if you want to allow consumers to customize a widget inside the custom widget body
|
@@ -1693,7 +1931,9 @@ shell {
|
|
1693
1931
|
|
1694
1932
|
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'`
|
1695
1933
|
|
1696
|
-
|
1934
|
+
#### Custom Widget Lifecycle Hooks
|
1935
|
+
|
1936
|
+
Last but not least, these are the available lifecycle hooks:
|
1697
1937
|
- `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`
|
1698
1938
|
- `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.
|
1699
1939
|
|
@@ -1727,6 +1967,11 @@ body {
|
|
1727
1967
|
|
1728
1968
|
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`.
|
1729
1969
|
|
1970
|
+
#### Final Notes
|
1971
|
+
|
1972
|
+
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:
|
1973
|
+
[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)
|
1974
|
+
|
1730
1975
|
### Custom Shells
|
1731
1976
|
|
1732
1977
|
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.
|
@@ -1792,94 +2037,77 @@ shell { |app_shell|
|
|
1792
2037
|
}.open
|
1793
2038
|
```
|
1794
2039
|
|
1795
|
-
###
|
2040
|
+
### Drag and Drop
|
1796
2041
|
|
1797
|
-
|
2042
|
+
Glimmer offers Drag and Drop support, thanks to [SWT](https://www.eclipse.org/swt/) and Glimmer's lightweight [DSL syntax](#glimmer-dsl-syntax).
|
1798
2043
|
|
1799
|
-
|
1800
|
-
- `on_about`: executes code when user selects App Name -> About
|
1801
|
-
- `on_preferences`: executes code when user selects App Name -> Preferences or hits 'CMD+,' on the Mac
|
2044
|
+
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)
|
1802
2045
|
|
1803
|
-
|
2046
|
+
To get started, simply follow these steps:
|
2047
|
+
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)
|
2048
|
+
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)
|
2049
|
+
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)
|
2050
|
+
1. Read `event.data` and consume it (e.g. change widget text) inside the `on_drop` event handler block.
|
2051
|
+
|
2052
|
+
Example (taken from [samples/hello/hello_drag_and_drop.rb](#hello-drag-and-drop) / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1804
2053
|
|
1805
2054
|
```ruby
|
1806
|
-
class
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
message_box.setText("About")
|
1812
|
-
message_box.setMessage("About Application")
|
1813
|
-
message_box.open
|
1814
|
-
}
|
1815
|
-
on_preferences {
|
1816
|
-
preferences_dialog = dialog {
|
1817
|
-
text 'Preferences'
|
1818
|
-
row_layout {
|
1819
|
-
type :vertical
|
1820
|
-
margin_left 15
|
1821
|
-
margin_top 15
|
1822
|
-
margin_right 15
|
1823
|
-
margin_bottom 15
|
1824
|
-
}
|
1825
|
-
label {
|
1826
|
-
text 'Check one of these options:'
|
1827
|
-
}
|
1828
|
-
button(:radio) {
|
1829
|
-
text 'Option 1'
|
1830
|
-
}
|
1831
|
-
button(:radio) {
|
1832
|
-
text 'Option 2'
|
1833
|
-
}
|
1834
|
-
}
|
1835
|
-
preferences_dialog.open
|
1836
|
-
}
|
1837
|
-
}
|
1838
|
-
@shell_proxy = shell {
|
1839
|
-
text 'Application Menu Items'
|
1840
|
-
fill_layout {
|
1841
|
-
margin_width 15
|
1842
|
-
margin_height 15
|
1843
|
-
}
|
1844
|
-
label {
|
1845
|
-
text 'Application Menu Items'
|
1846
|
-
font height: 30
|
1847
|
-
}
|
1848
|
-
}
|
1849
|
-
@shell_proxy.open
|
2055
|
+
class Location
|
2056
|
+
attr_accessor :country
|
2057
|
+
|
2058
|
+
def country_options
|
2059
|
+
%w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
1850
2060
|
end
|
1851
2061
|
end
|
1852
2062
|
|
1853
|
-
|
1854
|
-
```
|
1855
|
-
|
1856
|
-
#### App Name and Version
|
1857
|
-
|
1858
|
-
Application name (shows up on the Mac in top menu bar) and version may be specified upon [packaging](#packaging--distribution) by specifying "-Bmac.CFBundleName" and "-Bmac.CFBundleVersion" options.
|
1859
|
-
|
1860
|
-
Still, if you would like proper application name to show up on the Mac top menu bar during development, you may do so by invoking the SWT Display.setAppName method before any Display object has been instantiated (i.e. before any Glimmer widget like shell has been declared).
|
1861
|
-
|
1862
|
-
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2063
|
+
@location = Location.new
|
1863
2064
|
|
1864
|
-
|
1865
|
-
Display.setAppName('Glimmer Demo')
|
2065
|
+
include Glimmer
|
1866
2066
|
|
1867
|
-
shell
|
1868
|
-
text
|
1869
|
-
|
1870
|
-
|
2067
|
+
shell {
|
2068
|
+
text 'Hello, Drag and Drop!'
|
2069
|
+
list {
|
2070
|
+
selection bind(@location, :country)
|
2071
|
+
on_drag_set_data { |event|
|
2072
|
+
list = event.widget.getControl
|
2073
|
+
event.data = list.getSelection.first
|
2074
|
+
}
|
2075
|
+
}
|
2076
|
+
label(:center) {
|
2077
|
+
text 'Drag a country here!'
|
2078
|
+
font height: 20
|
2079
|
+
on_drop { |event|
|
2080
|
+
event.widget.getControl.setText(event.data)
|
2081
|
+
}
|
1871
2082
|
}
|
1872
2083
|
}.open
|
1873
2084
|
```
|
1874
2085
|
|
1875
|
-
|
2086
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2087
|
+
|
2088
|
+
Optional steps:
|
2089
|
+
- 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.
|
2090
|
+
- Specify `drag_source_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2091
|
+
- 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)
|
2092
|
+
- Specify `drop_target_style` operation (may be: :drop_copy (default), :drop_link, :drop_move, :drop_none, or an array of multiple operations)
|
2093
|
+
- 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)
|
2094
|
+
- Set drag operation in `event.detail` (e.g. DND::DROP_COPY) inside `on_drag_enter`
|
2095
|
+
|
2096
|
+
### Miscellaneous
|
1876
2097
|
|
1877
2098
|
#### Multi-DSL Support
|
1878
2099
|
|
1879
|
-
Glimmer
|
1880
|
-
|
2100
|
+
Glimmer is a DSL engine that supports multiple DSLs (Domain Specific Languages):
|
2101
|
+
- [SWT](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
2102
|
+
- [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
2103
|
+
- [XML](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML) - Useful with [SWT Browser Widget](#browser-widget)
|
2104
|
+
- [CSS](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets) - Useful with [SWT Browser Widget](#browser-widget)
|
2105
|
+
|
2106
|
+
Glimmer automatically recognizes top-level keywords in each DSL and activates DSL accordingly. Glimmer allows mixing DSLs, which comes in handy when doing things like using the SWT Browser widget with XML and CSS. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
|
1881
2107
|
|
1882
|
-
|
2108
|
+
##### SWT
|
2109
|
+
|
2110
|
+
The SWT DSL was already covered in detail. However, for the sake of mixing DSLs, you need to know that the SWT DSL has the following top-level keywords:
|
1883
2111
|
- `shell`
|
1884
2112
|
- `display`
|
1885
2113
|
- `color`
|
@@ -1887,7 +2115,13 @@ For example, the SWT DSL has the following top-level keywords:
|
|
1887
2115
|
- `async_exec`
|
1888
2116
|
- `sync_exec`
|
1889
2117
|
|
1890
|
-
#####
|
2118
|
+
##### Opal
|
2119
|
+
|
2120
|
+
Full instructions are found in the [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL page.
|
2121
|
+
|
2122
|
+
The [Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) DSL is simply a web GUI adapter for desktop apps written in Glimmer. As such, it supports all the DSL keywords of the SWT DSL and shares the same top-level keywords.
|
2123
|
+
|
2124
|
+
##### XML
|
1891
2125
|
|
1892
2126
|
Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
|
1893
2127
|
Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
|
@@ -1965,8 +2199,7 @@ Output:
|
|
1965
2199
|
<DOCUMENT><document:body document:id="main"></document:body></DOCUMENT>
|
1966
2200
|
```
|
1967
2201
|
|
1968
|
-
|
1969
|
-
##### CSS DSL
|
2202
|
+
##### CSS
|
1970
2203
|
|
1971
2204
|
Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
|
1972
2205
|
Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
|
@@ -2002,121 +2235,243 @@ Glimmer provides a number of methods on Glimmer::DSL::Engine to configure DSL su
|
|
2002
2235
|
- `Glimmer::DSL::Engine.enable_dsl(dsl_name)`: Re-enables disabled DSL
|
2003
2236
|
- `Glimmer::DSL::Engine.enabled_dsls=(dsl_names)`: Disables all DSLs except the ones specified.
|
2004
2237
|
|
2005
|
-
####
|
2006
|
-
|
2007
|
-
![Video Widget](images/glimmer-video-widget.png)
|
2008
|
-
|
2009
|
-
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
|
2010
|
-
|
2011
|
-
You may obtain via `glimmer-cw-video` gem.
|
2012
|
-
|
2013
|
-
#### Browser Widget
|
2014
|
-
|
2015
|
-
Glimmer supports SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged in Glimmer except for rare cases when leveraging a pre-existing web codebase in a desktop app).
|
2016
|
-
|
2017
|
-
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2238
|
+
#### Application Menu Items (About/Preferences)
|
2018
2239
|
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2022
|
-
browser {
|
2023
|
-
url 'http://brightonresort.com/about'
|
2024
|
-
}
|
2025
|
-
}.open
|
2026
|
-
```
|
2240
|
+
Mac applications always have About and Preferences menu items. Glimmer provides widget observer hooks for them on the `display`:
|
2241
|
+
- `on_about`: executes code when user selects App Name -> About
|
2242
|
+
- `on_preferences`: executes code when user selects App Name -> Preferences or hits 'CMD+,' on the Mac
|
2027
2243
|
|
2028
|
-
Example
|
2244
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2029
2245
|
|
2030
2246
|
```ruby
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
h1 { "Hello, World!" }
|
2247
|
+
class Example
|
2248
|
+
def initialize
|
2249
|
+
display {
|
2250
|
+
on_about {
|
2251
|
+
message_box(@shell_proxy) {
|
2252
|
+
text 'About'
|
2253
|
+
message 'About Application'
|
2254
|
+
}.open
|
2040
2255
|
}
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2256
|
+
on_preferences {
|
2257
|
+
preferences_dialog = dialog {
|
2258
|
+
text 'Preferences'
|
2259
|
+
row_layout {
|
2260
|
+
type :vertical
|
2261
|
+
margin_left 15
|
2262
|
+
margin_top 15
|
2263
|
+
margin_right 15
|
2264
|
+
margin_bottom 15
|
2265
|
+
}
|
2266
|
+
label {
|
2267
|
+
text 'Check one of these options:'
|
2268
|
+
}
|
2269
|
+
button(:radio) {
|
2270
|
+
text 'Option 1'
|
2271
|
+
}
|
2272
|
+
button(:radio) {
|
2273
|
+
text 'Option 2'
|
2274
|
+
}
|
2275
|
+
}
|
2276
|
+
preferences_dialog.open
|
2277
|
+
}
|
2278
|
+
}
|
2279
|
+
@shell_proxy = shell {
|
2280
|
+
text 'Application Menu Items'
|
2281
|
+
fill_layout {
|
2282
|
+
margin_width 15
|
2283
|
+
margin_height 15
|
2284
|
+
}
|
2285
|
+
label {
|
2286
|
+
text 'Application Menu Items'
|
2287
|
+
font height: 30
|
2288
|
+
}
|
2289
|
+
}
|
2290
|
+
@shell_proxy.open
|
2291
|
+
end
|
2292
|
+
end
|
2065
2293
|
|
2066
|
-
|
2294
|
+
Example.new
|
2295
|
+
```
|
2296
|
+
|
2297
|
+
#### App Name and Version
|
2298
|
+
|
2299
|
+
Application name (shows up on the Mac in top menu bar) and version may be specified upon [packaging](#packaging--distribution) by specifying "-Bmac.CFBundleName" and "-Bmac.CFBundleVersion" options.
|
2300
|
+
|
2301
|
+
Still, if you would like proper application name to show up on the Mac top menu bar during development, you may do so by invoking the SWT Display.setAppName method before any Display object has been instantiated (i.e. before any Glimmer widget like shell has been declared).
|
2067
2302
|
|
2068
|
-
|
2303
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2069
2304
|
|
2070
|
-
|
2305
|
+
```ruby
|
2306
|
+
Display.setAppName('Glimmer Demo')
|
2071
2307
|
|
2308
|
+
shell(:no_resize) {
|
2309
|
+
text "Glimmer"
|
2310
|
+
label {
|
2311
|
+
text "Hello, World!"
|
2312
|
+
}
|
2313
|
+
}.open
|
2072
2314
|
```
|
2073
|
-
|
2315
|
+
|
2316
|
+
Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app version identification reasons during development, replacing `'1.0.0'` with your application version.
|
2317
|
+
|
2318
|
+
#### Video Widget
|
2319
|
+
|
2320
|
+
![Video Widget](images/glimmer-video-widget.png)
|
2321
|
+
|
2322
|
+
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
|
2323
|
+
|
2324
|
+
You may obtain via `glimmer-cw-video` gem.
|
2325
|
+
|
2326
|
+
#### Browser Widget
|
2327
|
+
|
2328
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2329
|
+
|
2330
|
+
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).
|
2331
|
+
|
2332
|
+
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2333
|
+
|
2334
|
+
```ruby
|
2335
|
+
shell {
|
2336
|
+
minimum_size 1024, 860
|
2337
|
+
browser {
|
2338
|
+
url 'http://brightonresort.com/about'
|
2339
|
+
}
|
2340
|
+
}.open
|
2074
2341
|
```
|
2075
2342
|
|
2076
|
-
|
2343
|
+
Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command) provided you install and require [glimmer-dsl-xml gem](https://github.com/AndyObtiva/glimmer-dsl-xml)):
|
2077
2344
|
|
2078
|
-
|
2345
|
+
```ruby
|
2346
|
+
shell {
|
2347
|
+
minimum_size 130, 130
|
2348
|
+
@browser = browser {
|
2349
|
+
text html {
|
2350
|
+
head {
|
2351
|
+
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
2352
|
+
}
|
2353
|
+
body {
|
2354
|
+
h1 { "Hello, World!" }
|
2355
|
+
}
|
2356
|
+
}
|
2357
|
+
on_completed { # on load of the page execute this JavaScript
|
2358
|
+
@browser.swt_widget.execute("alert('Hello, World!');")
|
2359
|
+
}
|
2360
|
+
}
|
2361
|
+
}.open
|
2362
|
+
```
|
2363
|
+
|
2364
|
+
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).
|
2365
|
+
|
2366
|
+
## Glimmer Configuration
|
2367
|
+
|
2368
|
+
Glimmer configuration may be done via the `Glimmer::Config` module.
|
2079
2369
|
|
2370
|
+
### logger
|
2371
|
+
|
2372
|
+
Glimmer supports logging via a Ruby Logger configurable with the `Glimmer::Config.logger` config option.
|
2373
|
+
It is disabled by default to ensure not affecting desktop app performance.
|
2374
|
+
It may be enabled via `Glimmer::Config.enable_logging`
|
2375
|
+
When enabled, the Glimmer logger level defaults to `:warn` (aka `Logger::WARN`)
|
2376
|
+
It may be configured to show a different level of logging via `Glimmer::Config.logger.level` just ike with any Ruby Logger.
|
2377
|
+
|
2378
|
+
Example:
|
2379
|
+
|
2380
|
+
```ruby
|
2381
|
+
Glimmer::Config.enable_logging
|
2382
|
+
Glimmer::Config.logger.level = Logger::DEBUG
|
2080
2383
|
```
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2384
|
+
This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
|
2385
|
+
|
2386
|
+
Example log:
|
2387
|
+
```
|
2388
|
+
D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
|
2389
|
+
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2390
|
+
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2391
|
+
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2392
|
+
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2393
|
+
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2394
|
+
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2395
|
+
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2396
|
+
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2397
|
+
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2398
|
+
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2399
|
+
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2088
2400
|
```
|
2089
2401
|
|
2090
|
-
###
|
2402
|
+
### import_swt_packages
|
2091
2403
|
|
2092
|
-
|
2404
|
+
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.
|
2405
|
+
|
2406
|
+
As a result, you may call SWT Java classes from Glimmer Ruby code without mentioning Java package references explicitly.
|
2407
|
+
|
2408
|
+
For example, `org.eclipse.swt.graphics.Color` can be referenced as just `Color`
|
2093
2409
|
|
2410
|
+
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:
|
2094
2411
|
```
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2412
|
+
org.eclipse.swt.*
|
2413
|
+
org.eclipse.swt.widgets.*
|
2414
|
+
org.eclipse.swt.layout.*
|
2415
|
+
org.eclipse.swt.graphics.*
|
2416
|
+
org.eclipse.swt.browser.*
|
2417
|
+
org.eclipse.swt.custom.*
|
2418
|
+
org.eclipse.swt.dnd.*
|
2098
2419
|
```
|
2099
2420
|
|
2100
|
-
|
2421
|
+
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).
|
2101
2422
|
|
2102
|
-
|
2423
|
+
Example:
|
2103
2424
|
|
2104
|
-
|
2425
|
+
```ruby
|
2426
|
+
Glimmer::Config.import_swt_packages += [
|
2427
|
+
'org.eclipse.nebula.widgets.ganttchart'
|
2428
|
+
]
|
2429
|
+
```
|
2105
2430
|
|
2106
|
-
|
2431
|
+
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)
|
2107
2432
|
|
2108
|
-
|
2433
|
+
Nonetheless, you can disable automatic Java package import if needed via this Glimmer configuration option:
|
2109
2434
|
|
2110
|
-
|
2435
|
+
```ruby
|
2436
|
+
Glimmer::Config.import_swt_packages = false
|
2437
|
+
```
|
2111
2438
|
|
2112
|
-
|
2113
|
-
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
2439
|
+
Once disabled, to import SWT Java packages manually, you may simply:
|
2114
2440
|
|
2115
|
-
|
2441
|
+
1. `include Glimmer::SWT::Packages`: lazily imports all SWT Java packages to your class, lazy-loading SWT Java class constants on first reference.
|
2116
2442
|
|
2117
|
-
|
2443
|
+
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'`)
|
2118
2444
|
|
2119
|
-
|
2445
|
+
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.
|
2446
|
+
|
2447
|
+
You can learn more about importing Java packages into Ruby code at this JRuby WIKI page:
|
2448
|
+
|
2449
|
+
https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
|
2450
|
+
|
2451
|
+
### loop_max_count
|
2452
|
+
|
2453
|
+
Glimmer has infinite loop detection support.
|
2454
|
+
It can detect when an infinite loop is about to occur in method_missing and stops it.
|
2455
|
+
It detects potential infinite loops when the same keyword and args repeat more than 100 times, which is unusual in a GUI app.
|
2456
|
+
|
2457
|
+
The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` config option.
|
2458
|
+
|
2459
|
+
Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
|
2460
|
+
|
2461
|
+
## Glimmer Style Guide
|
2462
|
+
|
2463
|
+
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
2464
|
+
- Widget declarations may optionally have arguments and be followed by a block (to contain properties and content)
|
2465
|
+
- Widget blocks are always declared with curly braces
|
2466
|
+
- Widget arguments are always wrapped inside parentheses
|
2467
|
+
- Widget properties are declared with underscored lowercase versions of the SWT properties
|
2468
|
+
- Widget property declarations always have arguments and never take a block
|
2469
|
+
- Widget property arguments are never wrapped inside parentheses
|
2470
|
+
- Widget listeners are always declared starting with `on_` prefix and affixing listener event method name afterwards in underscored lowercase form
|
2471
|
+
- Widget listeners are always followed by a block using curly braces (Only when declared in DSL. When invoked on widget object directly outside of GUI declarations, standard Ruby conventions apply)
|
2472
|
+
- Data-binding is done via `bind` keyword, which always takes arguments wrapped in parentheses
|
2473
|
+
- Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
|
2474
|
+
- 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.
|
2120
2475
|
|
2121
2476
|
## SWT Reference
|
2122
2477
|
|
@@ -2142,101 +2497,254 @@ Here is a SWT style bit constant reference:
|
|
2142
2497
|
|
2143
2498
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
2144
2499
|
|
2145
|
-
|
2500
|
+
Here is an SWT Drag and Drop guide:
|
2501
|
+
|
2502
|
+
https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html
|
2503
|
+
|
2504
|
+
Here is an SWT Custom Widget guide:
|
2505
|
+
|
2506
|
+
https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
|
2507
|
+
|
2508
|
+
## Samples
|
2509
|
+
|
2510
|
+
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`).
|
2146
2511
|
|
2147
|
-
|
2512
|
+
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:
|
2148
2513
|
|
2149
|
-
Here are the Java packages imported:
|
2150
2514
|
```
|
2151
|
-
|
2152
|
-
org.eclipse.swt.widgets.*
|
2153
|
-
org.eclipse.swt.layout.*
|
2154
|
-
org.eclipse.swt.graphics.*
|
2155
|
-
org.eclipse.swt.browser.*
|
2156
|
-
org.eclipse.swt.custom.*
|
2515
|
+
samples/launch
|
2157
2516
|
```
|
2158
2517
|
|
2159
|
-
|
2518
|
+
### Hello Samples
|
2160
2519
|
|
2161
|
-
For
|
2520
|
+
For hello-type simple samples, check the following.
|
2162
2521
|
|
2163
|
-
|
2522
|
+
#### Hello, World! Sample
|
2164
2523
|
|
2165
|
-
|
2166
|
-
|
2524
|
+
Run:
|
2525
|
+
|
2526
|
+
```
|
2527
|
+
glimmer samples/hello/hello_world.rb
|
2167
2528
|
```
|
2168
2529
|
|
2169
|
-
|
2530
|
+
![Hello World](images/glimmer-hello-world.png)
|
2170
2531
|
|
2171
|
-
|
2532
|
+
#### Hello, Tab!
|
2172
2533
|
|
2173
|
-
|
2534
|
+
Run:
|
2174
2535
|
|
2175
|
-
|
2536
|
+
```
|
2537
|
+
glimmer samples/hello/hello_tab.rb
|
2538
|
+
```
|
2176
2539
|
|
2177
|
-
|
2540
|
+
![Hello Tab English](images/glimmer-hello-tab-english.png)
|
2541
|
+
![Hello Tab French](images/glimmer-hello-tab-french.png)
|
2178
2542
|
|
2179
|
-
|
2543
|
+
#### Hello, Combo!
|
2180
2544
|
|
2181
|
-
|
2545
|
+
This sample demonstrates combo data-binding.
|
2182
2546
|
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
Glimmer::Config.enable_logging
|
2188
|
-
Glimmer::Config.logger.level = Logger::DEBUG
|
2547
|
+
Run:
|
2548
|
+
|
2549
|
+
```
|
2550
|
+
glimmer samples/hello/hello_combo.rb
|
2189
2551
|
```
|
2190
|
-
This results in more verbose debugging log to `STDOUT`, which is helpful in troubleshooting Glimmer DSL syntax when needed.
|
2191
2552
|
|
2192
|
-
|
2553
|
+
![Hello Combo](images/glimmer-hello-combo.png)
|
2554
|
+
![Hello Combo Expanded](images/glimmer-hello-combo-expanded.png)
|
2555
|
+
|
2556
|
+
#### Hello, List Single Selection!
|
2557
|
+
|
2558
|
+
This sample demonstrates list single-selection data-binding.
|
2559
|
+
|
2560
|
+
Run:
|
2561
|
+
|
2193
2562
|
```
|
2194
|
-
|
2195
|
-
D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
|
2196
|
-
D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
|
2197
|
-
D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
|
2198
|
-
D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
|
2199
|
-
D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
|
2200
|
-
D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
|
2201
|
-
D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
|
2202
|
-
D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
|
2203
|
-
D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
|
2204
|
-
D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
|
2205
|
-
D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
|
2563
|
+
glimmer samples/hello/hello_list_single_selection.rb
|
2206
2564
|
```
|
2207
2565
|
|
2208
|
-
|
2566
|
+
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
2209
2567
|
|
2210
|
-
|
2211
|
-
|
2568
|
+
#### Hello, List Multi Selection!
|
2569
|
+
|
2570
|
+
This sample demonstrates list multi-selection data-binding.
|
2571
|
+
|
2572
|
+
Run:
|
2212
2573
|
|
2213
2574
|
```
|
2214
|
-
|
2575
|
+
glimmer samples/hello/hello_list_multi_selection.rb
|
2215
2576
|
```
|
2216
2577
|
|
2217
|
-
|
2218
|
-
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.
|
2578
|
+
![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
|
2219
2579
|
|
2220
|
-
|
2580
|
+
#### Hello, Computed!
|
2221
2581
|
|
2222
|
-
|
2582
|
+
This sample demonstrates computed data-binding.
|
2223
2583
|
|
2224
|
-
|
2584
|
+
Run:
|
2225
2585
|
|
2226
|
-
|
2586
|
+
```
|
2587
|
+
glimmer samples/hello/hello_computed.rb
|
2588
|
+
```
|
2589
|
+
|
2590
|
+
![Hello Browser](images/glimmer-hello-computed.png)
|
2591
|
+
|
2592
|
+
#### Hello, Message Box!
|
2593
|
+
|
2594
|
+
This sample demonstrates a `message_box` dialog.
|
2595
|
+
|
2596
|
+
Run:
|
2227
2597
|
|
2228
|
-
Example:
|
2229
2598
|
```
|
2230
|
-
|
2599
|
+
glimmer samples/hello/hello_message_box.rb
|
2600
|
+
```
|
2601
|
+
|
2602
|
+
![Hello Message Box](images/glimmer-hello-message-box.png)
|
2603
|
+
![Hello Message Box Dialog](images/glimmer-hello-message-box-dialog.png)
|
2604
|
+
|
2605
|
+
#### Hello, Browser!
|
2606
|
+
|
2607
|
+
This sample demonstrates the `browser` widget.
|
2608
|
+
|
2609
|
+
Run:
|
2610
|
+
|
2611
|
+
```
|
2612
|
+
glimmer samples/hello/hello_browser.rb
|
2231
2613
|
```
|
2232
2614
|
|
2615
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
2616
|
+
|
2617
|
+
#### Hello, Drag and Drop!
|
2618
|
+
|
2619
|
+
This sample demonstrates drag and drop in Glimmer.
|
2620
|
+
|
2621
|
+
Run:
|
2622
|
+
|
2623
|
+
```
|
2624
|
+
glimmer samples/hello/hello_drag_and_drop.rb
|
2625
|
+
```
|
2626
|
+
|
2627
|
+
![Hello Drag and Drop](images/glimmer-hello-drag-and-drop.gif)
|
2628
|
+
|
2629
|
+
#### Hello, Menu Bar!
|
2630
|
+
|
2631
|
+
This sample demonstrates menus in Glimmer.
|
2632
|
+
|
2633
|
+
Run:
|
2634
|
+
|
2635
|
+
```
|
2636
|
+
glimmer samples/hello/hello_menu_bar.rb
|
2637
|
+
```
|
2638
|
+
|
2639
|
+
![Hello Menu Bar](images/glimmer-hello-menu-bar.png)
|
2640
|
+
![Hello Menu Bar File Menu](images/glimmer-hello-menu-bar-file-menu.png)
|
2641
|
+
![Hello Menu Bar History Menu](images/glimmer-hello-menu-bar-history-menu.png)
|
2642
|
+
|
2643
|
+
#### Hello, Pop Up Context Menu!
|
2644
|
+
|
2645
|
+
This sample demonstrates pop up context menus in Glimmer.
|
2646
|
+
|
2647
|
+
Run:
|
2648
|
+
|
2649
|
+
```
|
2650
|
+
glimmer samples/hello/hello_pop_up_context_menu.rb
|
2651
|
+
```
|
2652
|
+
|
2653
|
+
![Hello Pop Up Context Menu](images/glimmer-hello-pop-up-context-menu.png)
|
2654
|
+
![Hello Pop Up Context Menu Popped Up](images/glimmer-hello-pop-up-context-menu-popped-up.png)
|
2655
|
+
|
2656
|
+
### Elaborate Samples
|
2657
|
+
|
2658
|
+
For more elaborate samples, check the following:
|
2659
|
+
|
2660
|
+
#### Login
|
2661
|
+
|
2662
|
+
```
|
2663
|
+
glimmer samples/elaborate/login.rb # demonstrates basic data-binding
|
2664
|
+
```
|
2665
|
+
|
2666
|
+
![Login](images/glimmer-login.png)
|
2667
|
+
![Login Filled In](images/glimmer-login-filled-in.png)
|
2668
|
+
![Login Logged In](images/glimmer-login-logged-in.png)
|
2669
|
+
|
2670
|
+
#### Tic Tac Toe Sample
|
2671
|
+
|
2672
|
+
```
|
2673
|
+
glimmer samples/elaborate/tic_tac_toe.rb # demonstrates a full MVC application
|
2674
|
+
```
|
2675
|
+
|
2676
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
2677
|
+
![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
|
2678
|
+
![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
|
2679
|
+
|
2680
|
+
#### Contact Manager
|
2681
|
+
|
2682
|
+
```
|
2683
|
+
glimmer samples/elaborate/contact_manager.rb # demonstrates table data-binding
|
2684
|
+
```
|
2685
|
+
|
2686
|
+
Contact Manager
|
2687
|
+
|
2688
|
+
![Contact Manager](images/glimmer-contact-manager.png)
|
2689
|
+
|
2690
|
+
Contact Manager - Find
|
2691
|
+
|
2692
|
+
![Contact Manager](images/glimmer-contact-manager-find.png)
|
2693
|
+
|
2694
|
+
Contact Manager - Edit Started
|
2695
|
+
|
2696
|
+
![Contact Manager](images/glimmer-contact-manager-edit-started.png)
|
2697
|
+
|
2698
|
+
Contact Manager - Edit In Progress
|
2699
|
+
|
2700
|
+
![Contact Manager](images/glimmer-contact-manager-edit-in-progress.png)
|
2701
|
+
|
2702
|
+
Contact Manager - Edit Done
|
2703
|
+
|
2704
|
+
![Contact Manager](images/glimmer-contact-manager-edit-done.png)
|
2705
|
+
|
2706
|
+
### External Samples
|
2707
|
+
|
2708
|
+
#### Glimmer Calculator
|
2709
|
+
|
2710
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/v1.0.0/glimmer-cs-calculator-screenshot.png" />](https://github.com/AndyObtiva/glimmer-cs-calculator)
|
2711
|
+
|
2712
|
+
[Glimmer Calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) is a basic calculator sample project demonstrating data-binding and TDD (test-driven-development) with Glimmer following the MVP pattern (Model-View-Presenter).
|
2713
|
+
|
2714
|
+
#### Gladiator
|
2715
|
+
|
2716
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
|
2717
|
+
|
2718
|
+
[Gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator) (short for Glimmer Editor) is a Glimmer sample project under on-going development.
|
2719
|
+
You may check it out to learn how to build a Glimmer Custom Shell gem.
|
2720
|
+
|
2721
|
+
Gladiator is a good demonstration of:
|
2722
|
+
- MVP Pattern
|
2723
|
+
- Tree data-binding
|
2724
|
+
- List data-binding
|
2725
|
+
- Text selection data-binding
|
2726
|
+
- Tabs
|
2727
|
+
- Context menus
|
2728
|
+
- Custom Shell
|
2729
|
+
- Custom widget
|
2730
|
+
|
2731
|
+
## In Production
|
2732
|
+
|
2733
|
+
The following production apps have been built with Glimmer:
|
2734
|
+
|
2735
|
+
[<img alt="Math Bowling Logo" src="https://raw.githubusercontent.com/AndyObtiva/MathBowling/master/images/math-bowling-logo.png" width="40" />Math Bowling](https://github.com/AndyObtiva/MathBowling): an educational math game for elementary level kids
|
2736
|
+
|
2737
|
+
[<img alt="Are We There Yet Logo" src="https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-logo.svg" width="40" />Are We There Yet?](https://github.com/AndyObtiva/are-we-there-yet): A tool that helps you learn when your small projects will finish
|
2738
|
+
|
2739
|
+
If you have a Glimmer app you would like referenced here, please mention in a Pull Request.
|
2740
|
+
|
2233
2741
|
## Packaging & Distribution
|
2234
2742
|
|
2235
2743
|
Glimmer apps may be packaged and distributed on the Mac, Windows, and Linux via these tools:
|
2236
2744
|
- Warbler (https://github.com/jruby/warbler): Enables bundling a Glimmer app into a JAR file
|
2237
2745
|
- javapackager (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html): Enables packaging a JAR file as a DMG file on Mac, EXE on Windows, and multiple Linux supported formats on Linux.
|
2238
2746
|
|
2239
|
-
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](
|
2747
|
+
Glimmer simplifies the process of Mac packaging via the `glimmer package` command. It works out of the box for any application generated by [Glimmer Scaffolding](#scaffolding):
|
2240
2748
|
|
2241
2749
|
```
|
2242
2750
|
glimmer package
|
@@ -2391,16 +2899,18 @@ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub
|
|
2391
2899
|
|
2392
2900
|
[Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
|
2393
2901
|
|
2394
|
-
###
|
2395
|
-
|
2396
|
-
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.
|
2902
|
+
### Chat
|
2397
2903
|
|
2398
|
-
|
2904
|
+
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)
|
2399
2905
|
|
2400
2906
|
## Feature Suggestions
|
2401
2907
|
|
2402
2908
|
These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
|
2403
2909
|
|
2910
|
+
[glimmer-dsl-swt/TODO.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md)
|
2911
|
+
|
2912
|
+
Glimmer DSL Engine specific tasks are at:
|
2913
|
+
|
2404
2914
|
[TODO.md](TODO.md)
|
2405
2915
|
|
2406
2916
|
## Change Log
|
@@ -2409,6 +2919,16 @@ These features have been suggested. You might see them in a future version of Gl
|
|
2409
2919
|
|
2410
2920
|
## Contributing
|
2411
2921
|
|
2922
|
+
**Contributors Wanted!**
|
2923
|
+
|
2924
|
+
If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](#swt-reference), run all Glimmer [samples](#samples), and build a small sample app to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
|
2925
|
+
|
2926
|
+
You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
|
2927
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
|
2928
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
2929
|
+
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
2930
|
+
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
2931
|
+
|
2412
2932
|
[CONTRIBUTING.md](CONTRIBUTING.md)
|
2413
2933
|
|
2414
2934
|
## Contributors
|
@@ -2418,7 +2938,13 @@ These features have been suggested. You might see them in a future version of Gl
|
|
2418
2938
|
|
2419
2939
|
[Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer/graphs/contributors)
|
2420
2940
|
|
2941
|
+
## Hire Me
|
2942
|
+
|
2943
|
+
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/).
|
2944
|
+
|
2421
2945
|
## License
|
2422
2946
|
|
2423
2947
|
Copyright (c) 2007-2020 Andy Maleh.
|
2424
2948
|
See LICENSE.txt for further details.
|
2949
|
+
|
2950
|
+
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>
|