wxruby3 0.9.3 → 0.9.5
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/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
|