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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +25 -23
- data/VERSION +1 -1
- data/examples/button_counter.rb +2 -1
- data/examples/meta_example.rb +17 -6
- data/examples/midi_player.rb +1 -1
- data/examples/tetris.rb +15 -18
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/checkbox_proxy.rb +5 -0
- data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +1 -1
- data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +5 -5
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/check_menu_item_proxy.rb +5 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +17 -4
- data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +20 -0
- data/lib/glimmer/libui/control_proxy.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 122c9e87c9613b6ebb29722c0c7d602b0850f369c613374b21df38699e61e669
|
4
|
+
data.tar.gz: fb156f42398d2c8d419de476dfe435fbdfe872545da343daadd035ed2667775c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
[](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[](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.
|
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
|

|
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
|
-
|
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 {
|
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 {
|
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
|
-
|
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
|
-
|
8434
|
-
|
8435
|
-
|
8436
|
-
end
|
8438
|
+
|
8439
|
+
radio_menu_item('Rotate Right on Up Arrow') { |r|
|
8440
|
+
checked <=> [@game, :rotate_right_on_up]
|
8437
8441
|
}
|
8438
|
-
|
8439
|
-
|
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.
|
1
|
+
0.4.8
|
data/examples/button_counter.rb
CHANGED
@@ -13,7 +13,8 @@ class ButtonCounter
|
|
13
13
|
window('Hello, Button!', 190, 20) {
|
14
14
|
vertical_box {
|
15
15
|
button {
|
16
|
-
|
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
|
data/examples/meta_example.rb
CHANGED
@@ -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
|
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
|
-
|
40
|
+
append_versions(basic_examples)
|
35
41
|
end
|
36
42
|
|
37
43
|
def advanced_examples_with_versions
|
38
|
-
|
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',
|
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])
|
data/examples/midi_player.rb
CHANGED
@@ -70,7 +70,7 @@ class TinyMidiPlayer
|
|
70
70
|
}
|
71
71
|
}
|
72
72
|
|
73
|
-
combobox {
|
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
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
150
|
+
|
151
|
+
radio_menu_item('Rotate Right on Up Arrow') { |r|
|
152
|
+
checked <=> [@game, :rotate_right_on_up]
|
154
153
|
}
|
155
|
-
|
156
|
-
|
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
|
data/glimmer-dsl-libui.gemspec
CHANGED
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
|
|
@@ -39,11 +39,11 @@ module Glimmer
|
|
39
39
|
end
|
40
40
|
alias set_items items
|
41
41
|
alias items= items
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
34
|
-
|
35
|
-
|
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
|
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)
|