glimmer 1.0.5 → 1.0.6

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: 308cb6947a4ddd903bda7c12eef7043dc05fa5c8473b679168e16245d0cb7097
4
- data.tar.gz: 6d49e9dfc418ab7ef67542e033e30b32e84497023f320853d694ad3c1ac8f808
3
+ metadata.gz: cc6506323777ae44ace532c9b99f7b8070c27343be8ec954f133b60970719380
4
+ data.tar.gz: 54946885ac6ff008e1b5034f30a31d04bd089a6c90deb444a5070602acc1efaf
5
5
  SHA512:
6
- metadata.gz: 6ca04445656d701c8729b92aae37f8dda83d11d382a3f489d0d10aad1616c40b830774998f844a713fa6c90651042178d32b47618aee29ecef7a63f4e92e2a8f
7
- data.tar.gz: a7d26e3e9aaa5fe6c559a7d86ca796933ad8e00d0bfd284e8d9ac59a27e3496291d1e1dc838e42d16e1bfdae8db88edaf9560d85df6c320813eb1598164e2968
6
+ metadata.gz: 6798e108d8dc6f66800872394d2f4b8d0aca7cb68e746b8fe09258938f871785f698e56d6ad61a16c5460087c08f6ef6c7c48acd33aa5c5ac1b6f1320aa66efb
7
+ data.tar.gz: 05b52b53015bd04689e465da7d6d2a6da6ec5db9603f87471ec550ca732c11cb31b9b2ad378d06da91f278d726c6bb670c572b02df0db73ba3db1ed547411f1f
@@ -3,6 +3,10 @@
3
3
  Related Change Logs:
4
4
  - [glimmer-dsl-swt/CHANGELOG.md](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/CHANGELOG.md)
5
5
 
6
+ ## 1.0.6
7
+
8
+ - Update ModelBinding to raise an error if called to make a change while configurd as binding_options[:read_only]=true
9
+
6
10
  ## 1.0.5
7
11
 
8
12
  - Fix issue in Opal regarding auto-definition of observable methods in a Class/Module directly (as opposed to a class instance)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" />](https://rubygems.org/gems/glimmer) Glimmer 1.0.5 - DSL Framework
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 style="position: relative; top: 20px;" />](https://rubygems.org/gems/glimmer) Glimmer 1.0.6 - DSL Framework
2
2
  [![Gem Version](https://badge.fury.io/rb/glimmer.svg)](http://badge.fury.io/rb/glimmer)
3
3
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
@@ -7,49 +7,45 @@
7
7
 
8
8
  **[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
9
9
 
10
- (The Original Glimmer Library Since 2007. Beware of Imitators!)
11
-
12
- [**Glimmer**](https://rubygems.org/gems/glimmer) is a DSL Framework that consists of:
13
- - DSL Engine: enables building DSLs for desktop GUI, XML/HTML documents, CSS styling, and webification of desktop apps.
14
- - Data-Binding/Observer/Observable Library: enables synchronizing GUI with Model Attributes bidirectionally.
10
+ **(The Original Glimmer Library Since 2007. Beware of Imitators!)**
15
11
 
16
12
  [**Glimmer**](https://rubygems.org/gems/glimmer) started out as [GUI Library](https://github.com/AndyObtiva/glimmer-dsl-swt) and grew into a full-fledged [DSL Framework](#multi-dsl-support). Glimmer's namesake is referring to the Glimmer of Ruby in Graphical User Interfaces (contrary to popular myth perpetrated by [Charles Nutter](http://blog.headius.com/2007/11/tab-sweep.html), Glimmer has nothing to do with the ill-fated Whitney Houston movie, which does not in fact share the same name)
17
13
 
14
+ [<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
15
+ Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
16
+
17
+ [**Glimmer**](https://rubygems.org/gems/glimmer) is a DSL Framework that consists of two things:
18
+ - [DSL Engine](#dsl-engine): enables building DSLs for desktop GUI, web GUI, XML/HTML documents, and CSS styling.
19
+ - [Data-Binding Support](#data-binding-support): enables synchronizing GUI with Model Attributes bidirectionally.
20
+
21
+ [**Glimmer**](https://rubygems.org/gems/glimmer) is ***the cream of the crop*** when it comes to building DSLs in Ruby:
22
+ - Supports building the tersest most concise domain specific language syntax in Ruby.
23
+ - No extra unnecessary block variables when not needed
24
+ - Maximum readability and maintainability
25
+ - DSL Blocks are true Ruby closures that can conveniently leverage variables from the outside and utilize standard Ruby code in and around. Just code in Ruby as usual and be happy! No surprising restrictions or strange uses of `instance_exec`/`eval`.
26
+ - DSL syntax is limited to classes that mixin the `Glimmer` module, so the rest of the code is fully safe from namespace pollution.
27
+ - Multiple DSLs may be mixed together safely to achieve maximum expressability, composability, and productivity
28
+ - DSLs are fully configurable, so you may activate and deactivate DSLs as per your current needs only
29
+
18
30
  [**Glimmer**](https://rubygems.org/gems/glimmer) supports the following DSLs:
19
- - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Library)
31
+ - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
20
32
  - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
21
- - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
33
+ - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
22
34
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
23
35
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
24
36
 
25
37
  [Glimmer and/or Glimmer DSLs receive two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer](https://rubygems.org/gems/glimmer) with your Ruby development needs.
26
38
 
27
- [<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
28
- Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
29
-
30
39
  ## Table of contents
31
40
 
32
- - [Glimmer 1.0.5](#-glimmer-105)
33
- - [Glimmer DSL for SWT (JRuby Desktop Development GUI Library)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-library)
34
- - [Glimmer DSL for SWT Samples](#glimmer-dsl-for-swt-samples)
35
- - [Hello, World!](#hello-world)
36
- - [Tic Tac Toe](#tic-tac-toe)
37
- - [Contact Manager](#contact-manager)
38
- - [Production Desktop Apps Built with Glimmer DSL for SWT](#production-desktop-apps-built-with-glimmer-dsl-for-swt)
41
+ - [Glimmer 1.0.6](#-glimmer-106---dsl-framework)
42
+ - [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
39
43
  - [Glimmer DSL for Tk (Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-ruby-desktop-development-gui-library)
40
- - [Glimmer DSL for Tk Samples](#glimmer-dsl-for-tk-samples)
41
- - [Hello, World!](#hello-world)
42
- - [Hello, Tab!](#hello-tab)
43
- - [Hello, Combo!](#hello-combo)
44
- - [Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)](#glimmer-dsl-for-opal-web-gui-adapter-for-desktop-apps)
45
- - [Glimmer DSL for Opal Samples](#glimmer-dsl-for-opal-samples)
46
- - [Hello, Computed!](#hello-computed)
47
- - [Glimmer Calculator](#glimmer-calculator)
44
+ - [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)
48
45
  - [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
49
- - [XML DSL](#xml-dsl)
50
46
  - [Glimmer DSL for CSS](#glimmer-dsl-for-css)
51
- - [CSS DSL](#css-dsl)
52
- - [Multi-DSL Support](#multi-dsl-support)
47
+ - [DSL Engine](#dsl-engine)
48
+ - [Data-Binding Support](#data-binding-support)
53
49
  - [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
54
50
  - [Glimmer Process](#glimmer-process)
55
51
  - [Resources](#resources)
@@ -63,7 +59,7 @@ Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.d
63
59
  - [Hire Me](#hire-me)
64
60
  - [License](#license)
65
61
 
66
- ## Glimmer DSL for SWT (JRuby Desktop Development GUI Library)
62
+ ## Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
67
63
 
68
64
  [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://rubygems.org/gems/glimmer)'s main innovation is a declarative [Ruby DSL](https://github.com/AndyObtiva/glimmer-dsl-swt#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) additionally innovates by having built-in [data-binding](https://github.com/AndyObtiva/glimmer-dsl-swt#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns. To get started quickly, [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) offers [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt#scaffolding) options for [Apps](https://github.com/AndyObtiva/glimmer-dsl-swt#in-production), [Gems](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-shell-gem), and [Custom Widgets](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-widgets). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) also includes native-executable [packaging](https://github.com/AndyObtiva/glimmer-dsl-swt#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/) and MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows).
69
65
 
@@ -73,7 +69,7 @@ To get started, visit the [Glimmer DSL for SWT project page](https://github.com/
73
69
 
74
70
  #### Hello, World!
75
71
 
76
- Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
72
+ Glimmer GUI code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/hello/hello_world.rb)):
77
73
  ```ruby
78
74
  include Glimmer
79
75
 
@@ -85,23 +81,16 @@ shell {
85
81
  }.open
86
82
  ```
87
83
 
88
- Run:
89
- ```
90
- glimmer sample:run[hello_world]
91
- ```
92
-
93
84
  Glimmer app:
94
85
 
95
86
  ![Hello World](images/glimmer-hello-world.png)
96
87
 
97
88
  #### Tic Tac Toe
98
89
 
99
- Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
90
+ Glimmer GUI code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/tic_tac_toe.rb)):
100
91
 
101
92
  ```ruby
102
93
  # ...
103
- @tic_tac_toe_board = Board.new
104
-
105
94
  @shell = shell {
106
95
  text "Tic-Tac-Toe"
107
96
  minimum_size 150, 178
@@ -122,27 +111,16 @@ Glimmer code (from [samples/elaborate/tic_tac_toe.rb](https://github.com/AndyObt
122
111
  }
123
112
  }
124
113
  }
125
-
126
- observe(@tic_tac_toe_board, :game_status) { |game_status|
127
- display_win_message if game_status == Board::WIN
128
- display_draw_message if game_status == Board::DRAW
129
- }
130
114
  # ...
131
115
  ```
132
116
 
133
- Run:
134
-
135
- ```
136
- glimmer sample:run[tic_tac_toe]
137
- ```
138
-
139
117
  Glimmer app:
140
118
 
141
119
  ![Tic Tac Toe](images/glimmer-tic-tac-toe-in-progress.png)
142
120
 
143
121
  #### Contact Manager
144
122
 
145
- Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
123
+ Glimmer GUI code (from [samples/elaborate/contact_manager.rb](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/samples/elaborate/contact_manager.rb)):
146
124
 
147
125
  ```ruby
148
126
  # ...
@@ -255,12 +233,6 @@ Glimmer code (from [samples/elaborate/contact_manager.rb](https://github.com/And
255
233
  # ...
256
234
  ```
257
235
 
258
- Run:
259
-
260
- ```
261
- glimmer sample:run[contact_manager]
262
- ```
263
-
264
236
  Glimmer App:
265
237
 
266
238
  ![Contact Manager](images/glimmer-contact-manager.png)
@@ -392,7 +364,7 @@ Glimmer app:
392
364
  ![glimmer dsl tk screenshot sample hello combo](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combo.png)
393
365
  ![glimmer dsl tk screenshot sample hello combo dropdown](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-combo-dropdown.png)
394
366
 
395
- ## Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
367
+ ## Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
396
368
 
397
369
  [Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) is an experimental proof-of-concept web GUI adapter for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/), allowing Ruby desktop apps to run on the web via [Opal Ruby](https://opalrb.com/) without changing a line of code. Apps may then be custom-styled for the web with standard CSS.
398
370
 
@@ -678,33 +650,114 @@ Output:
678
650
  body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2em}
679
651
  ```
680
652
 
681
- ## Multi-DSL Support
682
-
683
- Glimmer official DSL gems always start with `glimmer-dsl-`. That said, other libraries may use the Glimmer DSL engine too not for building GUI apps (e.g. `bundler-download`)
653
+ ## DSL Engine
684
654
 
685
- Glimmer allows mixing DSLs, which comes in handy when doing things like using a desktop Browser widget with HTML and CSS.
655
+ Glimmer is fundamentally a DSL Engine that can support any number of DSLs like the official Glimmer DSLs (gems starting with the `glimmer-dsl-` prefix like `glimmer-dsl-swt`) or any DSLs for that matter.
686
656
 
687
657
  Glimmer DSL syntax consists mainly of:
688
658
  - keywords (e.g. `table` for a table widget)
689
659
  - style/args (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
690
660
  - content (e.g. `{ table_column { text 'Name'} }` as in `table(:multi) { table_column { text 'name'} }` for a multi-line selection table widget with a table column having header text property `'Name'` as content)
691
661
 
692
- DSLs are activated by specific keywords. For example, the `html` keyword activates the Glimmer DSL for XML. Glimmer automatically recognizes top-level keywords in each DSL and activates the DSL accordingly. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
662
+ The Glimmer DSL Engine's architecture is based on the following Design Patterns and Data Structures:
663
+ - **Interpreter Design Pattern**: to define interpretable expressions of DSL keywords
664
+ - **Chain of Responsibility Design Pattern / Queue Data Structure**: to chain expression handlers in order of importance for processing DSL keywords
665
+ - **Adapter Design Pattern**: to adapt expressions into handlers in a chain of responsibility
666
+ - **Stack Data Structure**: to handle processing parent/child nesting of DSL keyword expressions in the correct order
667
+
668
+ Glimmer's use of the **Interpreter Design Pattern** in processing DSLs is also known as the **Virtual Machine Architectural Style**. After all, DSL expressions are virtual machine opcodes that process nested keywords stored in a stack. I built Glimmer's original DSL back in 2007 without knowing the **Virtual Machine Architectural Style**, but stumbled upon it anyways through following the Gang of Four Design Patterns mentioned above, chiefly the **Interpreter Design Pattern**.
669
+
670
+ Every keyword in a Glimmer DSL is represented by a DSL expression that is processed by an `Expression` subclass selected from a chain of expressions (interpreters) pre-configured in a DSL chain of responsibility via `Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)`.
671
+
672
+ Expressions are either:
673
+ - **Static** (subclass of `StaticExpression`, which is a subclass of `Expression`): if they represent a single pre-identified keyword (e.g. `color` or `display`)
674
+ - **Dynamic** (subclass of `Expression`): if they represent keywords calculated on the fly during processing (e.g. an SWT widget like `label` or a random XML element called `folder` representing `<folder></folder>`)
675
+
676
+ Optionally, expressions can be parent expressions that contain other expressions, and must include the `ParentExpression` mixin module as such.
677
+
678
+ Additionally, every expression that serves as a top-level entry point into the DSL must mixin `TopLevelExpression`
679
+
680
+ Static expressions are optimized in performance since they pre-define methods on the `Glimmer` module matching the static keywords they represent (e.g. `color` causes creating a `Glimmer#color` method for processing `color` expressions) and completely bypass as a result the Glimmer DSL Engine Chain of Responsibility. That said, they must be avoided if the same keyword might occur multiple times, but with different requirements for arguments, block, and parenthood type.
681
+
682
+ Every `Expression` sublcass must specify two methods at least:
683
+ - `can_interpret?(parent, keyword, *args, &block)`: to quickly test if the keyword and arg/block/parent combination qualifies for interpretation by the current `Expression` or to otherwise delegate to the next expression in the chain of responsibility.
684
+ - `interpret(parent, keyword, *args, &block)`: to go ahead and interpret a DSL expression that qualified for interpretation
685
+
686
+ `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.
687
+
688
+ `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:
689
+ - `add_content(parent, &block)`
690
+
691
+ For example, some parent widgets use their block for other reasons or process their children at very specific times, so they may override that method and disable it, or otherwise call `super` and do additional work.
692
+
693
+ DSL expressions go into the `glimmer/dsl/{dsl_name}` namespace directory.
694
+
695
+ Also, every DSL requires a `glimmer/dsl/{dsl_name}/dsl.rb` file, which configures the DSL into Glimmer via a call to:
696
+ ```ruby
697
+ Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)
698
+ ```
699
+
700
+ Expression names are underscored verions of `Expression` subclass names minus the `_expression` suffix.
701
+
702
+ For example, here is an SWT DSL configuration:
703
+
704
+ ```ruby
705
+ require 'glimmer/launcher'
706
+ require Glimmer::Launcher.swt_jar_file
707
+ require 'glimmer/dsl/engine'
708
+ Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
709
+
710
+ module Glimmer
711
+ module DSL
712
+ module SWT
713
+ Engine.add_dynamic_expressions(
714
+ SWT,
715
+ %w[
716
+ layout
717
+ widget_listener
718
+ combo_selection_data_binding
719
+ checkbox_group_selection_data_binding
720
+ radio_group_selection_data_binding
721
+ list_selection_data_binding
722
+ tree_items_data_binding
723
+ table_items_data_binding
724
+ data_binding
725
+ cursor
726
+ font
727
+ image
728
+ property
729
+ block_property
730
+ widget
731
+ custom_widget
732
+ ]
733
+ )
734
+ end
735
+ end
736
+ end
737
+ ```
738
+
739
+ In summary, these are the files needed to author a Glimmer DSL:
740
+ - `glimmer/dsl/[dsl_name]/dsl.rb`: requires and adds all dynamic expressions to [dsl_name] Glimmer DSL
741
+ - `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb`: needed for every [expresion_name] expression, whether dynamic or static
742
+
743
+ ### Multi-DSL Support
744
+
745
+ The Glimmer [DSL Engine](#dsl-engine) allows mixing DSLs, which comes in handy when doing things like using a desktop GUI DSL `browser` widget with the HTML DSL and CSS DSL.
746
+
747
+ DSLs are activated by top-level keywords (expressions denoted as `TopLevelExpression`). For example, the `html` keyword activates the Glimmer DSL for XML. Glimmer automatically recognizes top-level keywords in each DSL and activates the DSL accordingly. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
748
+
749
+ ## Data-Binding Support
750
+
751
+ Data-Binding enables binding GUI properties (like text and color) to Model attributes (like name and age).
693
752
 
694
- ## Glimmer Supporting Libraries
753
+ It relies on the Observer Design Pattern and MVP (Model-View-Presenter) Architectural Pattern (a variation on MVC)
695
754
 
696
- Here is a list of notable 3rd party gems used by Glimmer and Glimmer DSLs:
697
- - [jeweler](https://github.com/technicalpickles/jeweler): generates app gems during [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt#scaffolding)
698
- - [logging](https://github.com/TwP/logging): provides extra logging capabilities not available in Ruby Logger such as multi-threaded buffered asynchronous logging (to avoid affecting app performance) and support for multiple appenders such as stdout, syslog, and log files (the last one is needed on Windows where syslog is not supported)
699
- - [nested_inherited_jruby_include_package](https://github.com/AndyObtiva/nested_inherited_jruby_include_package): makes included [SWT](https://www.eclipse.org/swt/)/[Java](https://www.java.com/en/) packages available to all classes/modules that mix in the Glimmer module without having to manually reimport
700
- - [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
701
- - [puts_debuggerer](https://github.com/AndyObtiva/puts_debuggerer): helps in troubleshooting when adding `require 'pd'` and using the `pd` command instead of `puts` or `p` (also `#pd_inspect` or `#pdi` instead of `#inspect`)
702
- - [rake](https://github.com/ruby/rake): used to implement and execute `glimmer` commands
703
- - [rake-tui](https://github.com/AndyObtiva/rake-tui): Rake Text-based User Interface. Allows navigating rake tasks with arrow keys and filtering task list by typing to quickly find an run a rake task.
704
- - [rouge](https://github.com/rouge-ruby/rouge): Ruby syntax highlighter used in the `code_text` [Glimmer DSL for SWT custom widget](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-widgets) leveraged by the [Glimmer Meta-Sample](https://github.com/AndyObtiva/glimmer-dsl-swt#samples)
705
- - [super_module](https://github.com/AndyObtiva/super_module): used to cleanly write the Glimmer::UI:CustomWidget and Glimmer::UI::CustomShell modules
706
- - [text-table](https://github.com/aptinio/text-table): renders textual data in a textual table for the command-line interface of Glimmer
707
- - [warbler](https://github.com/jruby/warbler): converts a Glimmer app into a Java JAR file during packaging
755
+ These are the main classes concerning data-binding:
756
+ - `Observer`: Provides general observer support including unique registration and deregistration for cleanup and prevention of memory leaks. Main methods concerned are: `call`, `register` (alias: `observe`), and `unregister` (alias: `unobserve` or `deregister`)
757
+ - `Observable`: General super-module for all observables. Main methods concerned are: `add_observer` and `remove_observer`
758
+ - `ObservableModel`: Mixin module for any observable model with observable attributes. In addition to `Observable` methods, it has a `notify_observers` method to be called when changes occur. It automatically enhances all attribute setters (ending with `=`) to notify observers on changes. Also, it automatically handles observing array attributes using `ObservableArray` appropriately so they would notify observers upon array mutation changes.
759
+ - `ObservableArray`: Mixin module for any observable array collection that automatically handles notifying observers upon performing array mutation operations (e.g. `push` or `delete`)
760
+ - `ModelBinding`: a higher-level abstraction that relies on all the other observer/observable classes to support basic data-binding, nested data-binding, and computed data-binding
708
761
 
709
762
  ## Glimmer Process
710
763
 
@@ -756,7 +809,7 @@ Glimmer DSL Engine specific tasks are at:
756
809
  If you would like to contribute to Glimmer, please study up on Glimmer and [SWT](https://github.com/AndyObtiva/glimmer-dsl-swt#swt-reference), run all Glimmer [samples](https://github.com/AndyObtiva/glimmer-dsl-swt#samples), and build a small sample app (perhaps from [this TODO list](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/TODO.md#samples)) to add to [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) Hello or Elaborate samples via a Pull Request. Once done, contact me on [Chat](#chat).
757
810
 
758
811
  You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
759
- - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Library)
812
+ - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
760
813
  - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (Ruby Desktop Development GUI Library)
761
814
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
762
815
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.5
1
+ 1.0.6
@@ -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 1.0.5 ruby lib
5
+ # stub: glimmer 1.0.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer".freeze
9
- s.version = "1.0.5"
9
+ s.version = "1.0.6"
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 = "2020-12-02"
15
- s.description = "Glimmer is a Ruby DSL Framework consisting of a DSL Engine and Observable/Observer/Data-Binding Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Library), the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer DSL for CSS.".freeze
14
+ s.date = "2020-12-15"
15
+ s.description = "Glimmer is a Ruby DSL Framework consisting of a DSL Engine and Observable/Observer/Data-Binding Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer DSL for CSS.".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "CHANGELOG.md",
@@ -242,7 +242,7 @@ module Glimmer
242
242
  end
243
243
 
244
244
  def invoke_property_writer(object, property_expression, value)
245
- return if @binding_options[:read_only]
245
+ raise "Cannot invoke `#{property_expression}` because ModelBinding#binding_options[:read_only]=true" if @binding_options[:read_only]
246
246
  value = convert_on_write(value)
247
247
  if property_indexed?(property_expression)
248
248
  property_method = '[]='
@@ -51,6 +51,7 @@ module Glimmer
51
51
  observer.unobserve(observable, property)
52
52
  end
53
53
  alias unobserve unregister
54
+ alias deregister unregister
54
55
  end
55
56
 
56
57
  class << self
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2020 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
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -51,7 +51,7 @@ module Glimmer
51
51
  end
52
52
  if interpretation
53
53
  interpretation
54
- else
54
+ else
55
55
  raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
56
56
  Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
57
57
  static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
@@ -62,8 +62,8 @@ module Glimmer
62
62
  Glimmer::DSL::Engine.interpret_expression(static_expression, keyword, *args, &block)
63
63
  end
64
64
  end
65
- end
66
- end
65
+ end
66
+ end
67
67
  end
68
68
 
69
69
  class << self
@@ -115,7 +115,7 @@ module Glimmer
115
115
  # Static expressions indexed by keyword and dsl
116
116
  def static_expressions
117
117
  @static_expressions ||= {}
118
- end
118
+ end
119
119
 
120
120
  # Sets dynamic expression chains of responsibility. Useful for internal testing
121
121
  attr_writer :dynamic_expression_chains_of_responsibility
@@ -132,7 +132,7 @@ module Glimmer
132
132
  # Pattern when interpretting a DSL expression
133
133
  def add_dynamic_expressions(dsl_namespace, *expression_names)
134
134
  expression_names = expression_names.flatten
135
- dsl = dsl_namespace.name.split("::").last.downcase.to_sym
135
+ dsl = dsl_namespace.name.split("::").last.downcase.to_sym
136
136
  dynamic_expression_chains_of_responsibility[dsl] = expression_names.reverse.map do |expression_name|
137
137
  expression_class(dsl_namespace, expression_name).new
138
138
  end.reduce(nil) do |last_expresion_handler, expression|
@@ -140,7 +140,7 @@ module Glimmer
140
140
  expression_handler = ExpressionHandler.new(expression)
141
141
  expression_handler.next = last_expresion_handler if last_expresion_handler
142
142
  expression_handler
143
- end
143
+ end
144
144
  end
145
145
 
146
146
  def add_static_expression(static_expression)
@@ -161,7 +161,7 @@ module Glimmer
161
161
  end
162
162
 
163
163
  # Interprets Glimmer dynamic DSL expression consisting of keyword, args, and block (e.g. shell(:no_resize) { ... })
164
- def interpret(keyword, *args, &block)
164
+ def interpret(keyword, *args, &block)
165
165
  return puts(MESSAGE_NO_DSLS) if no_dsls?
166
166
  keyword = keyword.to_s
167
167
  dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).first if dsl.nil?
@@ -185,7 +185,7 @@ module Glimmer
185
185
  def add_content(parent, expression, &block)
186
186
  if block_given? && expression.is_a?(ParentExpression)
187
187
  dsl_stack.push(expression.class.dsl)
188
- parent_stack.push(parent)
188
+ parent_stack.push(parent)
189
189
  begin
190
190
  expression.add_content(parent, &block)
191
191
  ensure
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: 1.0.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-02 00:00:00.000000000 Z
11
+ date: 2020-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: array_include_methods
@@ -209,10 +209,10 @@ dependencies:
209
209
  - !ruby/object:Gem::Version
210
210
  version: '0'
211
211
  description: Glimmer is a Ruby DSL Framework consisting of a DSL Engine and Observable/Observer/Data-Binding
212
- Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Library),
212
+ Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework),
213
213
  the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for
214
- Opal (Web GUI Adapter for Desktop Apps), the Glimmer DSL for XML (& HTML), and the
215
- Glimmer DSL for CSS.
214
+ Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for
215
+ XML (& HTML), and the Glimmer DSL for CSS.
216
216
  email: andy.am@gmail.com
217
217
  executables: []
218
218
  extensions: []