glimmer-dsl-swt 4.17.10.4 → 4.18.0.0
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 +35 -0
- data/README.md +83 -56
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +51 -30
- data/lib/glimmer-dsl-swt.rb +1 -0
- data/lib/glimmer/swt/image_proxy.rb +11 -10
- data/lib/glimmer/swt/layout_proxy.rb +7 -3
- data/lib/glimmer/swt/menu_proxy.rb +9 -5
- data/lib/glimmer/swt/sash_form_proxy.rb +1 -1
- data/lib/glimmer/swt/style_constantizable.rb +8 -4
- data/lib/glimmer/swt/widget_proxy.rb +69 -23
- data/samples/elaborate/login.rb +10 -13
- data/samples/elaborate/meta_sample.rb +77 -19
- data/samples/hello/hello_browser.rb +2 -0
- data/samples/hello/hello_button.rb +46 -0
- data/samples/hello/hello_computed.rb +9 -3
- data/samples/hello/hello_link.rb +80 -0
- data/samples/hello/hello_list_multi_selection.rb +22 -17
- data/samples/hello/hello_list_single_selection.rb +5 -5
- data/samples/hello/hello_menu_bar.rb +184 -28
- data/samples/hello/hello_message_box.rb +9 -8
- data/samples/hello/hello_pop_up_context_menu.rb +33 -6
- data/vendor/swt/linux/swt.jar +0 -0
- data/vendor/swt/mac/swt.jar +0 -0
- data/vendor/swt/windows/swt.jar +0 -0
- metadata +54 -34
data/samples/elaborate/login.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2020 Andy Maleh
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
5
5
|
# "Software"), to deal in the Software without restriction, including
|
@@ -7,10 +7,10 @@
|
|
7
7
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
# permit persons to whom the Software is furnished to do so, subject to
|
9
9
|
# the following conditions:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# The above copyright notice and this permission notice shall be
|
12
12
|
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
15
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
16
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -19,7 +19,6 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
-
#Presents login screen data
|
23
22
|
class LoginPresenter
|
24
23
|
|
25
24
|
attr_accessor :user_name
|
@@ -35,7 +34,6 @@ class LoginPresenter
|
|
35
34
|
def status=(status)
|
36
35
|
@status = status
|
37
36
|
|
38
|
-
#TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
|
39
37
|
notify_observers("logged_in")
|
40
38
|
notify_observers("logged_out")
|
41
39
|
end
|
@@ -65,7 +63,6 @@ class LoginPresenter
|
|
65
63
|
|
66
64
|
end
|
67
65
|
|
68
|
-
#Login screen
|
69
66
|
class Login
|
70
67
|
include Glimmer
|
71
68
|
|
@@ -77,10 +74,10 @@ class Login
|
|
77
74
|
grid_layout 2, false #two columns with differing widths
|
78
75
|
|
79
76
|
label { text "Username:" } # goes in column 1
|
80
|
-
@user_name_text = text {
|
77
|
+
@user_name_text = text { # goes in column 2
|
81
78
|
text bind(presenter, :user_name)
|
82
79
|
enabled bind(presenter, :logged_out)
|
83
|
-
on_key_pressed { |event|
|
80
|
+
on_key_pressed { |event|
|
84
81
|
@password_text.set_focus if event.keyCode == swt(:cr)
|
85
82
|
}
|
86
83
|
}
|
@@ -89,7 +86,7 @@ class Login
|
|
89
86
|
@password_text = text(:password, :border) {
|
90
87
|
text bind(presenter, :password)
|
91
88
|
enabled bind(presenter, :logged_out)
|
92
|
-
on_key_pressed { |event|
|
89
|
+
on_key_pressed { |event|
|
93
90
|
presenter.login if event.keyCode == swt(:cr)
|
94
91
|
}
|
95
92
|
}
|
@@ -101,21 +98,21 @@ class Login
|
|
101
98
|
text "Login"
|
102
99
|
enabled bind(presenter, :logged_out)
|
103
100
|
on_widget_selected { presenter.login }
|
104
|
-
on_key_pressed { |event|
|
101
|
+
on_key_pressed { |event|
|
105
102
|
presenter.login if event.keyCode == swt(:cr)
|
106
|
-
}
|
103
|
+
}
|
107
104
|
}
|
108
105
|
|
109
106
|
button {
|
110
107
|
text "Logout"
|
111
108
|
enabled bind(presenter, :logged_in)
|
112
109
|
on_widget_selected { presenter.logout }
|
113
|
-
on_key_pressed { |event|
|
110
|
+
on_key_pressed { |event|
|
114
111
|
if event.keyCode == swt(:cr)
|
115
112
|
presenter.logout
|
116
113
|
@user_name_text.set_focus
|
117
114
|
end
|
118
|
-
}
|
115
|
+
}
|
119
116
|
}
|
120
117
|
}
|
121
118
|
}
|
@@ -1,4 +1,9 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'etc'
|
3
|
+
|
1
4
|
class Sample
|
5
|
+
include Glimmer::DataBinding::ObservableModel
|
6
|
+
|
2
7
|
attr_accessor :sample_directory, :file, :selected
|
3
8
|
|
4
9
|
def initialize(file, sample_directory: )
|
@@ -19,12 +24,39 @@ class Sample
|
|
19
24
|
@name
|
20
25
|
end
|
21
26
|
|
22
|
-
def
|
23
|
-
|
27
|
+
def code
|
28
|
+
reset_code! if @code.nil?
|
29
|
+
@code
|
24
30
|
end
|
25
|
-
|
26
|
-
def
|
27
|
-
|
31
|
+
|
32
|
+
def reset_code!
|
33
|
+
@code = File.read(file)
|
34
|
+
notify_observers('code')
|
35
|
+
end
|
36
|
+
|
37
|
+
def editable
|
38
|
+
File.basename(file) != 'meta_sample.rb'
|
39
|
+
end
|
40
|
+
alias launchable editable
|
41
|
+
|
42
|
+
def launch(modified_code)
|
43
|
+
parent_directory = File.basename(File.dirname(file))
|
44
|
+
modified_file_parent_directory = File.join(Etc.getpwuid.dir, '.glimmer', 'samples', parent_directory)
|
45
|
+
launch_file = modified_file = File.join(modified_file_parent_directory, File.basename(file))
|
46
|
+
begin
|
47
|
+
FileUtils.mkdir_p(modified_file_parent_directory)
|
48
|
+
FileUtils.cp_r(file, modified_file_parent_directory)
|
49
|
+
FileUtils.cp_r(file.sub(/\.rb/, ''), modified_file_parent_directory) if File.exist?(file.sub(/\.rb/, ''))
|
50
|
+
File.write(modified_file, modified_code)
|
51
|
+
rescue => e
|
52
|
+
puts 'Error writing sample modifications. Launching original sample.'
|
53
|
+
puts e.full_message
|
54
|
+
launch_file = file # load original file if failed to write changes
|
55
|
+
end
|
56
|
+
load(launch_file)
|
57
|
+
ensure
|
58
|
+
FileUtils.rm_rf(modified_file)
|
59
|
+
FileUtils.rm_rf(modified_file.sub(/\.rb/, ''))
|
28
60
|
end
|
29
61
|
end
|
30
62
|
|
@@ -111,18 +143,23 @@ end
|
|
111
143
|
class MetaSampleApplication
|
112
144
|
include Glimmer
|
113
145
|
|
146
|
+
def initialize
|
147
|
+
selected_sample_directory = SampleDirectory.sample_directories.first
|
148
|
+
selected_sample = selected_sample_directory.samples.first
|
149
|
+
selected_sample_directory.selected_sample_name = selected_sample.name
|
150
|
+
end
|
151
|
+
|
114
152
|
def launch
|
115
153
|
shell {
|
116
154
|
minimum_size 1280, 768
|
117
155
|
text 'Glimmer Meta-Sample (The Sample of Samples)'
|
118
156
|
|
119
|
-
on_swt_show {
|
120
|
-
SampleDirectory.selected_sample = SampleDirectory.all_samples.first
|
121
|
-
}
|
122
|
-
|
123
157
|
sash_form {
|
124
158
|
composite {
|
125
|
-
grid_layout
|
159
|
+
grid_layout(1, false) {
|
160
|
+
margin_width 0
|
161
|
+
margin_height 0
|
162
|
+
}
|
126
163
|
|
127
164
|
expand_bar {
|
128
165
|
layout_data(:fill, :fill, true, true)
|
@@ -144,22 +181,43 @@ class MetaSampleApplication
|
|
144
181
|
}
|
145
182
|
}
|
146
183
|
|
147
|
-
|
184
|
+
composite {
|
185
|
+
fill_layout
|
148
186
|
layout_data(:fill, :center, true, false) {
|
149
187
|
height_hint 120
|
150
188
|
}
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
189
|
+
|
190
|
+
button {
|
191
|
+
text 'Launch'
|
192
|
+
font height: 30
|
193
|
+
enabled bind(SampleDirectory, 'selected_sample.launchable')
|
194
|
+
|
195
|
+
on_widget_selected {
|
196
|
+
begin
|
197
|
+
SampleDirectory.selected_sample.launch(@code_text.text)
|
198
|
+
rescue StandardError, SyntaxError => launch_error
|
199
|
+
message_box {
|
200
|
+
text 'Error Launching'
|
201
|
+
message launch_error.full_message
|
202
|
+
}.open
|
203
|
+
end
|
204
|
+
}
|
205
|
+
}
|
206
|
+
button {
|
207
|
+
text 'Reset'
|
208
|
+
font height: 30
|
209
|
+
enabled bind(SampleDirectory, 'selected_sample.editable')
|
210
|
+
|
211
|
+
on_widget_selected {
|
212
|
+
SampleDirectory.selected_sample.reset_code!
|
213
|
+
}
|
155
214
|
}
|
156
215
|
}
|
157
216
|
}
|
158
217
|
|
159
|
-
code_text {
|
160
|
-
text bind(SampleDirectory, 'selected_sample.
|
161
|
-
editable
|
162
|
-
caret nil
|
218
|
+
@code_text = code_text {
|
219
|
+
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
220
|
+
editable bind(SampleDirectory, 'selected_sample.editable')
|
163
221
|
}
|
164
222
|
|
165
223
|
weights 4, 9
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright (c) 2007-2020 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
|
+
class HelloButton
|
23
|
+
include Glimmer
|
24
|
+
|
25
|
+
attr_accessor :count
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@count = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def launch
|
32
|
+
shell {
|
33
|
+
text 'Hello, Button!'
|
34
|
+
|
35
|
+
button {
|
36
|
+
text bind(self, :count) {|value| "Click To Increment: #{value} "}
|
37
|
+
|
38
|
+
on_widget_selected {
|
39
|
+
self.count += 1
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}.open
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
HelloButton.new.launch
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2020 Andy Maleh
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
5
5
|
# "Software"), to deal in the Software without restriction, including
|
@@ -7,10 +7,10 @@
|
|
7
7
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
# permit persons to whom the Software is furnished to do so, subject to
|
9
9
|
# the following conditions:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# The above copyright notice and this permission notice shall be
|
12
12
|
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
15
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
16
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -35,6 +35,7 @@ class HelloComputed
|
|
35
35
|
def launch
|
36
36
|
shell {
|
37
37
|
text 'Hello, Computed!'
|
38
|
+
|
38
39
|
composite {
|
39
40
|
grid_layout {
|
40
41
|
num_columns 2
|
@@ -42,6 +43,7 @@ class HelloComputed
|
|
42
43
|
horizontal_spacing 20
|
43
44
|
vertical_spacing 10
|
44
45
|
}
|
46
|
+
|
45
47
|
label {text 'First &Name: '}
|
46
48
|
text {
|
47
49
|
text bind(@contact, :first_name)
|
@@ -50,6 +52,7 @@ class HelloComputed
|
|
50
52
|
grab_excess_horizontal_space true
|
51
53
|
}
|
52
54
|
}
|
55
|
+
|
53
56
|
label {text '&Last Name: '}
|
54
57
|
text {
|
55
58
|
text bind(@contact, :last_name)
|
@@ -58,6 +61,7 @@ class HelloComputed
|
|
58
61
|
grab_excess_horizontal_space true
|
59
62
|
}
|
60
63
|
}
|
64
|
+
|
61
65
|
label {text '&Year of Birth: '}
|
62
66
|
text {
|
63
67
|
text bind(@contact, :year_of_birth)
|
@@ -66,6 +70,7 @@ class HelloComputed
|
|
66
70
|
grab_excess_horizontal_space true
|
67
71
|
}
|
68
72
|
}
|
73
|
+
|
69
74
|
label {text 'Name: '}
|
70
75
|
label {
|
71
76
|
text bind(@contact, :name, computed_by: [:first_name, :last_name])
|
@@ -74,6 +79,7 @@ class HelloComputed
|
|
74
79
|
grab_excess_horizontal_space true
|
75
80
|
}
|
76
81
|
}
|
82
|
+
|
77
83
|
label {text 'Age: '}
|
78
84
|
label {
|
79
85
|
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Copyright (c) 2007-2020 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
|
+
include Glimmer
|
23
|
+
|
24
|
+
shell { |main_shell|
|
25
|
+
grid_layout {
|
26
|
+
margin_width 20
|
27
|
+
margin_height 10
|
28
|
+
}
|
29
|
+
|
30
|
+
background :white
|
31
|
+
text 'Hello, Link!'
|
32
|
+
|
33
|
+
@link = link {
|
34
|
+
background :white
|
35
|
+
link_foreground :dark_green
|
36
|
+
font height: 16
|
37
|
+
text <<~MULTI_LINE_STRING
|
38
|
+
|
39
|
+
You may click on any <a>link</a> to get help.
|
40
|
+
|
41
|
+
How do you know <a href="which-link-href-value">which link</a> you clicked?
|
42
|
+
|
43
|
+
Just keep clicking <a href="all links">links</a> to find out!
|
44
|
+
MULTI_LINE_STRING
|
45
|
+
|
46
|
+
on_widget_selected { |selection_event|
|
47
|
+
# This retrieves the clicked link href (or contained text if no href is set)
|
48
|
+
@selected_link = selection_event.text
|
49
|
+
}
|
50
|
+
on_mouse_up { |mouse_event|
|
51
|
+
unless @selected_link.nil?
|
52
|
+
@help_shell.close unless @help_shell.nil? || @help_shell.is_disposed
|
53
|
+
@help_shell = shell(:no_trim) {
|
54
|
+
grid_layout {
|
55
|
+
margin_width 10
|
56
|
+
margin_height 10
|
57
|
+
}
|
58
|
+
|
59
|
+
background :yellow
|
60
|
+
|
61
|
+
label {
|
62
|
+
background :yellow
|
63
|
+
text "Did someone ask for help about \"#{@selected_link}\"?\nYou don't really need help. You did it!"
|
64
|
+
}
|
65
|
+
|
66
|
+
on_swt_show {
|
67
|
+
x = main_shell.location.x + @link.location.x + mouse_event.x
|
68
|
+
y = main_shell.location.y + @link.location.y + mouse_event.y + 20
|
69
|
+
@help_shell.location = Point.new(x, y)
|
70
|
+
}
|
71
|
+
on_focus_lost {
|
72
|
+
@selected_link = nil
|
73
|
+
@help_shell.close
|
74
|
+
}
|
75
|
+
}
|
76
|
+
@help_shell.open
|
77
|
+
end
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}.open
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2020 Andy Maleh
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
5
5
|
# "Software"), to deal in the Software without restriction, including
|
@@ -7,10 +7,10 @@
|
|
7
7
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
# permit persons to whom the Software is furnished to do so, subject to
|
9
9
|
# the following conditions:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# The above copyright notice and this permission notice shall be
|
12
12
|
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
15
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
16
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -24,22 +24,27 @@ class HelloListMultiSelection
|
|
24
24
|
attr_accessor :provinces, :provinces_options
|
25
25
|
|
26
26
|
def initialize
|
27
|
-
self.provinces_options=[
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
27
|
+
self.provinces_options = [
|
28
|
+
'',
|
29
|
+
'Alberta',
|
30
|
+
'British Columbia',
|
31
|
+
'Manitoba',
|
32
|
+
'New Brunswick',
|
33
|
+
'Newfoundland and Labrador',
|
34
|
+
'Northwest Territories',
|
35
|
+
'Nova Scotia',
|
36
|
+
'Nunavut',
|
37
|
+
'Ontario',
|
38
|
+
'Prince Edward Island',
|
39
|
+
'Quebec',
|
40
|
+
'Saskatchewan',
|
41
|
+
'Yukon'
|
37
42
|
]
|
38
|
-
|
43
|
+
reset_provinces
|
39
44
|
end
|
40
45
|
|
41
46
|
def reset_provinces
|
42
|
-
self.provinces = [
|
47
|
+
self.provinces = ['Quebec', 'Manitoba', 'Alberta']
|
43
48
|
end
|
44
49
|
end
|
45
50
|
|
@@ -49,7 +54,7 @@ class HelloListMultiSelection
|
|
49
54
|
person = Person.new
|
50
55
|
|
51
56
|
shell {
|
52
|
-
grid_layout
|
57
|
+
grid_layout
|
53
58
|
|
54
59
|
text 'Hello, List Multi Selection!'
|
55
60
|
|
@@ -58,7 +63,7 @@ class HelloListMultiSelection
|
|
58
63
|
}
|
59
64
|
|
60
65
|
button {
|
61
|
-
text
|
66
|
+
text 'Reset Selections To Default Values'
|
62
67
|
|
63
68
|
on_widget_selected { person.reset_provinces }
|
64
69
|
}
|