glimmer-dsl-libui 0.10.2 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a37cb8210f604b9307693af84b47ba0e21cf2a2b1059139af1d4ffa2eb727bf8
4
- data.tar.gz: 88443d069ff718e8d28c90dbb59fc6ff5e5a05a5f3e9f5be78418d1754868769
3
+ metadata.gz: 3089dc0655a6c58f1b514e61ee7994ad1e51949ac79556228832fea732302fea
4
+ data.tar.gz: edeada4eafa026c2f1f6c4d10d581d8e2c416d87c66f142e9225aa809c72322a
5
5
  SHA512:
6
- metadata.gz: 1a2e8c3f162744fe2266d66a088bceb7595b04643a141b0dd526309b6155362e24fad6c760cc8eb060030fec35352ab96b9dfad7e601e5a168271e1150aa7789
7
- data.tar.gz: 90674bbf9623bcd0e985a94824698c3117a8a70bea79f7ee81d11364054c70d57f260466123717d2f292aa50f113cfb11201580a3f74bc74400a100f9c049d6d
6
+ metadata.gz: 1a3b4bb480862eee93488bc703c7a32f4c21e7d7a80c2668f262833d8eed3600d7b6169e2c3670666cb030cd94b547b3055df79289679f87618ff411cc8dc729
7
+ data.tar.gz: '0294d1117c0fbfec011f358d2570adb3ea78b95cd656e9b5803467d9eef8e7f9e6e8f615220a1b46c094779b634106ccd31965d00e9dc9365e305d710a5d7c4d'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.11.1
4
+
5
+ - Refactor `examples/dynamic_form.rb`
6
+ - Freeze LibUI version at 0.1.2.pre because 0.1.3.pre has issues like preventing the ability to close window with CMD+Q shortcut by default on Mac
7
+
8
+ ## 0.11.0
9
+
10
+ - Control `content` data-binding to generate nested controls dynamically based on a model attribute change
11
+ - `examples/dynamic_form.rb` to demonstrate control `content` data-binding
12
+
3
13
  ## 0.10.2
4
14
 
5
15
  - In Snake example, change snake direction on key press instead of key release to be more responsive for players who are not used to releasing pressed keys quickly
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.10.2
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.11.1
2
2
  ## Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library ([Fukuoka Award Winning](http://www.digitalfukuoka.jp/topics/187?locale=ja))
3
3
  ### The Quickest Way From Zero To GUI
4
4
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
@@ -431,7 +431,7 @@ gem install glimmer-dsl-libui
431
431
  Or install via Bundler `Gemfile`:
432
432
 
433
433
  ```ruby
434
- gem 'glimmer-dsl-libui', '~> 0.10.2'
434
+ gem 'glimmer-dsl-libui', '~> 0.11.1'
435
435
  ```
436
436
 
437
437
  Test that installation worked by running the [Glimmer Meta-Example](#examples):
@@ -452,8 +452,19 @@ Mac | Windows | Linux
452
452
 
453
453
  ## Usage
454
454
 
455
- Require [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui) (whether through a Ruby `require` statement or `Bundler`) and then include the `Glimmer` or `Glimmer::LibUI::Application` module to enable access to the Glimmer GUI DSL in one of multiple approaches.
456
-
455
+ Start by requiring the [glimmer-dsl-libui](https://rubygems.org/gems/glimmer-dsl-libui) Ruby gem, whether through a Ruby `require 'glimmer-dsl-libui` statement or `Bundler`.
456
+
457
+ Afterwards, to access the Glimmer GUI DSL:
458
+ - If you are learning/experimenting/prototyping with Glimmer DSL for LibUI, include the `Glimmer` module into the top-level scope or a Ruby class.
459
+ - If you are building a serious application, include `Glimmer::LibUI::Application` into the main view Ruby class
460
+ - If you are building a custom control, include [`Glimmer::LibUI::CustomControl`](#custom-components) into a Ruby class
461
+ - If you are building a cusotm window, include [`Glimmer::LibUI::CustomWindow`](#custom-components) into a Ruby class
462
+ - If you are building a custom shape, include [`Glimmer::LibUI::CustomShape`](#custom-components) into a Ruby class.
463
+
464
+ You may learn more about the different options above with basic examples in the following subsections: [Experimentation Usage](#experimentation-usage), [Prototyping Usage](#prototyping-usage), [Serious Usage](#serious-usage).
465
+
466
+ If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) (beginner), after going through the subsections below, check out the RubyConf 2022 talk ["Building Native GUI Apps in Ruby"](https://andymaleh.blogspot.com/2023/02/rubyconf-2022-talk-video-for-building.html), [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts), [Glimmer Command](#glimmer-command) (just the basics, how to run an app, and how to run examples to start), [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. It is very important for beginners to go through all the [Examples](#examples) from the most basic to the most advanced while reading the README topics that relate to the examples. You may refer to the [API](#api) on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
467
+
457
468
  ### Experimentation Usage
458
469
 
459
470
  For experimenting and learning, add `include Glimmer` into the top-level main object and start using the Glimmer GUI DSL directly.
@@ -534,9 +545,6 @@ SomeGlimmerApp.launch
534
545
 
535
546
  (note: `Glimmer::LibUI::Application` is an alias for `Glimmer::LibUI::CustomWindow` since that is what it represents)
536
547
 
537
- If you are new to [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui), check out the [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts), [Glimmer Command](#glimmer-command), [Girb](#girb-glimmer-irb) and [Examples](#examples) to quickly learn through copy/paste. You may refer to the [API](#api) later on once you have gotten your feet wet with [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) and need more detailed reference information.
538
-
539
-
540
548
  ## Glimmer Command
541
549
 
542
550
  The `glimmer` command allows you to conveniently run applications (`glimmer app_path`), run examples (`glimmer examples`), and scaffold applications (`glimmer "scaffold[app_name]"`).
@@ -1591,6 +1599,44 @@ button('greet') { |b|
1591
1599
  }
1592
1600
  ```
1593
1601
 
1602
+ If there is ever a need to add more content to a control, you can re-open its content with the `control.content { ... }` method.
1603
+
1604
+ Example:
1605
+
1606
+ ```ruby
1607
+ box1 = vertical_box {
1608
+ label('First Name')
1609
+ }
1610
+ # re-open content of box1 and add another control
1611
+ box1.content {
1612
+ entry {
1613
+ text 'fill in your first name'
1614
+ }
1615
+ }
1616
+ ```
1617
+
1618
+ Content Data-Binding also allows you to use [data-binding](#data-binding) with content blocks to generate content dynamically based on changes in a model attribute. The only difference in syntax in this case would be to wrap the content with an explicit `content(*binding_args) { ... }` block (like `content(model, attribute) { somecontrols }` ) that includes data-binding arguments for a model attribute.
1619
+
1620
+ Example:
1621
+
1622
+ ```ruby
1623
+ form {
1624
+ stretchy false
1625
+
1626
+ content(@user, :customizable_attributes) {
1627
+ # this content will be re-rendered whenever @user.customizable_attributes changes
1628
+ @user.customizable_attributes.each do |attribute|
1629
+ entry {
1630
+ label attribute.to_s.split('_').map(&:capitalize).join(' ')
1631
+ text <=> [@user, attribute]
1632
+ }
1633
+ end
1634
+ }
1635
+ }
1636
+ ```
1637
+
1638
+ The form above will only display fields for a model's customizable attributes, so if they change, the form content will change too. Learn more at the [Dynamic Form](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#dynamic-form) example.
1639
+
1594
1640
  **Property**: Control properties may be declared inside keyword blocks with lower-case underscored name followed by property value args (e.g. `title "hello world"` inside `group`). Behind the scenes, properties correspond to `LibUI.control_set_property` methods.
1595
1641
 
1596
1642
  **Listener**: Control listeners may be declared inside keyword blocks with listener lower-case underscored name beginning with `on_` and receiving required block handler (always followed by a `do; end` style block to signify logic).
@@ -2062,8 +2108,8 @@ Learn more in the [Paginated Refined Table](/docs/examples/GLIMMER-DSL-LIBUI-ADV
2062
2108
  ### Area API
2063
2109
 
2064
2110
  The `area` control is a canvas-like control for drawing paths that can be used in one of two ways:
2065
- - Declaratively via stable paths: useful for stable paths that will not change often later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are preserved across redraws assuming there would be relatively few stable paths (mostly for decorative reasons).
2066
- - Semi-declaratively via on_draw listener dynamic paths: useful for more dynamic paths that will definitely change very often. Open an `on_draw` listener block that receives an [`area_draw_params`](#area-draw-params) argument and nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are destroyed (thrown-away) at the end of drawing, thus having less memory overhead for drawing thousands of dynamic paths.
2111
+ - Retained Mode (declaratively via stable shape structures): useful for stable paths that will not change often later on. Simply nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are preserved across redraws assuming there would be relatively few stable paths (mostly for decorative reasons).
2112
+ - Immediate Mode (semi-declaratively via `on_draw` listener dynamic shapes): useful for more dynamic paths that will definitely change very often. Open an `on_draw` listener block that receives an [`area_draw_params`](#area-draw-params) argument and nest `path` and figures like `rectangle` and all drawing logic is generated automatically. Path proxy objects are destroyed (thrown-away) at the end of drawing, thus having less memory overhead for drawing thousands of dynamic paths.
2067
2113
 
2068
2114
  Note that when nesting an `area` directly underneath `window` (without a layout control like `vertical_box`), it is automatically reparented with `vertical_box` in between the `window` and `area` since it would not show up on Linux otherwise.
2069
2115
 
@@ -2119,6 +2165,59 @@ window('Basic Area', 400, 400) {
2119
2165
 
2120
2166
  Check [examples/dynamic_area.rb](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#dynamic-area) for a more detailed semi-declarative example.
2121
2167
 
2168
+ In Retained Mode, you can still generate `area` shapes dynamically by relying on Content Data-Binding.
2169
+
2170
+ ```ruby
2171
+ require 'glimmer-dsl-libui'
2172
+
2173
+ class LineCollection
2174
+ attr_accessor :line_count
2175
+
2176
+ def initialize
2177
+ @line_count = 3
2178
+ end
2179
+ end
2180
+
2181
+ class View
2182
+ include Glimmer::LibUI::Application
2183
+
2184
+ before_body do
2185
+ @line_collection = LineCollection.new
2186
+ end
2187
+
2188
+ body {
2189
+ window('Area Shapes - Line', 400, 400) {
2190
+ vertical_box {
2191
+ button('Generate Lines') {
2192
+ stretchy false
2193
+
2194
+ on_clicked do
2195
+ @line_collection.line_count = rand(3..10)
2196
+ end
2197
+ }
2198
+ area {
2199
+ content(@line_collection, :line_count) { # generated dynamically
2200
+ point_range = (50..350)
2201
+ color_range = (0..255)
2202
+ @line_collection.line_count.times do
2203
+ line(rand(point_range), rand(point_range), rand(point_range), rand(point_range)) {
2204
+ stroke rand(color_range), rand(color_range), rand(color_range), thickness: 3
2205
+ }
2206
+ end
2207
+ }
2208
+ }
2209
+ }
2210
+ }
2211
+ }
2212
+ end
2213
+
2214
+ View.launch
2215
+ ```
2216
+
2217
+ ![area shape content data-binding](/images/glimmer-dsl-libui-mac-area-shape-content-data-binding.png)
2218
+
2219
+ ![area shape content data-binding regenerated](/images/glimmer-dsl-libui-mac-area-shape-content-data-binding-regenerated.png)
2220
+
2122
2221
  #### Scrolling Area
2123
2222
 
2124
2223
  `scrolling_area(width as Numeric = main_window.width, height as Numeric = main_window.height)` is similar to `area`, but has the following additional methods:
@@ -3387,11 +3486,11 @@ Another example of bidirectional data-binding with an option:
3387
3486
 
3388
3487
  ```ruby
3389
3488
  entry {
3390
- text <=> [self, :entered_text, after_write: ->(text) {puts text}]
3489
+ text <=> [model, :entered_text, after_write: ->(text) {puts text}]
3391
3490
  }
3392
3491
  ```
3393
3492
 
3394
- That is data-binding `entered_text` attribute on `self` to `entry` `text` property and printing text after write to the model.
3493
+ That is data-binding `entered_text` attribute on `model` to `entry` `text` property and printing text after write to the model.
3395
3494
 
3396
3495
  ##### Table Data-Binding
3397
3496
 
@@ -3573,6 +3672,27 @@ window {
3573
3672
 
3574
3673
  That is data-binding the `window` `title` property to the `score` attribute of a `@game`, but converting on read from the Model to a `String`.
3575
3674
 
3675
+ You can also use unidirectional [data-binding](#data-binding) with content blocks to generate content dynamically based on changes in a model attribute. The only difference in syntax in this case would be to wrap the content with an explicit `content(*binding_args) { ... }` block that includes data-binding arguments for a model attribute.
3676
+
3677
+ Example:
3678
+
3679
+ ```ruby
3680
+ form {
3681
+ stretchy false
3682
+
3683
+ content(@user, :customizable_attributes) {
3684
+ @user.customizable_attributes.each do |attribute|
3685
+ entry {
3686
+ label attribute.to_s.split('_').map(&:capitalize).join(' ')
3687
+ text <=> [@user, attribute]
3688
+ }
3689
+ end
3690
+ }
3691
+ }
3692
+ ```
3693
+
3694
+ The form above will only display fields for a model's customizable attributes, so if they change, the form content will change too. Learn more at the [Dynamic Form](/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#dynamic-form) example.
3695
+
3576
3696
  #### Data-Binding API
3577
3697
 
3578
3698
  To summarize the data-binding API:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.2
1
+ 0.11.1
@@ -8,6 +8,7 @@
8
8
  - [CPU Percentage](#cpu-percentage)
9
9
  - [Custom Draw Text](#custom-draw-text)
10
10
  - [Dynamic Area](#dynamic-area)
11
+ - [Dynamic Form](#dynamic-form)
11
12
  - [Editable Column Table](#editable-column-table)
12
13
  - [Editable Table](#editable-table)
13
14
  - [Form Table](#form-table)
@@ -211,6 +212,33 @@ Version 4 (declarative stable `path` approach without [data-binding](#data-bindi
211
212
 
212
213
  [examples/dynamic_area4.rb](/examples/dynamic_area4.rb)
213
214
 
215
+
216
+ ## Dynamic Form
217
+
218
+ [examples/dynamic_form.rb](/examples/dynamic_form.rb)
219
+
220
+ Run with this command from the root of the project if you cloned the project:
221
+
222
+ ```
223
+ ruby -r './lib/glimmer-dsl-libui' examples/dynamic_form.rb
224
+ ```
225
+
226
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
227
+
228
+ ```
229
+ ruby -r glimmer-dsl-libui -e "require 'examples/dynamic_form'"
230
+ ```
231
+
232
+ ![glimmer-dsl-libui-mac-dynamic-form.png](/images/glimmer-dsl-libui-mac-dynamic-form.png)
233
+
234
+ ![glimmer-dsl-libui-mac-dynamic-form-filled.png](/images/glimmer-dsl-libui-mac-dynamic-form-filled.png)
235
+
236
+ ![glimmer-dsl-libui-mac-dynamic-form-summarized.png](/images/glimmer-dsl-libui-mac-dynamic-form-summarized.png)
237
+
238
+ ![glimmer-dsl-libui-mac-dynamic-form-without-some-fields.png](/images/glimmer-dsl-libui-mac-dynamic-form-without-some-fields.png)
239
+
240
+ ![glimmer-dsl-libui-mac-dynamic-form-without-some-fields-summarized.png](/images/glimmer-dsl-libui-mac-dynamic-form-without-some-fields-summarized.png)
241
+
214
242
  ## Editable Column Table
215
243
 
216
244
  [examples/editable_column_table.rb](/examples/editable_column_table.rb)
@@ -1,28 +1,35 @@
1
1
  require 'glimmer-dsl-libui'
2
2
 
3
- class ButtonCounter
4
- include Glimmer
5
-
3
+ class Counter
6
4
  attr_accessor :count
7
-
5
+
8
6
  def initialize
9
7
  self.count = 0
10
8
  end
9
+ end
11
10
 
12
- def launch
11
+ class ButtonCounter
12
+ include Glimmer::LibUI::Application
13
+
14
+ before_body do
15
+ @counter = Counter.new
16
+ end
17
+
18
+ body {
13
19
  window('Hello, Button!', 190, 20) {
14
20
  vertical_box {
15
21
  button {
16
- # data-bind button text to self count, converting to string on read.
17
- text <= [self, :count, on_read: ->(count) {"Count: #{count}"}]
22
+ # data-bind button text to @counter count, converting to string on read from model.
23
+ text <= [@counter, :count, on_read: ->(count) {"Count: #{count}"}]
18
24
 
19
25
  on_clicked do
20
- self.count += 1
26
+ # This change will automatically propagate to button text through data-binding above
27
+ @counter.count += 1
21
28
  end
22
29
  }
23
30
  }
24
- }.show
25
- end
31
+ }
32
+ }
26
33
  end
27
34
 
28
- ButtonCounter.new.launch
35
+ ButtonCounter.launch
@@ -0,0 +1,71 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class User
4
+ ALL_ATTRIBUTES = [:first_name, :last_name, :email, :street, :city, :state, :zip_code, :country]
5
+
6
+ attr_accessor :customizable_attributes, *ALL_ATTRIBUTES
7
+
8
+ def initialize
9
+ # allow customizing all attributes by default
10
+ self.customizable_attributes = ALL_ATTRIBUTES.dup
11
+ end
12
+
13
+ def select_customizable_attribute(attribute, selected)
14
+ if selected
15
+ customizable_attributes.push(attribute)
16
+ else
17
+ customizable_attributes.delete(attribute)
18
+ end
19
+ customizable_attributes.sort_by! {|attribute| User::ALL_ATTRIBUTES.index(attribute)}
20
+ end
21
+ end
22
+
23
+ class DynamicForm
24
+ include Glimmer::LibUI::Application
25
+
26
+ before_body do
27
+ @user = User.new
28
+ end
29
+
30
+ body {
31
+ window('Dynamic Form') {
32
+ margined true
33
+
34
+ vertical_box {
35
+ horizontal_box {
36
+ User::ALL_ATTRIBUTES.each do |attribute|
37
+ checkbox(attribute.to_s) {
38
+ checked <=> [@user, :customizable_attributes,
39
+ on_read: -> (attributes) { @user.customizable_attributes.include?(attribute) },
40
+ on_write: -> (checked_value) { @user.select_customizable_attribute(attribute, checked_value) }
41
+ ]
42
+ }
43
+ end
44
+ }
45
+
46
+ form {
47
+ stretchy false
48
+
49
+ # Control content data-binding allows dynamically changing content based on changes in a model attribute
50
+ content(@user, :customizable_attributes) {
51
+ @user.customizable_attributes.each do |attribute|
52
+ entry {
53
+ label attribute.to_s.split('_').map(&:capitalize).join(' ')
54
+ text <=> [@user, attribute]
55
+ }
56
+ end
57
+ }
58
+ }
59
+
60
+ button('Summarize') {
61
+ on_clicked do
62
+ summary = @user.customizable_attributes.map { |attribute| @user.send(attribute) }.join(', ')
63
+ msg_box('Summary', summary)
64
+ end
65
+ }
66
+ }
67
+ }
68
+ }
69
+ end
70
+
71
+ DynamicForm.launch
Binary file
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2021-2023 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/dsl/static_expression'
23
+
24
+ module Glimmer
25
+ module DSL
26
+ module Libui
27
+ class ContentExpression < StaticExpression
28
+ def can_interpret?(parent, keyword, *args, &block)
29
+ keyword == 'content' &&
30
+ block_given? &&
31
+ args.size > 0 &&
32
+ parent&.respond_to?(:bind_content)
33
+ end
34
+
35
+ def interpret(parent, keyword, *args, &block)
36
+ parent.bind_content(*args, &block)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -40,6 +40,7 @@ module Glimmer
40
40
  data_binding
41
41
  shine_data_binding
42
42
  property
43
+ content
43
44
  string
44
45
  operation
45
46
  control
@@ -384,6 +384,19 @@ module Glimmer
384
384
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ControlExpression.new, @keyword, {post_add_content: @content_added}, &block)
385
385
  end
386
386
 
387
+ # Data-binds the generation of nested content to a model/property (in binding args)
388
+ # consider providing an option to avoid initial rendering without any changes happening
389
+ def bind_content(*binding_args, &content_block)
390
+ # TODO in the future, consider optimizing code by diffing content if that makes sense
391
+ content_binding_work = proc do |*values|
392
+ children.dup.each { |child| child.destroy }
393
+ content(&content_block)
394
+ end
395
+ content_binding_observer = Glimmer::DataBinding::Observer.proc(&content_binding_work)
396
+ content_binding_observer.observe(*binding_args)
397
+ content_binding_work.call # TODO inspect if we need to pass args here (from observed attributes) [but it's simpler not to pass anything at first]
398
+ end
399
+
387
400
  private
388
401
 
389
402
  def build_control
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-28 00:00:00.000000000 Z
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -150,14 +150,14 @@ dependencies:
150
150
  name: libui
151
151
  requirement: !ruby/object:Gem::Requirement
152
152
  requirements:
153
- - - "~>"
153
+ - - '='
154
154
  - !ruby/object:Gem::Version
155
155
  version: 0.1.2.pre
156
156
  type: :runtime
157
157
  prerelease: false
158
158
  version_requirements: !ruby/object:Gem::Requirement
159
159
  requirements:
160
- - - "~>"
160
+ - - '='
161
161
  - !ruby/object:Gem::Version
162
162
  version: 0.1.2.pre
163
163
  - !ruby/object:Gem::Dependency
@@ -437,6 +437,7 @@ files:
437
437
  - examples/dynamic_area2.rb
438
438
  - examples/dynamic_area3.rb
439
439
  - examples/dynamic_area4.rb
440
+ - examples/dynamic_form.rb
440
441
  - examples/editable_column_table.rb
441
442
  - examples/editable_table.rb
442
443
  - examples/font_button.rb
@@ -500,6 +501,7 @@ files:
500
501
  - lib/glimmer-dsl-libui/ext/rouge/theme/glimmer.rb
501
502
  - lib/glimmer/Rakefile
502
503
  - lib/glimmer/dsl/libui/bind_expression.rb
504
+ - lib/glimmer/dsl/libui/content_expression.rb
503
505
  - lib/glimmer/dsl/libui/control_expression.rb
504
506
  - lib/glimmer/dsl/libui/custom_control_expression.rb
505
507
  - lib/glimmer/dsl/libui/custom_shape_expression.rb
@@ -638,7 +640,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
638
640
  - !ruby/object:Gem::Version
639
641
  version: '0'
640
642
  requirements: []
641
- rubygems_version: 3.4.10
643
+ rubygems_version: 3.4.6
642
644
  signing_key:
643
645
  specification_version: 4
644
646
  summary: Glimmer DSL for LibUI (Fukuoka Award Winning Prerequisite-Free Ruby Desktop