wxruby3 0.9.3 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/INSTALL.md +1 -1
- data/README.md +2 -2
- data/ext/wxruby3/include/wxruby-ComboPopup.h +777 -0
- data/ext/wxruby3/include/wxruby-Config.h +23 -5
- data/ext/wxruby3/include/wxruby-Persistence.h +79 -0
- data/ext/wxruby3/swig/memory_management.i +6 -0
- data/lib/wx/core/book_ctrl_base.rb +16 -0
- data/lib/wx/core/combo_ctrl.rb +171 -0
- data/lib/wx/core/config.rb +454 -83
- data/lib/wx/core/notebook.rb +10 -8
- data/lib/wx/core/peristent_object.rb +15 -0
- data/lib/wx/core/persistence_manager.rb +39 -0
- data/lib/wx/core/persistent_window.rb +16 -0
- data/lib/wx/core/top_level_window.rb +16 -0
- data/lib/wx/core/treebook.rb +18 -0
- data/lib/wx/core.rb +4 -0
- data/lib/wx/doc/book_ctrl_base.rb +19 -0
- data/lib/wx/doc/comboctrl.rb +128 -3
- data/lib/wx/doc/config.rb +101 -41
- data/lib/wx/doc/extra/14_config.md +101 -0
- data/lib/wx/doc/extra/15_persistence.md +148 -0
- data/lib/wx/doc/owner_drawn_combobox.rb +5 -1
- data/lib/wx/doc/persistence_manager.rb +36 -0
- data/lib/wx/doc/persistent_object.rb +27 -0
- data/lib/wx/doc/top_level_window.rb +19 -0
- data/lib/wx/doc/treebook.rb +6 -1
- data/lib/wx/version.rb +1 -1
- data/rakelib/build.rb +1 -1
- data/rakelib/lib/core/include/funcall.inc +2 -1
- data/rakelib/lib/core/package.rb +22 -1
- data/rakelib/lib/core/spec.rb +10 -0
- data/rakelib/lib/core/spec_helper.rb +1 -1
- data/rakelib/lib/director/comboctrl.rb +104 -3
- data/rakelib/lib/director/config_base.rb +490 -19
- data/rakelib/lib/director/defs.rb +1 -3
- data/rakelib/lib/director/event_filter.rb +1 -1
- data/rakelib/lib/director/event_loop.rb +1 -1
- data/rakelib/lib/director/file_dialog_customize_hook.rb +2 -2
- data/rakelib/lib/director/gdicommon.rb +6 -0
- data/rakelib/lib/director/grid_cell_attr.rb +1 -1
- data/rakelib/lib/director/grid_cell_editor.rb +1 -1
- data/rakelib/lib/director/grid_cell_renderer.rb +1 -1
- data/rakelib/lib/director/header_ctrl.rb +3 -0
- data/rakelib/lib/director/html_listbox.rb +2 -1
- data/rakelib/lib/director/menu_item.rb +1 -1
- data/rakelib/lib/director/num_validator.rb +5 -7
- data/rakelib/lib/director/owner_drawn_combobox.rb +1 -0
- data/rakelib/lib/director/persistence_manager.rb +410 -0
- data/rakelib/lib/director/persistent_object.rb +70 -0
- data/rakelib/lib/director/persistent_window.rb +73 -0
- data/rakelib/lib/director/pgeditor.rb +1 -1
- data/rakelib/lib/director/pgproperties.rb +3 -3
- data/rakelib/lib/director/pgproperty.rb +5 -1
- data/rakelib/lib/director/richtext_style_listbox.rb +5 -0
- data/rakelib/lib/director/sizer.rb +1 -1
- data/rakelib/lib/director/static_bitmap.rb +4 -0
- data/rakelib/lib/director/text_entry.rb +1 -1
- data/rakelib/lib/director/window.rb +4 -0
- data/rakelib/lib/extractor/module.rb +15 -0
- data/rakelib/lib/generate/analyzer.rb +43 -43
- data/rakelib/lib/generate/doc/combo_ctrl.yaml +135 -0
- data/rakelib/lib/generate/doc/file_dialog_customize_hook.yaml +62 -0
- data/rakelib/lib/generate/doc/file_system.yaml +28 -0
- data/rakelib/lib/generate/doc.rb +1 -1
- data/rakelib/lib/generate/interface.rb +12 -4
- data/rakelib/lib/specs/interfaces.rb +3 -0
- data/rakelib/lib/swig_runner.rb +7 -4
- data/rakelib/lib/typemap/combo_popup.rb +42 -0
- data/rakelib/lib/typemap/config.rb +8 -0
- data/samples/widgets/widgets.rb +5 -9
- data/tests/test_combo_ctrl.rb +196 -0
- data/tests/test_config.rb +207 -42
- data/tests/test_persistence.rb +142 -0
- metadata +26 -2
@@ -0,0 +1,196 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
require_relative './lib/wxframe_runner'
|
6
|
+
require_relative './lib/text_entry_tests'
|
7
|
+
|
8
|
+
class ComboCtrlCtrlTests < WxRuby::Test::GUITests
|
9
|
+
|
10
|
+
include TextEntryTests
|
11
|
+
|
12
|
+
class LVComboPopup < Wx::ListView
|
13
|
+
|
14
|
+
include Wx::ComboPopup
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
# call default control ctor; need to call Wx::ListView#create later
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def init
|
22
|
+
@value = -1
|
23
|
+
end
|
24
|
+
|
25
|
+
def create(parent)
|
26
|
+
# need to finish creating the list view here
|
27
|
+
# as calling super here would just call Wx::ComboPopup#create and not Wx::ListView#create
|
28
|
+
# we need to use Ruby magic
|
29
|
+
wx_lv_create = (Wx::ListView.instance_method :create).bind(self)
|
30
|
+
wx_lv_create.call(parent, 1, [0,0], Wx::DEFAULT_SIZE)
|
31
|
+
evt_motion :on_mouse_move
|
32
|
+
evt_left_up :on_mouse_click
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return pointer to the created control
|
36
|
+
def get_control
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def lv_find_item(*args)
|
41
|
+
unless @wx_lv_find_item
|
42
|
+
@wx_lv_find_item = (Wx::ListView.instance_method :find_item).bind(self)
|
43
|
+
end
|
44
|
+
@wx_lv_find_item.call(*args)
|
45
|
+
end
|
46
|
+
protected :lv_find_item
|
47
|
+
|
48
|
+
# Translate string into a list selection
|
49
|
+
def set_string_value(s)
|
50
|
+
n = lv_find_item(-1, s)
|
51
|
+
if n >= 0 && n < get_item_count
|
52
|
+
select(n)
|
53
|
+
@value = n
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get list selection as a string
|
58
|
+
def get_string_value
|
59
|
+
return get_item_text(@value) if @value >= 0
|
60
|
+
''
|
61
|
+
end
|
62
|
+
|
63
|
+
# Do mouse hot-tracking (which is typical in list popups)
|
64
|
+
def on_mouse_move(event)
|
65
|
+
# Move selection to cursor ...
|
66
|
+
end
|
67
|
+
|
68
|
+
# On mouse left up, set the value and close the popup
|
69
|
+
def on_mouse_click(_event)
|
70
|
+
@value = get_first_selected
|
71
|
+
|
72
|
+
# Send event as well ...
|
73
|
+
|
74
|
+
dismiss
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def setup
|
80
|
+
super
|
81
|
+
@combo = Wx::ComboCtrl.new(frame_win, name: 'ComboCtrl')
|
82
|
+
@combo.set_popup_control(LVComboPopup.new)
|
83
|
+
end
|
84
|
+
|
85
|
+
def cleanup
|
86
|
+
@combo.destroy
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
attr_reader :combo
|
91
|
+
alias :text_entry :combo
|
92
|
+
|
93
|
+
def fill_list(list)
|
94
|
+
list.insert_item(0, 'This is the first item')
|
95
|
+
list.insert_item(1, 'This is the second item')
|
96
|
+
list.insert_item(2, 'This is the third item')
|
97
|
+
list.insert_item(3, 'This is the fourth item')
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_popup
|
101
|
+
assert_equal('', combo.get_value)
|
102
|
+
|
103
|
+
assert_kind_of(Wx::ComboPopup, combo.get_popup_control)
|
104
|
+
assert_kind_of(Wx::ListView, combo.get_popup_control)
|
105
|
+
assert_kind_of(Wx::ListView, combo.get_popup_control.get_control)
|
106
|
+
|
107
|
+
assert_nothing_raised { fill_list(combo.get_popup_control) }
|
108
|
+
combo.popup
|
109
|
+
|
110
|
+
combo.set_value_by_user('This is the second item')
|
111
|
+
|
112
|
+
assert_equal('This is the second item', combo.get_popup_control.get_string_value)
|
113
|
+
|
114
|
+
combo.dismiss
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
class OwnerDrawnCBTests < WxRuby::Test::GUITests
|
120
|
+
|
121
|
+
include TextEntryTests
|
122
|
+
|
123
|
+
class TestODComboBox < Wx::OwnerDrawnComboBox
|
124
|
+
|
125
|
+
def on_draw_item(dc, rect, item, _flags)
|
126
|
+
return if item == Wx::NOT_FOUND
|
127
|
+
|
128
|
+
dc.set_text_foreground(Wx::BLACK)
|
129
|
+
dc.draw_text(get_string(item),
|
130
|
+
rect.x + 3,
|
131
|
+
rect.y + ((rect.height - dc.char_height)/2))
|
132
|
+
end
|
133
|
+
|
134
|
+
def on_draw_background(dc, rect, item, flags)
|
135
|
+
# If item is selected or even, or we are painting the
|
136
|
+
# combo control itself, use the default rendering.
|
137
|
+
if flags.anybits?(Wx::ODCB_PAINTING_CONTROL|Wx::ODCB_PAINTING_SELECTED) || (item & 1) == 0
|
138
|
+
super(dc,rect,item,flags)
|
139
|
+
return
|
140
|
+
end
|
141
|
+
|
142
|
+
# Otherwise, draw every other background with different colour.
|
143
|
+
bgCol = Wx::Colour.new(240,240,250)
|
144
|
+
dc.set_brush(Wx::Brush.new(bgCol))
|
145
|
+
dc.set_pen(Wx::Pen.new(bgCol))
|
146
|
+
dc.draw_rectangle(rect)
|
147
|
+
end
|
148
|
+
|
149
|
+
def on_measure_item(_item)
|
150
|
+
48
|
151
|
+
end
|
152
|
+
|
153
|
+
def on_measure_item_width(_item)
|
154
|
+
-1 # default - will be measured from text width
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
def setup
|
160
|
+
super
|
161
|
+
@combo = TestODComboBox.new(frame_win, name: 'ODComboBox')
|
162
|
+
end
|
163
|
+
|
164
|
+
def cleanup
|
165
|
+
@combo.destroy
|
166
|
+
super
|
167
|
+
end
|
168
|
+
|
169
|
+
attr_reader :combo
|
170
|
+
alias :text_entry :combo
|
171
|
+
|
172
|
+
def fill_list(list)
|
173
|
+
list.append('This is the first item')
|
174
|
+
list.append('This is the second item')
|
175
|
+
list.append('This is the third item')
|
176
|
+
list.append('This is the fourth item')
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_popup
|
180
|
+
assert_equal('', combo.get_value)
|
181
|
+
|
182
|
+
assert_kind_of(Wx::ComboPopup, combo.get_popup_control)
|
183
|
+
assert_kind_of(Wx::ComboPopupWx, combo.get_popup_control)
|
184
|
+
assert_kind_of(Wx::VListBox, combo.get_popup_control.get_control)
|
185
|
+
|
186
|
+
assert_nothing_raised { fill_list(combo) }
|
187
|
+
combo.popup
|
188
|
+
|
189
|
+
combo.set_value_by_user('This is the third item')
|
190
|
+
|
191
|
+
assert_equal('This is the third item', combo.get_popup_control.get_string_value)
|
192
|
+
|
193
|
+
combo.dismiss
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
data/tests/test_config.rb
CHANGED
@@ -13,21 +13,21 @@ class TestConfig < Test::Unit::TestCase
|
|
13
13
|
'RootEntry4' => 3.14,
|
14
14
|
'Group1' => {
|
15
15
|
'Group1Entry' => 'Group1 string',
|
16
|
-
'
|
17
|
-
'
|
18
|
-
'
|
19
|
-
'
|
16
|
+
'Group1_1' => {
|
17
|
+
'Group1_1Integer' => 999,
|
18
|
+
'Group1_1Bignum' => 2**999,
|
19
|
+
'Group1_1Float' => (2**999)-0.1
|
20
20
|
}
|
21
21
|
},
|
22
22
|
'Group2' => {
|
23
|
-
'
|
24
|
-
'
|
23
|
+
'Group2_1' => {
|
24
|
+
'Group2_1_1' => {
|
25
25
|
'String' => 'hello'
|
26
26
|
},
|
27
|
-
'
|
27
|
+
'Group2_1_2' => {
|
28
28
|
'String' => 'world'
|
29
29
|
},
|
30
|
-
'
|
30
|
+
'Group2_1_3' => {
|
31
31
|
'True' => true,
|
32
32
|
'False' => false
|
33
33
|
}
|
@@ -35,79 +35,222 @@ class TestConfig < Test::Unit::TestCase
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
|
38
|
+
def stringified_entry(val)
|
39
|
+
case val
|
40
|
+
when TrueClass,FalseClass
|
41
|
+
val ? '1' : '0'
|
42
|
+
when Float
|
43
|
+
'%g' % val
|
44
|
+
else
|
45
|
+
val.to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def stringified(val)
|
50
|
+
val.is_a?(::Hash) ? val.inject({}) { |hash, pair| hash[pair.first] = stringified(pair.last); hash } : stringified_entry(val)
|
51
|
+
end
|
52
|
+
|
53
|
+
def assert_true_cfg(val)
|
54
|
+
assert_block('expected "1" or true') do
|
55
|
+
val == '1' || val == 1 || val == true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def assert_false_cfg(val)
|
60
|
+
assert_block("expected '0' or false") do
|
61
|
+
val == '0' || val == 0 || val == false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_equal_cfg(expected, val)
|
66
|
+
assert_block("expected #{expected.is_a?(::Hash) ? stringified(expected) : %Q['#{stringified(expected)}']} \nor #{expected}\nbut got #{val}") do
|
67
|
+
expected == val || stringified(expected) == stringified(val)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
38
71
|
def run_config_tests(cfg)
|
39
|
-
|
72
|
+
assert_equal_cfg(DEMO_CONFIG, cfg.to_h)
|
40
73
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
74
|
+
assert_equal_cfg(4, cfg.number_of_entries)
|
75
|
+
assert_equal_cfg(2, cfg.number_of_groups)
|
76
|
+
assert_equal_cfg(12, cfg.number_of_entries(recurse: true))
|
77
|
+
assert_equal_cfg(7, cfg.number_of_groups(recurse: true))
|
45
78
|
|
46
79
|
assert_true(cfg.has_entry?('/RootEntry2'))
|
47
80
|
assert_true(cfg.has_entry?('/Group1/Group1Entry'))
|
48
|
-
assert_true(cfg.has_entry?('/Group2/
|
81
|
+
assert_true(cfg.has_entry?('/Group2/Group2_1/Group2_1_2/String'))
|
49
82
|
|
50
|
-
assert_false(cfg.has_entry?('/Group2/Group2.2/
|
83
|
+
assert_false(cfg.has_entry?('/Group2/Group2.2/Group2_1_2/String'))
|
51
84
|
|
52
85
|
assert_true(cfg.has_group?('/Group2'))
|
53
|
-
assert_true(cfg.has_group?('/Group1/
|
54
|
-
assert_true(cfg.has_group?('/Group2/
|
86
|
+
assert_true(cfg.has_group?('/Group1/Group1_1'))
|
87
|
+
assert_true(cfg.has_group?('/Group2/Group2_1/Group2_1_2'))
|
55
88
|
|
56
|
-
assert_false(cfg.has_group?('/Group2/
|
89
|
+
assert_false(cfg.has_group?('/Group2/Group2_1/Group2_1_2/String'))
|
57
90
|
|
58
|
-
grp = cfg['/Group1/
|
91
|
+
grp = cfg['/Group1/Group1_1']
|
59
92
|
|
60
|
-
|
93
|
+
assert_equal_cfg(DEMO_CONFIG['Group1']['Group1_1'], grp.to_h)
|
61
94
|
|
62
95
|
assert_equal(3, grp.number_of_entries)
|
63
96
|
assert_equal(0, grp.number_of_groups)
|
64
97
|
|
65
|
-
assert_true(grp.has_entry?('
|
98
|
+
assert_true(grp.has_entry?('Group1_1Integer'))
|
66
99
|
assert_false(grp.has_entry?('Group1Entry'))
|
67
100
|
assert_true(grp.has_entry?('../Group1Entry'))
|
68
101
|
|
69
|
-
assert_true(grp.has_group?('/Group2/
|
102
|
+
assert_true(grp.has_group?('/Group2/Group2_1/Group2_1_2'))
|
70
103
|
|
71
104
|
assert_equal('This is a string value', cfg['/RootEntry1'])
|
72
|
-
|
73
|
-
|
74
|
-
|
105
|
+
assert_equal_cfg(true, cfg['/RootEntry2'])
|
106
|
+
assert_equal_cfg(101, cfg['/RootEntry3'])
|
107
|
+
assert_equal_cfg(3.14, cfg['/RootEntry4'])
|
75
108
|
|
76
|
-
grp = cfg['/Group2/
|
77
|
-
|
78
|
-
|
79
|
-
|
109
|
+
grp = cfg['/Group2/Group2_1/Group2_1_3']
|
110
|
+
assert_true_cfg(grp.get('True'))
|
111
|
+
assert_false_cfg(grp.get('False'))
|
112
|
+
assert_raise(ArgumentError) { grp.get('../Group2_1_2/String') }
|
80
113
|
|
81
|
-
|
82
|
-
|
83
|
-
assert_equal('world', grp['../
|
114
|
+
assert_true_cfg(grp['True'])
|
115
|
+
assert_false_cfg(grp['False'])
|
116
|
+
assert_equal('world', grp['../Group2_1_2/String'])
|
84
117
|
|
85
118
|
cfg.set('RootEntry1', 'Altered string value')
|
86
119
|
assert_equal('Altered string value', cfg['RootEntry1'])
|
87
120
|
assert_equal('Altered string value', cfg['/RootEntry1'])
|
88
121
|
assert_equal('Altered string value', cfg.get('RootEntry1'))
|
89
122
|
|
90
|
-
cfg.set('RootEntry3', cfg.
|
91
|
-
|
123
|
+
cfg.set('RootEntry3', cfg.read('RootEntry3', ::Integer)+99)
|
124
|
+
assert_equal_cfg(200, cfg['/RootEntry3'])
|
125
|
+
|
126
|
+
cfg.set('Group1', { 'Group1_2' => { 'Integer' => 777 }})
|
127
|
+
assert_equal_cfg(777, cfg['/Group1/Group1_2/Integer'])
|
128
|
+
|
129
|
+
cfg['/Group1/Group1_2/Integer'] = 666
|
130
|
+
assert_equal_cfg(666, cfg['/Group1/Group1_2'].get('Integer'))
|
131
|
+
|
132
|
+
cfg['/Group1/Group1_2'] = { 'Float' => 0.3330 }
|
133
|
+
assert_equal_cfg(0.3330, cfg['/Group1/Group1_2'].get('Float'))
|
134
|
+
|
135
|
+
assert_equal(0.3330, cfg.read('/Group1/Group1_2/Float').to_f)
|
136
|
+
assert_equal(0.3330, cfg.read('/Group1/Group1_2/Float', Float))
|
137
|
+
assert_equal(0.3330, cfg.read('/Group1/Group1_2/Float', ->(v) { v.to_f }))
|
138
|
+
|
139
|
+
cfg.replace(DEMO_CONFIG) # reset
|
140
|
+
end
|
141
|
+
|
142
|
+
def run_auto_accessor_tests(cfg)
|
143
|
+
assert_not_nil(cfg.RootEntry2)
|
144
|
+
assert_not_nil(cfg.Group1.Group1Entry)
|
145
|
+
assert_not_nil(cfg.Group2.Group2_1.Group2_1_2.String)
|
146
|
+
|
147
|
+
assert_nil(cfg.Group2.Group2_1.Group2_1_2.AString)
|
148
|
+
|
149
|
+
assert_kind_of(cfg.class::Group, cfg.Group2)
|
150
|
+
assert_kind_of(cfg.class::Group, cfg.Group1.Group1_1)
|
151
|
+
assert_kind_of(cfg.class::Group, cfg.Group2.Group2_1.Group2_1_2)
|
152
|
+
|
153
|
+
assert_not_kind_of(cfg.class::Group, cfg.Group2.Group2_1.Group2_1_2.String)
|
154
|
+
|
155
|
+
grp = cfg.Group1
|
156
|
+
|
157
|
+
assert_equal_cfg(DEMO_CONFIG['Group1'], grp.to_h)
|
158
|
+
|
159
|
+
assert_not_nil(grp.Group1Entry)
|
160
|
+
assert_nil(grp.Group1_1Integer)
|
161
|
+
|
162
|
+
assert_kind_of(grp.class, grp.Group1_1)
|
163
|
+
assert_not_nil(grp.Group1_1.Group1_1Integer)
|
164
|
+
|
165
|
+
assert_true(grp.has_entry?('../RootEntry1'))
|
166
|
+
|
167
|
+
assert_true(grp.has_group?('/Group2/Group2_1/Group2_1_2'))
|
168
|
+
|
169
|
+
assert_equal_cfg('This is a string value', cfg.RootEntry1)
|
170
|
+
assert_equal_cfg(true, cfg.RootEntry2)
|
171
|
+
assert_equal_cfg(101, cfg.RootEntry3)
|
172
|
+
assert_equal_cfg(3.14, cfg.RootEntry4)
|
92
173
|
|
93
|
-
|
94
|
-
|
174
|
+
grp = cfg.Group2.Group2_1.Group2_1_3
|
175
|
+
assert_true_cfg(grp.True)
|
176
|
+
assert_false_cfg(grp.False)
|
95
177
|
|
96
|
-
|
97
|
-
|
178
|
+
assert_true_cfg(grp['True'])
|
179
|
+
assert_false_cfg(grp['False'])
|
180
|
+
assert_equal_cfg('world', grp['../Group2_1_2/String'])
|
98
181
|
|
99
|
-
cfg
|
100
|
-
|
182
|
+
cfg.RootEntry1 = 'Altered string value'
|
183
|
+
assert_equal_cfg('Altered string value', cfg['RootEntry1'])
|
184
|
+
assert_equal_cfg('Altered string value', cfg['/RootEntry1'])
|
185
|
+
assert_equal_cfg('Altered string value', cfg.get('RootEntry1'))
|
186
|
+
assert_equal_cfg('Altered string value', cfg.RootEntry1)
|
187
|
+
|
188
|
+
cfg.RootEntry3 = (Kernel.Integer(cfg.RootEntry3) rescue 0)+99
|
189
|
+
assert_equal_cfg(200, cfg.RootEntry3)
|
190
|
+
|
191
|
+
cfg.Group1 = { 'Group1_2' => { 'Integer' => 777 }}
|
192
|
+
assert_equal_cfg(777, cfg.Group1.Group1_2.Integer)
|
193
|
+
|
194
|
+
cfg.Group1.Group1_2.Integer = 666
|
195
|
+
assert_equal_cfg(666, cfg.Group1.Group1_2.get('Integer'))
|
196
|
+
|
197
|
+
cfg.Group1.Group1_2 = { 'Float' => 0.3330 }
|
198
|
+
assert_equal_cfg(0.3330, cfg.Group1.Group1_2.get('Float'))
|
199
|
+
|
200
|
+
cfg.replace(DEMO_CONFIG) # reset
|
201
|
+
end
|
202
|
+
|
203
|
+
def run_env_var_tests(cfg)
|
204
|
+
# by default expansion is on
|
205
|
+
|
206
|
+
# add a number of entries for env var in new group 'Environment'
|
207
|
+
cfg['/Environment/HOME'] = '$HOME'
|
208
|
+
cfg['Environment'].USER = Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}'
|
209
|
+
cfg['/Environment/PATH'] = '$(PATH)'
|
210
|
+
|
211
|
+
assert_equal(ENV['HOME'], cfg.Environment['HOME'])
|
212
|
+
assert_equal(ENV[Wx::PLATFORM == 'WXMSW' ? 'USERNAME' : 'USER'], cfg['/Environment/USER'])
|
213
|
+
assert_equal(ENV['PATH'], cfg.Environment.PATH)
|
214
|
+
|
215
|
+
# test escaping
|
216
|
+
cfg['/Environment/Escaped_HOME'] = '\$HOME'
|
217
|
+
cfg['/Environment/Escaped_HOME2'] = '\\$HOME'
|
218
|
+
cfg['/Environment/Escaped_HOME3'] = '\\\$HOME'
|
219
|
+
|
220
|
+
assert_equal('$HOME', cfg.Environment['Escaped_HOME'])
|
221
|
+
assert_equal('$HOME', cfg.Environment['Escaped_HOME2'])
|
222
|
+
assert_equal('\$HOME', cfg.Environment['Escaped_HOME3'])
|
223
|
+
|
224
|
+
cfg['/Environment/NONSENSE'] = '${NonExistingLongNonsenseVariable}'
|
225
|
+
|
226
|
+
assert_equal('${NonExistingLongNonsenseVariable}', cfg.Environment['NONSENSE'])
|
227
|
+
|
228
|
+
cfg['/Environment/MULTIPLE'] = "$HOME / #{Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}'}"
|
229
|
+
|
230
|
+
assert_equal("#{ENV['HOME']} / #{Wx::PLATFORM == 'WXMSW' ? ENV['USERNAME'] : ENV['USER']}", cfg.Environment['MULTIPLE'])
|
231
|
+
|
232
|
+
# disable env var expansion
|
233
|
+
cfg.expand_env_vars = false
|
234
|
+
begin
|
235
|
+
assert_equal('$HOME', cfg.Environment['HOME'])
|
236
|
+
ensure
|
237
|
+
# re-enable
|
238
|
+
cfg.set_expand_env_vars(true)
|
239
|
+
end
|
101
240
|
end
|
102
241
|
|
103
242
|
def test_basic
|
104
243
|
cfg = Wx::Config.new(DEMO_CONFIG)
|
105
244
|
|
106
245
|
run_config_tests(cfg)
|
246
|
+
run_auto_accessor_tests(cfg)
|
247
|
+
run_env_var_tests(cfg)
|
107
248
|
end
|
108
249
|
|
109
250
|
def test_global
|
110
|
-
cfg = Wx::ConfigBase.create
|
251
|
+
cfg = Wx::ConfigBase.create(true, use_hash_config: true)
|
252
|
+
|
253
|
+
assert_kind_of(Wx::Config, cfg)
|
111
254
|
|
112
255
|
cfg.replace(DEMO_CONFIG)
|
113
256
|
|
@@ -116,6 +259,8 @@ class TestConfig < Test::Unit::TestCase
|
|
116
259
|
assert_equal(cfg, Wx::ConfigBase.get(false))
|
117
260
|
|
118
261
|
run_config_tests(cfg)
|
262
|
+
run_auto_accessor_tests(cfg)
|
263
|
+
run_env_var_tests(cfg)
|
119
264
|
|
120
265
|
cfg_old = Wx::ConfigBase.set(nil)
|
121
266
|
|
@@ -123,8 +268,28 @@ class TestConfig < Test::Unit::TestCase
|
|
123
268
|
assert_nil(Wx::ConfigBase.get(false))
|
124
269
|
end
|
125
270
|
|
271
|
+
# default registry based config does not seem to do well in CI build env
|
272
|
+
unless is_ci_build? && Wx::PLATFORM == 'WXMSW'
|
273
|
+
|
274
|
+
def test_default_wx
|
275
|
+
Wx::ConfigBase.set(nil) # reset global instance
|
276
|
+
cfg = Wx::ConfigBase.get # forced auto creation of default config
|
277
|
+
|
278
|
+
assert_kind_of(Wx::ConfigWx, cfg)
|
279
|
+
|
280
|
+
cfg.replace(DEMO_CONFIG)
|
281
|
+
|
282
|
+
run_config_tests(cfg)
|
283
|
+
run_auto_accessor_tests(cfg)
|
284
|
+
run_env_var_tests(cfg)
|
285
|
+
|
286
|
+
assert_true(cfg.clear) # cleanup
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
|
126
291
|
def test_html_help
|
127
|
-
cfg = Wx::ConfigBase.create
|
292
|
+
cfg = Wx::ConfigBase.create(true, use_hash_config: true)
|
128
293
|
|
129
294
|
assert_true(cfg.to_h.empty?)
|
130
295
|
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
require_relative './lib/wxframe_runner'
|
6
|
+
|
7
|
+
class TopLevelPersistenceTests < WxRuby::Test::GUITests
|
8
|
+
|
9
|
+
PERSIST_ROOT = 'Persistent_Options'
|
10
|
+
|
11
|
+
def run_frame_props_tests
|
12
|
+
Wx.persistent_register_and_restore(frame_win, 'TestFrame')
|
13
|
+
|
14
|
+
frame_win.size = [450, 350]
|
15
|
+
frame_win.position = [100, 150]
|
16
|
+
|
17
|
+
Wx::PersistenceManager.get.save_and_unregister(frame_win)
|
18
|
+
|
19
|
+
cfg = Wx::ConfigBase.get
|
20
|
+
assert_kind_of(Wx::ConfigBase, cfg)
|
21
|
+
grp = cfg.get(PERSIST_ROOT)
|
22
|
+
assert_kind_of(cfg.class::Group, grp)
|
23
|
+
grp = grp.get('Window')
|
24
|
+
assert_kind_of(cfg.class::Group, grp)
|
25
|
+
grp = grp.get('TestFrame')
|
26
|
+
assert_kind_of(cfg.class::Group, grp)
|
27
|
+
|
28
|
+
assert_equal(100, Integer(grp['x']))
|
29
|
+
assert_equal(150, Integer(grp['y']))
|
30
|
+
assert_equal(450, Integer(grp.w))
|
31
|
+
assert_equal(350, Integer(grp.h))
|
32
|
+
|
33
|
+
grp.x = 110
|
34
|
+
grp.y = 140
|
35
|
+
|
36
|
+
assert_equal(110, Integer(grp['x']))
|
37
|
+
assert_equal(140, Integer(grp['y']))
|
38
|
+
|
39
|
+
Wx.persistent_register_and_restore(frame_win, 'TestFrame')
|
40
|
+
|
41
|
+
assert_equal(Wx::Point.new(110, 140), frame_win.position)
|
42
|
+
|
43
|
+
Wx::PersistenceManager.get.unregister(frame_win)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_frame_props_ruby_config
|
47
|
+
# force creation of hash based Wx::Config instance
|
48
|
+
Wx::ConfigBase.create(true, use_hash_config: true)
|
49
|
+
|
50
|
+
run_frame_props_tests
|
51
|
+
|
52
|
+
Wx::ConfigBase.get.clear
|
53
|
+
end
|
54
|
+
|
55
|
+
# default registry based config does not seem to do well in CI build env
|
56
|
+
unless is_ci_build? && Wx::PLATFORM == 'WXMSW'
|
57
|
+
|
58
|
+
def test_frame_props_default_config
|
59
|
+
# force creation of default C++ config instance
|
60
|
+
Wx::ConfigBase.create(true)
|
61
|
+
|
62
|
+
run_frame_props_tests
|
63
|
+
|
64
|
+
Wx::ConfigBase.get.clear
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
class PersistentButton < Wx::PersistentWindowBase
|
70
|
+
|
71
|
+
def get_kind
|
72
|
+
'Button'
|
73
|
+
end
|
74
|
+
|
75
|
+
def save
|
76
|
+
save_value('w', get.size.width)
|
77
|
+
save_value('h', get.size.height)
|
78
|
+
save_value('label', get.label)
|
79
|
+
save_value('my_custom_value', get.my_custom_value)
|
80
|
+
end
|
81
|
+
|
82
|
+
def restore
|
83
|
+
get.size = [Integer(restore_value('w')), Integer(restore_value('h'))]
|
84
|
+
get.label = restore_value('label')
|
85
|
+
get.my_custom_value = Float(restore_value('my_custom_value'))
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
class MyButton < Wx::Button
|
92
|
+
|
93
|
+
def initialize(parent=nil, name)
|
94
|
+
super(parent, label: '', name: name)
|
95
|
+
@my_custom_value = ''
|
96
|
+
end
|
97
|
+
|
98
|
+
attr_accessor :my_custom_value
|
99
|
+
|
100
|
+
def create_persistent_object
|
101
|
+
PersistentButton.new(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_custom_persistent_object
|
107
|
+
# force creation of hash based Wx::Config instance
|
108
|
+
Wx::ConfigBase.create(true, use_hash_config: true)
|
109
|
+
|
110
|
+
assert_false(Wx::ConfigBase.get.has_group?(PERSIST_ROOT))
|
111
|
+
|
112
|
+
btn = MyButton.new(frame_win, 'AButton')
|
113
|
+
btn.label = 'Hello world'
|
114
|
+
btn.my_custom_value = 3.14
|
115
|
+
|
116
|
+
Wx::PersistenceManager.get.register(btn)
|
117
|
+
|
118
|
+
assert_false(Wx::ConfigBase.get.has_group?(PERSIST_ROOT))
|
119
|
+
|
120
|
+
# destroying window should save and unregister
|
121
|
+
btn.destroy
|
122
|
+
btn = nil
|
123
|
+
|
124
|
+
|
125
|
+
assert_true(Wx::ConfigBase.get.has_group?(PERSIST_ROOT))
|
126
|
+
|
127
|
+
cfg = Wx::ConfigBase.get[PERSIST_ROOT]['Button']['AButton']
|
128
|
+
assert_true(cfg.has_entry?('w'))
|
129
|
+
assert_true(cfg.has_entry?('h'))
|
130
|
+
assert_true(cfg.has_entry?('label'))
|
131
|
+
assert_true(cfg.has_entry?('my_custom_value'))
|
132
|
+
|
133
|
+
|
134
|
+
btn = MyButton.new(frame_win, 'AButton')
|
135
|
+
|
136
|
+
Wx::PersistenceManager.get.register_and_restore(btn)
|
137
|
+
|
138
|
+
assert_equal('Hello world', btn.label)
|
139
|
+
assert_equal(3.14, btn.my_custom_value)
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|