glimmer 1.1.1 → 1.1.2

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: 8406be710971b09333b5620c761f4f2e8f462386f97c4921f945947ad6592967
4
- data.tar.gz: b10c91c73e32356c3a8de92ad19f8364e2b1005fab08a0acc34db42bedadcdb3
3
+ metadata.gz: 9d0de24c574be6e42a7cade68606d7dace341333cd2922307d15aee307f77a42
4
+ data.tar.gz: 3ae8fe64ba1fc958bca990d13c02966101f7eef91b03d60ddf28cd6f406b1af8
5
5
  SHA512:
6
- metadata.gz: da71f67bc904f0141492508e3f084386e98bf4a148d24431672bbe96154dab20a08458cc64f647c1ea3d8204e0278d236917568f12b43c50e68e5a05b67304a0
7
- data.tar.gz: 1d28c8c659c5a10621085e719586b0e096d17538550b868beb9fc1f31a2ddfa09093ee7832a420c00d0ebd81d5ff3c40f8730d6c96defebbc351c19e1aa6f38e
6
+ metadata.gz: 3ea0f3c6733f9274b06067f6e3888a017f4ff4a7bf99b5c446f4cadf38eb705b6ddbc1f76a2b0e2d4ee9e6620626f07069d2c4ff199b682f7be38fda1a6d6749
7
+ data.tar.gz: 5ae1155117530b0e3808000057fae31a5ee5345dbc8fc28b4eae797d916d72ec1c7c643e2f314f8ffcb26121d33a7dc43080a2d30639ded865bb90c4a2bfbebc
data/CHANGELOG.md CHANGED
@@ -3,6 +3,11 @@
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.1.2
7
+
8
+ - Add more logging for which DSL is assumed before interpreting expressions
9
+ - Switch DSL Engine puts statement to a log statement for the error about no DSLs available
10
+
6
11
  ## 1.1.1
7
12
 
8
13
  - Ensured after_read hook truly happens after notifying observers in ModelBinding
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  **[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
9
9
 
10
- **(The Original Glimmer Library Since 2007. Beware of Imitators!)**
10
+ **(The Original Glimmer Library Handling the World’s Ruby GUI Needs Since 2007. Beware of Imitators!)**
11
11
 
12
12
  [**Glimmer**](https://rubygems.org/gems/glimmer) started out as a [GUI Library](https://github.com/AndyObtiva/glimmer-dsl-swt) and grew into a full-fledged [DSL Framework](#dsl-engine) with support for multiple GUI DSLs. Glimmer's namesake is referring to the Glimmer of Ruby in Graphical User Interfaces (contrary to [popular myth](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)
13
13
 
@@ -39,14 +39,16 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
39
39
  ## Table of Contents
40
40
 
41
41
  - [Glimmer](#-glimmer---dsl-framework-for-ruby-gui-and-more)
42
- - [Official DSLs](#official-dsls)
43
- - [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
44
- - [Glimmer DSL for 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)
45
- - [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
46
- - [Glimmer DSL for CSS](#glimmer-dsl-for-css)
47
- - [Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-mri-ruby-desktop-development-gui-library)
48
42
  - [DSL Engine](#dsl-engine)
43
+ - [Setup](#setup)
44
+ - [Configuration](#configuration)
49
45
  - [Multi-DSL Support](#multi-dsl-support)
46
+ - [Official DSLs](#official-dsls)
47
+ - [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](#glimmer-dsl-for-swt-jruby-desktop-development-gui-framework)
48
+ - [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)
49
+ - [Glimmer DSL for XML (& HTML)](#glimmer-dsl-for-xml--html)
50
+ - [Glimmer DSL for CSS](#glimmer-dsl-for-css)
51
+ - [Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)](#glimmer-dsl-for-tk-mri-ruby-desktop-development-gui-library)
50
52
  - [Data-Binding Library](#data-binding-library)
51
53
  - [Glimmer Process](#glimmer-process)
52
54
  - [Resources](#resources)
@@ -60,21 +62,298 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
60
62
  - [Hire Me](#hire-me)
61
63
  - [License](#license)
62
64
 
63
- ## Official DSLs
65
+ ## DSL Engine
66
+
67
+ 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.
68
+
69
+ Glimmer DSL syntax consists mainly of:
70
+ - **keywords** (e.g. `table` for a table widget)
71
+ - **style/args** (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
72
+ - **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)
73
+
74
+ The Glimmer DSL Engine's architecture is based on the following Design Patterns and Data Structures:
75
+ - **Interpreter Design Pattern**: to define interpretable expressions of DSL keywords
76
+ - **Chain of Responsibility Design Pattern / Queue Data Structure**: to chain expression handlers in order of importance for processing DSL keywords
77
+ - **Adapter Design Pattern**: to adapt expressions into handlers in a chain of responsibility
78
+ - **Stack Data Structure**: to handle processing parent/child nesting of DSL keyword expressions in the correct order
79
+
80
+ 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**.
81
+
82
+ 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)`.
83
+
84
+ Expressions are either:
85
+ - **Static** (subclass of `StaticExpression`, which is a subclass of `Expression`): if they represent a single pre-identified keyword (e.g. `color` or `display`)
86
+ - **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>`)
87
+
88
+ Optionally, expressions can be parent expressions that contain other expressions, and must include the `ParentExpression` mixin module as such.
89
+
90
+ Additionally, every expression that serves as a top-level entry point into the DSL must mixin `TopLevelExpression`
91
+
92
+ 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.
93
+
94
+ Every `Expression` sublcass must specify two methods at least:
95
+ - `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.
96
+ - `interpret(parent, keyword, *args, &block)`: to go ahead and interpret a DSL expression that qualified for interpretation
97
+
98
+ `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.
99
+
100
+ `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:
101
+ - `add_content(parent, &block)`
102
+
103
+ 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.
104
+
105
+ Example of a dynamic expression:
106
+
107
+ ```ruby
108
+ module Glimmer
109
+ module DSL
110
+ module SWT
111
+ class WidgetExpression < Expression
112
+ include ParentExpression
113
+
114
+ EXCLUDED_KEYWORDS = %w[shell display tab_item]
115
+
116
+ def can_interpret?(parent, keyword, *args, &block)
117
+ !EXCLUDED_KEYWORDS.include?(keyword) and
118
+ parent.respond_to?(:swt_widget) and
119
+ Glimmer::SWT::WidgetProxy.widget_exists?(keyword)
120
+ end
121
+
122
+ def interpret(parent, keyword, *args, &block)
123
+ Glimmer::SWT::WidgetProxy.create(keyword, parent, args)
124
+ end
125
+
126
+ def add_content(parent, &block)
127
+ super
128
+ parent.post_add_content
129
+ end
130
+
131
+ end
132
+ end
133
+ end
134
+ end
135
+ ```
136
+
137
+ Example of a static expression (does not need `can_interpret?`):
138
+
139
+ ```ruby
140
+ module Glimmer
141
+ module DSL
142
+ module Opal
143
+ class ColorExpression < StaticExpression
144
+ include TopLevelExpression
145
+
146
+ def interpret(parent, keyword, *args, &block)
147
+ Glimmer::SWT::ColorProxy.new(*args)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ ```
154
+
155
+ DSL expressions go into the `glimmer/dsl/{dsl_name}` namespace directory.
156
+
157
+ Also, every DSL requires a `glimmer/dsl/{dsl_name}/dsl.rb` file, which configures the DSL into Glimmer via a call to:
158
+ ```ruby
159
+ Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)
160
+ ```
161
+
162
+ Expression names are underscored verions of `Expression` subclass names minus the `_expression` suffix.
163
+
164
+ For example, here is an SWT DSL configuration:
165
+
166
+ ```ruby
167
+ require 'glimmer/launcher'
168
+ require Glimmer::Launcher.swt_jar_file
169
+ require 'glimmer/dsl/engine'
170
+ Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
171
+
172
+ module Glimmer
173
+ module DSL
174
+ module SWT
175
+ Engine.add_dynamic_expressions(
176
+ SWT,
177
+ %w[
178
+ layout
179
+ widget_listener
180
+ combo_selection_data_binding
181
+ checkbox_group_selection_data_binding
182
+ radio_group_selection_data_binding
183
+ list_selection_data_binding
184
+ tree_items_data_binding
185
+ table_items_data_binding
186
+ data_binding
187
+ cursor
188
+ font
189
+ image
190
+ property
191
+ block_property
192
+ widget
193
+ custom_widget
194
+ ]
195
+ )
196
+ end
197
+ end
198
+ end
199
+ ```
200
+
201
+ ### Setup
202
+
203
+ Follow these steps to author a [Glimmer](https://rubygems.org/gems/glimmer) DSL:
204
+ - Add `gem 'glimmer', '~> 1.1.2'` to `Gemfile` and run `bundle` or run `gem install glimmer -v1.1.2` and add `require 'glimmer'`
205
+ - 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)
206
+ - Create `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb` for every [expresion_name] expression needed, whether dynamic or static
207
+
208
+ ### Configuration
209
+
210
+ Glimmer configuration may be done via the [`Glimmer::Config`](https://github.com/AndyObtiva/glimmer/blob/master/lib/glimmer/config.rb) module.
211
+
212
+ #### logger
213
+
214
+ The Glimmer DSL engine supports logging via a standard `STDOUT` Ruby `Logger` configured in the `Glimmer::Config.logger` config option.
215
+ It is set to level Logger::ERROR by default.
216
+ Log level may be adjusted via `Glimmer::Config.logger.level` just like any other Ruby Logger.
217
+
218
+ Example:
219
+
220
+ ```ruby
221
+ Glimmer::Config.logger.level = :debug
222
+ ```
223
+ This results in more verbose debug loggging to `STDOUT`, which is very helpful in troubleshooting Glimmer DSL syntax when needed.
224
+
225
+ Example log:
226
+ ```
227
+ D, [2017-07-21T19:23:12.587870 #35707] DEBUG -- : method: shell and args: []
228
+ D, [2017-07-21T19:23:12.594405 #35707] DEBUG -- : ShellCommandHandler will handle command: shell with arguments []
229
+ D, [2017-07-21T19:23:12.844775 #35707] DEBUG -- : method: composite and args: []
230
+ D, [2017-07-21T19:23:12.845388 #35707] DEBUG -- : parent is a widget: true
231
+ D, [2017-07-21T19:23:12.845833 #35707] DEBUG -- : on listener?: false
232
+ D, [2017-07-21T19:23:12.864395 #35707] DEBUG -- : WidgetCommandHandler will handle command: composite with arguments []
233
+ D, [2017-07-21T19:23:12.864893 #35707] DEBUG -- : widget styles are: []
234
+ D, [2017-07-21T19:23:12.874296 #35707] DEBUG -- : method: list and args: [:multi]
235
+ D, [2017-07-21T19:23:12.874969 #35707] DEBUG -- : parent is a widget: true
236
+ D, [2017-07-21T19:23:12.875452 #35707] DEBUG -- : on listener?: false
237
+ D, [2017-07-21T19:23:12.878434 #35707] DEBUG -- : WidgetCommandHandler will handle command: list with arguments [:multi]
238
+ D, [2017-07-21T19:23:12.878798 #35707] DEBUG -- : widget styles are: [:multi]
239
+ ```
240
+
241
+ The `logger` instance may be replaced with a custom logger via `Glimmer::Config.logger = custom_logger`
242
+
243
+ To reset `logger` to the default instance, you may call `Glimmer::Config.reset_logger!`
244
+
245
+ All logging is done lazily via blocks (e.g. `logger.debug {message}`) to avoid affecting app performance with logging when below the configured logging level threshold.
246
+
247
+ [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) enhances Glimmer default logging support via the Ruby [`logging`](https://github.com/TwP/logging) gem, enabling buffered asynchronous logging in a separate thread, thus completely unhindering normal desktop app performance.
248
+
249
+ #### loop_max_count
250
+
251
+ Glimmer has infinite loop detection support.
252
+ It can detect when an infinite loop is about to occur in method_missing and stops it.
253
+ It detects potential infinite loops when the same keyword and args repeat more than 100 times, which is unusual in a GUI app.
254
+
255
+ The max limit can be changed via the `Glimmer::Config::loop_max_count=(count)` config option.
256
+
257
+ Infinite loop detection may be disabled altogether if needed by setting `Glimmer::Config::loop_max_count` to `-1`
258
+
259
+ #### excluded_keyword_checkers
260
+
261
+ Glimmer permits consumers to exclude keywords from DSL processing by its engine via the `excluded_keyword_checkers` config option.
262
+
263
+ To do so, add a proc to it that returns a boolean indicating if a keyword is excluded or not.
264
+
265
+ Note that this proc runs within the context of the Glimmer object (as in the object mixing in the Glimmer module), so checker can can pretend to run there with its `self` object assumption.
266
+
267
+ Example of keywords excluded by [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt):
268
+
269
+ ```ruby
270
+ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
271
+ method = method_symbol.to_s
272
+ result = false
273
+ result ||= method.start_with?('on_swt_') && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
274
+ result ||= method == 'dispose' && is_a?(Glimmer::UI::CustomWidget) && respond_to?(method)
275
+ result ||= ['drag_source_proxy', 'drop_target_proxy'].include?(method) && is_a?(Glimmer::UI::CustomWidget)
276
+ result ||= method == 'post_initialize_child'
277
+ result ||= method.end_with?('=')
278
+ result ||= ['finish_edit!', 'search', 'all_tree_items', 'depth_first_search'].include?(method) && is_a?(Glimmer::UI::CustomWidget) && body_root.respond_to?(method)
279
+ end
280
+ ```
281
+
282
+ #### log_excluded_keywords
283
+
284
+ (default = false)
285
+
286
+ This just tells Glimmer whether to log excluded keywords or not (at the debug level). It is off by default.
287
+
288
+
289
+ ### Multi-DSL Support
290
+
291
+ The Glimmer [DSL Engine](#dsl-engine) allows mixing DSLs, which comes in handy when doing things like rendering a desktop GUI DSL `browser` widget additionally leveraging the HTML DSL and CSS DSL for its content.
292
+
293
+ DSLs are activated by top-level keywords (expressions denoted as `TopLevelExpression`). For example, the `html` keyword activates the [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and the `css` keyword activates the [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css). Glimmer automatically recognizes top-level keywords in each DSL and activates the DSL accordingly. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
294
+
295
+ By default, all loaded DSLs (required glimmer DSL gems) are enabled.
296
+
297
+ For example, this shows "Hello, World!" inside a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app `browser` widget using `html` and `css` from [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css):
298
+
299
+ ```ruby
300
+ require 'glimmer-dsl-swt'
301
+ require 'glimmer-dsl-xml'
302
+ require 'glimmer-dsl-css'
303
+
304
+ include Glimmer
305
+
306
+ shell {
307
+ minimum_size 130, 130
308
+ @browser = browser {
309
+ text html {
310
+ head {
311
+ meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
312
+ style {
313
+ css {
314
+ h1 {
315
+ background 'yellow'
316
+ }
317
+ }
318
+ }
319
+ }
320
+ body {
321
+ h1 { "Hello, World!" }
322
+ }
323
+ }
324
+ }
325
+ }.open
326
+ ```
327
+
328
+ **API methods to enable/disable DSLs:**
329
+
330
+ `Glimmer::DSL::Engine.disable_dsl(dsl)`: disables a particular DSL
331
+
332
+ Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
333
+
334
+ `Glimmer::DSL::Engine.enable_dsl(dsl)`: enables a particular DSL
335
+
336
+ Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
337
+
338
+ `Glimmer::DSL::Engine.enabled_dsls=(dsls)`: enables only the specified DSLs, disabling all other loaded DSLs
339
+
340
+ Example: `Glimmer::DSL::Engine.enabled_dsls = [:xml, :css]`
341
+
342
+ ### Official DSLs
64
343
 
65
344
  Here, we showcase official Glimmer DSLs; that is [gems starting with the `glimmer-dsl-` prefix](https://rubygems.org/search?query=glimmer-dsl-).
66
345
 
67
346
  (you can skip ahead if you prefer to learn more about the Glimmer [DSL Engine](#dsl-engine) or [Data-Binding Library](#data-binding-library) first)
68
347
 
69
- ### Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
348
+ #### Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
70
349
 
71
350
  [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://rubygems.org/gems/glimmer)'s main innovation is a declarative [Ruby DSL](https://github.com/AndyObtiva/glimmer-dsl-swt#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) additionally innovates by having built-in [data-binding](https://github.com/AndyObtiva/glimmer-dsl-swt#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. To get started quickly, [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) offers [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt#scaffolding) options for [Apps](https://github.com/AndyObtiva/glimmer-dsl-swt#in-production), [Gems](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-shell-gem), and [Custom Widgets](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-widgets). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) also includes native-executable [packaging](https://github.com/AndyObtiva/glimmer-dsl-swt#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/) and MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows).
72
351
 
73
352
  To get started, visit the [Glimmer DSL for SWT project page](https://github.com/AndyObtiva/glimmer-dsl-swt#pre-requisites) for instructions on installing the [glimmer-dsl-swt gem](https://rubygems.org/gems/glimmer-dsl-swt).
74
353
 
75
- #### Glimmer DSL for SWT Samples
354
+ ##### Glimmer DSL for SWT Samples
76
355
 
77
- ##### Hello, World!
356
+ ###### Hello, World!
78
357
 
79
358
  ![Hello World](images/glimmer-hello-world.png)
80
359
 
@@ -90,7 +369,7 @@ shell {
90
369
  }.open
91
370
  ```
92
371
 
93
- ##### Glimmer Tetris
372
+ ###### Glimmer Tetris
94
373
 
95
374
  ![Tetris](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-swt/v4.18.3.1/images/glimmer-tetris.png)
96
375
 
@@ -118,15 +397,11 @@ Glimmer GUI code (from [samples/elaborate/tetris.rb](https://github.com/AndyObti
118
397
  score_lane(game: game, block_size: BLOCK_SIZE) {
119
398
  layout_data(:fill, :fill, true, true)
120
399
  }
121
-
122
- on_widget_disposed {
123
- deregister_observers
124
- }
125
400
  }
126
401
  # ...
127
402
  ```
128
403
 
129
- ##### Hello, Table!
404
+ ###### Hello, Table!
130
405
 
131
406
  ![Hello Table](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-swt/master/images/glimmer-hello-table.png)
132
407
 
@@ -225,7 +500,7 @@ Glimmer GUI code (from [samples/hello/hello_table.rb](https://github.com/AndyObt
225
500
  # ...
226
501
  ```
227
502
 
228
- #### Production Desktop Apps Built with Glimmer DSL for SWT
503
+ ##### Production Desktop Apps Built with Glimmer DSL for SWT
229
504
 
230
505
  [<img alt="Are We There Yet Logo" src="https://raw.githubusercontent.com/AndyObtiva/are-we-there-yet/master/are-we-there-yet-logo.svg" width="40" />Are We There Yet?](https://github.com/AndyObtiva/are-we-there-yet) - Small Project Tracking App
231
506
 
@@ -239,7 +514,7 @@ Glimmer GUI code (from [samples/hello/hello_table.rb](https://github.com/AndyObt
239
514
 
240
515
  [![Garderie Rainbow Daily Agenda App Screenshot](https://raw.githubusercontent.com/AndyObtiva/garderie_rainbow_daily_agenda/master/images/garderie_rainbow_daily_agenda_screenshot.png)](https://github.com/AndyObtiva/garderie_rainbow_daily_agenda)
241
516
 
242
- ### Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
517
+ #### Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
243
518
 
244
519
  [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.
245
520
 
@@ -247,9 +522,9 @@ Glimmer DSL for Opal webifier successfully reuses the entire [Glimmer](https://g
247
522
 
248
523
  To get started, visit the [Glimmer DSL for Opal project page](https://github.com/AndyObtiva/glimmer-dsl-opal) for instructions on installing the [glimmer-dsl-opal gem](https://rubygems.org/gems/glimmer-dsl-opal).
249
524
 
250
- #### Glimmer DSL for Opal Samples
525
+ ##### Glimmer DSL for Opal Samples
251
526
 
252
- ##### Hello, Computed!
527
+ ###### Hello, Computed!
253
528
 
254
529
  Add the following require statement to `app/assets/javascripts/application.rb`
255
530
 
@@ -368,7 +643,7 @@ You should see "Hello, Computed!"
368
643
 
369
644
  ![Glimmer DSL for Opal Hello Computed](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-opal/master/images/glimmer-dsl-opal-hello-computed.png)
370
645
 
371
- ##### Glimmer Calculator
646
+ ###### Glimmer Calculator
372
647
 
373
648
  Add the [glimmer-cs-calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) gem to `Gemfile` (without requiring):
374
649
 
@@ -385,6 +660,7 @@ require 'glimmer-cs-calculator/launch'
385
660
  Sample GUI code (relies on custom widgets `command_button`, `operation_button`, and `number_button`):
386
661
 
387
662
  ```ruby
663
+ # ...
388
664
  shell {
389
665
  minimum_size (OS.mac? ? 320 : (OS.windows? ? 390 : 520)), 240
390
666
  image File.join(APP_ROOT, 'package', 'windows', "Glimmer Calculator.ico") if OS.windows?
@@ -403,9 +679,9 @@ shell {
403
679
  caret nil
404
680
  }
405
681
  command_button('AC')
406
- operation_button('÷')
407
- operation_button('�')
408
- operation_button('−')
682
+ operation_button('÷')
683
+ operation_button('×')
684
+ operation_button('')
409
685
  (7..9).each { |number|
410
686
  number_button(number)
411
687
  }
@@ -420,6 +696,7 @@ shell {
420
696
  number_button(0, horizontal_span: 2)
421
697
  operation_button('.')
422
698
  }
699
+ # ...
423
700
  ```
424
701
 
425
702
  Glimmer app on the desktop (using the [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
@@ -448,13 +725,13 @@ You should see "Apple Calculator Theme"
448
725
 
449
726
  [![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)
450
727
 
451
- ### Glimmer DSL for XML (& HTML)
728
+ #### Glimmer DSL for XML (& HTML)
452
729
 
453
730
  [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) provides Ruby syntax for building XML (eXtensible Markup Language) documents.
454
731
 
455
732
  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).
456
733
 
457
- #### XML DSL
734
+ ##### XML DSL
458
735
 
459
736
  Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
460
737
  Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
@@ -486,13 +763,13 @@ Output:
486
763
  <html><head><meta name="viewport" content="width=device-width, initial-scale=2.0" /></head><body><h1>Hello, World!</h1></body></html>
487
764
  ```
488
765
 
489
- ### Glimmer DSL for CSS
766
+ #### Glimmer DSL for CSS
490
767
 
491
768
  [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) provides Ruby syntax for building CSS (Cascading Style Sheets).
492
769
 
493
770
  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).
494
771
 
495
- #### CSS DSL
772
+ ##### CSS DSL
496
773
 
497
774
  Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
498
775
  Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
@@ -525,7 +802,7 @@ Output:
525
802
  body{font-size:1.1em;background:white}body > h1{background-color:red;font-size:2em}
526
803
  ```
527
804
 
528
- ### Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
805
+ #### Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library)
529
806
 
530
807
  [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.).
531
808
 
@@ -544,9 +821,9 @@ The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a pleth
544
821
 
545
822
  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).
546
823
 
547
- #### Glimmer DSL for Tk Samples
824
+ ##### Glimmer DSL for Tk Samples
548
825
 
549
- ##### Hello, World!
826
+ ###### Hello, World!
550
827
 
551
828
  Glimmer code (from [samples/hello/hello_world.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_world.rb)):
552
829
 
@@ -570,7 +847,7 @@ Glimmer app:
570
847
 
571
848
  ![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)
572
849
 
573
- ##### Hello, Tab!
850
+ ###### Hello, Tab!
574
851
 
575
852
  Glimmer code (from [samples/hello/hello_tab.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_tab.rb)):
576
853
 
@@ -607,7 +884,7 @@ Glimmer app:
607
884
  ![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)
608
885
  ![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)
609
886
 
610
- ##### Hello, Combo!
887
+ ###### Hello, Combo!
611
888
 
612
889
  Glimmer code (from [samples/hello/hello_combo.rb](https://github.com/AndyObtiva/glimmer-dsl-tk/blob/master/samples/hello/hello_combo.rb)):
613
890
 
@@ -642,199 +919,6 @@ Glimmer app:
642
919
  ![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)
643
920
  ![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)
644
921
 
645
- ## DSL Engine
646
-
647
- 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.
648
-
649
- Glimmer DSL syntax consists mainly of:
650
- - **keywords** (e.g. `table` for a table widget)
651
- - **style/args** (e.g. :multi as in `table(:multi)` for a multi-line selection table widget)
652
- - **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)
653
-
654
- The Glimmer DSL Engine's architecture is based on the following Design Patterns and Data Structures:
655
- - **Interpreter Design Pattern**: to define interpretable expressions of DSL keywords
656
- - **Chain of Responsibility Design Pattern / Queue Data Structure**: to chain expression handlers in order of importance for processing DSL keywords
657
- - **Adapter Design Pattern**: to adapt expressions into handlers in a chain of responsibility
658
- - **Stack Data Structure**: to handle processing parent/child nesting of DSL keyword expressions in the correct order
659
-
660
- 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**.
661
-
662
- 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)`.
663
-
664
- Expressions are either:
665
- - **Static** (subclass of `StaticExpression`, which is a subclass of `Expression`): if they represent a single pre-identified keyword (e.g. `color` or `display`)
666
- - **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>`)
667
-
668
- Optionally, expressions can be parent expressions that contain other expressions, and must include the `ParentExpression` mixin module as such.
669
-
670
- Additionally, every expression that serves as a top-level entry point into the DSL must mixin `TopLevelExpression`
671
-
672
- 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.
673
-
674
- Every `Expression` sublcass must specify two methods at least:
675
- - `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.
676
- - `interpret(parent, keyword, *args, &block)`: to go ahead and interpret a DSL expression that qualified for interpretation
677
-
678
- `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.
679
-
680
- `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:
681
- - `add_content(parent, &block)`
682
-
683
- 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.
684
-
685
- Example of a dynamic expression:
686
-
687
- ```ruby
688
- module Glimmer
689
- module DSL
690
- module SWT
691
- class WidgetExpression < Expression
692
- include ParentExpression
693
-
694
- EXCLUDED_KEYWORDS = %w[shell display tab_item]
695
-
696
- def can_interpret?(parent, keyword, *args, &block)
697
- !EXCLUDED_KEYWORDS.include?(keyword) and
698
- parent.respond_to?(:swt_widget) and
699
- Glimmer::SWT::WidgetProxy.widget_exists?(keyword)
700
- end
701
-
702
- def interpret(parent, keyword, *args, &block)
703
- Glimmer::SWT::WidgetProxy.create(keyword, parent, args)
704
- end
705
-
706
- def add_content(parent, &block)
707
- super
708
- parent.post_add_content
709
- end
710
-
711
- end
712
- end
713
- end
714
- end
715
- ```
716
-
717
- Example of a static expression (does not need `can_interpret?`):
718
-
719
- ```ruby
720
- module Glimmer
721
- module DSL
722
- module Opal
723
- class ColorExpression < StaticExpression
724
- include TopLevelExpression
725
-
726
- def interpret(parent, keyword, *args, &block)
727
- Glimmer::SWT::ColorProxy.new(*args)
728
- end
729
- end
730
- end
731
- end
732
- end
733
- ```
734
-
735
- DSL expressions go into the `glimmer/dsl/{dsl_name}` namespace directory.
736
-
737
- Also, every DSL requires a `glimmer/dsl/{dsl_name}/dsl.rb` file, which configures the DSL into Glimmer via a call to:
738
- ```ruby
739
- Glimmer::DSL::Engine.add_dynamic_expressions(DSLNameModule, expression_names_array)
740
- ```
741
-
742
- Expression names are underscored verions of `Expression` subclass names minus the `_expression` suffix.
743
-
744
- For example, here is an SWT DSL configuration:
745
-
746
- ```ruby
747
- require 'glimmer/launcher'
748
- require Glimmer::Launcher.swt_jar_file
749
- require 'glimmer/dsl/engine'
750
- Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
751
-
752
- module Glimmer
753
- module DSL
754
- module SWT
755
- Engine.add_dynamic_expressions(
756
- SWT,
757
- %w[
758
- layout
759
- widget_listener
760
- combo_selection_data_binding
761
- checkbox_group_selection_data_binding
762
- radio_group_selection_data_binding
763
- list_selection_data_binding
764
- tree_items_data_binding
765
- table_items_data_binding
766
- data_binding
767
- cursor
768
- font
769
- image
770
- property
771
- block_property
772
- widget
773
- custom_widget
774
- ]
775
- )
776
- end
777
- end
778
- end
779
- ```
780
-
781
- In summary, these are the files needed to author a Glimmer DSL:
782
- - `glimmer/dsl/[dsl_name]/dsl.rb`: requires and adds all dynamic expressions to [dsl_name] Glimmer DSL
783
- - `glimmer/dsl/[dsl_name]/[expresion_name]_expresion.rb`: needed for every [expresion_name] expression, whether dynamic or static
784
-
785
- ### Multi-DSL Support
786
-
787
- The Glimmer [DSL Engine](#dsl-engine) allows mixing DSLs, which comes in handy when doing things like rendering a desktop GUI DSL `browser` widget additionally leveraging the HTML DSL and CSS DSL for its content.
788
-
789
- DSLs are activated by top-level keywords (expressions denoted as `TopLevelExpression`). For example, the `html` keyword activates the [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and the `css` keyword activates the [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css). Glimmer automatically recognizes top-level keywords in each DSL and activates the DSL accordingly. Once done processing a nested DSL top-level keyword, Glimmer switches back to the prior DSL automatically.
790
-
791
- By default, all loaded DSLs (required glimmer DSL gems) are enabled.
792
-
793
- For example, this shows "Hello, World!" inside a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app `browser` widget using `html` and `css` from [Glimmer DSL for XML](https://github.com/AndyObtiva/glimmer-dsl-xml) and [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css):
794
-
795
- ```ruby
796
- require 'glimmer-dsl-swt'
797
- require 'glimmer-dsl-xml'
798
- require 'glimmer-dsl-css'
799
-
800
- include Glimmer
801
-
802
- shell {
803
- minimum_size 130, 130
804
- @browser = browser {
805
- text html {
806
- head {
807
- meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
808
- style {
809
- css {
810
- h1 {
811
- background 'yellow'
812
- }
813
- }
814
- }
815
- }
816
- body {
817
- h1 { "Hello, World!" }
818
- }
819
- }
820
- }
821
- }.open
822
- ```
823
-
824
- **API methods to enable/disable DSLs:**
825
-
826
- `Glimmer::DSL::Engine.disable_dsl(dsl)`: disables a particular DSL
827
-
828
- Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
829
-
830
- `Glimmer::DSL::Engine.enable_dsl(dsl)`: enables a particular DSL
831
-
832
- Example: `Glimmer::DSL::Engine.disable_dsl(:swt)`
833
-
834
- `Glimmer::DSL::Engine.enabled_dsls=(dsls)`: enables only the specified DSLs, disabling all other loaded DSLs
835
-
836
- Example: `Glimmer::DSL::Engine.enabled_dsls = [:xml, :css]`
837
-
838
922
  ## Data-Binding Library
839
923
 
840
924
  Data-Binding enables mapping GUI properties (like text and color) to Model attributes (like name and age).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.1.2
data/glimmer.gemspec CHANGED
@@ -1,18 +1,18 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: glimmer 1.1.1 ruby lib
5
+ # stub: glimmer 1.1.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer".freeze
9
- s.version = "1.1.1"
9
+ s.version = "1.1.2"
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-02-09"
15
- s.description = "Glimmer is a Ruby DSL Framework consisting of a DSL Engine and an 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
14
+ s.date = "2021-02-20"
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. 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",
@@ -46,41 +46,27 @@ Gem::Specification.new do |s|
46
46
  ]
47
47
  s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
48
48
  s.licenses = ["MIT".freeze]
49
- s.rubygems_version = "3.0.6".freeze
49
+ s.rubygems_version = "3.2.3".freeze
50
50
  s.summary = "Glimmer - DSL Engine for Ruby GUI and More".freeze
51
51
 
52
52
  if s.respond_to? :specification_version then
53
53
  s.specification_version = 4
54
+ end
54
55
 
55
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
- s.add_runtime_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
57
- s.add_runtime_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
58
- s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
59
- s.add_development_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
60
- s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
61
- s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
62
- s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
63
- s.add_development_dependency(%q<jeweler>.freeze, [">= 2.0.0", "< 3.0.0"])
64
- s.add_development_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
65
- s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
66
- s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
67
- s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
68
- s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
69
- else
70
- s.add_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
71
- s.add_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
72
- s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
73
- s.add_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
74
- s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
75
- s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
76
- s.add_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
77
- s.add_dependency(%q<jeweler>.freeze, [">= 2.0.0", "< 3.0.0"])
78
- s.add_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
79
- s.add_dependency(%q<coveralls>.freeze, [">= 0"])
80
- s.add_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
81
- s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
82
- s.add_dependency(%q<rake-tui>.freeze, [">= 0"])
83
- end
56
+ if s.respond_to? :add_runtime_dependency then
57
+ s.add_runtime_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
58
+ s.add_runtime_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
59
+ s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
60
+ s.add_development_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
61
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
62
+ s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
63
+ s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
64
+ s.add_development_dependency(%q<jeweler>.freeze, [">= 2.0.0", "< 3.0.0"])
65
+ s.add_development_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
66
+ s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
67
+ s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
68
+ s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
69
+ s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
84
70
  else
85
71
  s.add_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
86
72
  s.add_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
data/lib/glimmer.rb CHANGED
@@ -81,6 +81,7 @@ module Glimmer
81
81
  Glimmer.loop_reset!
82
82
  end
83
83
  Glimmer.loop_last_data = new_loop_data
84
+ Glimmer::Config.logger.info {">"*80}
84
85
  Glimmer::Config.logger.info {"Interpreting keyword: #{method_symbol}"}
85
86
  Glimmer::DSL::Engine.interpret(method_symbol, *args, &block)
86
87
  end
@@ -56,10 +56,10 @@ module Glimmer
56
56
  end
57
57
 
58
58
  def reset_logger!
59
- self.logger = Logger.new(STDOUT).tap do |logger|
59
+ self.logger = Logger.new($stdout).tap do |logger|
60
60
  logger.level = Logger::ERROR
61
61
  begin
62
- logger.level = ENV['GLIMMER_LOGGER_LEVEL'].strip.downcase if ENV['GLIMMER_LOGGER_LEVEL']
62
+ logger.level = ENV['GLIMMER_LOGGER_LEVEL']&.strip&.downcase
63
63
  rescue => e
64
64
  puts e.message
65
65
  end
@@ -37,7 +37,7 @@ module Glimmer
37
37
  STATIC_EXPRESSION_METHOD_FACTORY = lambda do |keyword|
38
38
  lambda do |*args, &block|
39
39
  if Glimmer::DSL::Engine.no_dsls?
40
- puts Glimmer::DSL::Engine::MESSAGE_NO_DSLS # TODO consider switching to an error log statement
40
+ Glimmer::Config.logger.error {Glimmer::DSL::Engine::MESSAGE_NO_DSLS}
41
41
  else
42
42
  retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
43
43
  # TODO consider replacing Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls with Glimmer::DSL::Engine.enabled_static_expression_dsls(keyword)
@@ -55,6 +55,7 @@ module Glimmer
55
55
  else
56
56
  raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
57
57
  Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
58
+ Glimmer::Config.logger.info {"Assuming DSL: #{Glimmer::DSL::Engine.dsl_stack.last}"}
58
59
  static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
59
60
  static_expression_can_interpret = nil
60
61
  if static_expression.nil? || !(static_expression_can_interpret = static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block))
@@ -169,6 +170,7 @@ module Glimmer
169
170
  dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).first if dsl.nil?
170
171
  # TODO consider pushing this code into interpret_expresion to provide hooks that work around it regardless of static vs dynamic
171
172
  dsl_stack.push(dynamic_expression_dsl || dsl)
173
+ Glimmer::Config.logger.info {"Assuming DSL: #{dsl_stack.last}"}
172
174
  expression = dynamic_expression_chains_of_responsibility[dsl].handle(parent, keyword, *args, &block)
173
175
  interpret_expression(expression, keyword, *args, &block)
174
176
  end
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: array_include_methods
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - ">="
@@ -19,7 +20,6 @@ dependencies:
19
20
  - - "<"
20
21
  - !ruby/object:Gem::Version
21
22
  version: 2.0.0
22
- name: array_include_methods
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,6 +31,7 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: 2.0.0
33
33
  - !ruby/object:Gem::Dependency
34
+ name: facets
34
35
  requirement: !ruby/object:Gem::Requirement
35
36
  requirements:
36
37
  - - ">="
@@ -39,7 +40,6 @@ dependencies:
39
40
  - - "<"
40
41
  - !ruby/object:Gem::Version
41
42
  version: 4.0.0
42
- name: facets
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,6 +51,7 @@ dependencies:
51
51
  - !ruby/object:Gem::Version
52
52
  version: 4.0.0
53
53
  - !ruby/object:Gem::Dependency
54
+ name: concurrent-ruby
54
55
  requirement: !ruby/object:Gem::Requirement
55
56
  requirements:
56
57
  - - ">="
@@ -59,7 +60,6 @@ dependencies:
59
60
  - - "<"
60
61
  - !ruby/object:Gem::Version
61
62
  version: 2.0.0
62
- name: concurrent-ruby
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,12 +71,12 @@ dependencies:
71
71
  - !ruby/object:Gem::Version
72
72
  version: 2.0.0
73
73
  - !ruby/object:Gem::Dependency
74
+ name: rspec-mocks
74
75
  requirement: !ruby/object:Gem::Requirement
75
76
  requirements:
76
77
  - - "~>"
77
78
  - !ruby/object:Gem::Version
78
79
  version: 3.5.0
79
- name: rspec-mocks
80
80
  type: :development
81
81
  prerelease: false
82
82
  version_requirements: !ruby/object:Gem::Requirement
@@ -85,12 +85,12 @@ dependencies:
85
85
  - !ruby/object:Gem::Version
86
86
  version: 3.5.0
87
87
  - !ruby/object:Gem::Dependency
88
+ name: rspec
88
89
  requirement: !ruby/object:Gem::Requirement
89
90
  requirements:
90
91
  - - "~>"
91
92
  - !ruby/object:Gem::Version
92
93
  version: 3.5.0
93
- name: rspec
94
94
  type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
@@ -99,12 +99,12 @@ dependencies:
99
99
  - !ruby/object:Gem::Version
100
100
  version: 3.5.0
101
101
  - !ruby/object:Gem::Dependency
102
+ name: puts_debuggerer
102
103
  requirement: !ruby/object:Gem::Requirement
103
104
  requirements:
104
105
  - - "~>"
105
106
  - !ruby/object:Gem::Version
106
107
  version: 0.10.0
107
- name: puts_debuggerer
108
108
  type: :development
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
@@ -113,6 +113,7 @@ dependencies:
113
113
  - !ruby/object:Gem::Version
114
114
  version: 0.10.0
115
115
  - !ruby/object:Gem::Dependency
116
+ name: rake
116
117
  requirement: !ruby/object:Gem::Requirement
117
118
  requirements:
118
119
  - - ">="
@@ -121,7 +122,6 @@ dependencies:
121
122
  - - "<"
122
123
  - !ruby/object:Gem::Version
123
124
  version: 14.0.0
124
- name: rake
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
@@ -133,6 +133,7 @@ dependencies:
133
133
  - !ruby/object:Gem::Version
134
134
  version: 14.0.0
135
135
  - !ruby/object:Gem::Dependency
136
+ name: jeweler
136
137
  requirement: !ruby/object:Gem::Requirement
137
138
  requirements:
138
139
  - - ">="
@@ -141,7 +142,6 @@ dependencies:
141
142
  - - "<"
142
143
  - !ruby/object:Gem::Version
143
144
  version: 3.0.0
144
- name: jeweler
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
@@ -153,6 +153,7 @@ dependencies:
153
153
  - !ruby/object:Gem::Version
154
154
  version: 3.0.0
155
155
  - !ruby/object:Gem::Dependency
156
+ name: rdoc
156
157
  requirement: !ruby/object:Gem::Requirement
157
158
  requirements:
158
159
  - - ">="
@@ -161,7 +162,6 @@ dependencies:
161
162
  - - "<"
162
163
  - !ruby/object:Gem::Version
163
164
  version: 7.0.0
164
- name: rdoc
165
165
  type: :development
166
166
  prerelease: false
167
167
  version_requirements: !ruby/object:Gem::Requirement
@@ -173,12 +173,12 @@ dependencies:
173
173
  - !ruby/object:Gem::Version
174
174
  version: 7.0.0
175
175
  - !ruby/object:Gem::Dependency
176
+ name: coveralls
176
177
  requirement: !ruby/object:Gem::Requirement
177
178
  requirements:
178
179
  - - ">="
179
180
  - !ruby/object:Gem::Version
180
181
  version: '0'
181
- name: coveralls
182
182
  type: :development
183
183
  prerelease: false
184
184
  version_requirements: !ruby/object:Gem::Requirement
@@ -187,12 +187,12 @@ dependencies:
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  - !ruby/object:Gem::Dependency
190
+ name: simplecov
190
191
  requirement: !ruby/object:Gem::Requirement
191
192
  requirements:
192
193
  - - "~>"
193
194
  - !ruby/object:Gem::Version
194
195
  version: 0.16.1
195
- name: simplecov
196
196
  type: :development
197
197
  prerelease: false
198
198
  version_requirements: !ruby/object:Gem::Requirement
@@ -201,12 +201,12 @@ dependencies:
201
201
  - !ruby/object:Gem::Version
202
202
  version: 0.16.1
203
203
  - !ruby/object:Gem::Dependency
204
+ name: simplecov-lcov
204
205
  requirement: !ruby/object:Gem::Requirement
205
206
  requirements:
206
207
  - - "~>"
207
208
  - !ruby/object:Gem::Version
208
209
  version: 0.7.0
209
- name: simplecov-lcov
210
210
  type: :development
211
211
  prerelease: false
212
212
  version_requirements: !ruby/object:Gem::Requirement
@@ -215,12 +215,12 @@ dependencies:
215
215
  - !ruby/object:Gem::Version
216
216
  version: 0.7.0
217
217
  - !ruby/object:Gem::Dependency
218
+ name: rake-tui
218
219
  requirement: !ruby/object:Gem::Requirement
219
220
  requirements:
220
221
  - - ">="
221
222
  - !ruby/object:Gem::Version
222
223
  version: '0'
223
- name: rake-tui
224
224
  type: :development
225
225
  prerelease: false
226
226
  version_requirements: !ruby/object:Gem::Requirement
@@ -228,11 +228,12 @@ dependencies:
228
228
  - - ">="
229
229
  - !ruby/object:Gem::Version
230
230
  version: '0'
231
- description: Glimmer is a Ruby DSL Framework consisting of a DSL Engine and an Observable/Observer/Data-Binding
232
- Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework),
233
- the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for
234
- Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for
235
- XML (& HTML), and the Glimmer DSL for CSS.
231
+ description: Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of
232
+ a DSL Engine and an Observable/Observer/Data-Binding Library. Used in the Glimmer
233
+ DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby
234
+ Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and
235
+ Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer
236
+ DSL for CSS.
236
237
  email: andy.am@gmail.com
237
238
  executables: []
238
239
  extensions: []
@@ -283,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
284
  - !ruby/object:Gem::Version
284
285
  version: '0'
285
286
  requirements: []
286
- rubygems_version: 3.0.6
287
+ rubygems_version: 3.2.3
287
288
  signing_key:
288
289
  specification_version: 4
289
290
  summary: Glimmer - DSL Engine for Ruby GUI and More