glimmer-dsl-libui 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1256d99b9a792c92f657e9320af1264a275f26e7de5586d3f174daaf33b35f07
4
- data.tar.gz: 5d8dcf4a6eb8870136579240d8d5337e72c6e2bac76b78fd506a3c1335ecd8a7
3
+ metadata.gz: 122c9e87c9613b6ebb29722c0c7d602b0850f369c613374b21df38699e61e669
4
+ data.tar.gz: fb156f42398d2c8d419de476dfe435fbdfe872545da343daadd035ed2667775c
5
5
  SHA512:
6
- metadata.gz: 8c99de618602038c939715d95a03ac6b8296e6f46bff298808df977c161dead4859aa6e7cca1e7d72bac6216e2c4f6cbbc090e4648ab933db406aced2028cf14
7
- data.tar.gz: ed6e9d34fe546651d72918f2e5895cfb0cfd13a6eb2ab0f5e55b78a5cf8ecbbff1bc362afb9356f0839a80852c7a5bf30e262ddd05ee76f750e98129ae980a25
6
+ metadata.gz: 0d9587a6a19b25436fb8b810034d4663d2bd6e6dd478ab7397727978b5cec3100016032a0b3b9787ffcdb7245c2df4826829fa3e0d0afd60b69a26f4e45fcdcd
7
+ data.tar.gz: 8793a26d3383e981db6654b2e5e2705e677436e89eb1f678ec8289d17328d825151cb06ab67eacd19a398092ef77bafc6baa3e729c5152df57cf73189d9ad40e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.4.8
4
+
5
+ - Support `checkbox` `checked` bidirectional data-binding (with `<=>` sign)
6
+ - Support `check_menu_item` `checked` bidirectional data-binding (with `<=>` sign)
7
+ - Support `radio_menu_item` `checked` bidirectional data-binding (with `<=>` sign)
8
+ - Support `radio_buttons` `selected` property bidirectional data-binding (with `<=>` sign)
9
+ - Improve examples/tetris.rb with bidirectional data-binding for `check_menu_item`/`radio_menu_item` `checked`
10
+ - Update default dimensions of Meta-Example to `1000x500`
11
+ - Fix minor issue with Meta-Example selecting first radio button in Advanced examples despite it not being the truly selected example on launch of the app (now, it starts explicitly deselected)
12
+ - Fix minor issue with Meta-Example showing basic examples as advanced
13
+
3
14
  ## 0.4.7
4
15
 
5
16
  - Support `date_time_picker`/`date_picker`/`time_picker` `time` bidirectional data-binding (with `<=>` sign)
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.4.7
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.4.8
2
2
  ## Prerequisite-Free Ruby Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -373,7 +373,7 @@ gem install glimmer-dsl-libui
373
373
  Or install via Bundler `Gemfile`:
374
374
 
375
375
  ```ruby
376
- gem 'glimmer-dsl-libui', '~> 0.4.7'
376
+ gem 'glimmer-dsl-libui', '~> 0.4.8'
377
377
  ```
378
378
 
379
379
  Add `require 'glimmer-dsl-libui'` at the top, and then `include Glimmer` into the top-level main object for testing or into an actual class for serious usage.
@@ -1382,6 +1382,8 @@ Data-binding supports utilizing the [MVP (Model View Presenter)](https://en.wiki
1382
1382
  ![MVP](https://www.researchgate.net/profile/Gilles-Perrouin/publication/320249584/figure/fig8/AS:668260987068418@1536337243385/Model-view-presenter-architecture.png)
1383
1383
 
1384
1384
  [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) supports bidirectional (two-way) data-binding of the following controls/properties via the `<=>` operator (indicating data is moving in both directions between View and Model):
1385
+ - `checkbox`: `checked`
1386
+ - `check_menu_item`: `checked`
1385
1387
  - `color_button`: `color`
1386
1388
  - `combobox`: `selected`, `selected_item`
1387
1389
  - `date_picker`: `time`
@@ -1391,6 +1393,8 @@ Data-binding supports utilizing the [MVP (Model View Presenter)](https://en.wiki
1391
1393
  - `font_button`: `font`
1392
1394
  - `multiline_entry`: `text`
1393
1395
  - `non_wrapping_multiline_entry`: `text`
1396
+ - `radio_buttons`: `selected`
1397
+ - `radio_menu_item`: `checked`
1394
1398
  - `search_entry`: `text`
1395
1399
  - `slider`: `value`
1396
1400
  - `spinbox`: `value`
@@ -5043,7 +5047,8 @@ class ButtonCounter
5043
5047
  def launch
5044
5048
  window('Hello, Button!') {
5045
5049
  button {
5046
- text <= [self, :count, on_read: ->(count) {"Count: #{count}"}] # data-bind button text to self count, converting to string on read.
5050
+ # data-bind button text to self count, converting to string on read.
5051
+ text <= [self, :count, on_read: ->(count) {"Count: #{count}"}]
5047
5052
 
5048
5053
  on_clicked do
5049
5054
  self.count += 1
@@ -7965,7 +7970,7 @@ class TinyMidiPlayer
7965
7970
  }
7966
7971
  }
7967
7972
 
7968
- combobox { |c|
7973
+ combobox {
7969
7974
  items @midi_files.map { |path| File.basename(path) }
7970
7975
  # data-bind selected item (String) to self.selected_file with on-read/on-write converters and after_write operation
7971
7976
  selected_item <=> [self, :selected_file, on_read: ->(f) {File.basename(f.to_s)}, on_write: ->(f) {File.join(@music_directory, f)}, after_write: -> { play_midi if @th&.alive? }]
@@ -8051,7 +8056,7 @@ class TinyMidiPlayer
8051
8056
  }
8052
8057
  }
8053
8058
 
8054
- combobox { |c|
8059
+ combobox {
8055
8060
  items @midi_files.map { |path| File.basename(path) }
8056
8061
  # data-bind selected index (Integer) to self.selected_file with on-read/on-write converters and after_write operation
8057
8062
  selected <=> [self, :selected_file, on_read: ->(f) {@midi_files.index(f)}, on_write: ->(i) {@midi_files[i]}, after_write: -> { play_midi if @th&.alive? }]
@@ -8392,22 +8397,23 @@ class Tetris
8392
8397
  menu('Game') {
8393
8398
  @pause_menu_item = check_menu_item('Pause') {
8394
8399
  enabled false
8395
-
8396
- on_clicked do
8397
- @game.paused = @pause_menu_item.checked?
8398
- end
8400
+ checked <=> [@game, :paused]
8399
8401
  }
8402
+
8400
8403
  menu_item('Restart') {
8401
8404
  on_clicked do
8402
8405
  @game.restart!
8403
8406
  end
8404
8407
  }
8408
+
8405
8409
  separator_menu_item
8410
+
8406
8411
  menu_item('Exit') {
8407
8412
  on_clicked do
8408
8413
  exit(0)
8409
8414
  end
8410
8415
  }
8416
+
8411
8417
  quit_menu_item if OS.mac?
8412
8418
  }
8413
8419
 
@@ -8417,6 +8423,7 @@ class Tetris
8417
8423
  show_high_scores
8418
8424
  end
8419
8425
  }
8426
+
8420
8427
  menu_item('Clear High Scores') {
8421
8428
  on_clicked {
8422
8429
  @game.clear_high_scores!
@@ -8425,22 +8432,16 @@ class Tetris
8425
8432
  }
8426
8433
 
8427
8434
  menu('Options') {
8428
- radio_menu_item('Instant Down on Up Arrow') {
8429
- on_clicked do
8430
- @game.instant_down_on_up = true
8431
- end
8435
+ radio_menu_item('Instant Down on Up Arrow') { |r|
8436
+ checked <=> [@game, :instant_down_on_up]
8432
8437
  }
8433
- radio_menu_item('Rotate Right on Up Arrow') {
8434
- on_clicked do
8435
- @game.rotate_right_on_up = true
8436
- end
8438
+
8439
+ radio_menu_item('Rotate Right on Up Arrow') { |r|
8440
+ checked <=> [@game, :rotate_right_on_up]
8437
8441
  }
8438
- radio_menu_item('Rotate Left on Up Arrow') {
8439
- checked true
8440
-
8441
- on_clicked do
8442
- @game.rotate_left_on_up = true
8443
- end
8442
+
8443
+ radio_menu_item('Rotate Left on Up Arrow') { |r|
8444
+ checked <=> [@game, :rotate_left_on_up]
8444
8445
  }
8445
8446
  }
8446
8447
 
@@ -8452,6 +8453,7 @@ class Tetris
8452
8453
  end
8453
8454
  }
8454
8455
  end
8456
+
8455
8457
  menu_item('About') {
8456
8458
  on_clicked do
8457
8459
  show_about_dialog
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.7
1
+ 0.4.8
@@ -13,7 +13,8 @@ class ButtonCounter
13
13
  window('Hello, Button!', 190, 20) {
14
14
  vertical_box {
15
15
  button {
16
- text <= [self, :count, on_read: ->(count) {"Count: #{count}"}] # data-bind button text to self count, converting to string on read.
16
+ # data-bind button text to self count, converting to string on read.
17
+ text <= [self, :count, on_read: ->(count) {"Count: #{count}"}]
17
18
 
18
19
  on_clicked do
19
20
  self.count += 1
@@ -24,18 +24,28 @@ class MetaExample
24
24
  @examples
25
25
  end
26
26
 
27
+ def basic_examples
28
+ examples.select {|example| example.start_with?('Basic') || ADDITIONAL_BASIC_EXAMPLES.include?(example) }
29
+ end
30
+
31
+ def advanced_examples
32
+ examples - basic_examples
33
+ end
34
+
27
35
  def examples_with_versions
28
- examples.map do |example|
29
- version_count_for(example) > 1 ? "#{example} (#{version_count_for(example)} versions)" : example
30
- end
36
+ append_versions(examples)
31
37
  end
32
38
 
33
39
  def basic_examples_with_versions
34
- examples_with_versions.select {|example| example.start_with?('Basic') || ADDITIONAL_BASIC_EXAMPLES.include?(example) }
40
+ append_versions(basic_examples)
35
41
  end
36
42
 
37
43
  def advanced_examples_with_versions
38
- examples_with_versions - basic_examples_with_versions
44
+ append_versions(advanced_examples)
45
+ end
46
+
47
+ def append_versions(examples)
48
+ examples.map { |example| version_count_for(example) > 1 ? "#{example} (#{version_count_for(example)} versions)" : example }
39
49
  end
40
50
 
41
51
  def file_path_for(example)
@@ -72,7 +82,7 @@ class MetaExample
72
82
  end
73
83
 
74
84
  def launch
75
- window('Meta-Example', 700, 500) {
85
+ window('Meta-Example', 1000, 500) {
76
86
  margined true
77
87
 
78
88
  horizontal_box {
@@ -107,6 +117,7 @@ class MetaExample
107
117
  @advanced_example_radio_buttons = radio_buttons {
108
118
  stretchy false
109
119
  items advanced_examples_with_versions
120
+ selected -1
110
121
 
111
122
  on_selected do
112
123
  @selected_example_index = examples_with_versions.index(advanced_examples_with_versions[@advanced_example_radio_buttons.selected])
@@ -70,7 +70,7 @@ class TinyMidiPlayer
70
70
  }
71
71
  }
72
72
 
73
- combobox { |c|
73
+ combobox {
74
74
  items @midi_files.map { |path| File.basename(path) }
75
75
  # data-bind selected item (String) to self.selected_file with on-read/on-write converters and after_write operation
76
76
  selected_item <=> [self, :selected_file, on_read: ->(f) {File.basename(f.to_s)}, on_write: ->(f) {File.join(@music_directory, f)}, after_write: -> { play_midi if @th&.alive? }]
data/examples/tetris.rb CHANGED
@@ -109,22 +109,23 @@ class Tetris
109
109
  menu('Game') {
110
110
  @pause_menu_item = check_menu_item('Pause') {
111
111
  enabled false
112
-
113
- on_clicked do
114
- @game.paused = @pause_menu_item.checked?
115
- end
112
+ checked <=> [@game, :paused]
116
113
  }
114
+
117
115
  menu_item('Restart') {
118
116
  on_clicked do
119
117
  @game.restart!
120
118
  end
121
119
  }
120
+
122
121
  separator_menu_item
122
+
123
123
  menu_item('Exit') {
124
124
  on_clicked do
125
125
  exit(0)
126
126
  end
127
127
  }
128
+
128
129
  quit_menu_item if OS.mac?
129
130
  }
130
131
 
@@ -134,6 +135,7 @@ class Tetris
134
135
  show_high_scores
135
136
  end
136
137
  }
138
+
137
139
  menu_item('Clear High Scores') {
138
140
  on_clicked {
139
141
  @game.clear_high_scores!
@@ -142,22 +144,16 @@ class Tetris
142
144
  }
143
145
 
144
146
  menu('Options') {
145
- radio_menu_item('Instant Down on Up Arrow') {
146
- on_clicked do
147
- @game.instant_down_on_up = true
148
- end
147
+ radio_menu_item('Instant Down on Up Arrow') { |r|
148
+ checked <=> [@game, :instant_down_on_up]
149
149
  }
150
- radio_menu_item('Rotate Right on Up Arrow') {
151
- on_clicked do
152
- @game.rotate_right_on_up = true
153
- end
150
+
151
+ radio_menu_item('Rotate Right on Up Arrow') { |r|
152
+ checked <=> [@game, :rotate_right_on_up]
154
153
  }
155
- radio_menu_item('Rotate Left on Up Arrow') {
156
- checked true
157
-
158
- on_clicked do
159
- @game.rotate_left_on_up = true
160
- end
154
+
155
+ radio_menu_item('Rotate Left on Up Arrow') { |r|
156
+ checked <=> [@game, :rotate_left_on_up]
161
157
  }
162
158
  }
163
159
 
@@ -169,6 +165,7 @@ class Tetris
169
165
  end
170
166
  }
171
167
  end
168
+
172
169
  menu_item('About') {
173
170
  on_clicked do
174
171
  show_about_dialog
Binary file
@@ -29,6 +29,11 @@ module Glimmer
29
29
  # Follows the Proxy Design Pattern
30
30
  class CheckboxProxy < ControlProxy
31
31
  DEFAULT_TEXT = ''
32
+
33
+ def data_bind(property, model_binding)
34
+ super
35
+ handle_listener('on_toggled') { model_binding.call(checked) } if property == 'checked'
36
+ end
32
37
 
33
38
  private
34
39
 
@@ -65,7 +65,7 @@ module Glimmer
65
65
  alias selected_item= selected_item
66
66
 
67
67
  def data_bind(property, model_binding)
68
- super
68
+ super # model to view data-binding
69
69
  case property
70
70
  when 'selected'
71
71
  handle_listener('on_selected') { model_binding.call(selected) }
@@ -39,11 +39,11 @@ module Glimmer
39
39
  end
40
40
  alias set_items items
41
41
  alias items= items
42
- end
43
-
44
- def data_bind(property, model_binding)
45
- super
46
- handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
42
+
43
+ def data_bind(property, model_binding)
44
+ super
45
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
46
+ end
47
47
  end
48
48
  end
49
49
  end
@@ -29,6 +29,11 @@ module Glimmer
29
29
  #
30
30
  # Follows the Proxy Design Pattern
31
31
  class CheckMenuItemProxy < MenuItemProxy
32
+ def data_bind(property, model_binding)
33
+ super
34
+ handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
35
+ end
36
+
32
37
  private
33
38
 
34
39
  def build_control
@@ -29,15 +29,23 @@ module Glimmer
29
29
  #
30
30
  # Follows the Proxy Design Pattern
31
31
  class RadioMenuItemProxy < MenuItemProxy
32
+ def initialize(keyword, parent, args, &block)
33
+ @last_checked = nil
34
+ super
35
+ end
36
+
32
37
  def checked(value = nil)
33
- if !value.nil?
34
- if Glimmer::LibUI.integer_to_boolean(value) != checked?
35
- super
38
+ if value.nil?
39
+ super()
40
+ else
41
+ super
42
+ if Glimmer::LibUI.integer_to_boolean(value, allow_nil: false) != Glimmer::LibUI.integer_to_boolean(@last_checked, allow_nil: false)
36
43
  if Glimmer::LibUI.integer_to_boolean(value)
37
44
  (@parent_proxy.children - [self]).select {|c| c.is_a?(MenuItemProxy)}.each do |menu_item|
38
45
  menu_item.checked = false
39
46
  end
40
47
  end
48
+ @last_checked = checked
41
49
  end
42
50
  end
43
51
  end
@@ -48,7 +56,7 @@ module Glimmer
48
56
  def handle_listener(listener_name, &listener)
49
57
  if listener_name.to_s == 'on_clicked'
50
58
  radio_listener = Proc.new do
51
- self.checked = true if !checked?
59
+ self.checked = true
52
60
  listener.call(self)
53
61
  end
54
62
  super(listener_name, &radio_listener)
@@ -57,6 +65,11 @@ module Glimmer
57
65
  end
58
66
  end
59
67
 
68
+ def data_bind(property, model_binding)
69
+ super
70
+ handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
71
+ end
72
+
60
73
  private
61
74
 
62
75
  def build_control
@@ -39,6 +39,26 @@ module Glimmer
39
39
  end
40
40
  alias set_items items
41
41
  alias items= items
42
+
43
+ def selected_item(value = nil)
44
+ if value.nil?
45
+ items[selected]
46
+ else
47
+ self.selected = items.index(value) || -1
48
+ end
49
+ end
50
+ alias set_selected_item selected_item
51
+ alias selected_item= selected_item
52
+
53
+ def data_bind(property, model_binding)
54
+ super # model to view data-binding
55
+ case property
56
+ when 'selected'
57
+ handle_listener('on_selected') { model_binding.call(selected) }
58
+ when 'selected_item'
59
+ handle_listener('on_selected') { model_binding.call(selected_item) }
60
+ end
61
+ end
42
62
  end
43
63
  end
44
64
  end
@@ -245,8 +245,8 @@ module Glimmer
245
245
  args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
246
246
  args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
247
247
  if property.to_s == 'checked'
248
- current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui))
249
- new_value = Glimmer::LibUI.integer_to_boolean(args[0])
248
+ current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui), allow_nil: false)
249
+ new_value = Glimmer::LibUI.integer_to_boolean(args[0], allow_nil: false)
250
250
  ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args) if new_value != current_value
251
251
  else
252
252
  ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh