glimmer-dsl-libui 0.4.7 → 0.4.8

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: 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