glimmer 1.0.2 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -3
- data/LICENSE.txt +1 -1
- data/PROCESS.md +2 -2
- data/README.md +335 -230
- data/VERSION +1 -1
- data/glimmer.gemspec +8 -8
- data/lib/glimmer.rb +5 -5
- data/lib/glimmer/config.rb +6 -6
- data/lib/glimmer/data_binding/model_binding.rb +10 -10
- data/lib/glimmer/data_binding/observable.rb +4 -4
- data/lib/glimmer/data_binding/observable_array.rb +12 -12
- data/lib/glimmer/data_binding/observable_model.rb +30 -11
- data/lib/glimmer/data_binding/observer.rb +8 -6
- data/lib/glimmer/dsl/engine.rb +13 -12
- data/lib/glimmer/dsl/expression.rb +5 -5
- data/lib/glimmer/dsl/expression_handler.rb +4 -4
- data/lib/glimmer/dsl/parent_expression.rb +4 -4
- data/lib/glimmer/dsl/static_expression.rb +6 -6
- data/lib/glimmer/dsl/top_level_expression.rb +4 -4
- data/lib/glimmer/error.rb +4 -4
- data/lib/glimmer/invalid_keyword_error.rb +4 -4
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 352b655dc654c87123cc2fb6b127f113ece434c0dac1ff18139caf8c709423d8
|
4
|
+
data.tar.gz: 6cb1ca7341fee34373460c7760bda62ce6ecbf52bf033b98590471868e114ff5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c80e09354d3851493cf3883ccf1706e3590d8945c54d7ddc35ce6e017b9aeb3b3b65c59cbc691944130007e49a24ad8e47e57667ab16d9e57ebf9ce73a75b01
|
7
|
+
data.tar.gz: c69d37a79ba5b2afd58dab6aa28cd0b88c912b9f57d28c48ac88ea5c8ae476ce6c84d49bec5503810418bdf0d6c6d9ab39e68d69828ee7a36d558eb46cc560ab
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,28 @@
|
|
3
3
|
Related Change Logs:
|
4
4
|
- [glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
|
5
5
|
|
6
|
+
## 1.0.7
|
7
|
+
|
8
|
+
- Refactor generated `__original_{method_name}` methods in `ObservableModel` to have double-underscore after the word "original" as `__original__{method_name}` to improve clarity that the method is generated via meta-programming of a pre-existing method
|
9
|
+
- Fix issue regarding testing array object observer on a nil object
|
10
|
+
|
11
|
+
## 1.0.6
|
12
|
+
|
13
|
+
- Update ModelBinding to raise an error if called to make a change while configurd as binding_options[:read_only]=true
|
14
|
+
|
15
|
+
## 1.0.5
|
16
|
+
|
17
|
+
- Fix issue in Opal regarding auto-definition of observable methods in a Class/Module directly (as opposed to a class instance)
|
18
|
+
|
19
|
+
## 1.0.4
|
20
|
+
|
21
|
+
- Ensure that `ObservableModel#remove_observer` clears observer registrations from `Observer` (just like `Observer#unobserve`)
|
22
|
+
- `ObservableModel#remove_observers` and `ObservableModel#remove_all_observers` methods
|
23
|
+
|
24
|
+
## 1.0.3
|
25
|
+
|
26
|
+
- Upgraded array_include_methods gem to v1.0.4
|
27
|
+
|
6
28
|
## 1.0.2
|
7
29
|
|
8
30
|
- Support ObservableArray notifications on `unshift`, `prepend`, and `append`
|
@@ -30,7 +52,7 @@ Related Change Logs:
|
|
30
52
|
|
31
53
|
## 0.10.1
|
32
54
|
|
33
|
-
- excluded_keyword_checkers option for filtering certain keywords from Glimmer DSL processing
|
55
|
+
- excluded_keyword_checkers option for filtering certain keywords from Glimmer DSL processing
|
34
56
|
- Updates to logging levels to be more appropriate
|
35
57
|
- Fixed an issue to avoid crashing when calling observer.unregister/unobserve on a non-observable
|
36
58
|
|
@@ -92,7 +114,7 @@ Related Change Logs:
|
|
92
114
|
- Fix verbiage for summary/description in scaffolding custom shell gems (change custom widget reference to custom shell)
|
93
115
|
- Scaffolding builds a proper binary for custom shell gems and includes it in executables in Rakefile
|
94
116
|
- Scaffolding adds about/preferences menu actions to apps/custom-shell-gems
|
95
|
-
- Make custom widget/shell options writable
|
117
|
+
- Make custom widget/shell options writable
|
96
118
|
- Support "dialog" Glimmer DSL keyword
|
97
119
|
|
98
120
|
## 0.7.7
|
@@ -142,7 +164,7 @@ Related Change Logs:
|
|
142
164
|
- Fix freezing issue upon logging observables and raising observable errors by overriding inspect on Observable to avoid printing nested tree of observers
|
143
165
|
- Added validation for shell widget parentage (accepting a shell or nil) in shell expression
|
144
166
|
- Support bidirectional data-binding of menu item selection (e.g. radio menu item)
|
145
|
-
- Make shell auto-activate on show with 0.25 delay
|
167
|
+
- Make shell auto-activate on show with 0.25 delay
|
146
168
|
|
147
169
|
## 0.7.0
|
148
170
|
|
data/LICENSE.txt
CHANGED
data/PROCESS.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Glimmer Process (Beyond Agile)
|
2
2
|
|
3
|
-
**Glimmer Process** is the lightweight software development process used for building [Glimmer](https://github.com/AndyObtiva/glimmer) libraries and [Glimmer](https://github.com/AndyObtiva/glimmer) apps, which goes beyond Agile, rendering all Agile processes obsolete. **Glimmer Process** is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied. Not all guidelines need to be incorporated into every project, but it is still important to think through every one of them before ruling any out. Guidelines can be followed in any order.
|
3
|
+
**Glimmer Process** is the lightweight software development process used for building [Glimmer](https://github.com/AndyObtiva/glimmer) libraries and [Glimmer](https://github.com/AndyObtiva/glimmer) apps, which goes beyond Agile, rendering all Agile processes obsolete. **Glimmer Process** is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied. Not all guidelines need to be incorporated into every project, but it is still important to think through every one of them before ruling any out. Guidelines can be followed in any order.
|
4
4
|
|
5
5
|
## GPG (Glimmer Process Guidelines):
|
6
6
|
1. **Requirements Gathering**: Spend no more than a few hours writing the initial requirements you know from the business owner, gathering missing requirements, and planning to elicit more requirements from users, customers, and stakeholders. Requirements are not set in stone, but serve as a good starting point in understanding what a project is about. After initial release, only document small tasks going forward.
|
@@ -13,7 +13,7 @@
|
|
13
13
|
|
14
14
|
--
|
15
15
|
|
16
|
-
Copyright (c) 2020 Andy Maleh
|
16
|
+
Copyright (c) 2020-2021 Andy Maleh
|
17
17
|
|
18
18
|
Permission is hereby granted, free of charge, to any person obtaining
|
19
19
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -1,57 +1,53 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" />](https://rubygems.org/gems/glimmer) Glimmer 1.0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" />](https://rubygems.org/gems/glimmer) Glimmer 1.0.7 - DSL Framework
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/glimmer.svg)](http://badge.fury.io/rb/glimmer)
|
3
|
-
[![
|
3
|
+
[![rspec](https://github.com/AndyObtiva/glimmer/workflows/rspec/badge.svg)](https://github.com/AndyObtiva/glimmer/actions?query=workflow%3Arspec)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
5
5
|
[![Maintainability](https://api.codeclimate.com/v1/badges/38fbc278022862794414/maintainability)](https://codeclimate.com/github/AndyObtiva/glimmer/maintainability)
|
6
6
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
|
8
8
|
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
9
9
|
|
10
|
-
(The Original Glimmer Library Since 2007. Beware of Imitators!)
|
10
|
+
**(The Original Glimmer Library Since 2007. Beware of Imitators!)**
|
11
11
|
|
12
|
-
[**Glimmer**](https://rubygems.org/gems/glimmer)
|
13
|
-
- DSL Engine: enables building DSLs for desktop GUI, XML/HTML documents, CSS styling, and webification of desktop apps.
|
14
|
-
- Data-Binding/Observer/Observable Library: enables synchronizing GUI with Model Attributes bidirectionally.
|
12
|
+
[**Glimmer**](https://rubygems.org/gems/glimmer) started out as a [GUI Library](https://github.com/AndyObtiva/glimmer-dsl-swt) and grew into a full-fledged [DSL Framework](#dsl-engine) with support for multiple GUI DSLs. Glimmer's namesake is referring to the Glimmer of Ruby in Graphical User Interfaces (contrary to popular myth perpetrated by [Charles Nutter](http://blog.headius.com/2007/11/tab-sweep.html), Glimmer has nothing to do with the ill-fated Whitney Houston movie, which does not in fact share the same name)
|
15
13
|
|
16
|
-
[
|
14
|
+
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
15
|
+
Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) and [Chalmers/Gothenburg University Software Engineering Master's Lecture Material](http://www.cse.chalmers.se/~bergert/slides/guest_lecture_DSLs.pdf)
|
17
16
|
|
18
|
-
[**Glimmer**](https://rubygems.org/gems/glimmer)
|
19
|
-
- [
|
20
|
-
- [
|
21
|
-
|
17
|
+
[**Glimmer**](https://rubygems.org/gems/glimmer) is a DSL (Domain-Specific Language) Framework that consists of two things:
|
18
|
+
- [DSL Engine](#dsl-engine): enables building internal DSLs embedded in Ruby (e.g. for GUI, XML, or CSS).
|
19
|
+
- [Data-Binding Library](#data-binding-library): enables synchronizing GUI with Model Attributes bidirectionally.
|
20
|
+
|
21
|
+
[**Glimmer**](https://rubygems.org/gems/glimmer) is ***the cream of the crop*** when it comes to building DSLs in Ruby:
|
22
|
+
- Supports building the tersest most concise domain specific language syntax in Ruby.
|
23
|
+
- Maximum readability and maintainability.
|
24
|
+
- No extra unnecessary block variables when not needed.
|
25
|
+
- DSL Blocks are true Ruby closures that can conveniently leverage variables from the outside and utilize standard Ruby code in and around. Just code in Ruby as usual and be happy! No surprising restrictions or strange uses of `instance_exec`/`eval`.
|
26
|
+
- DSL syntax is limited to classes that mixin the `Glimmer` module, so the rest of the code is fully safe from namespace pollution.
|
27
|
+
- Multiple DSLs may be [mixed](#multi-dsl-support) together safely to achieve maximum expressability, composability, and productivity.
|
28
|
+
- DSLs are fully configurable, so you may activate and deactivate DSLs as per your current needs only.
|
29
|
+
|
30
|
+
[**Glimmer**](https://rubygems.org/gems/glimmer) supports the following DSLs:
|
31
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
32
|
+
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
|
22
33
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
23
34
|
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
|
35
|
+
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
|
24
36
|
|
25
37
|
[Glimmer and/or Glimmer DSLs receive two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer](https://rubygems.org/gems/glimmer) with your Ruby development needs.
|
26
38
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
- [Glimmer
|
33
|
-
|
34
|
-
- [Glimmer DSL for
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
- [Glimmer DSL for Tk (Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-ruby-desktop-development-gui-library)
|
40
|
-
- [Glimmer DSL for Tk Samples](#glimmer-dsl-for-tk-samples)
|
41
|
-
- [Hello, World!](#hello-world)
|
42
|
-
- [Hello, Tab!](#hello-tab)
|
43
|
-
- [Hello, Combo!](#hello-combo)
|
44
|
-
- [Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)](#glimmer-dsl-for-opal-web-gui-adapter-for-desktop-apps)
|
45
|
-
- [Glimmer DSL for Opal Samples](#glimmer-dsl-for-opal-samples)
|
46
|
-
- [Hello, Computed!](#hello-computed)
|
47
|
-
- [Hello, List Single Selection!](#hello-list-single-selection)
|
48
|
-
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
49
|
-
- [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
|
50
|
-
- [XML DSL](#xml-dsl)
|
51
|
-
- [Glimmer DSL for CSS](#glimmer-dsl-for-css)
|
52
|
-
- [CSS DSL](#css-dsl)
|
53
|
-
- [Multi-DSL Support](#multi-dsl-support)
|
54
|
-
- [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
|
39
|
+
## Table of Contents
|
40
|
+
|
41
|
+
- [Glimmer 1.0.7](#-glimmer-107---dsl-framework)
|
42
|
+
- [Official DSLs](#official-dsls)
|
43
|
+
- [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
|
44
|
+
- [Glimmer DSL for Tk (Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-ruby-desktop-development-gui-library)
|
45
|
+
- [Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)](#glimmer-dsl-for-opal-pure-ruby-web-gui-and-auto-webifier-of-desktop-apps)
|
46
|
+
- [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
|
47
|
+
- [Glimmer DSL for CSS](#glimmer-dsl-for-css)
|
48
|
+
- [DSL Engine](#dsl-engine)
|
49
|
+
- [Multi-DSL Support](#multi-dsl-support)
|
50
|
+
- [Data-Binding Library](#data-binding-library)
|
55
51
|
- [Glimmer Process](#glimmer-process)
|
56
52
|
- [Resources](#resources)
|
57
53
|
- [Help](#help)
|
@@ -63,16 +59,24 @@ Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.d
|
|
63
59
|
- [Contributors](#contributors)
|
64
60
|
- [Hire Me](#hire-me)
|
65
61
|
- [License](#license)
|
66
|
-
|
67
|
-
## Glimmer DSL for SWT (JRuby Desktop Development GUI Library)
|
68
62
|
|
69
|
-
|
63
|
+
## Official DSLs
|
64
|
+
|
65
|
+
Here, we showcase official Glimmer DSLs; that is [gems starting with the `glimmer-dsl-` prefix](https://rubygems.org/search?query=glimmer-dsl-).
|
66
|
+
|
67
|
+
(you can skip ahead if you prefer to learn more about the Glimmer [DSL Engine](#dsl-engine) or [Data-Binding Library](#data-binding-library) first)
|
68
|
+
|
69
|
+
### Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
70
|
+
|
71
|
+
[Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://rubygems.org/gems/glimmer)'s main innovation is a declarative [Ruby DSL](https://github.com/AndyObtiva/glimmer-dsl-swt#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) additionally innovates by having built-in [data-binding](https://github.com/AndyObtiva/glimmer-dsl-swt#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. To get started quickly, [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) offers [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt#scaffolding) options for [Apps](https://github.com/AndyObtiva/glimmer-dsl-swt#in-production), [Gems](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-shell-gem), and [Custom Widgets](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-widgets). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) also includes native-executable [packaging](https://github.com/AndyObtiva/glimmer-dsl-swt#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/) and MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows).
|
72
|
+
|
73
|
+
To get started, visit the [Glimmer DSL for SWT project page](https://github.com/AndyObtiva/glimmer-dsl-swt#pre-requisites) for instructions on installing the [glimmer-dsl-swt gem](https://rubygems.org/gems/glimmer-dsl-swt).
|
70
74
|
|
71
|
-
|
75
|
+
#### Glimmer DSL for SWT Samples
|
72
76
|
|
73
|
-
|
77
|
+
##### Hello, World!
|
74
78
|
|
75
|
-
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
|
79
|
+
Glimmer GUI code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
|
76
80
|
```ruby
|
77
81
|
include Glimmer
|
78
82
|
|
@@ -84,23 +88,16 @@ shell {
|
|
84
88
|
}.open
|
85
89
|
```
|
86
90
|
|
87
|
-
Run:
|
88
|
-
```
|
89
|
-
glimmer sample:run[hello_world]
|
90
|
-
```
|
91
|
-
|
92
91
|
Glimmer app:
|
93
92
|
|
94
93
|
![Hello World](images/glimmer-hello-world.png)
|
95
94
|
|
96
|
-
|
95
|
+
##### Tic Tac Toe
|
97
96
|
|
98
|
-
Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
|
97
|
+
Glimmer GUI code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
|
99
98
|
|
100
99
|
```ruby
|
101
100
|
# ...
|
102
|
-
@tic_tac_toe_board = Board.new
|
103
|
-
|
104
101
|
@shell = shell {
|
105
102
|
text "Tic-Tac-Toe"
|
106
103
|
minimum_size 150, 178
|
@@ -121,27 +118,16 @@ Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObt
|
|
121
118
|
}
|
122
119
|
}
|
123
120
|
}
|
124
|
-
|
125
|
-
observe(@tic_tac_toe_board, :game_status) { |game_status|
|
126
|
-
display_win_message if game_status == Board::WIN
|
127
|
-
display_draw_message if game_status == Board::DRAW
|
128
|
-
}
|
129
121
|
# ...
|
130
122
|
```
|
131
123
|
|
132
|
-
Run:
|
133
|
-
|
134
|
-
```
|
135
|
-
glimmer sample:run[tic_tac_toe]
|
136
|
-
```
|
137
|
-
|
138
124
|
Glimmer app:
|
139
125
|
|
140
126
|
![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
|
141
127
|
|
142
|
-
|
128
|
+
##### Contact Manager
|
143
129
|
|
144
|
-
Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
|
130
|
+
Glimmer GUI code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
|
145
131
|
|
146
132
|
```ruby
|
147
133
|
# ...
|
@@ -254,27 +240,21 @@ Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/And
|
|
254
240
|
# ...
|
255
241
|
```
|
256
242
|
|
257
|
-
Run:
|
258
|
-
|
259
|
-
```
|
260
|
-
glimmer sample:run[contact_manager]
|
261
|
-
```
|
262
|
-
|
263
243
|
Glimmer App:
|
264
244
|
|
265
245
|
![Contact Manager](images/glimmer-contact-manager.png)
|
266
246
|
|
267
|
-
|
247
|
+
#### Production Desktop Apps Built with Glimmer DSL for SWT
|
268
248
|
|
269
249
|
[<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) - Small Project Tracking App
|
270
250
|
|
271
|
-
![Are We There Yet? App Screenshot](https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-screenshot-windows.png)
|
251
|
+
[![Are We There Yet? App Screenshot](https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-screenshot-windows.png)](https://github.com/AndyObtiva/are-we-there-yet)
|
272
252
|
|
273
253
|
[<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) - Elementary Level Math Game Featuring Bowling Rules
|
274
254
|
|
275
|
-
![Math Bowling App Screenshot](https://raw.githubusercontent.com/AndyObtiva/MathBowling/master/Math-Bowling-Screenshot.png)
|
255
|
+
[![Math Bowling App Screenshot](https://raw.githubusercontent.com/AndyObtiva/MathBowling/master/Math-Bowling-Screenshot.png)](https://github.com/AndyObtiva/MathBowling)
|
276
256
|
|
277
|
-
|
257
|
+
### Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
|
278
258
|
|
279
259
|
[Tcl/Tk](https://www.tcl.tk/) has evolved into a practical desktop GUI toolkit due to gaining truely native looking widgets on Mac, Windows, and Linux in [Tk version 8.5](https://www.tcl.tk/software/tcltk/8.5.html#:~:text=Highlights%20of%20Tk%208.5&text=Font%20rendering%3A%20Now%20uses%20anti,and%20window%20layout%2C%20and%20more.).
|
280
260
|
|
@@ -291,9 +271,11 @@ The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a pleth
|
|
291
271
|
- Scaffolding for new custom widgets, apps, and gems
|
292
272
|
- Native-Executable packaging on Mac, Windows, and Linux
|
293
273
|
|
294
|
-
|
274
|
+
To get started, visit the [Glimmer DSL for Tk project page](https://github.com/AndyObtiva/glimmer-dsl-tk#pre-requisites) for instructions on installing the [glimmer-dsl-tk gem](https://rubygems.org/gems/glimmer-dsl-tk).
|
275
|
+
|
276
|
+
#### Glimmer DSL for Tk Samples
|
295
277
|
|
296
|
-
|
278
|
+
##### Hello, World!
|
297
279
|
|
298
280
|
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_world.rb)):
|
299
281
|
|
@@ -317,14 +299,14 @@ Glimmer app:
|
|
317
299
|
|
318
300
|
![glimmer dsl tk screenshot sample hello world](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-world.png)
|
319
301
|
|
320
|
-
|
302
|
+
##### Hello, Tab!
|
321
303
|
|
322
304
|
Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_tab.rb)):
|
323
305
|
|
324
306
|
```ruby
|
325
307
|
include Glimmer
|
326
308
|
|
327
|
-
root {
|
309
|
+
root {
|
328
310
|
title 'Hello, Tab!'
|
329
311
|
|
330
312
|
notebook {
|
@@ -354,7 +336,7 @@ Glimmer app:
|
|
354
336
|
![glimmer dsl tk screenshot sample hello tab English](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-tab-english.png)
|
355
337
|
![glimmer dsl tk screenshot sample hello tab French](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-tab-french.png)
|
356
338
|
|
357
|
-
|
339
|
+
##### Hello, Combo!
|
358
340
|
|
359
341
|
Glimmer code (from [samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combo.rb)):
|
360
342
|
|
@@ -364,7 +346,7 @@ root {
|
|
364
346
|
title 'Hello, Combo!'
|
365
347
|
|
366
348
|
combobox { |proxy|
|
367
|
-
state 'readonly'
|
349
|
+
state 'readonly'
|
368
350
|
text bind(person, :country)
|
369
351
|
}
|
370
352
|
|
@@ -389,15 +371,17 @@ Glimmer app:
|
|
389
371
|
![glimmer dsl tk screenshot sample hello combo](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combo.png)
|
390
372
|
![glimmer dsl tk screenshot sample hello combo dropdown](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combo-dropdown.png)
|
391
373
|
|
392
|
-
|
374
|
+
### Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
|
393
375
|
|
394
|
-
[Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) is an experimental proof-of-concept web GUI adapter for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/), allowing Ruby desktop apps to run on the web via [Opal Ruby](https://opalrb.com/) without changing a line of code. Apps may then be custom-styled for the web with standard CSS.
|
376
|
+
[Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) is an experimental proof-of-concept web GUI adapter for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/), allowing Ruby desktop apps to run on the web via [Opal Ruby](https://opalrb.com/) without changing a line of code. Apps may then be custom-styled for the web with standard CSS.
|
395
377
|
|
396
378
|
Glimmer DSL for Opal webifier successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of powerful Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web.
|
397
379
|
|
398
|
-
|
380
|
+
To get started, visit the [Glimmer DSL for Opal project page](https://github.com/AndyObtiva/glimmer-dsl-opal) for instructions on installing the [glimmer-dsl-opal gem](https://rubygems.org/gems/glimmer-dsl-opal).
|
381
|
+
|
382
|
+
#### Glimmer DSL for Opal Samples
|
399
383
|
|
400
|
-
|
384
|
+
##### Hello, Computed!
|
401
385
|
|
402
386
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
403
387
|
|
@@ -516,129 +500,63 @@ You should see "Hello, Computed!"
|
|
516
500
|
|
517
501
|
![Glimmer DSL for Opal Hello Computed](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-opal/master/images/glimmer-dsl-opal-hello-computed.png)
|
518
502
|
|
519
|
-
|
520
|
-
|
521
|
-
Add the following require statement to `app/assets/javascripts/application.rb`
|
522
|
-
|
523
|
-
|
524
|
-
```ruby
|
525
|
-
require 'samples/hello/hello_list_single_selection'
|
526
|
-
```
|
527
|
-
|
528
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
529
|
-
|
530
|
-
```ruby
|
531
|
-
class Person
|
532
|
-
attr_accessor :country, :country_options
|
533
|
-
|
534
|
-
def initialize
|
535
|
-
self.country_options=["", "Canada", "US", "Mexico"]
|
536
|
-
self.country = "Canada"
|
537
|
-
end
|
538
|
-
|
539
|
-
def reset_country
|
540
|
-
self.country = "Canada"
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
class HelloListSingleSelection
|
545
|
-
include Glimmer
|
546
|
-
def launch
|
547
|
-
person = Person.new
|
548
|
-
shell {
|
549
|
-
composite {
|
550
|
-
list {
|
551
|
-
selection bind(person, :country)
|
552
|
-
}
|
553
|
-
button {
|
554
|
-
text "Reset"
|
555
|
-
on_widget_selected do
|
556
|
-
person.reset_country
|
557
|
-
end
|
558
|
-
}
|
559
|
-
}
|
560
|
-
}.open
|
561
|
-
end
|
562
|
-
end
|
503
|
+
##### Glimmer Calculator
|
563
504
|
|
564
|
-
|
565
|
-
```
|
566
|
-
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
567
|
-
|
568
|
-
![Glimmer DSL for SWT Hello List Single Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-single-selection.png)
|
569
|
-
|
570
|
-
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
505
|
+
Add the [glimmer-cs-calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) gem to `Gemfile` (without requiring):
|
571
506
|
|
572
|
-
Start the Rails server:
|
573
507
|
```
|
574
|
-
|
508
|
+
gem 'glimmer-cs-calculator', require: false
|
575
509
|
```
|
576
510
|
|
577
|
-
Visit `http://localhost:3000`
|
578
|
-
|
579
|
-
You should see "Hello, List Single Selection!"
|
580
|
-
|
581
|
-
![Glimmer DSL for Opal Hello List Single Selection](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-opal/master/images/glimmer-dsl-opal-hello-list-single-selection.png)
|
582
|
-
|
583
|
-
#### Hello, List Multi Selection!
|
584
|
-
|
585
511
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
586
512
|
|
587
513
|
```ruby
|
588
|
-
require '
|
514
|
+
require 'glimmer-cs-calculator/launch'
|
589
515
|
```
|
590
516
|
|
591
|
-
|
517
|
+
Sample GUI code (relies on custom widgets `command_button`, `operation_button`, and `number_button`):
|
592
518
|
|
593
519
|
```ruby
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
person.reset_provinces
|
630
|
-
end
|
631
|
-
}
|
632
|
-
}
|
633
|
-
}.open
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
|
-
HelloListMultiSelection.new.launch
|
520
|
+
shell {
|
521
|
+
minimum_size (OS.mac? ? 320 : (OS.windows? ? 390 : 520)), 240
|
522
|
+
image File.join(APP_ROOT, 'package', 'windows', "Glimmer Calculator.ico") if OS.windows?
|
523
|
+
text "Glimmer - Calculator"
|
524
|
+
grid_layout 4, true
|
525
|
+
# Setting styled_text to multi in order for alignment options to activate
|
526
|
+
styled_text(:multi, :wrap, :border) {
|
527
|
+
text bind(@presenter, :result)
|
528
|
+
alignment swt(:right)
|
529
|
+
right_margin 5
|
530
|
+
font height: 40
|
531
|
+
layout_data(:fill, :fill, true, true) {
|
532
|
+
horizontal_span 4
|
533
|
+
}
|
534
|
+
editable false
|
535
|
+
caret nil
|
536
|
+
}
|
537
|
+
command_button('AC')
|
538
|
+
operation_button('÷')
|
539
|
+
operation_button('×')
|
540
|
+
operation_button('−')
|
541
|
+
(7..9).each { |number|
|
542
|
+
number_button(number)
|
543
|
+
}
|
544
|
+
operation_button('+', font: @button_font_big, vertical_span: 2)
|
545
|
+
(4..6).each { |number|
|
546
|
+
number_button(number)
|
547
|
+
}
|
548
|
+
(1..3).each { |number|
|
549
|
+
number_button(number)
|
550
|
+
}
|
551
|
+
command_button('=', font: @button_font_big, vertical_span: 2)
|
552
|
+
number_button(0, horizontal_span: 2)
|
553
|
+
operation_button('.')
|
554
|
+
}
|
638
555
|
```
|
639
|
-
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
640
556
|
|
641
|
-
|
557
|
+
Glimmer app on the desktop (using the [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
558
|
+
|
559
|
+
![Glimmer Calculator Linux](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-linux.png)
|
642
560
|
|
643
561
|
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
644
562
|
|
@@ -648,18 +566,27 @@ rails s
|
|
648
566
|
```
|
649
567
|
|
650
568
|
Visit `http://localhost:3000`
|
569
|
+
(or visit: http://glimmer-cs-calculator-server.herokuapp.com)
|
570
|
+
|
571
|
+
You should see "Glimmer Calculator"
|
572
|
+
|
573
|
+
[![Glimmer Calculator Opal](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal.png)](http://glimmer-cs-calculator-server.herokuapp.com)
|
651
574
|
|
652
|
-
|
575
|
+
Here is an Apple Calculator CSS themed version (with [CSS only](https://github.com/AndyObtiva/glimmer-cs-calculator/blob/master/server/glimmer-cs-calculator-server/app/assets/stylesheets/welcomes_apple.scss), no app code changes):
|
653
576
|
|
654
|
-
|
577
|
+
Visit http://glimmer-cs-calculator-server.herokuapp.com/welcomes/apple
|
655
578
|
|
656
|
-
|
579
|
+
You should see "Apple Calculator Theme"
|
580
|
+
|
581
|
+
[![Glimmer Calculator Opal Apple Calculator Theme](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal-apple.png)](http://glimmer-cs-calculator-server.herokuapp.com/welcomes/apple)
|
582
|
+
|
583
|
+
### Glimmer DSL for XML (& HTML)
|
657
584
|
|
658
585
|
[Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) provides Ruby syntax for building XML (eXtensible Markup Language) documents.
|
659
586
|
|
660
587
|
Within the context of desktop development, Glimmer DSL for XML is useful in providing XML data for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
|
661
588
|
|
662
|
-
|
589
|
+
#### XML DSL
|
663
590
|
|
664
591
|
Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
|
665
592
|
Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
|
@@ -691,13 +618,13 @@ Output:
|
|
691
618
|
<html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
|
692
619
|
```
|
693
620
|
|
694
|
-
|
621
|
+
### Glimmer DSL for CSS
|
695
622
|
|
696
623
|
[Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) provides Ruby syntax for building CSS (Cascading Style Sheets).
|
697
624
|
|
698
625
|
Within the context of [Glimmer](https://github.com/AndyObtiva/glimmer) app development, Glimmer DSL for CSS is useful in providing CSS for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
|
699
626
|
|
700
|
-
|
627
|
+
#### CSS DSL
|
701
628
|
|
702
629
|
Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
|
703
630
|
Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
|
@@ -730,37 +657,215 @@ Output:
|
|
730
657
|
body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2em}
|
731
658
|
```
|
732
659
|
|
733
|
-
##
|
734
|
-
|
735
|
-
Glimmer official DSL gems always start with `glimmer-dsl-`. That said, other libraries may use the Glimmer DSL engine too not for building GUI apps (e.g. `bundler-download`)
|
660
|
+
## DSL Engine
|
736
661
|
|
737
|
-
Glimmer
|
662
|
+
Glimmer is fundamentally a DSL Engine that can support any number of DSLs like the official Glimmer DSLs (gems starting with the `glimmer-dsl-` prefix like `glimmer-dsl-swt`) or any DSLs for that matter.
|
738
663
|
|
739
664
|
Glimmer DSL syntax consists mainly of:
|
740
|
-
- keywords (e.g. `table` for a table widget)
|
741
|
-
- style/args (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
|
742
|
-
- content (e.g. `{ table_column { text 'Name'} }` as in `table(:multi) { table_column { text '
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
-
|
756
|
-
-
|
757
|
-
|
758
|
-
|
759
|
-
|
665
|
+
- **keywords** (e.g. `table` for a table widget)
|
666
|
+
- **style/args** (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
|
667
|
+
- **content** (e.g. `{ table_column { text 'Name'} }` as in `table(:multi) { table_column { text 'Name'} }` for a multi-line selection table widget with a table column having header text property `'Name'` as content)
|
668
|
+
|
669
|
+
The Glimmer DSL Engine's architecture is based on the following Design Patterns and Data Structures:
|
670
|
+
- **Interpreter Design Pattern**: to define interpretable expressions of DSL keywords
|
671
|
+
- **Chain of Responsibility Design Pattern / Queue Data Structure**: to chain expression handlers in order of importance for processing DSL keywords
|
672
|
+
- **Adapter Design Pattern**: to adapt expressions into handlers in a chain of responsibility
|
673
|
+
- **Stack Data Structure**: to handle processing parent/child nesting of DSL keyword expressions in the correct order
|
674
|
+
|
675
|
+
Glimmer's use of the **Interpreter Design Pattern** in processing DSLs is also known as the **Virtual Machine Architectural Style**. After all, DSL expressions are virtual machine opcodes that process nested keywords stored in a stack. I built Glimmer's original DSL back in 2007 without knowing the **Virtual Machine Architectural Style** (except perhaps as an esoteric technology powering Java), but stumbled upon it anyways through following the Gang of Four Design Patterns mentioned above, chiefly the **Interpreter Design Pattern**.
|
676
|
+
|
677
|
+
Every keyword in a Glimmer DSL is represented by a DSL expression that is processed by an `Expression` subclass selected from a chain of expressions (interpreters) pre-configured in a DSL chain of responsibility via `Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)`.
|
678
|
+
|
679
|
+
Expressions are either:
|
680
|
+
- **Static** (subclass of `StaticExpression`, which is a subclass of `Expression`): if they represent a single pre-identified keyword (e.g. `color` or `display`)
|
681
|
+
- **Dynamic** (subclass of `Expression`): if they represent keywords calculated on the fly during processing (e.g. an SWT widget like `label` or a random XML element called `folder` representing `<folder></folder>`)
|
682
|
+
|
683
|
+
Optionally, expressions can be parent expressions that contain other expressions, and must include the `ParentExpression` mixin module as such.
|
684
|
+
|
685
|
+
Additionally, every expression that serves as a top-level entry point into the DSL must mixin `TopLevelExpression`
|
686
|
+
|
687
|
+
Static expressions are optimized in performance since they pre-define methods on the `Glimmer` module matching the static keywords they represent (e.g. `color` causes creating a `Glimmer#color` method for processing `color` expressions) and completely bypass as a result the Glimmer DSL Engine Chain of Responsibility. That said, they must be avoided if the same keyword might occur multiple times, but with different requirements for arguments, block, and parenthood type.
|
688
|
+
|
689
|
+
Every `Expression` sublcass must specify two methods at least:
|
690
|
+
- `can_interpret?(parent, keyword, *args, &block)`: to quickly test if the keyword and arg/block/parent combination qualifies for interpretation by the current `Expression` or to otherwise delegate to the next expression in the chain of responsibility.
|
691
|
+
- `interpret(parent, keyword, *args, &block)`: to go ahead and interpret a DSL expression that qualified for interpretation
|
692
|
+
|
693
|
+
`StaticExpression` sublcasses may skip the `can_interpret?` method since they include a default implementation for it that matches the name of the keyword from the class name by convention. For example, a `color` keyword would have a `ColorExpression` class, so `color` is inferred automatically from class name and used in deciding whether the class can handle a `color` keyword or not.
|
694
|
+
|
695
|
+
`ParentExpression` subclasses can optionally override this extra method, which is included by default and simply invokes the parent's passed block to process its children:
|
696
|
+
- `add_content(parent, &block)`
|
697
|
+
|
698
|
+
For example, some parent widgets use their block for other reasons or process their children at very specific times, so they may override that method and disable it, or otherwise call `super` and do additional work.
|
699
|
+
|
700
|
+
Example of a dynamic expression:
|
701
|
+
|
702
|
+
```ruby
|
703
|
+
module Glimmer
|
704
|
+
module DSL
|
705
|
+
module SWT
|
706
|
+
class WidgetExpression < Expression
|
707
|
+
include ParentExpression
|
708
|
+
|
709
|
+
EXCLUDED_KEYWORDS = %w[shell display tab_item]
|
710
|
+
|
711
|
+
def can_interpret?(parent, keyword, *args, &block)
|
712
|
+
!EXCLUDED_KEYWORDS.include?(keyword) and
|
713
|
+
parent.respond_to?(:swt_widget) and
|
714
|
+
Glimmer::SWT::WidgetProxy.widget_exists?(keyword)
|
715
|
+
end
|
716
|
+
|
717
|
+
def interpret(parent, keyword, *args, &block)
|
718
|
+
Glimmer::SWT::WidgetProxy.create(keyword, parent, args)
|
719
|
+
end
|
720
|
+
|
721
|
+
def add_content(parent, &block)
|
722
|
+
super
|
723
|
+
parent.post_add_content
|
724
|
+
end
|
725
|
+
|
726
|
+
end
|
727
|
+
end
|
728
|
+
end
|
729
|
+
end
|
730
|
+
```
|
731
|
+
|
732
|
+
Example of a static expression (does not need `can_interpret?`):
|
733
|
+
|
734
|
+
```ruby
|
735
|
+
module Glimmer
|
736
|
+
module DSL
|
737
|
+
module Opal
|
738
|
+
class ColorExpression < StaticExpression
|
739
|
+
include TopLevelExpression
|
740
|
+
|
741
|
+
def interpret(parent, keyword, *args, &block)
|
742
|
+
Glimmer::SWT::ColorProxy.new(*args)
|
743
|
+
end
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
748
|
+
```
|
749
|
+
|
750
|
+
DSL expressions go into the `glimmer/dsl/{dsl_name}` namespace directory.
|
751
|
+
|
752
|
+
Also, every DSL requires a `glimmer/dsl/{dsl_name}/dsl.rb` file, which configures the DSL into Glimmer via a call to:
|
753
|
+
```ruby
|
754
|
+
Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)
|
755
|
+
```
|
756
|
+
|
757
|
+
Expression names are underscored verions of `Expression` subclass names minus the `_expression` suffix.
|
758
|
+
|
759
|
+
For example, here is an SWT DSL configuration:
|
760
|
+
|
761
|
+
```ruby
|
762
|
+
require 'glimmer/launcher'
|
763
|
+
require Glimmer::Launcher.swt_jar_file
|
764
|
+
require 'glimmer/dsl/engine'
|
765
|
+
Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
|
766
|
+
|
767
|
+
module Glimmer
|
768
|
+
module DSL
|
769
|
+
module SWT
|
770
|
+
Engine.add_dynamic_expressions(
|
771
|
+
SWT,
|
772
|
+
%w[
|
773
|
+
layout
|
774
|
+
widget_listener
|
775
|
+
combo_selection_data_binding
|
776
|
+
checkbox_group_selection_data_binding
|
777
|
+
radio_group_selection_data_binding
|
778
|
+
list_selection_data_binding
|
779
|
+
tree_items_data_binding
|
780
|
+
table_items_data_binding
|
781
|
+
data_binding
|
782
|
+
cursor
|
783
|
+
font
|
784
|
+
image
|
785
|
+
property
|
786
|
+
block_property
|
787
|
+
widget
|
788
|
+
custom_widget
|
789
|
+
]
|
790
|
+
)
|
791
|
+
end
|
792
|
+
end
|
793
|
+
end
|
794
|
+
```
|
795
|
+
|
796
|
+
In summary, these are the files needed to author a Glimmer DSL:
|
797
|
+
- `glimmer/dsl/[dsl_name]/dsl.rb`: requires and adds all dynamic expressions to [dsl_name] Glimmer DSL
|
798
|
+
- `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb`: needed for every [expresion_name] expression, whether dynamic or static
|
799
|
+
|
800
|
+
### Multi-DSL Support
|
801
|
+
|
802
|
+
The Glimmer [DSL Engine](#dsl-engine) allows mixing DSLs, which comes in handy when doing things like rendering a desktop GUI DSL `browser` widget additionally leveraging the HTML DSL and CSS DSL for its content.
|
803
|
+
|
804
|
+
DSLs are activated by top-level keywords (expressions denoted as `TopLevelExpression`). For example, the `html` keyword activates the [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and the `css` keyword activates the [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css). Glimmer automatically recognizes top-level keywords in each DSL and activates the DSL accordingly. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
|
805
|
+
|
806
|
+
By default, all loaded DSLs (required glimmer DSL gems) are enabled.
|
807
|
+
|
808
|
+
For example, this shows "Hello, World!" inside a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app `browser` widget using `html` and `css` from [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css):
|
809
|
+
|
810
|
+
```ruby
|
811
|
+
require 'glimmer-dsl-swt'
|
812
|
+
require 'glimmer-dsl-xml'
|
813
|
+
require 'glimmer-dsl-css'
|
814
|
+
|
815
|
+
include Glimmer
|
816
|
+
|
817
|
+
shell {
|
818
|
+
minimum_size 130, 130
|
819
|
+
@browser = browser {
|
820
|
+
text html {
|
821
|
+
head {
|
822
|
+
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
823
|
+
style {
|
824
|
+
css {
|
825
|
+
h1 {
|
826
|
+
background 'yellow'
|
827
|
+
}
|
828
|
+
}
|
829
|
+
}
|
830
|
+
}
|
831
|
+
body {
|
832
|
+
h1 { "Hello, World!" }
|
833
|
+
}
|
834
|
+
}
|
835
|
+
}
|
836
|
+
}.open
|
837
|
+
```
|
838
|
+
|
839
|
+
**API methods to enable/disable DSLs:**
|
840
|
+
|
841
|
+
`Glimmer::DSL::Engine.disable_dsl(dsl)`: disables a particular DSL
|
842
|
+
|
843
|
+
Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
|
844
|
+
|
845
|
+
`Glimmer::DSL::Engine.enable_dsl(dsl)`: enables a particular DSL
|
846
|
+
|
847
|
+
Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
|
848
|
+
|
849
|
+
`Glimmer::DSL::Engine.enabled_dsls=(dsls)`: enables only the specified DSLs, disabling all other loaded DSLs
|
850
|
+
|
851
|
+
Example: `Glimmer::DSL::Engine.enabled_dsls = [:xml, :css]`
|
852
|
+
|
853
|
+
## Data-Binding Library
|
854
|
+
|
855
|
+
Data-Binding enables binding GUI properties (like text and color) to Model attributes (like name and age).
|
856
|
+
|
857
|
+
It relies on the Observer Design Pattern and MVP (Model-View-Presenter) Architectural Pattern (a variation on MVC)
|
858
|
+
|
859
|
+
These are the main classes concerning data-binding:
|
860
|
+
- `Observer`: Provides general observer support including unique registration and deregistration for cleanup and prevention of memory leaks. Main methods concerned are: `call`, `register` (alias: `observe`), and `unregister` (alias: `unobserve` or `deregister`)
|
861
|
+
- `Observable`: General super-module for all observables. Main methods concerned are: `add_observer` and `remove_observer`
|
862
|
+
- `ObservableModel`: Mixin module for any observable model with observable attributes. In addition to `Observable` methods, it has a `notify_observers` method to be called when changes occur. It automatically enhances all attribute setters (ending with `=`) to notify observers on changes. Also, it automatically handles observing array attributes using `ObservableArray` appropriately so they would notify observers upon array mutation changes.
|
863
|
+
- `ObservableArray`: Mixin module for any observable array collection that automatically handles notifying observers upon performing array mutation operations (e.g. `push` or `delete`)
|
864
|
+
- `ModelBinding`: a higher-level abstraction that relies on all the other observer/observable classes to support basic data-binding, nested data-binding, and computed data-binding
|
760
865
|
|
761
866
|
## Glimmer Process
|
762
867
|
|
763
|
-
[Glimmer Process](PROCESS.md) is the lightweight software development process used for building Glimmer libraries and Glimmer apps, which goes beyond Agile, rendering all Agile processes obsolete. [Glimmer Process](PROCESS.md) is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied.
|
868
|
+
[Glimmer Process](PROCESS.md) is the lightweight software development process used for building Glimmer libraries and Glimmer apps, which goes beyond Agile, rendering all Agile processes obsolete. [Glimmer Process](PROCESS.md) is simply made up of 7 guidelines to pick and choose as necessary until software development needs are satisfied.
|
764
869
|
|
765
870
|
Learn more by reading the [GPG](PROCESS.md) (Glimmer Process Guidelines)
|
766
871
|
|
@@ -783,7 +888,7 @@ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub
|
|
783
888
|
|
784
889
|
### Chat
|
785
890
|
|
786
|
-
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)
|
891
|
+
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)
|
787
892
|
|
788
893
|
## Feature Suggestions
|
789
894
|
|
@@ -808,7 +913,7 @@ Glimmer DSL Engine specific tasks are at:
|
|
808
913
|
If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](https://github.com/AndyObtiva/glimmer-dsl-swt#swt-reference), run all Glimmer [samples](https://github.com/AndyObtiva/glimmer-dsl-swt#samples), and build a small sample app (perhaps from [this TODO list](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md#samples)) to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
|
809
914
|
|
810
915
|
You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
|
811
|
-
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI
|
916
|
+
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
812
917
|
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
|
813
918
|
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
814
919
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
@@ -831,7 +936,7 @@ If your company would like to invest fulltime in further development of the Glim
|
|
831
936
|
|
832
937
|
[MIT](LICENSE.txt)
|
833
938
|
|
834
|
-
Copyright (c) 2007-
|
939
|
+
Copyright (c) 2007-2021 - Andy Maleh.
|
835
940
|
|
836
941
|
--
|
837
942
|
|