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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9732781d2374eced24ceef11e7b403f0345e63b71e34f35a6c322580b0323123
4
- data.tar.gz: f3421f6c71847386eba06848ab2039e62032a3636528bb07ee5ee809f6ea19fa
3
+ metadata.gz: b7e7983379ea9281e26719f66718fb706d475d3dd9904e20cfd51237625d9322
4
+ data.tar.gz: '08fa76d4f37a422a8d6b68845f22ce3a8f41f1b53c8a6d9dced1044c55a14aa6'
5
5
  SHA512:
6
- metadata.gz: b9ebb4484cc2cc7379c4d27c77fe451b9a884201af50dacbb533cdfc420f4a523a44bac16a34df17c28cee1a1f9e9058d69ec0ef4301994c2944f5899827a785
7
- data.tar.gz: 607cc126a4193fa251c163794d5a19dbb96fe23b604721695c2a57b8bf22352bd3f209ad612c1b0c5211262ce1d196248a056919901a2e4fc3de810a14d1f3c4
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2021 Andy Maleh
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
data/PROCESS.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  --
15
15
 
16
- Copyright (c) 2020-2021 Andy Maleh
16
+ Copyright (c) 2020-2022 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,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 - DSL Framework for Ruby GUI and More
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 (100% complete); [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), and Glimmer's CRuby GUI DSL (100% complete), which has no prerequisites beyond installing the Ruby gem; [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui).
31
-
32
- [**Glimmer**](https://rubygems.org/gems/glimmer) supports the following DSLs:
33
- - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
34
- - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
35
- - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
36
- - [glimmer-dsl-libui](https://github.com/AndyObtiva/glimmer-dsl-libui): Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)
37
- - [glimmer-dsl-gtk](https://github.com/AndyObtiva/glimmer-dsl-gtk): Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)
38
- - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
39
- - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
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 attributes/keywords)** (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)
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.5.5'` to `Gemfile` and run `bundle` or run `gem install glimmer -v2.5.5` and add `require 'glimmer'`
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 and/or indexed array changes (specifying a nested array index/indices), you can use the more advanced `Glimmer::DataBinding::ModelBinding` class instead.
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.5.5
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.5 ruby lib
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.5.5"
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-01-09"
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 Tk (Ruby Desktop Development GUI Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS.".freeze
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 Engine for Ruby GUI and More".freeze
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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.to_i if property_argument.match(/\d+/)
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.to_i if property_argument.match(/\d+/)
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-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
- 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}"
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 add_static_expression(static_expression)
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-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
- true
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
data/lib/glimmer/error.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
data/lib/glimmer.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2021 Andy Maleh
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
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.5.5
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-01-09 00:00:00.000000000 Z
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 Tk (Ruby Desktop Development GUI
210
- Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI
211
- Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer
212
- DSL for XML (& HTML), and Glimmer DSL for CSS.
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 Engine for Ruby GUI and More
275
+ summary: Glimmer - DSL Framework for Ruby GUI and More
274
276
  test_files: []