glimmer-dsl-libui 0.4.5 → 0.4.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/README.md +388 -57
- data/VERSION +1 -1
- data/examples/button_counter.rb +2 -1
- data/examples/color_button.rb +18 -13
- data/examples/color_button2.rb +14 -0
- data/examples/date_time_picker.rb +19 -14
- data/examples/date_time_picker2.rb +20 -0
- data/examples/font_button.rb +17 -12
- data/examples/font_button2.rb +18 -0
- data/examples/histogram.rb +1 -6
- data/examples/meta_example.rb +17 -6
- data/examples/midi_player.rb +5 -6
- data/examples/midi_player2.rb +83 -0
- data/examples/midi_player3.rb +84 -0
- data/examples/snake.rb +19 -10
- data/examples/tetris.rb +15 -18
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/checkbox_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +17 -2
- data/lib/glimmer/libui/control_proxy/date_time_picker_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +8 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/check_menu_item_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +16 -4
- data/lib/glimmer/libui/control_proxy/multiline_entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +19 -0
- data/lib/glimmer/libui/control_proxy/slider_proxy.rb +37 -0
- data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy.rb +2 -2
- data/lib/glimmer/libui/data_bindable.rb +27 -2
- metadata +8 -2
@@ -2,19 +2,24 @@
|
|
2
2
|
|
3
3
|
require 'glimmer-dsl-libui'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
date_time_picker { |dtp|
|
10
|
-
on_changed do
|
11
|
-
time = dtp.time
|
12
|
-
p time
|
13
|
-
end
|
14
|
-
}
|
15
|
-
}
|
5
|
+
class DateTimePicker
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
attr_accessor :picked_time
|
16
9
|
|
17
|
-
|
18
|
-
|
10
|
+
def launch
|
11
|
+
window('Date Time Pickers', 300, 200) {
|
12
|
+
vertical_box {
|
13
|
+
date_time_picker {
|
14
|
+
time <=> [self, :picked_time, after_write: ->(time) { p time }]
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
on_closing do
|
19
|
+
puts 'Bye Bye'
|
20
|
+
end
|
21
|
+
}.show
|
19
22
|
end
|
20
|
-
|
23
|
+
end
|
24
|
+
|
25
|
+
DateTimePicker.new.launch
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
include Glimmer
|
6
|
+
|
7
|
+
window('Date Time Pickers', 300, 200) {
|
8
|
+
vertical_box {
|
9
|
+
date_time_picker { |dtp|
|
10
|
+
on_changed do
|
11
|
+
time = dtp.time
|
12
|
+
p time
|
13
|
+
end
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
on_closing do
|
18
|
+
puts 'Bye Bye'
|
19
|
+
end
|
20
|
+
}.show
|
data/examples/font_button.rb
CHANGED
@@ -2,17 +2,22 @@
|
|
2
2
|
|
3
3
|
require 'glimmer-dsl-libui'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
on_changed do
|
10
|
-
font_descriptor = fb.font
|
11
|
-
p font_descriptor
|
12
|
-
end
|
13
|
-
}
|
5
|
+
class FontButton
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
attr_accessor :font_descriptor
|
14
9
|
|
15
|
-
|
16
|
-
|
10
|
+
def launch
|
11
|
+
window('hello world', 300, 200) {
|
12
|
+
font_button {
|
13
|
+
font <=> [self, :font_descriptor, after_write: -> { p font_descriptor }]
|
14
|
+
}
|
15
|
+
|
16
|
+
on_closing do
|
17
|
+
puts 'Bye Bye'
|
18
|
+
end
|
19
|
+
}.show
|
17
20
|
end
|
18
|
-
|
21
|
+
end
|
22
|
+
|
23
|
+
FontButton.new.launch
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
include Glimmer
|
6
|
+
|
7
|
+
window('hello world', 300, 200) {
|
8
|
+
font_button { |fb|
|
9
|
+
on_changed do
|
10
|
+
font_descriptor = fb.font
|
11
|
+
p font_descriptor
|
12
|
+
end
|
13
|
+
}
|
14
|
+
|
15
|
+
on_closing do
|
16
|
+
puts 'Bye Bye'
|
17
|
+
end
|
18
|
+
}.show
|
data/examples/histogram.rb
CHANGED
@@ -71,12 +71,7 @@ class Histogram
|
|
71
71
|
|
72
72
|
color_button { |cb|
|
73
73
|
stretchy false
|
74
|
-
color
|
75
|
-
|
76
|
-
on_changed do
|
77
|
-
@histogram_color = cb.color
|
78
|
-
@area.queue_redraw_all
|
79
|
-
end
|
74
|
+
color <=> [self, :histogram_color, after_write: -> { @area.queue_redraw_all }]
|
80
75
|
}
|
81
76
|
}
|
82
77
|
|
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
@@ -6,6 +6,8 @@ class TinyMidiPlayer
|
|
6
6
|
include Glimmer
|
7
7
|
|
8
8
|
VERSION = '0.0.1'
|
9
|
+
|
10
|
+
attr_accessor :selected_file
|
9
11
|
|
10
12
|
def initialize
|
11
13
|
@pid = nil
|
@@ -68,13 +70,10 @@ class TinyMidiPlayer
|
|
68
70
|
}
|
69
71
|
}
|
70
72
|
|
71
|
-
combobox {
|
73
|
+
combobox {
|
72
74
|
items @midi_files.map { |path| File.basename(path) }
|
73
|
-
|
74
|
-
|
75
|
-
@selected_file = @midi_files[c.selected]
|
76
|
-
play_midi if @th&.alive?
|
77
|
-
end
|
75
|
+
# data-bind selected item (String) to self.selected_file with on-read/on-write converters and after_write operation
|
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? }]
|
78
77
|
}
|
79
78
|
}
|
80
79
|
}.show
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
class TinyMidiPlayer
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
VERSION = '0.0.1'
|
9
|
+
|
10
|
+
attr_accessor :selected_file
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@pid = nil
|
14
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
15
|
+
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
16
|
+
.sort_by { |path| File.basename(path) }
|
17
|
+
at_exit { stop_midi }
|
18
|
+
create_gui
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop_midi
|
22
|
+
if @pid
|
23
|
+
Process.kill(:SIGKILL, @pid) if @th.alive?
|
24
|
+
@pid = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def play_midi
|
29
|
+
stop_midi
|
30
|
+
if @pid.nil? && @selected_file
|
31
|
+
begin
|
32
|
+
@pid = spawn "timidity #{@selected_file}"
|
33
|
+
@th = Process.detach @pid
|
34
|
+
rescue Errno::ENOENT
|
35
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
36
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def show_version
|
42
|
+
msg_box('Tiny Midi Player',
|
43
|
+
"Written in Ruby\n" \
|
44
|
+
"https://github.com/kojix2/libui\n" \
|
45
|
+
"Version #{VERSION}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_gui
|
49
|
+
menu('Help') {
|
50
|
+
menu_item('Version') {
|
51
|
+
on_clicked do
|
52
|
+
show_version
|
53
|
+
end
|
54
|
+
}
|
55
|
+
}
|
56
|
+
window('Tiny Midi Player', 200, 50) {
|
57
|
+
horizontal_box {
|
58
|
+
vertical_box {
|
59
|
+
stretchy false
|
60
|
+
|
61
|
+
button('▶') {
|
62
|
+
on_clicked do
|
63
|
+
play_midi
|
64
|
+
end
|
65
|
+
}
|
66
|
+
button('■') {
|
67
|
+
on_clicked do
|
68
|
+
stop_midi
|
69
|
+
end
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
combobox { |c|
|
74
|
+
items @midi_files.map { |path| File.basename(path) }
|
75
|
+
# data-bind selected index (Integer) to self.selected_file with on-read/on-write converters and after_write operation
|
76
|
+
selected <=> [self, :selected_file, on_read: ->(f) {@midi_files.index(f)}, on_write: ->(i) {@midi_files[i]}, after_write: -> { play_midi if @th&.alive? }]
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}.show
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
TinyMidiPlayer.new
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
class TinyMidiPlayer
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
VERSION = '0.0.1'
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@pid = nil
|
12
|
+
@music_directory = File.expand_path('../sounds', __dir__)
|
13
|
+
@midi_files = Dir.glob(File.join(@music_directory, '**/*.mid'))
|
14
|
+
.sort_by { |path| File.basename(path) }
|
15
|
+
at_exit { stop_midi }
|
16
|
+
create_gui
|
17
|
+
end
|
18
|
+
|
19
|
+
def stop_midi
|
20
|
+
if @pid
|
21
|
+
Process.kill(:SIGKILL, @pid) if @th.alive?
|
22
|
+
@pid = nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def play_midi
|
27
|
+
stop_midi
|
28
|
+
if @pid.nil? && @selected_file
|
29
|
+
begin
|
30
|
+
@pid = spawn "timidity #{@selected_file}"
|
31
|
+
@th = Process.detach @pid
|
32
|
+
rescue Errno::ENOENT
|
33
|
+
warn 'Timidty++ not found. Please install Timidity++.'
|
34
|
+
warn 'https://sourceforge.net/projects/timidity/'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def show_version
|
40
|
+
msg_box('Tiny Midi Player',
|
41
|
+
"Written in Ruby\n" \
|
42
|
+
"https://github.com/kojix2/libui\n" \
|
43
|
+
"Version #{VERSION}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_gui
|
47
|
+
menu('Help') {
|
48
|
+
menu_item('Version') {
|
49
|
+
on_clicked do
|
50
|
+
show_version
|
51
|
+
end
|
52
|
+
}
|
53
|
+
}
|
54
|
+
window('Tiny Midi Player', 200, 50) {
|
55
|
+
horizontal_box {
|
56
|
+
vertical_box {
|
57
|
+
stretchy false
|
58
|
+
|
59
|
+
button('▶') {
|
60
|
+
on_clicked do
|
61
|
+
play_midi
|
62
|
+
end
|
63
|
+
}
|
64
|
+
button('■') {
|
65
|
+
on_clicked do
|
66
|
+
stop_midi
|
67
|
+
end
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
combobox { |c|
|
72
|
+
items @midi_files.map { |path| File.basename(path) }
|
73
|
+
|
74
|
+
on_selected do
|
75
|
+
@selected_file = @midi_files[c.selected]
|
76
|
+
play_midi if @th&.alive?
|
77
|
+
end
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}.show
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
TinyMidiPlayer.new
|
data/examples/snake.rb
CHANGED
@@ -12,6 +12,7 @@ class Snake
|
|
12
12
|
@game = Model::Game.new
|
13
13
|
@grid = Presenter::Grid.new(@game)
|
14
14
|
@game.start
|
15
|
+
@keypress_queue = []
|
15
16
|
create_gui
|
16
17
|
register_observers
|
17
18
|
end
|
@@ -31,7 +32,23 @@ class Snake
|
|
31
32
|
end
|
32
33
|
|
33
34
|
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
34
|
-
|
35
|
+
unless @game.over?
|
36
|
+
process_queued_keypress
|
37
|
+
@game.snake.move
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_queued_keypress
|
43
|
+
# key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
|
44
|
+
key = @keypress_queue.shift
|
45
|
+
case [@game.snake.head.orientation, key]
|
46
|
+
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
47
|
+
@game.snake.turn_right
|
48
|
+
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
49
|
+
@game.snake.turn_left
|
50
|
+
else
|
51
|
+
# No Op
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
@@ -56,15 +73,7 @@ class Snake
|
|
56
73
|
}
|
57
74
|
|
58
75
|
on_key_up do |area_key_event|
|
59
|
-
|
60
|
-
case orientation_and_key
|
61
|
-
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
62
|
-
@game.snake.turn_right
|
63
|
-
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
64
|
-
@game.snake.turn_left
|
65
|
-
else
|
66
|
-
# No Op
|
67
|
-
end
|
76
|
+
@keypress_queue << area_key_event[:ext_key]
|
68
77
|
end
|
69
78
|
}
|
70
79
|
end
|
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,10 @@ module Glimmer
|
|
29
29
|
# Follows the Proxy Design Pattern
|
30
30
|
class CheckboxProxy < ControlProxy
|
31
31
|
DEFAULT_TEXT = ''
|
32
|
+
|
33
|
+
def data_bind_write(property, model_binding)
|
34
|
+
handle_listener('on_toggled') { model_binding.call(checked) } if property == 'checked'
|
35
|
+
end
|
32
36
|
|
33
37
|
private
|
34
38
|
|
@@ -54,8 +54,23 @@ module Glimmer
|
|
54
54
|
alias set_items items
|
55
55
|
alias items= items
|
56
56
|
|
57
|
-
def selected_item
|
58
|
-
|
57
|
+
def selected_item(value = nil)
|
58
|
+
if value.nil?
|
59
|
+
items[selected]
|
60
|
+
else
|
61
|
+
self.selected = items.index(value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias set_selected_item selected_item
|
65
|
+
alias selected_item= selected_item
|
66
|
+
|
67
|
+
def data_bind_write(property, model_binding)
|
68
|
+
case property
|
69
|
+
when 'selected'
|
70
|
+
handle_listener('on_selected') { model_binding.call(selected) }
|
71
|
+
when 'selected_item'
|
72
|
+
handle_listener('on_selected') { model_binding.call(selected_item) }
|
73
|
+
end
|
59
74
|
end
|
60
75
|
end
|
61
76
|
end
|
@@ -28,8 +28,7 @@ module Glimmer
|
|
28
28
|
#
|
29
29
|
# Follows the Proxy Design Pattern
|
30
30
|
class EntryProxy < ControlProxy
|
31
|
-
def
|
32
|
-
super
|
31
|
+
def data_bind_write(property, model_binding)
|
33
32
|
handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
|
34
33
|
end
|
35
34
|
|
@@ -64,6 +64,14 @@ module Glimmer
|
|
64
64
|
::LibUI.free_font_button_font(@font_descriptor) unless @font_descriptor.nil?
|
65
65
|
super
|
66
66
|
end
|
67
|
+
|
68
|
+
def data_bind_read(property, model_binding)
|
69
|
+
# No Op
|
70
|
+
end
|
71
|
+
|
72
|
+
def data_bind_write(property, model_binding)
|
73
|
+
handle_listener('on_changed') { model_binding.call(font) } if property == 'font'
|
74
|
+
end
|
67
75
|
end
|
68
76
|
end
|
69
77
|
end
|
@@ -29,6 +29,10 @@ module Glimmer
|
|
29
29
|
#
|
30
30
|
# Follows the Proxy Design Pattern
|
31
31
|
class CheckMenuItemProxy < MenuItemProxy
|
32
|
+
def data_bind_write(property, model_binding)
|
33
|
+
handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
|
34
|
+
end
|
35
|
+
|
32
36
|
private
|
33
37
|
|
34
38
|
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,10 @@ module Glimmer
|
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
68
|
+
def data_bind_write(property, model_binding)
|
69
|
+
handle_listener('on_clicked') { model_binding.call(checked) } if property == 'checked'
|
70
|
+
end
|
71
|
+
|
60
72
|
private
|
61
73
|
|
62
74
|
def build_control
|
@@ -28,8 +28,7 @@ module Glimmer
|
|
28
28
|
#
|
29
29
|
# Follows the Proxy Design Pattern
|
30
30
|
class MultilineEntryProxy < ControlProxy
|
31
|
-
def
|
32
|
-
super
|
31
|
+
def data_bind_write(property, model_binding)
|
33
32
|
handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
|
34
33
|
end
|
35
34
|
|