glimmer 2.5.5 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/LICENSE.txt +1 -1
- data/PROCESS.md +1 -1
- data/README.md +182 -156
- data/VERSION +1 -1
- data/glimmer.gemspec +5 -5
- data/lib/glimmer/config.rb +1 -1
- data/lib/glimmer/data_binding/model_binding.rb +23 -4
- data/lib/glimmer/data_binding/observable.rb +1 -1
- data/lib/glimmer/data_binding/observable_array.rb +2 -3
- data/lib/glimmer/data_binding/observable_hash.rb +1 -1
- data/lib/glimmer/data_binding/observable_hashable.rb +1 -1
- data/lib/glimmer/data_binding/observable_model.rb +1 -1
- data/lib/glimmer/data_binding/observer.rb +1 -1
- data/lib/glimmer/data_binding/shine.rb +1 -1
- data/lib/glimmer/dsl/bind_expression.rb +1 -1
- data/lib/glimmer/dsl/engine.rb +29 -4
- data/lib/glimmer/dsl/expression.rb +1 -1
- data/lib/glimmer/dsl/expression_handler.rb +1 -1
- data/lib/glimmer/dsl/observe_expression.rb +1 -1
- data/lib/glimmer/dsl/parent_expression.rb +1 -1
- data/lib/glimmer/dsl/shine_data_binding_expression.rb +1 -1
- data/lib/glimmer/dsl/static_expression.rb +29 -3
- data/lib/glimmer/dsl/top_level_expression.rb +1 -1
- data/lib/glimmer/error.rb +1 -1
- data/lib/glimmer/invalid_keyword_error.rb +1 -1
- data/lib/glimmer.rb +1 -1
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7e7983379ea9281e26719f66718fb706d475d3dd9904e20cfd51237625d9322
|
4
|
+
data.tar.gz: '08fa76d4f37a422a8d6b68845f22ce3a8f41f1b53c8a6d9dced1044c55a14aa6'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc96cb57a317ebce264b45c916dd6f3d66ecafade85d95dcb357a45ee4a33aed8285f07a2168fd3dbf179d379170645ed7c07b9731a53293ad5817ce3056c875
|
7
|
+
data.tar.gz: 4d48a96a17918d61527e77a771755a7ffd6c08e365a0d128b51c047e33a57e03fbdfc3b92a45bcab32f7b9a6139140f3ad2eec90b987ed029cf6784aa4163414
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,18 @@
|
|
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
|
+
### 2.7.1
|
7
|
+
|
8
|
+
- Support upcased static expressions (in addition to default downcased ones)
|
9
|
+
|
10
|
+
### 2.7.0
|
11
|
+
|
12
|
+
- Support Hash keyed properties via `ModelBinding` (e.g. property as `some_hash_attribute[:some_key]`, `some_hash_attribute['some_key']`, `some_hash_attribute["some_key"]`)
|
13
|
+
|
14
|
+
### 2.6.0
|
15
|
+
|
16
|
+
- If a static expression cannot handle keyword, it is tried with available dynamic expressions instead of erroring out.
|
17
|
+
|
6
18
|
### 2.5.5
|
7
19
|
|
8
20
|
- Support observing an array object index directly (e.g. `ModelBinding.new(array, '[0]')` as opposed to `ModelBinding.new(self, 'array[0]')`)
|
data/LICENSE.txt
CHANGED
data/PROCESS.md
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,11 @@
|
|
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
|
+
# [<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 2.7.1
|
2
|
+
## DSL Framework for Ruby GUI and More
|
2
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer.svg)](http://badge.fury.io/rb/glimmer)
|
3
4
|
[![rspec](https://github.com/AndyObtiva/glimmer/workflows/rspec/badge.svg)](https://github.com/AndyObtiva/glimmer/actions?query=workflow%3Arspec)
|
4
5
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
5
6
|
[![Maintainability](https://api.codeclimate.com/v1/badges/38fbc278022862794414/maintainability)](https://codeclimate.com/github/AndyObtiva/glimmer/maintainability)
|
6
7
|
[![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
8
|
|
8
|
-
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
9
|
-
|
10
9
|
**(The Original Glimmer Library Handling the World’s Ruby GUI Needs Since 2007. Beware of Imitators!)**
|
11
10
|
|
12
11
|
[**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](http://blog.headius.com/2007/11/tab-sweep.html) 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)
|
@@ -27,16 +26,21 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
|
|
27
26
|
- Multiple DSLs may be [mixed](#multi-dsl-support) together safely to achieve maximum expressability, composability, and productivity.
|
28
27
|
- DSLs are fully configurable, so you may activate and deactivate DSLs as per your current needs only.
|
29
28
|
|
30
|
-
Start by checking out Glimmer's original GUI DSL (for [JRuby](https://www.jruby.org/)), which got extracted into its own gem
|
31
|
-
|
32
|
-
[
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
|
39
|
-
-
|
29
|
+
Start by checking out [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), Glimmer's original GUI DSL (for [JRuby](https://www.jruby.org/)), which got extracted into its own gem; and [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui), Glimmer's CRuby GUI DSL, which has no prerequisites beyond installing the Ruby gem.
|
30
|
+
|
31
|
+
**[Glimmer](https://rubygems.org/gems/glimmer) DSL Comparison Table:**
|
32
|
+
DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
|
33
|
+
----|-----------|---------|------------------|------|------|--------
|
34
|
+
[Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](https://github.com/AndyObtiva/glimmer-dsl-swt) | Mac / Windows / Linux | Yes | Yes (Canvas Shape DSL) | Very Mature / Scaffolding / Native Executable Packaging / Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint | Java / JRuby
|
35
|
+
[Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)](https://github.com/AndyObtiva/glimmer-dsl-opal) | All Web Browsers | No | Yes (Canvas Shape DSL) | Simpler than All JavaScript Technologies / Auto-Webify Desktop Apps | Setup Process / Incomplete Alpha | Rails
|
36
|
+
[Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-libui) | Mac / Windows / Linux | Yes | Yes (Area API) | Very Simple Setup / Fast Startup Time / Light Memory Footprint | LibUI is an Incomplete Mid-Alpha Only | None Other Than MRI Ruby
|
37
|
+
[Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-tk) | Mac / Windows / Linux | Some Native-Themed Widgets (Not Truly Native) | Yes (Canvas) | Fast Startup Time / Light Memory Footprint | Complicated setup / Widgets Do Not Look Truly Native, Espcially on Linux | ActiveTcl / MRI Ruby
|
38
|
+
[Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-gtk) | Mac / Windows / Linux | Only on Linux | Yes (Cairo) | Complete Access to GNOME Features on Linux | Not Native on Mac and Windows | None Other Than MRI Ruby on Linux / Brew Packages on Mac / MSYS & MING Toolchains on Windows / MRI Ruby
|
39
|
+
[Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-fx) | Mac (requires XQuartz) / Windows / Linux | No | Yes (Canvas) | No Prerequisites on Windows | Widgets Do Not Look Native / Mac Usage Obtrusively Starts XQuartz | None Other Than MRI Ruby on Windows / XQuarts on Mac / MRI Ruby
|
40
|
+
[Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-jfx) | Mac / Windows / Linux | No | Yes (javafx.scene.shape and javafx.scene.canvas) | Rich in Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby / JavaFX SDK
|
41
|
+
[Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-swing) | Mac / Windows / Linux | No | Yes (Java2D) | Very Mature | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby
|
42
|
+
[Glimmer DSL for XML (& HTML)](https://github.com/AndyObtiva/glimmer-dsl-xml) | All Web Browsers | No | Yes (SVG) | Programmable / Lighter-weight Than Actual XML | XML Elements Are Sometimes Not Well-Named (Many Types of Input) | None
|
43
|
+
[Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) | All Web Browsers | No | Yes | Programmable | CSS Is Over-Engineered / Too Many Features To Learn | None
|
40
44
|
|
41
45
|
## Table of Contents
|
42
46
|
|
@@ -48,10 +52,14 @@ Start by checking out Glimmer's original GUI DSL (for [JRuby](https://www.jruby.
|
|
48
52
|
- [Official DSLs](#official-dsls)
|
49
53
|
- [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
|
50
54
|
- [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)
|
51
|
-
- [Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-mri-ruby-desktop-development-gui-library)
|
52
55
|
- [Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)](#glimmer-dsl-for-libui-prerequisite-free-ruby-desktop-development-gui-library)
|
56
|
+
- [Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-mri-ruby-desktop-development-gui-library)
|
53
57
|
- [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
|
54
58
|
- [Glimmer DSL for CSS](#glimmer-dsl-for-css)
|
59
|
+
- [Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-gtk)
|
60
|
+
- [Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-fx)
|
61
|
+
- [Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-jfx)
|
62
|
+
- [Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-swing)
|
55
63
|
- [Data-Binding Library](#data-binding-library)
|
56
64
|
- [Glimmer Process](#glimmer-process)
|
57
65
|
- [Resources](#resources)
|
@@ -72,7 +80,8 @@ Glimmer is fundamentally a DSL Engine that can support any number of DSLs like t
|
|
72
80
|
Glimmer DSL syntax consists mainly of:
|
73
81
|
- **keywords** (e.g. `table` for a table widget)
|
74
82
|
- **style/args** (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
|
75
|
-
- **content (nested
|
83
|
+
- **content (nested properties/keywords/listeners)** (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)
|
84
|
+
- **methods** (e.g. `shell.show` opens a window)
|
76
85
|
|
77
86
|
Here is a Hello, World! example from [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt):
|
78
87
|
|
@@ -118,6 +127,9 @@ Every `Expression` sublcass must specify two methods at least:
|
|
118
127
|
- `interpret(parent, keyword, *args, &block)`: to go ahead and interpret a DSL expression that qualified for interpretation
|
119
128
|
|
120
129
|
`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.
|
130
|
+
`StaticExpression` may declare the following class method options (if any other than `downcased` (default) is set, then `downcased` must be set explicitly if needed):
|
131
|
+
- `downcased true` (default): indicates that the StaticExpression expects downcased keywords (e.g. `COLOR {}`)
|
132
|
+
- `upcased true`: indicates that the StaticExpression expects upcased keywords (e.g. `COLOR {}`). Note that upcased static expressions always expect either arguments parentheses or block curly braces to be invoked as a static expression method instead of a constant.
|
121
133
|
|
122
134
|
`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:
|
123
135
|
- `add_content(parent, keyword, *args, &block)`
|
@@ -232,7 +244,7 @@ end
|
|
232
244
|
### Setup
|
233
245
|
|
234
246
|
Follow these steps to author a [Glimmer](https://rubygems.org/gems/glimmer) DSL:
|
235
|
-
- Add `gem 'glimmer', '~> 2.
|
247
|
+
- Add `gem 'glimmer', '~> 2.7.1'` to `Gemfile` and run `bundle` or run `gem install glimmer -v2.7.1` and add `require 'glimmer'`
|
236
248
|
- Create `glimmer/dsl/[dsl_name]/dsl.rb`, which requires and adds all dynamic expressions for the [dsl_name] Glimmer DSL module as per the code shown in the previous section (or [Official DSLs](#official-dsls) as examples)
|
237
249
|
- Create `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb` for every [expresion_name] expression needed, whether dynamic or static
|
238
250
|
|
@@ -756,144 +768,6 @@ You should see "Apple Calculator Theme"
|
|
756
768
|
|
757
769
|
[![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)
|
758
770
|
|
759
|
-
#### Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
|
760
|
-
|
761
|
-
[Tcl/Tk](https://www.tcl.tk/) has recently improved by gaining native looking themed 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.). Additionally, [Ruby](https://www.ruby-lang.org/en/) 3.0 Ractor (formerly known as [Guilds](https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/)) supports truly parallel multi-threading, making both [MRI](https://github.com/ruby/ruby) and [Tk](https://www.tcl.tk/) finally viable for support in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library) as an alternative to [JRuby on SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
|
762
|
-
|
763
|
-
The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a plethora of high quality reusable widgets for the Enterprise (such as [Nebula](https://www.eclipse.org/nebula/)), [Tk](https://www.tcl.tk/) enables very fast app startup time and a small memory footprint via [MRI Ruby](https://www.ruby-lang.org/en/).
|
764
|
-
|
765
|
-
[Glimmer DSL for Tk](https://github.com/AndyObtiva/glimmer-dsl-tk) aims to provide a DSL similar to the [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) to enable more productive desktop development in Ruby with:
|
766
|
-
- Declarative DSL syntax that visually maps to the GUI widget hierarchy
|
767
|
-
- Convention over configuration via smart defaults and automation of low-level details
|
768
|
-
- Requiring the least amount of syntax possible to build GUI
|
769
|
-
- Bidirectional Data-Binding to declaratively wire and automatically synchronize GUI with Business Models
|
770
|
-
- Custom Widget support
|
771
|
-
- Scaffolding for new custom widgets, apps, and gems
|
772
|
-
- Native-Executable packaging on Mac, Windows, and Linux
|
773
|
-
|
774
|
-
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).
|
775
|
-
|
776
|
-
##### Glimmer DSL for Tk Samples
|
777
|
-
|
778
|
-
###### Hello, World!
|
779
|
-
|
780
|
-
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_world.rb)):
|
781
|
-
|
782
|
-
```ruby
|
783
|
-
include Glimmer
|
784
|
-
|
785
|
-
root {
|
786
|
-
label {
|
787
|
-
text 'Hello, World!'
|
788
|
-
}
|
789
|
-
}.open
|
790
|
-
```
|
791
|
-
|
792
|
-
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
793
|
-
|
794
|
-
```
|
795
|
-
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_world.rb'"
|
796
|
-
```
|
797
|
-
|
798
|
-
Glimmer app:
|
799
|
-
|
800
|
-
![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)
|
801
|
-
|
802
|
-
###### Hello, Notebook!
|
803
|
-
|
804
|
-
Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_tab.rb)):
|
805
|
-
|
806
|
-
```ruby
|
807
|
-
include Glimmer
|
808
|
-
|
809
|
-
root {
|
810
|
-
title 'Hello, Notebook!'
|
811
|
-
|
812
|
-
notebook {
|
813
|
-
frame(text: 'English') {
|
814
|
-
label {
|
815
|
-
text 'Hello, World!'
|
816
|
-
}
|
817
|
-
}
|
818
|
-
|
819
|
-
frame(text: 'French') {
|
820
|
-
label {
|
821
|
-
text 'Bonjour, Univers!'
|
822
|
-
}
|
823
|
-
}
|
824
|
-
}
|
825
|
-
}.open
|
826
|
-
```
|
827
|
-
|
828
|
-
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
829
|
-
|
830
|
-
```
|
831
|
-
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_notebook.rb'"
|
832
|
-
```
|
833
|
-
|
834
|
-
Glimmer app:
|
835
|
-
|
836
|
-
![glimmer dsl tk screenshot sample hello notebook English](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-notebook-english.png)
|
837
|
-
![glimmer dsl tk screenshot sample hello notebook French](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-notebook-french.png)
|
838
|
-
|
839
|
-
###### Hello, Combobox!
|
840
|
-
|
841
|
-
Glimmer code (from [samples/hello/hello_combobox.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combobox.rb)):
|
842
|
-
|
843
|
-
```ruby
|
844
|
-
require 'glimmer-dsl-tk'
|
845
|
-
|
846
|
-
class Person
|
847
|
-
attr_accessor :country, :country_options
|
848
|
-
|
849
|
-
def initialize
|
850
|
-
self.country_options=["", "Canada", "US", "Mexico"]
|
851
|
-
self.country = "Canada"
|
852
|
-
end
|
853
|
-
|
854
|
-
def reset_country
|
855
|
-
self.country = "Canada"
|
856
|
-
end
|
857
|
-
end
|
858
|
-
|
859
|
-
class HelloCombobox
|
860
|
-
include Glimmer
|
861
|
-
|
862
|
-
def launch
|
863
|
-
person = Person.new
|
864
|
-
|
865
|
-
root {
|
866
|
-
title 'Hello, Combobox!'
|
867
|
-
|
868
|
-
combobox {
|
869
|
-
readonly true # this applies to text editing only (item selection still triggers a write to model)
|
870
|
-
text <=> [person, :country]
|
871
|
-
}
|
872
|
-
|
873
|
-
button {
|
874
|
-
text "Reset Selection"
|
875
|
-
command {
|
876
|
-
person.reset_country
|
877
|
-
}
|
878
|
-
}
|
879
|
-
}.open
|
880
|
-
end
|
881
|
-
end
|
882
|
-
|
883
|
-
HelloCombobox.new.launch
|
884
|
-
```
|
885
|
-
|
886
|
-
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
887
|
-
|
888
|
-
```
|
889
|
-
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_combobox.rb'"
|
890
|
-
```
|
891
|
-
|
892
|
-
Glimmer app:
|
893
|
-
|
894
|
-
![glimmer dsl tk screenshot sample hello combobox](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combobox.png)
|
895
|
-
![glimmer dsl tk screenshot sample hello combobox dropdown](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combobox-dropdown.png)
|
896
|
-
|
897
771
|
#### Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)
|
898
772
|
|
899
773
|
[Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui) is a prerequisite-free Ruby desktop development GUI library. No need to pre-install any prerequisites. Just install the gem and have platform-independent native GUI that just works!
|
@@ -1099,6 +973,144 @@ Linux
|
|
1099
973
|
|
1100
974
|
![glimmer-dsl-libui-linux-area-gallery.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-area-gallery.png)
|
1101
975
|
|
976
|
+
#### Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
|
977
|
+
|
978
|
+
[Tcl/Tk](https://www.tcl.tk/) has recently improved by gaining native looking themed 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.). Additionally, [Ruby](https://www.ruby-lang.org/en/) 3.0 Ractor (formerly known as [Guilds](https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/)) supports truly parallel multi-threading, making both [MRI](https://github.com/ruby/ruby) and [Tk](https://www.tcl.tk/) finally viable for support in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library) as an alternative to [JRuby on SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
|
979
|
+
|
980
|
+
The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a plethora of high quality reusable widgets for the Enterprise (such as [Nebula](https://www.eclipse.org/nebula/)), [Tk](https://www.tcl.tk/) enables very fast app startup time and a small memory footprint via [MRI Ruby](https://www.ruby-lang.org/en/).
|
981
|
+
|
982
|
+
[Glimmer DSL for Tk](https://github.com/AndyObtiva/glimmer-dsl-tk) aims to provide a DSL similar to the [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) to enable more productive desktop development in Ruby with:
|
983
|
+
- Declarative DSL syntax that visually maps to the GUI widget hierarchy
|
984
|
+
- Convention over configuration via smart defaults and automation of low-level details
|
985
|
+
- Requiring the least amount of syntax possible to build GUI
|
986
|
+
- Bidirectional Data-Binding to declaratively wire and automatically synchronize GUI with Business Models
|
987
|
+
- Custom Widget support
|
988
|
+
- Scaffolding for new custom widgets, apps, and gems
|
989
|
+
- Native-Executable packaging on Mac, Windows, and Linux
|
990
|
+
|
991
|
+
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).
|
992
|
+
|
993
|
+
##### Glimmer DSL for Tk Samples
|
994
|
+
|
995
|
+
###### Hello, World!
|
996
|
+
|
997
|
+
Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_world.rb)):
|
998
|
+
|
999
|
+
```ruby
|
1000
|
+
include Glimmer
|
1001
|
+
|
1002
|
+
root {
|
1003
|
+
label {
|
1004
|
+
text 'Hello, World!'
|
1005
|
+
}
|
1006
|
+
}.open
|
1007
|
+
```
|
1008
|
+
|
1009
|
+
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
1010
|
+
|
1011
|
+
```
|
1012
|
+
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_world.rb'"
|
1013
|
+
```
|
1014
|
+
|
1015
|
+
Glimmer app:
|
1016
|
+
|
1017
|
+
![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)
|
1018
|
+
|
1019
|
+
###### Hello, Notebook!
|
1020
|
+
|
1021
|
+
Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_tab.rb)):
|
1022
|
+
|
1023
|
+
```ruby
|
1024
|
+
include Glimmer
|
1025
|
+
|
1026
|
+
root {
|
1027
|
+
title 'Hello, Notebook!'
|
1028
|
+
|
1029
|
+
notebook {
|
1030
|
+
frame(text: 'English') {
|
1031
|
+
label {
|
1032
|
+
text 'Hello, World!'
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
frame(text: 'French') {
|
1037
|
+
label {
|
1038
|
+
text 'Bonjour, Univers!'
|
1039
|
+
}
|
1040
|
+
}
|
1041
|
+
}
|
1042
|
+
}.open
|
1043
|
+
```
|
1044
|
+
|
1045
|
+
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
1046
|
+
|
1047
|
+
```
|
1048
|
+
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_notebook.rb'"
|
1049
|
+
```
|
1050
|
+
|
1051
|
+
Glimmer app:
|
1052
|
+
|
1053
|
+
![glimmer dsl tk screenshot sample hello notebook English](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-notebook-english.png)
|
1054
|
+
![glimmer dsl tk screenshot sample hello notebook French](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-notebook-french.png)
|
1055
|
+
|
1056
|
+
###### Hello, Combobox!
|
1057
|
+
|
1058
|
+
Glimmer code (from [samples/hello/hello_combobox.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combobox.rb)):
|
1059
|
+
|
1060
|
+
```ruby
|
1061
|
+
require 'glimmer-dsl-tk'
|
1062
|
+
|
1063
|
+
class Person
|
1064
|
+
attr_accessor :country, :country_options
|
1065
|
+
|
1066
|
+
def initialize
|
1067
|
+
self.country_options=["", "Canada", "US", "Mexico"]
|
1068
|
+
self.country = "Canada"
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def reset_country
|
1072
|
+
self.country = "Canada"
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
class HelloCombobox
|
1077
|
+
include Glimmer
|
1078
|
+
|
1079
|
+
def launch
|
1080
|
+
person = Person.new
|
1081
|
+
|
1082
|
+
root {
|
1083
|
+
title 'Hello, Combobox!'
|
1084
|
+
|
1085
|
+
combobox {
|
1086
|
+
readonly true # this applies to text editing only (item selection still triggers a write to model)
|
1087
|
+
text <=> [person, :country]
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
button {
|
1091
|
+
text "Reset Selection"
|
1092
|
+
command {
|
1093
|
+
person.reset_country
|
1094
|
+
}
|
1095
|
+
}
|
1096
|
+
}.open
|
1097
|
+
end
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
HelloCombobox.new.launch
|
1101
|
+
```
|
1102
|
+
|
1103
|
+
Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
|
1104
|
+
|
1105
|
+
```
|
1106
|
+
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_combobox.rb'"
|
1107
|
+
```
|
1108
|
+
|
1109
|
+
Glimmer app:
|
1110
|
+
|
1111
|
+
![glimmer dsl tk screenshot sample hello combobox](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combobox.png)
|
1112
|
+
![glimmer dsl tk screenshot sample hello combobox dropdown](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combobox-dropdown.png)
|
1113
|
+
|
1102
1114
|
#### Glimmer DSL for XML (& HTML)
|
1103
1115
|
|
1104
1116
|
[Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) provides Ruby syntax for building XML (eXtensible Markup Language) documents.
|
@@ -1180,6 +1192,10 @@ body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2
|
|
1180
1192
|
|
1181
1193
|
Data-Binding enables mapping GUI properties (like text and color) to Model attributes (like name and age) for bidirectional or unidirectional synchronization and conversion as needed.
|
1182
1194
|
|
1195
|
+
Data-binding supports utilizing the [MVP (Model View Presenter)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter) flavor of [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) by observing both the View and a Presenter for changes and updating the opposite side upon encountering them. This enables writing more decoupled cleaner code that keeps View code and Model code disentangled and highly maintainable.
|
1196
|
+
|
1197
|
+
![MVP](https://www.researchgate.net/profile/Gilles-Perrouin/publication/320249584/figure/fig8/AS:668260987068418@1536337243385/Model-view-presenter-architecture.png)
|
1198
|
+
|
1183
1199
|
Glimmer enhances observed models automatically (including array operations like `<<`, `delete`, and `reject!`) on first observation. As such, you get automatic observable support, including nested and computed observations. No need to change your model code to data-bind it to the view or add repetitive boilerplate modules. View data-binding is truly decoupled from model logic by being able to observe any model attribute (Ruby attribute reader/writer combo or Ruby attribute reader alone for read-only data-binding when needed)
|
1184
1200
|
|
1185
1201
|
This relies mainly on the Observer Design Pattern and the MVP (Model-View-Presenter) Architectural Pattern (a variation on MVC)
|
@@ -1227,7 +1243,7 @@ Glimmer::DataBinding::Observer.proc do |new_value, changed_key|
|
|
1227
1243
|
end.observe(hash)
|
1228
1244
|
```
|
1229
1245
|
|
1230
|
-
If you would like to observe nested model attribute changes
|
1246
|
+
If you would like to observe nested model attribute changes, you can use the more advanced `Glimmer::DataBinding::ModelBinding` class instead.
|
1231
1247
|
|
1232
1248
|
Example of observing nested model attributes:
|
1233
1249
|
|
@@ -1237,7 +1253,7 @@ ModelBinding.new(model, "address1.street").add_observer do |new_address1_street_
|
|
1237
1253
|
end
|
1238
1254
|
```
|
1239
1255
|
|
1240
|
-
Example of observing indexed array changes (combined with a nested model attribute):
|
1256
|
+
Example of observing indexed array changes (specifying an array index) (combined with a nested model attribute):
|
1241
1257
|
|
1242
1258
|
```ruby
|
1243
1259
|
ModelBinding.new(model, "employees[5].name").add_observer do |new_employee_6_name|
|
@@ -1253,10 +1269,19 @@ ModelBinding.new(model, "grid[5][7]").add_observer do |new_grid_cell_value|
|
|
1253
1269
|
end
|
1254
1270
|
```
|
1255
1271
|
|
1272
|
+
Example of observing keyed hash changes (specifying a hash key as `Symbol` or single/double-quoted `String`) (combined with a nested model attribute):
|
1273
|
+
|
1274
|
+
```ruby
|
1275
|
+
ModelBinding.new(model, "employees[:manager].name").add_observer do |new_employee_6_name|
|
1276
|
+
# Do some work with new manager employee's name
|
1277
|
+
end
|
1278
|
+
```
|
1279
|
+
|
1256
1280
|
Data-bound `ModelBinding` attribute can be:
|
1257
1281
|
- **Direct:** `Symbol` representing attribute reader/writer (e.g. `[person, :name`])
|
1258
1282
|
- **Nested:** `String` representing nested attribute path (e.g. `[company, 'address.street']`). That results in "nested data-binding"
|
1259
1283
|
- **Indexed:** `String` containing array attribute index (e.g. `[customer, 'addresses[0].street']`). That results in "indexed data-binding"
|
1284
|
+
- **Keyed:** `String` containing hash attribute key (e.g. `[customer, 'addresses[:main].street']`). That results in "keyed data-binding"
|
1260
1285
|
|
1261
1286
|
Data-binding options include:
|
1262
1287
|
- `before_read {|value| ...}`: performs an operation before reading data from Model to update View.
|
@@ -1311,6 +1336,7 @@ Learn more by reading the [GPG](PROCESS.md) (Glimmer Process Guidelines)
|
|
1311
1336
|
|
1312
1337
|
## Resources
|
1313
1338
|
|
1339
|
+
* [Glimmer DSL for SWT Video Tutorials](https://andymaleh.blogspot.com/search/label/Tutorial+SWT)
|
1314
1340
|
* [Code Master Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
|
1315
1341
|
* [JRuby Cookbook by Justin Edelson & Henry Liu](http://shop.oreilly.com/product/9780596519650.do)
|
1316
1342
|
* [MountainWest RubyConf 2011 Video](https://confreaks.tv/videos/mwrc2011-whatever-happened-to-desktop-development-in-ruby)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.1
|
data/glimmer.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer 2.
|
5
|
+
# stub: glimmer 2.7.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer".freeze
|
9
|
-
s.version = "2.
|
9
|
+
s.version = "2.7.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2022-
|
15
|
-
s.description = "Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), Glimmer DSL for
|
14
|
+
s.date = "2022-02-26"
|
15
|
+
s.description = "Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library), Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library), Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library), Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"CHANGELOG.md",
|
@@ -54,7 +54,7 @@ Gem::Specification.new do |s|
|
|
54
54
|
s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
|
55
55
|
s.licenses = ["MIT".freeze]
|
56
56
|
s.rubygems_version = "3.3.1".freeze
|
57
|
-
s.summary = "Glimmer - DSL
|
57
|
+
s.summary = "Glimmer - DSL Framework for Ruby GUI and More".freeze
|
58
58
|
|
59
59
|
if s.respond_to? :specification_version then
|
60
60
|
s.specification_version = 4
|
data/lib/glimmer/config.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-
|
1
|
+
# Copyright (c) 2007-2022 Andy Maleh
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
@@ -27,6 +27,11 @@ module Glimmer
|
|
27
27
|
class ModelBinding
|
28
28
|
include Observable
|
29
29
|
include Observer
|
30
|
+
|
31
|
+
ARRAY_INDEXED_PROPERTY_ARGUMENT_REGEX = /\d+/
|
32
|
+
HASH_SYMBOL_INDEXED_PROPERTY_ARGUMENT_REGEX = /:[^:]+/
|
33
|
+
HASH_SINGLE_QUOTE_INDEXED_PROPERTY_ARGUMENT_REGEX = /'[^']+'/
|
34
|
+
HASH_DOUBLE_QUOTE_INDEXED_PROPERTY_ARGUMENT_REGEX = /"[^"]+"/
|
30
35
|
|
31
36
|
attr_reader :binding_options, :property_name_expression
|
32
37
|
|
@@ -206,7 +211,7 @@ module Glimmer
|
|
206
211
|
def call(value, *extra_args)
|
207
212
|
return if model.nil?
|
208
213
|
converted_value = value
|
209
|
-
invoke_property_writer(model, model.is_a?(Hash) ? property_name : "#{property_name}=", converted_value) unless converted_value == evaluate_property || property_name.nil?
|
214
|
+
invoke_property_writer(model, model.is_a?(Hash) && !property_indexed?(property_name) ? property_name : "#{property_name}=", converted_value) unless converted_value == evaluate_property || property_name.nil?
|
210
215
|
end
|
211
216
|
|
212
217
|
def evaluate_property
|
@@ -260,7 +265,7 @@ module Glimmer
|
|
260
265
|
if property_indexed?(property_expression)
|
261
266
|
property_method = '[]'
|
262
267
|
property_argument = property_expression[1...-1]
|
263
|
-
property_argument = property_argument
|
268
|
+
property_argument = indexed_property_argument(property_argument)
|
264
269
|
object.send(property_method, property_argument)
|
265
270
|
else
|
266
271
|
if property_expression.nil?
|
@@ -281,7 +286,7 @@ module Glimmer
|
|
281
286
|
if property_indexed?(property_expression)
|
282
287
|
property_method = '[]='
|
283
288
|
property_argument = property_expression[1...-2]
|
284
|
-
property_argument = property_argument
|
289
|
+
property_argument = indexed_property_argument(property_argument)
|
285
290
|
object.send(property_method, property_argument, converted_value)
|
286
291
|
else
|
287
292
|
if object.is_a?(Hash)
|
@@ -292,6 +297,20 @@ module Glimmer
|
|
292
297
|
end
|
293
298
|
apply_processor(@binding_options[:after_write], converted_value)
|
294
299
|
end
|
300
|
+
|
301
|
+
def indexed_property_argument(property_argument)
|
302
|
+
if property_argument.match(ARRAY_INDEXED_PROPERTY_ARGUMENT_REGEX)
|
303
|
+
property_argument.to_i
|
304
|
+
elsif property_argument.match(HASH_SYMBOL_INDEXED_PROPERTY_ARGUMENT_REGEX)
|
305
|
+
property_argument.sub(':', '').to_sym
|
306
|
+
elsif property_argument.match(HASH_SINGLE_QUOTE_INDEXED_PROPERTY_ARGUMENT_REGEX)
|
307
|
+
property_argument.gsub("'", '')
|
308
|
+
elsif property_argument.match(HASH_DOUBLE_QUOTE_INDEXED_PROPERTY_ARGUMENT_REGEX)
|
309
|
+
property_argument.gsub('"', '')
|
310
|
+
else
|
311
|
+
property_argument
|
312
|
+
end
|
313
|
+
end
|
295
314
|
end
|
296
315
|
end
|
297
316
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-
|
1
|
+
# Copyright (c) 2007-2022 Andy Maleh
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
@@ -47,8 +47,7 @@ module Glimmer
|
|
47
47
|
|
48
48
|
def add_observer(observer, *args)
|
49
49
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
|
-
element_properties = args
|
51
|
-
element_properties = element_properties.flatten.compact.uniq
|
50
|
+
element_properties = args.flatten.compact.uniq
|
52
51
|
return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties)
|
53
52
|
property_observer_list[observer] = options
|
54
53
|
observer_element_properties[observer] = Concurrent::Set.new(Concurrent::Array.new(element_properties_for(observer).to_a) + Concurrent::Array.new(element_properties)) # converting to Array as a workaround to jruby-9.3.2.0 issue TODO remove this workaround when no longer needed
|
data/lib/glimmer/dsl/engine.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-
|
1
|
+
# Copyright (c) 2007-2022 Andy Maleh
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
@@ -59,7 +59,11 @@ module Glimmer
|
|
59
59
|
static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
60
60
|
static_expression_can_interpret = nil
|
61
61
|
if static_expression.nil? || !(static_expression_can_interpret = static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block))
|
62
|
-
|
62
|
+
begin
|
63
|
+
Glimmer::DSL::Engine.interpret(keyword, *args, &block)
|
64
|
+
rescue => e
|
65
|
+
raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent.inspect} with DSL #{Glimmer::DSL::Engine.dsl.inspect} and static expression #{static_expression.inspect} having can_interpret? as #{static_expression_can_interpret.inspect} and no dynamic expressions to be able to handle either!"
|
66
|
+
end
|
63
67
|
else
|
64
68
|
Glimmer::Config.logger.info {"#{static_expression.class.name} will handle expression keyword #{keyword}"}
|
65
69
|
Glimmer::DSL::Engine.interpret_expression(static_expression, keyword, *args, &block)
|
@@ -146,14 +150,35 @@ module Glimmer
|
|
146
150
|
end
|
147
151
|
end
|
148
152
|
|
149
|
-
def
|
153
|
+
def add_downcased_static_expression(static_expression)
|
150
154
|
Glimmer::Config.logger.info {"Adding static expression: #{static_expression.class.name}"}
|
151
155
|
keyword = static_expression.class.keyword
|
152
|
-
static_expression_dsl = static_expression.class.dsl
|
153
156
|
static_expressions[keyword] ||= Concurrent::Hash.new
|
157
|
+
static_expression_dsl = static_expression.class.dsl
|
154
158
|
static_expressions[keyword][static_expression_dsl] = static_expression
|
155
159
|
Glimmer.send(:define_method, keyword, &STATIC_EXPRESSION_METHOD_FACTORY.call(keyword))
|
156
160
|
end
|
161
|
+
alias add_static_expression add_downcased_static_expression
|
162
|
+
|
163
|
+
def remove_downcased_static_expression(static_expression)
|
164
|
+
if !static_expression.class.downcased?
|
165
|
+
keyword = static_expression.class.keyword
|
166
|
+
static_expressions[keyword].delete(static_expression_dsl) if static_expressions[keyword]
|
167
|
+
static_expressions.delete(keyword) if static_expressions[keyword].empty?
|
168
|
+
Glimmer.send(:undef_method, keyword) if (Glimmer.method(keyword) rescue nil)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def add_upcased_static_expression(static_expression)
|
173
|
+
if static_expression.class.upcased?
|
174
|
+
Glimmer::Config.logger.info {"Adding upcased static expression: #{static_expression.class.name}"}
|
175
|
+
keyword = static_expression.class.keyword
|
176
|
+
static_expression_dsl = static_expression.class.dsl
|
177
|
+
static_expressions[keyword.upcase] ||= Concurrent::Hash.new
|
178
|
+
static_expressions[keyword.upcase][static_expression_dsl] = static_expression
|
179
|
+
Glimmer.send(:define_method, keyword.upcase, &STATIC_EXPRESSION_METHOD_FACTORY.call(keyword.upcase))
|
180
|
+
end
|
181
|
+
end
|
157
182
|
|
158
183
|
def expression_class(dsl_namespace, expression_name)
|
159
184
|
dsl_namespace.const_get(expression_class_name(expression_name).to_sym)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-
|
1
|
+
# Copyright (c) 2007-2022 Andy Maleh
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
@@ -44,16 +44,42 @@ module Glimmer
|
|
44
44
|
Glimmer::DSL::Engine.add_static_expression(base.new)
|
45
45
|
super
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def keyword
|
49
49
|
@keyword ||= name.split(/::/).last.sub(/Expression$/, '').underscore
|
50
50
|
end
|
51
|
+
|
52
|
+
def downcased(value)
|
53
|
+
@downcased = value
|
54
|
+
Glimmer::DSL::Engine.add_downcased_static_expression(new) if @downcased
|
55
|
+
end
|
56
|
+
alias downcase downcased
|
57
|
+
|
58
|
+
def downcased?
|
59
|
+
# default is true when no attributes are set
|
60
|
+
@downcased.nil? && @upcased.nil? ? true : @downcased
|
61
|
+
end
|
62
|
+
alias downcase? downcased?
|
63
|
+
|
64
|
+
def upcased(value)
|
65
|
+
@upcased = value
|
66
|
+
Glimmer::DSL::Engine.add_upcased_static_expression(new) if @upcased
|
67
|
+
end
|
68
|
+
alias upcase upcased
|
69
|
+
|
70
|
+
def upcased?
|
71
|
+
@upcased
|
72
|
+
end
|
73
|
+
alias upcase? upcased?
|
51
74
|
end
|
52
75
|
|
53
76
|
# Subclasses may optionally implement, but by default it only ensures that
|
54
77
|
# the keyword matches lower case static expression class name minus `Expression`
|
55
78
|
def can_interpret?(parent, keyword, *args, &block)
|
56
|
-
|
79
|
+
result = false
|
80
|
+
result ||= keyword.downcase == keyword if self.class.downcased?
|
81
|
+
result ||= keyword.upcase == keyword if self.class.upcased?
|
82
|
+
result
|
57
83
|
end
|
58
84
|
end
|
59
85
|
end
|
data/lib/glimmer/error.rb
CHANGED
data/lib/glimmer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: array_include_methods
|
@@ -206,10 +206,12 @@ description: Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting o
|
|
206
206
|
a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable
|
207
207
|
Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby
|
208
208
|
Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI and
|
209
|
-
Auto-Webifier of Desktop Apps), Glimmer DSL for
|
210
|
-
Library), Glimmer DSL for
|
211
|
-
|
212
|
-
|
209
|
+
Auto-Webifier of Desktop Apps), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop
|
210
|
+
Development GUI Library), Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library),
|
211
|
+
Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer DSL for
|
212
|
+
FX (FOX Toolkit Ruby Desktop Development GUI Library), Glimmer DSL for Swing (JRuby
|
213
|
+
Swing Desktop Development GUI Library), Glimmer DSL for JFX (JRuby JavaFX Desktop
|
214
|
+
Development GUI Library), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS.
|
213
215
|
email: andy.am@gmail.com
|
214
216
|
executables: []
|
215
217
|
extensions: []
|
@@ -270,5 +272,5 @@ requirements: []
|
|
270
272
|
rubygems_version: 3.3.1
|
271
273
|
signing_key:
|
272
274
|
specification_version: 4
|
273
|
-
summary: Glimmer - DSL
|
275
|
+
summary: Glimmer - DSL Framework for Ruby GUI and More
|
274
276
|
test_files: []
|