glimmer 2.2.2 → 2.5.0

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: 672161d98054249c5d807ee86ba9209a471fdc7bf1ce6a2a861f2b363493cb13
4
- data.tar.gz: 1d811ea1139eda01c8593416669b1088624def2df0fbc3ee9dc9deb992ab8215
3
+ metadata.gz: 4819523f794404e37e2dc3c9c673b4e33f80e20825a077a775d9d14b7bb2e437
4
+ data.tar.gz: ce87b095f130bd8bde0b076bd8499dfa5ce2e3ccf5d8d956b8452537e181d314
5
5
  SHA512:
6
- metadata.gz: 38e7efff7b054c7eb1ebbdc1c32fb6f9df7b19522e17124f6e63076295a0e46e22c8f12b061cfba2a789326c9a2ef1d24921ae2fdb999ab4f6ad9dec22865ee3
7
- data.tar.gz: d149a78a300cc1f572d61fa894bb265948ed11fa0ee5b8ba8fcba8f2e3af096dfa492cb7f6b3e51d1dc0f37585491846bdbd17abee335902bc9ab36c40543bb1
6
+ metadata.gz: 41362408327087fd238ac81ecf3a449505c43eb57a31b0c69253abd2a8c523ca64c48da31ab47030dbba1a756b90435908e19d67cde33fd939bc4b27c7480527
7
+ data.tar.gz: d37570e378e876331282db59bb5276d280d8cfbd8b3d70694a654733fd7cd5d5db9ff08dc7cec1f1fe24a92e413f2b00217d210204bc0d7559130f7195085216
data/CHANGELOG.md CHANGED
@@ -3,6 +3,30 @@
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.5.0
7
+
8
+ - Support observing `Struct`/`OpenStruct` changes via `:[]=` method in addition to attribute writers.
9
+ - Support read-only direct observation of `Hash` object without key via `ModelBinding` (e.g. `ModelBinding.new(some_hash)`)
10
+ - Support read-only direct observation of `Array` object without index via `ModelBinding` (e.g. `ModelBinding.new(some_array)`)
11
+ - Support observing `Hash` attribute with `ModelBinding` (all keys or a single key)
12
+ - Disable `#ensure_hash_object_observer` in ObservableModel/ObservableHash/ObservableArray since it has performance implications and is not necessary
13
+ - Fix issue with `#ensure_array_object_observer` not receiving `recursive: true` option when updating value of an attribute in `ObservableArray`, `ObservableModel`, and `ObservableHash`
14
+
15
+ ### 2.4.1
16
+
17
+ - Support `recursive: [integer]` option for ObservableArray#add_observer for finite recursion
18
+
19
+ ### 2.4.0
20
+
21
+ - Support passing arbitrary options to `Observer` `#observe` (`#register`) method (not just properties, like `recursive: true` for example)
22
+ - Make observing nested arrays within an array optional with `recursive: true` option
23
+ - Make `Observer` `dependents` collection rely on Concurrent::Hash when available
24
+ - Fix `Observer` cleanup of registrations and dependents on `#deregister` (was not cleaning up everything because observables were changing `#hash` value on content change and slipping through the cracks as a result)
25
+
26
+ ### 2.3.0
27
+
28
+ - Have observing `ObservableArray` automatically notice if any values are nested arrays and observe them for micro-changes (recursively all the way down)
29
+
6
30
  ### 2.2.2
7
31
 
8
32
  - Support auto-notifying on `ObservableArray#replace` observed changes
data/README.md CHANGED
@@ -16,7 +16,7 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
16
16
 
17
17
  [**Glimmer**](https://rubygems.org/gems/glimmer) is a DSL (Domain-Specific Language) Framework that consists of two things:
18
18
  - [DSL Engine](#dsl-engine): enables building internal DSLs embedded in Ruby (e.g. for GUI, XML, or CSS).
19
- - [Data-Binding Library](#data-binding-library): enables synchronizing GUI with Model Attributes bidirectionally **(now with Shine syntax support in v2)**.
19
+ - [Data-Binding Library](#data-binding-library): enables synchronizing GUI with Model Attributes bidirectionally **(now with [Shine](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#shine) syntax support in v2)**.
20
20
 
21
21
  [**Glimmer**](https://rubygems.org/gems/glimmer) is ***the cream of the crop*** when it comes to building DSLs in Ruby:
22
22
  - Supports building the tersest most concise domain specific language syntax in Ruby.
@@ -32,10 +32,11 @@ Start by checking out Glimmer's original GUI DSL, which got extracted into its o
32
32
  [**Glimmer**](https://rubygems.org/gems/glimmer) supports the following DSLs:
33
33
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
34
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-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
36
- - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
37
35
  - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
38
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
39
40
 
40
41
  ## Table of Contents
41
42
 
@@ -47,10 +48,10 @@ Start by checking out Glimmer's original GUI DSL, which got extracted into its o
47
48
  - [Official DSLs](#official-dsls)
48
49
  - [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
49
50
  - [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)
50
- - [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
51
- - [Glimmer DSL for CSS](#glimmer-dsl-for-css)
52
51
  - [Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-mri-ruby-desktop-development-gui-library)
53
52
  - [Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)](#glimmer-dsl-for-libui-prerequisite-free-ruby-desktop-development-gui-library)
53
+ - [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
54
+ - [Glimmer DSL for CSS](#glimmer-dsl-for-css)
54
55
  - [Data-Binding Library](#data-binding-library)
55
56
  - [Glimmer Process](#glimmer-process)
56
57
  - [Resources](#resources)
@@ -71,13 +72,32 @@ Glimmer is fundamentally a DSL Engine that can support any number of DSLs like t
71
72
  Glimmer DSL syntax consists mainly of:
72
73
  - **keywords** (e.g. `table` for a table widget)
73
74
  - **style/args** (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
74
- - **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)
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)
76
+
77
+ Here is a Hello, World! example from [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt):
78
+
79
+ ```ruby
80
+ include Glimmer
81
+
82
+ shell(:no_resize) { # keyword + style arg
83
+ text "Glimmer" # attribute content
84
+
85
+ label { # keyword content
86
+ text "Hello, World!" # attribute content
87
+ }
88
+ }.open
89
+ ```
90
+
91
+ That code renders the following GUI (Graphical User Interface):
92
+
93
+ ![Hello World](images/glimmer-hello-world.png)
75
94
 
76
95
  The Glimmer DSL Engine's architecture is based on the following Design Patterns and Data Structures:
77
96
  - **Interpreter Design Pattern**: to define interpretable expressions of DSL keywords
78
97
  - **Chain of Responsibility Design Pattern / Queue Data Structure**: to chain expression handlers in order of importance for processing DSL keywords
79
98
  - **Adapter Design Pattern**: to adapt expressions into handlers in a chain of responsibility
80
99
  - **Stack Data Structure**: to handle processing parent/child nesting of DSL keyword expressions in the correct order
100
+ - **Proxy Design Pattern**: to shield consumers of GUI libraries built with Glimmer from low-level GUI widget details
81
101
 
82
102
  Glimmer's use of the **Interpreter Design Pattern** in processing DSLs is also known as the **Virtual Machine Architectural Style**. After all, DSL expressions are virtual machine opcodes that process nested keywords stored in a stack. I built Glimmer's original DSL back in 2007 without knowing the **Virtual Machine Architectural Style** (except perhaps as an esoteric technology powering Java), but stumbled upon it anyways through following the Gang of Four Design Patterns mentioned above, chiefly the **Interpreter Design Pattern**.
83
103
 
@@ -210,7 +230,7 @@ end
210
230
  ### Setup
211
231
 
212
232
  Follow these steps to author a [Glimmer](https://rubygems.org/gems/glimmer) DSL:
213
- - Add `gem 'glimmer', '~> 2.2.2'` to `Gemfile` and run `bundle` or run `gem install glimmer -v2.2.2` and add `require 'glimmer'`
233
+ - Add `gem 'glimmer', '~> 2.5.0'` to `Gemfile` and run `bundle` or run `gem install glimmer -v2.5.0` and add `require 'glimmer'`
214
234
  - 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)
215
235
  - Create `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb` for every [expresion_name] expression needed, whether dynamic or static
216
236
 
@@ -734,83 +754,6 @@ You should see "Apple Calculator Theme"
734
754
 
735
755
  [![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)
736
756
 
737
- #### Glimmer DSL for XML (& HTML)
738
-
739
- [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) provides Ruby syntax for building XML (eXtensible Markup Language) documents.
740
-
741
- Within the context of desktop development, Glimmer DSL for XML is useful in providing XML data for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
742
-
743
- ##### XML DSL
744
-
745
- Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
746
- Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
747
-
748
- Here are all the Glimmer XML DSL top-level keywords:
749
- - `html`
750
- - `tag`: enables custom tag creation for exceptional cases by passing tag name as '_name' attribute
751
- - `name_space`: enables namespacing html tags
752
-
753
- Element properties are typically passed as a key/value hash (e.g. `section(id: 'main', class: 'accordion')`) . However, for properties like "selected" or "checked", you must leave value `nil` or otherwise pass in front of the hash (e.g. `input(:checked, type: 'checkbox')` )
754
-
755
- Example (basic HTML):
756
-
757
- ```ruby
758
- @xml = html {
759
- head {
760
- meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
761
- }
762
- body {
763
- h1 { "Hello, World!" }
764
- }
765
- }
766
- puts @xml
767
- ```
768
-
769
- Output:
770
-
771
- ```
772
- <html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
773
- ```
774
-
775
- #### Glimmer DSL for CSS
776
-
777
- [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) provides Ruby syntax for building CSS (Cascading Style Sheets).
778
-
779
- Within the context of [Glimmer](https://github.com/AndyObtiva/glimmer) app development, Glimmer DSL for CSS is useful in providing CSS for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
780
-
781
- ##### CSS DSL
782
-
783
- Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
784
- Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
785
-
786
- `css` is the only top-level keyword in the Glimmer CSS DSL
787
-
788
- Selectors may be specified by `s` keyword or HTML element keyword directly (e.g. `body`)
789
- Rule property values may be specified by `pv` keyword or underscored property name directly (e.g. `font_size`)
790
-
791
- Example:
792
-
793
- ```ruby
794
- @css = css {
795
- body {
796
- font_size '1.1em'
797
- pv 'background', 'white'
798
- }
799
-
800
- s('body > h1') {
801
- background_color :red
802
- pv 'font-size', '2em'
803
- }
804
- }
805
- puts @css
806
- ```
807
-
808
- Output:
809
-
810
- ```
811
- body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2em}
812
- ```
813
-
814
757
  #### Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
815
758
 
816
759
  [Tcl/Tk](https://www.tcl.tk/) has evolved into a practical desktop GUI toolkit due to gaining truely native looking widgets on Mac, Windows, and Linux in [Tk version 8.5](https://www.tcl.tk/software/tcltk/8.5.html#:~:text=Highlights%20of%20Tk%208.5&text=Font%20rendering%3A%20Now%20uses%20anti,and%20window%20layout%2C%20and%20more.).
@@ -856,7 +799,7 @@ Glimmer app:
856
799
 
857
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)
858
801
 
859
- ###### Hello, Tab!
802
+ ###### Hello, Notebook!
860
803
 
861
804
  Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_tab.rb)):
862
805
 
@@ -864,7 +807,7 @@ Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/gl
864
807
  include Glimmer
865
808
 
866
809
  root {
867
- title 'Hello, Tab!'
810
+ title 'Hello, Notebook!'
868
811
 
869
812
  notebook {
870
813
  frame(text: 'English') {
@@ -885,48 +828,71 @@ root {
885
828
  Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
886
829
 
887
830
  ```
888
- ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_tab.rb'"
831
+ ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_notebook.rb'"
889
832
  ```
890
833
 
891
834
  Glimmer app:
892
835
 
893
- ![glimmer dsl tk screenshot sample hello tab English](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-tab-english.png)
894
- ![glimmer dsl tk screenshot sample hello tab French](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-tk/master/images/glimmer-dsl-tk-screenshot-sample-hello-tab-french.png)
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)
895
838
 
896
- ###### Hello, Combo!
839
+ ###### Hello, Combobox!
897
840
 
898
- Glimmer code (from [samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combo.rb)):
841
+ Glimmer code (from [samples/hello/hello_combobox.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combobox.rb)):
899
842
 
900
843
  ```ruby
901
- # ... more code precedes
902
- root {
903
- title 'Hello, Combo!'
904
-
905
- combobox { |proxy|
906
- state 'readonly'
907
- text bind(person, :country)
908
- }
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
909
861
 
910
- button { |proxy|
911
- text "Reset Selection"
912
- command {
913
- person.reset_country
914
- }
915
- }
916
- }.open
917
- # ... more code follows
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
918
884
  ```
919
885
 
920
886
  Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
921
887
 
922
888
  ```
923
- ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_combo.rb'"
889
+ ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_combobox.rb'"
924
890
  ```
925
891
 
926
892
  Glimmer app:
927
893
 
928
- ![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)
929
- ![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)
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)
930
896
 
931
897
  #### Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)
932
898
 
@@ -961,39 +927,13 @@ Mac
961
927
 
962
928
  ![glimmer-dsl-libui-mac-basic-window.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-mac-basic-window.png)
963
929
 
964
- Linux
965
-
966
- ![glimmer-dsl-libui-linux-basic-window.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-basic-window.png)
967
-
968
- ###### Basic Button
969
-
970
- ```ruby
971
- require 'glimmer-dsl-libui'
972
-
973
- include Glimmer
930
+ Windows
974
931
 
975
- window('hello world', 300, 200) {
976
- button('Button') {
977
- on_clicked do
978
- msg_box('Information', 'You clicked the button')
979
- end
980
- }
981
-
982
- on_closing do
983
- puts 'Bye Bye'
984
- end
985
- }.show
986
- ```
987
-
988
- Mac
989
-
990
- ![glimmer-dsl-libui-mac-basic-button.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-mac-basic-button.png)
991
- ![glimmer-dsl-libui-mac-basic-button-msg-box.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-mac-basic-button-msg-box.png)
932
+ ![glimmer-dsl-libui-windows-basic-window.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-windows-basic-window.png)
992
933
 
993
934
  Linux
994
935
 
995
- ![glimmer-dsl-libui-linux-basic-button.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-basic-button.png)
996
- ![glimmer-dsl-libui-linux-basic-button-msg-box.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-basic-button-msg-box.png)
936
+ ![glimmer-dsl-libui-linux-basic-window.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-basic-window.png)
997
937
 
998
938
  ###### Basic Table Progress Bar
999
939
 
@@ -1036,6 +976,10 @@ Mac
1036
976
 
1037
977
  ![glimmer-dsl-libui-mac-basic-table-progress-bar.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-mac-basic-table-progress-bar.png)
1038
978
 
979
+ Windows
980
+
981
+ ![glimmer-dsl-libui-windows-basic-table-progress-bar.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-windows-basic-table-progress-bar.png)
982
+
1039
983
  Linux
1040
984
 
1041
985
  ![glimmer-dsl-libui-linux-basic-table-progress-bar.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-basic-table-progress-bar.png)
@@ -1147,10 +1091,91 @@ Mac
1147
1091
 
1148
1092
  ![glimmer-dsl-libui-mac-area-gallery.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-mac-area-gallery.png)
1149
1093
 
1094
+ Windows
1095
+
1096
+ ![glimmer-dsl-libui-windows-area-gallery.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-windows-area-gallery.png)
1097
+
1150
1098
  Linux
1151
1099
 
1152
1100
  ![glimmer-dsl-libui-linux-area-gallery.png](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-libui/master/images/glimmer-dsl-libui-linux-area-gallery.png)
1153
1101
 
1102
+ #### Glimmer DSL for XML (& HTML)
1103
+
1104
+ [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) provides Ruby syntax for building XML (eXtensible Markup Language) documents.
1105
+
1106
+ Within the context of desktop development, Glimmer DSL for XML is useful in providing XML data for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
1107
+
1108
+ ##### XML DSL
1109
+
1110
+ Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
1111
+ Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
1112
+
1113
+ Here are all the Glimmer XML DSL top-level keywords:
1114
+ - `html`
1115
+ - `tag`: enables custom tag creation for exceptional cases by passing tag name as '_name' attribute
1116
+ - `name_space`: enables namespacing html tags
1117
+
1118
+ Element properties are typically passed as a key/value hash (e.g. `section(id: 'main', class: 'accordion')`) . However, for properties like "selected" or "checked", you must leave value `nil` or otherwise pass in front of the hash (e.g. `input(:checked, type: 'checkbox')` )
1119
+
1120
+ Example (basic HTML):
1121
+
1122
+ ```ruby
1123
+ @xml = html {
1124
+ head {
1125
+ meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
1126
+ }
1127
+ body {
1128
+ h1 { "Hello, World!" }
1129
+ }
1130
+ }
1131
+ puts @xml
1132
+ ```
1133
+
1134
+ Output:
1135
+
1136
+ ```
1137
+ <html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
1138
+ ```
1139
+
1140
+ #### Glimmer DSL for CSS
1141
+
1142
+ [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) provides Ruby syntax for building CSS (Cascading Style Sheets).
1143
+
1144
+ Within the context of [Glimmer](https://github.com/AndyObtiva/glimmer) app development, Glimmer DSL for CSS is useful in providing CSS for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
1145
+
1146
+ ##### CSS DSL
1147
+
1148
+ Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
1149
+ Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
1150
+
1151
+ `css` is the only top-level keyword in the Glimmer CSS DSL
1152
+
1153
+ Selectors may be specified by `s` keyword or HTML element keyword directly (e.g. `body`)
1154
+ Rule property values may be specified by `pv` keyword or underscored property name directly (e.g. `font_size`)
1155
+
1156
+ Example:
1157
+
1158
+ ```ruby
1159
+ @css = css {
1160
+ body {
1161
+ font_size '1.1em'
1162
+ pv 'background', 'white'
1163
+ }
1164
+
1165
+ s('body > h1') {
1166
+ background_color :red
1167
+ pv 'font-size', '2em'
1168
+ }
1169
+ }
1170
+ puts @css
1171
+ ```
1172
+
1173
+ Output:
1174
+
1175
+ ```
1176
+ body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2em}
1177
+ ```
1178
+
1154
1179
  ## Data-Binding Library
1155
1180
 
1156
1181
  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.
@@ -1162,13 +1187,77 @@ This relies mainly on the Observer Design Pattern and the MVP (Model-View-Presen
1162
1187
  These are the main classes concerning data-binding:
1163
1188
  - `Glimmer::DataBinding::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`)
1164
1189
  - `Glimmer::DataBinding::Observable`: General super-module for all observables. Main methods concerned are: `add_observer` and `remove_observer`
1165
- - `Glimmer::DataBinding::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.
1166
- - `Glimmer::DataBinding::ObservableArray`: Mixin module for any observable array collection that automatically handles notifying observers upon performing array mutation operations (e.g. `push`, `select!`, or `delete`)
1167
- - `Glimmer::DataBinding::ObservableHash`: Mixin module for any observable hash that automatically handles notifying observers upon performing hash mutation operations (e.g. `hash[key]=value`, `select!`, `merge!`)
1190
+ - `Glimmer::DataBinding::ObservableModel`: Mixin module for any observable model (`Object`, `Struct` or `OpenStruct`) with observable attributes (observes attribute writers and `Struct`/`OpenStruct` `:[]=` method). 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.
1191
+ - `Glimmer::DataBinding::ObservableArray`: Mixin module for any observable array collection that automatically handles notifying observers upon performing array mutation operations (e.g. `push`, `select!`, or `delete`) recursively (meaning if an array contained arrays and they changed, observers are notified). Accepts `recursive: true` option in `add_observer` method to recursively observe nested arrays all the way down. Alternatively, pass `recursive: [integer]` to limit recursion in `Array` observation to a specific number of levels beyond the first level (which is always included).
1192
+ - `Glimmer::DataBinding::ObservableHash`: Mixin module for any observable hash that automatically handles notifying observers upon performing hash mutation operations (e.g. `hash[key]=value`, `select!`, `merge!`). Also, it automatically handles observing array values using `ObservableArray` appropriately so they would notify observers upon array mutation changes.
1168
1193
  - `Glimmer::DataBinding::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
1169
1194
  - `Glimmer::DataBinding::Shine`: enables highly intuitive and visually expressive syntax to perform bidirectional (two-way) data-binding with `<=>` and unidirectional (one-way) data-binding with `<=`
1170
1195
 
1171
- You may learn more from [Data-Binding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#data-binding) and [Observer](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#observer) usage in [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)
1196
+ To do simple observation of models, arrays, or hashes, you can use the `Glimmer::DataBinding::Observer::proc` method, which builds an observer from a block. When invoking the `#observe` method on it, it automatically enhances the object argument being observed into an `Observable` (whether `ObservableModel`, `ObservableArray`, or `ObervableHash`).
1197
+
1198
+ Example of observing a model attribute:
1199
+
1200
+ ```ruby
1201
+ Glimmer::DataBinding::Observer.proc do |new_value|
1202
+ # Do some work with new value for model attribute
1203
+ end.observe(model, attribute)
1204
+ ```
1205
+
1206
+ Example of observing an array recursively (avoid recursion unless really needed since it fires on all fine-grained nested array changes):
1207
+
1208
+ ```ruby
1209
+ Glimmer::DataBinding::Observer.proc do |new_value|
1210
+ # Do some work with new array value
1211
+ end.observe(array, recursive: true)
1212
+ ```
1213
+
1214
+ Example of observing a hash key:
1215
+
1216
+ ```ruby
1217
+ Glimmer::DataBinding::Observer.proc do |new_value|
1218
+ # Do some work with new value for hash key
1219
+ end.observe(hash, :price)
1220
+ ```
1221
+
1222
+ Example of observing a hash for all key changes:
1223
+
1224
+ ```ruby
1225
+ Glimmer::DataBinding::Observer.proc do |new_value, changed_key|
1226
+ # Do some work with new value and changed key for hash
1227
+ end.observe(hash)
1228
+ ```
1229
+
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.
1231
+
1232
+ Example of observing nested model attributes:
1233
+
1234
+ ```ruby
1235
+ ModelBinding.new(model, "address1.street").add_observer do |new_address1_street_value|
1236
+ # Do some work with new address 1 street value
1237
+ end
1238
+ ```
1239
+
1240
+ Example of observing indexed array changes (combined with a nested model attribute):
1241
+
1242
+ ```ruby
1243
+ ModelBinding.new(model, "employees[5].name").add_observer do |new_employee_6_name|
1244
+ # Do some work with new employee 6 (index 5)'s name
1245
+ end
1246
+ ```
1247
+
1248
+ Example of observing double-indexed nested array changes:
1249
+
1250
+ ```ruby
1251
+ ModelBinding.new(model, "grid[5][7]").add_observer do |new_grid_cell_value|
1252
+ # Do some work with new grid cell value for row index 5 and column index 7
1253
+ end
1254
+ ```
1255
+
1256
+ Note that if an observed model attribute or hash key is an array, it is automatically observed for array changes, not just attribute/key-value changes.
1257
+
1258
+ All of the features above make Glimmer's data-binding library one of the most sophisticated and advanced in the industry since it automates everything instead of requiring endless manual configuration, thus resulting in some of the tersest most declarative syntax for using observers and data-binding.
1259
+
1260
+ You may learn more by looking into [data-binding specs](/Users/andy/code/glimmer/spec/lib/glimmer/data_binding) as well as [Data-Binding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#data-binding) and [Observer](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#observer) usage in [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)
1172
1261
 
1173
1262
  ## Glimmer Process
1174
1263
 
@@ -1221,8 +1310,9 @@ If you would like to contribute to Glimmer, please study up on Glimmer and [SWT]
1221
1310
 
1222
1311
  You may apply for contributing to any of these Glimmer DSL gems whether you prefer to focus on the desktop or web:
1223
1312
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
1224
- - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
1225
1313
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
1314
+ - [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
1315
+ - [glimmer-dsl-libui](https://github.com/AndyObtiva/glimmer-dsl-libui): Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)
1226
1316
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
1227
1317
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS
1228
1318
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.5.0
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.2.2 ruby lib
5
+ # stub: glimmer 2.5.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer".freeze
9
- s.version = "2.2.2"
9
+ s.version = "2.5.0"
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 = "2021-10-03"
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 ObservableModel, ObservableArray, and ObservableHash). 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
14
+ s.date = "2021-11-19"
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
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "CHANGELOG.md",
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  "lib/glimmer/data_binding/observable.rb",
34
34
  "lib/glimmer/data_binding/observable_array.rb",
35
35
  "lib/glimmer/data_binding/observable_hash.rb",
36
+ "lib/glimmer/data_binding/observable_hashable.rb",
36
37
  "lib/glimmer/data_binding/observable_model.rb",
37
38
  "lib/glimmer/data_binding/observer.rb",
38
39
  "lib/glimmer/data_binding/shine.rb",
@@ -51,7 +52,7 @@ Gem::Specification.new do |s|
51
52
  ]
52
53
  s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
53
54
  s.licenses = ["MIT".freeze]
54
- s.rubygems_version = "3.2.28".freeze
55
+ s.rubygems_version = "3.2.31".freeze
55
56
  s.summary = "Glimmer - DSL Engine for Ruby GUI and More".freeze
56
57
 
57
58
  if s.respond_to? :specification_version then
@@ -70,7 +71,7 @@ Gem::Specification.new do |s|
70
71
  s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
71
72
  s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
72
73
  s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
73
- s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
74
+ s.add_development_dependency(%q<rake-tui>.freeze, ["> 0"])
74
75
  else
75
76
  s.add_dependency(%q<array_include_methods>.freeze, ["~> 1.4.0"])
76
77
  s.add_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
@@ -83,7 +84,7 @@ Gem::Specification.new do |s|
83
84
  s.add_dependency(%q<coveralls>.freeze, [">= 0"])
84
85
  s.add_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
85
86
  s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
86
- s.add_dependency(%q<rake-tui>.freeze, [">= 0"])
87
+ s.add_dependency(%q<rake-tui>.freeze, ["> 0"])
87
88
  end
88
89
  end
89
90