wxruby3 1.6.0 → 1.6.1

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.
@@ -0,0 +1,857 @@
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 PropGridTests < WxRuby::Test::GUITests
8
+
9
+ def yield_for_a_while(msec)
10
+ timeout = msec / 1000.0 # sec float
11
+ start = ::Time.now
12
+ while (Time.now - start) < timeout
13
+ Wx.get_app.yield
14
+ end
15
+ end
16
+
17
+ def populate_with_standard_items(pgman)
18
+ pg = pgman.get_page("Standard Items")
19
+
20
+ # Append is ideal way to add items to wxPropertyGrid.
21
+ pg.append(Wx::PG::PropertyCategory.new("Appearance", Wx::PG::PG_LABEL))
22
+
23
+ pg.append(Wx::PG::StringProperty.new("Label", Wx::PG::PG_LABEL, 'PropertyGridTest'))
24
+ pg.append(Wx::PG::FontProperty.new("Font", Wx::PG::PG_LABEL))
25
+ pg.set_property_help_string("Font", "Editing this will change font used in the property grid.")
26
+
27
+ pg.append(Wx::PG::SystemColourProperty.new("Margin Colour",Wx::PG::PG_LABEL,
28
+ Wx::PG::ColourPropertyValue.new(pg.get_grid.get_margin_colour)))
29
+
30
+ pg.append(Wx::PG::SystemColourProperty.new("Cell Colour",Wx::PG::PG_LABEL,
31
+ pg.grid.get_cell_background_colour))
32
+ pg.append(Wx::PG::SystemColourProperty.new("Cell Text Colour",Wx::PG::PG_LABEL,
33
+ pg.grid.get_cell_text_colour))
34
+ pg.append(Wx::PG::SystemColourProperty.new("Line Colour",Wx::PG::PG_LABEL,
35
+ pg.grid.get_line_colour))
36
+ combinedFlags = Wx::PG::PGChoices.new
37
+ combinedFlags.add(%w[Wx::ICONIZE, Wx::CAPTION, Wx::MINIMIZE_BOX, Wx::MAXIMIZE_BOX],
38
+ [Wx::ICONIZE, Wx::CAPTION, Wx::MINIMIZE_BOX, Wx::MAXIMIZE_BOX])
39
+ pg.append(Wx::PG::FlagsProperty.new("Window Styles",Wx::PG::PG_LABEL,
40
+ combinedFlags, frame_win.get_window_style))
41
+
42
+ pg.append(Wx::PG::CursorProperty.new("Cursor",Wx::PG::PG_LABEL))
43
+
44
+ pg.append(Wx::PG::PropertyCategory.new("Position","PositionCategory"))
45
+ pg.set_property_help_string("PositionCategory", "Change in items in this category will cause respective changes in frame.")
46
+
47
+ # Let's demonstrate 'Units' attribute here
48
+
49
+ # Note that we use many attribute constants instead of strings here
50
+ # (for instance, Wx::PG::PG_ATTR_MIN, instead of "min").
51
+ # Using constant may reduce binary size.
52
+
53
+ pg.append(Wx::PG::IntProperty.new("Height",Wx::PG::PG_LABEL,480))
54
+ pg.set_property_attribute("Height", Wx::PG::PG_ATTR_MIN, 10)
55
+ pg.set_property_attribute("Height", Wx::PG::PG_ATTR_MAX, 2048)
56
+ pg.set_property_attribute("Height", Wx::PG::PG_ATTR_UNITS, "Pixels")
57
+
58
+ # Set value to unspecified so that Hint attribute will be demonstrated
59
+ pg.set_property_value_unspecified("Height")
60
+ pg.set_property_attribute("Height", Wx::PG::PG_ATTR_HINT,
61
+ "Enter new height for window")
62
+
63
+ # Difference between hint and help string is that the hint is shown in
64
+ # an empty value cell, while help string is shown either in the
65
+ # description text box, as a tool tip, or on the status bar.
66
+ pg.set_property_help_string("Height",
67
+ "This property uses attributes \"Units\" and \"Hint\".")
68
+
69
+ pg.append(Wx::PG::IntProperty.new("Width",Wx::PG::PG_LABEL,640))
70
+ pg.set_property_attribute("Width", Wx::PG::PG_ATTR_MIN, 10)
71
+ pg.set_property_attribute("Width", Wx::PG::PG_ATTR_MAX, 2048)
72
+ pg.set_property_attribute("Width", Wx::PG::PG_ATTR_UNITS, "Pixels")
73
+
74
+ pg.set_property_value_unspecified("Width")
75
+ pg.set_property_attribute("Width", Wx::PG::PG_ATTR_HINT,
76
+ "Enter new width for window")
77
+ pg.set_property_help_string("Width",
78
+ "This property uses attributes \"Units\" and \"Hint\".")
79
+
80
+ pg.append(Wx::PG::IntProperty.new("X",Wx::PG::PG_LABEL,10))
81
+ pg.set_property_attribute("X", Wx::PG::PG_ATTR_UNITS, "Pixels")
82
+ pg.set_property_help_string("X", "This property uses \"Units\" attribute.")
83
+
84
+ pg.append Wx::PG::IntProperty.new("Y",Wx::PG::PG_LABEL,10)
85
+ pg.set_property_attribute("Y", Wx::PG::PG_ATTR_UNITS, "Pixels")
86
+ pg.set_property_help_string("Y", "This property uses \"Units\" attribute.")
87
+
88
+ disabledHelpString = "This property is simply disabled. In order to have label disabled as well, "+
89
+ "you need to set Wx::PG::PG_EX_GREY_LABEL_WHEN_DISABLED using SetExtraStyle."
90
+
91
+ pg.append(Wx::PG::PropertyCategory.new("Environment",Wx::PG::PG_LABEL))
92
+ pg.append(Wx::PG::StringProperty.new("Operating System",Wx::PG::PG_LABEL, Wx.get_os_description))
93
+
94
+ pg.append(Wx::PG::StringProperty.new("User Id",Wx::PG::PG_LABEL, Wx.get_user_id))
95
+ pg.append(Wx::PG::DirProperty.new("User Home",Wx::PG::PG_LABEL, Wx.get_user_home))
96
+ pg.append(Wx::PG::StringProperty.new("User Name",Wx::PG::PG_LABEL, Wx.get_user_name))
97
+
98
+ # Disable some of them
99
+ pg.disable_property("Operating System")
100
+ pg.disable_property("User Id")
101
+ pg.disable_property("User Name")
102
+
103
+ pg.set_property_help_string("Operating System", disabledHelpString)
104
+ pg.set_property_help_string("User Id", disabledHelpString)
105
+ pg.set_property_help_string("User Name", disabledHelpString)
106
+
107
+ pg.append(Wx::PG::PropertyCategory.new("More Examples",Wx::PG::PG_LABEL))
108
+
109
+ pg.append(Wx::PG::LongStringProperty.new("Information",Wx::PG::PG_LABEL,
110
+ "Editing properties will have immediate effect on this window, "+
111
+ "and vice versa (at least in most cases, that is)."))
112
+ pg.set_property_help_string("Information",
113
+ "This property is read-only.")
114
+
115
+ pg.set_property_read_only("Information", true)
116
+
117
+ #
118
+ # Set test information for cells in columns 3 and 4
119
+ # (reserve column 2 for displaying units)
120
+ bmp = Wx::ArtProvider.get_bitmap(Wx::ART_FOLDER)
121
+
122
+ pg.grid.each_property do |p|
123
+ continue if p.category?
124
+
125
+ pg.set_property_cell(p, 3, "Cell 3", bmp)
126
+ pg.set_property_cell(p, 4, "Cell 4", Wx::BitmapBundle.new, Wx::WHITE, Wx::BLACK)
127
+ end
128
+ end
129
+
130
+ def populate_with_examples(pgman)
131
+ pg = pgman.get_page("Examples")
132
+
133
+ pg.append(Wx::PG::IntProperty.new("IntProperty", Wx::PG::PG_LABEL, 12345678))
134
+
135
+ if Wx.has_feature?(:USE_SPINBTN)
136
+ pg.append(Wx::PG::IntProperty.new("SpinCtrl", Wx::PG::PG_LABEL, 0))
137
+
138
+ pg.set_property_editor("SpinCtrl", Wx::PG::PG_EDITOR_SPIN_CTRL)
139
+ pg.set_property_attribute("SpinCtrl", Wx::PG::PG_ATTR_MIN, -2) # Use constants instead of string
140
+ pg.set_property_attribute("SpinCtrl", Wx::PG::PG_ATTR_MAX, 16384) # for reduced binary size.
141
+ pg.set_property_attribute("SpinCtrl", Wx::PG::PG_ATTR_SPINCTRL_STEP, 2)
142
+ pg.set_property_attribute("SpinCtrl", Wx::PG::PG_ATTR_SPINCTRL_MOTION, true)
143
+ pg.set_property_attribute("SpinCtrl", Wx::PG::PG_ATTR_SPINCTRL_WRAP, true)
144
+
145
+ pg.set_property_help_string("SpinCtrl",
146
+ "This is regular Wx::PG::IntProperty, which editor has been "+
147
+ "changed to Wx::PG::PGEditor_SpinCtrl. Note however that "+
148
+ "static wxPropertyGrid::RegisterAdditionalEditors() "+
149
+ "needs to be called prior to using it.")
150
+ end
151
+
152
+ # Add bool property
153
+ pg.append(Wx::PG::BoolProperty.new("BoolProperty", Wx::PG::PG_LABEL, false))
154
+
155
+ # Add bool property with check box
156
+ pg.append(Wx::PG::BoolProperty.new("BoolProperty with CheckBox", Wx::PG::PG_LABEL, false))
157
+ pg.set_property_attribute("BoolProperty with CheckBox",
158
+ Wx::PG::PG_BOOL_USE_CHECKBOX,
159
+ true)
160
+
161
+ pg.set_property_help_string("BoolProperty with CheckBox",
162
+ "Property attribute Wx::PG::PG_BOOL_USE_CHECKBOX has been set to true.")
163
+
164
+ prop = pg.append(Wx::PG::FloatProperty.new("FloatProperty",
165
+ Wx::PG::PG_LABEL,
166
+ 1234500.23))
167
+ prop.set_attribute(Wx::PG::PG_ATTR_MIN, -100.12)
168
+
169
+ # A string property that can be edited in a separate editor dialog.
170
+ pg.append(Wx::PG::LongStringProperty.new("LongStringProperty", "LongStringProp",
171
+ "This is much longer string than the first one. Edit it by clicking the button."))
172
+
173
+ # A property that edits a wxArrayString.
174
+ example_array = [
175
+ "String 1",
176
+ "String 2",
177
+ "String 3"
178
+ ]
179
+ pg.append(Wx::PG::ArrayStringProperty.new("ArrayStringProperty", Wx::PG::PG_LABEL,
180
+ example_array))
181
+
182
+ # A file selector property. Note that argument between name
183
+ # and initial value is wildcard (format same as in wxFileDialog).
184
+ prop = Wx::PG::FileProperty.new("FileProperty", "TextFile")
185
+ pg.append(prop)
186
+
187
+ prop.set_attribute(Wx::PG::PG_FILE_WILDCARD,"Text Files (*.txt)|*.txt")
188
+ prop.set_attribute(Wx::PG::PG_DIALOG_TITLE,"Custom File Dialog Title")
189
+ prop.set_attribute(Wx::PG::PG_FILE_SHOW_FULL_PATH,false)
190
+
191
+ if Wx::PLATFORM == 'WXMSW'
192
+ prop.set_attribute(Wx::PG::PG_FILE_SHOW_RELATIVE_PATH,"C:\\Windows")
193
+ pg.set_property_value(prop,"C:\\Windows\\System32\\msvcrt71.dll")
194
+ end
195
+
196
+ if Wx.has_feature? :USE_IMAGE
197
+ # An image file property. Arguments are just like for FileProperty, but
198
+ # wildcard is missing (it is autogenerated from supported image formats).
199
+ # If you really need to override it, create property separately, and call
200
+ # its SetWildcard method.
201
+ pg.append(Wx::PG::ImageFileProperty.new("ImageFile", Wx::PG::PG_LABEL))
202
+ end
203
+
204
+ pid = pg.append(Wx::PG::ColourProperty.new("ColourProperty",Wx::PG::PG_LABEL,Wx::RED))
205
+ pg.set_property_editor("ColourProperty", Wx::PG::PG_EDITOR_COMBO_BOX)
206
+ pg.get_property("ColourProperty").set_auto_unspecified(true)
207
+ pg.set_property_help_string("ColourProperty",
208
+ "wxPropertyGrid::SetPropertyEditor method has been used to change "+
209
+ "editor of this property to Wx::PG::PGEditor_ComboBox)")
210
+
211
+ pid = pg.append(Wx::PG::ColourProperty.new("ColourPropertyWithAlpha",
212
+ Wx::PG::PG_LABEL,
213
+ Wx::Colour.new(15, 200, 95, 128)))
214
+ pg.set_property_attribute("ColourPropertyWithAlpha", Wx::PG::PG_COLOUR_HAS_ALPHA, true)
215
+ pg.set_property_help_string("ColourPropertyWithAlpha",
216
+ "Attribute \"HasAlpha\" is set to true for this property.")
217
+
218
+ #
219
+ # This demonstrates using alternative editor for colour property
220
+ # to trigger colour dialog directly from button.
221
+ pg.append(Wx::PG::ColourProperty.new("ColourProperty2",Wx::PG::PG_LABEL,Wx::GREEN))
222
+
223
+ #
224
+ # Wx::PG::EnumProperty does not store strings or even list of strings
225
+ # (so that's why they are static in function).
226
+ enum_prop_labels = [
227
+ "One Item",
228
+ "Another Item",
229
+ "One More",
230
+ "This Is Last" ]
231
+
232
+ # this value array would be optional if values matched string indexes
233
+ enum_prop_values = [ 40, 80, 120, 160 ]
234
+
235
+ # note that the initial value (the last argument) is the actual value,
236
+ # not index or anything like that. Thus, our value selects "Another Item".
237
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty",Wx::PG::PG_LABEL,
238
+ enum_prop_labels, enum_prop_values, 80))
239
+
240
+ soc = Wx::PG::PGChoices.new
241
+
242
+ # use basic table from our previous example
243
+ # can also set/add wxArrayStrings and wxArrayInts directly.
244
+ soc.set(enum_prop_labels, enum_prop_values)
245
+
246
+ # add extra items
247
+ soc.add("Look, it continues", 200)
248
+ soc.add("Even More", 240)
249
+ soc.add("And More", 280)
250
+ soc.add('', 300)
251
+ soc.add("True End of the List", 320)
252
+
253
+ # Test custom colours ([] operator of Wx::PG::PGChoices returns
254
+ # references to Wx::PG::PGChoiceEntry).
255
+ soc[1].set_fg_col(Wx::RED)
256
+ soc[1].set_bg_col(Wx::LIGHT_GREY)
257
+ soc[2].set_fg_col(Wx::GREEN)
258
+ soc[2].set_bg_col(Wx::LIGHT_GREY)
259
+ soc[3].set_fg_col(Wx::BLUE)
260
+ soc[3].set_bg_col(Wx::LIGHT_GREY)
261
+ soc[4].set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FOLDER))
262
+
263
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty 2",
264
+ Wx::PG::PG_LABEL,
265
+ soc,
266
+ 240))
267
+ pg.get_property("EnumProperty 2").add_choice("Testing Extra", 360)
268
+
269
+ # Here we only display the original 'soc' choices
270
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty 3",Wx::PG::PG_LABEL,
271
+ soc, 240))
272
+
273
+ # Test Hint attribute in EnumProperty
274
+ pg.get_property("EnumProperty 3").set_attribute(Wx::PG::PG_ATTR_HINT, "Dummy Hint")
275
+
276
+ pg.set_property_help_string("EnumProperty 3",
277
+ "This property uses \"Hint\" attribute.")
278
+
279
+ # 'soc' plus one exclusive extra choice "4th only"
280
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty 4",Wx::PG::PG_LABEL,
281
+ soc, 240))
282
+ pg.get_property("EnumProperty 4").add_choice("4th only", 360)
283
+
284
+ pg.set_property_help_string("EnumProperty 4",
285
+ "Should have one extra item when compared to EnumProperty 3")
286
+
287
+ # Plus property value bitmap
288
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty With Bitmap", "EnumProperty 5",
289
+ soc, 280))
290
+ pg.set_property_help_string("EnumProperty 5",
291
+ "Should have bitmap in front of the displayed value")
292
+ bmpVal = Wx::ArtProvider.get_bitmap(Wx::ART_REMOVABLE)
293
+ pg.set_property_image("EnumProperty 5", bmpVal)
294
+
295
+ # Password property example.
296
+ pg.append(Wx::PG::StringProperty.new("Password",Wx::PG::PG_LABEL, "password"))
297
+ pg.set_property_attribute("Password", Wx::PG::PG_STRING_PASSWORD, true)
298
+ pg.set_property_help_string("Password",
299
+ "Has attribute Wx::PG::PG_STRING_PASSWORD set to true")
300
+
301
+ # String editor with dir selector button. Uses wxEmptyString as name, which
302
+ # is allowed (naturally, in this case property cannot be accessed by name).
303
+ pg.append(Wx::PG::DirProperty.new("DirProperty", Wx::PG::PG_LABEL, Wx.get_user_home))
304
+ pg.set_property_attribute("DirProperty",
305
+ Wx::PG::PG_DIALOG_TITLE,
306
+ "This is a custom dir dialog title")
307
+
308
+ # Add string property - first arg is label, second name, and third initial value
309
+ pg.append(Wx::PG::StringProperty.new("StringProperty", Wx::PG::PG_LABEL))
310
+ pg.set_property_max_length("StringProperty", 6)
311
+ pg.set_property_help_string("StringProperty",
312
+ "Max length of this text has been limited to 6, using wxPropertyGrid::SetPropertyMaxLength.")
313
+
314
+ # Set value after limiting so that it will be applied
315
+ pg.set_property_value("StringProperty", "some text")
316
+
317
+ #
318
+ # Demonstrate "AutoComplete" attribute
319
+ pg.append(Wx::PG::StringProperty.new("StringProperty AutoComplete",
320
+ Wx::PG::PG_LABEL))
321
+
322
+ autoCompleteStrings = [
323
+ "One choice",
324
+ "Another choice",
325
+ "Another choice, yeah",
326
+ "Yet another choice",
327
+ "Yet another choice, bear with me"
328
+ ]
329
+ pg.set_property_attribute("StringProperty AutoComplete",
330
+ Wx::PG::PG_ATTR_AUTOCOMPLETE,
331
+ autoCompleteStrings)
332
+
333
+ pg.set_property_help_string("StringProperty AutoComplete",
334
+ "AutoComplete attribute has been set for this property "+
335
+ "(try writing something beginning with 'a', 'o' or 'y').")
336
+
337
+
338
+ # Add string property with arbitrarily wide bitmap in front of it. We
339
+ # intentionally lower-than-typical row height here so that the ugly
340
+ # scaling code won't be run.
341
+ pg.append(Wx::PG::StringProperty.new("StringPropertyWithBitmap",
342
+ Wx::PG::PG_LABEL,
343
+ "Test Text"))
344
+ myTestBitmap1x = Wx::Bitmap.new(60, 15, 32)
345
+ Wx::MemoryDC.draw_on(myTestBitmap1x) do |mdc|
346
+ mdc.set_background(Wx::WHITE_BRUSH)
347
+ mdc.clear
348
+ mdc.set_pen(Wx::BLACK_PEN)
349
+ mdc.set_brush(Wx::WHITE_BRUSH)
350
+ mdc.draw_rectangle(0, 0, 60, 15)
351
+ mdc.draw_line(0, 0, 59, 14)
352
+ mdc.set_text_foreground(Wx::BLACK)
353
+ mdc.draw_text("x1", 0, 0)
354
+ end
355
+
356
+ myTestBitmap2x = Wx::Bitmap.new(120, 30, 32)
357
+ Wx::MemoryDC.draw_on(myTestBitmap2x) do |mdc|
358
+ mdc.set_background(Wx::WHITE_BRUSH)
359
+ mdc.clear
360
+ mdc.set_pen(Wx::Pen.new(Wx::BLUE, 2))
361
+ mdc.set_brush(Wx::WHITE_BRUSH)
362
+ mdc.draw_rectangle(0, 0, 120, 30)
363
+ mdc.draw_line(0, 0, 119, 31)
364
+ mdc.set_text_foreground(Wx::BLUE)
365
+ f = mdc.font
366
+ f.set_pixel_size(f.get_pixel_size * 2)
367
+ mdc.set_font(f)
368
+ mdc.draw_text("x2", 0, 0)
369
+ end
370
+
371
+ myTestBitmap2x.set_scale_factor(2)
372
+ pg.set_property_image("StringPropertyWithBitmap", Wx::BitmapBundle.from_bitmaps(myTestBitmap1x, myTestBitmap2x))
373
+
374
+ # Multi choice dialog.
375
+ tchoices = %w[Cabbage Carrot Onion Potato Strawberry]
376
+
377
+ tchoicesValues = %w[Carrot Potato]
378
+
379
+ pg.append(Wx::PG::EnumProperty.new("EnumProperty X",Wx::PG::PG_LABEL, tchoices))
380
+
381
+ pg.append(Wx::PG::MultiChoiceProperty.new("MultiChoiceProperty", Wx::PG::PG_LABEL,
382
+ tchoices, tchoicesValues))
383
+ pg.set_property_attribute("MultiChoiceProperty", Wx::PG::PG_ATTR_MULTICHOICE_USERSTRINGMODE, 1)
384
+
385
+ # UInt samples
386
+ pg.append(Wx::PG::UIntProperty.new("UIntProperty", Wx::PG::PG_LABEL, 0xFEEEFEEEFEEE))
387
+ pg.set_property_attribute("UIntProperty", Wx::PG::PG_UINT_PREFIX, Wx::PG::PG_PREFIX_NONE)
388
+ pg.set_property_attribute("UIntProperty", Wx::PG::PG_UINT_BASE, Wx::PG::PG_BASE_HEX)
389
+ #pg.set_property_attribute("UIntProperty", Wx::PG::PG_UINT_PREFIX, Wx::PG::PG_PREFIX_NONE)
390
+ #pg.set_property_attribute("UIntProperty", Wx::PG::PG_UINT_BASE, Wx::PG::PG_BASE_OCT)
391
+
392
+ #
393
+ # Wx::PG::EditEnumProperty
394
+ eech = Wx::PG::PGChoices.new([
395
+ "Choice 1",
396
+ "Choice 2",
397
+ "Choice 3"
398
+ ])
399
+ pg.append(Wx::PG::EditEnumProperty.new("EditEnumProperty",
400
+ Wx::PG::PG_LABEL,
401
+ eech,
402
+ "Choice not in the list"))
403
+
404
+ # Test Hint attribute in EditEnumProperty
405
+ pg.get_property("EditEnumProperty").set_attribute(Wx::PG::PG_ATTR_HINT, "Dummy Hint")
406
+
407
+ #wxString v_;
408
+ #wxTextValidator validator1(wxFILTER_NUMERIC,&v_)
409
+ #pg.SetPropertyValidator("EditEnumProperty", validator1)
410
+
411
+ if Wx.has_feature? :USE_DATETIME
412
+ #
413
+ # Wx::PG::DateTimeProperty
414
+ pg.append(Wx::PG::DateProperty.new("DateProperty", Wx::PG::PG_LABEL, Time.now))
415
+
416
+ if Wx.has_feature? :USE_DATEPICKCTRL
417
+ pg.set_property_attribute("DateProperty", Wx::PG::PG_DATE_PICKER_STYLE,
418
+ Wx::DP_DROPDOWN|Wx::DP_SHOWCENTURY|Wx::DP_ALLOWNONE)
419
+
420
+ pg.set_property_help_string("DateProperty",
421
+ "Attribute Wx::PG::PG_DATE_PICKER_STYLE has been set to (long)"+
422
+ "(wxDP_DROPDOWN | wxDP_SHOWCENTURY | wxDP_ALLOWNONE).")
423
+ end
424
+
425
+ end
426
+
427
+ #
428
+ # This snippet is a doc sample test
429
+ #
430
+ carProp = pg.append(Wx::PG::StringProperty.new("Car",
431
+ Wx::PG::PG_LABEL,
432
+ '<composed>'))
433
+
434
+ pg.append_in(carProp, Wx::PG::StringProperty.new("Model",
435
+ Wx::PG::PG_LABEL,
436
+ "Lamborghini Diablo SV"))
437
+
438
+ pg.append_in(carProp, Wx::PG::IntProperty.new("Engine Size (cc)",
439
+ Wx::PG::PG_LABEL,
440
+ 5707))
441
+
442
+ speedsProp = pg.append_in(carProp,
443
+ Wx::PG::StringProperty.new("Speeds",
444
+ Wx::PG::PG_LABEL,
445
+ '<composed>'))
446
+
447
+ pg.append_in(speedsProp, Wx::PG::IntProperty.new("Max. Speed (mph)",
448
+ Wx::PG::PG_LABEL,290))
449
+ pg.append_in(speedsProp, Wx::PG::FloatProperty.new("0-100 mph (sec)",
450
+ Wx::PG::PG_LABEL,3.9))
451
+ pg.append_in(speedsProp, Wx::PG::FloatProperty.new("1/4 mile (sec)",
452
+ Wx::PG::PG_LABEL,8.6))
453
+
454
+ # This is how child property can be referred to by name
455
+ pg.set_property_value("Car.Speeds.Max. Speed (mph)", 300)
456
+
457
+ pg.append_in(carProp, Wx::PG::IntProperty.new("Price ($)",
458
+ Wx::PG::PG_LABEL,
459
+ 300000))
460
+
461
+ pg.append_in(carProp, Wx::PG::BoolProperty.new("Convertible",
462
+ Wx::PG::PG_LABEL,
463
+ false))
464
+
465
+ # Displayed value of "Car" property is now very close to this:
466
+ # "Lamborghini Diablo SV; 5707 [300; 3.9; 8.6] 300000"
467
+
468
+ #
469
+ # Test adding variable height bitmaps in Wx::PG::PGChoices
470
+ bc = Wx::PG::PGChoices.new
471
+ bc.add("Wee",
472
+ Wx::ArtProvider.get_bitmap(Wx::ART_CDROM, Wx::ART_OTHER, [16, 16]))
473
+ bc.add("Not so wee",
474
+ Wx::ArtProvider.get_bitmap(Wx::ART_FLOPPY, Wx::ART_OTHER, [32, 32]))
475
+ bc.add("Friggin' huge",
476
+ Wx::ArtProvider.get_bitmap(Wx::ART_HARDDISK, Wx::ART_OTHER, [64, 64]))
477
+
478
+ pg.append(Wx::PG::EnumProperty.new("Variable Height Bitmaps",
479
+ Wx::PG::PG_LABEL,
480
+ bc,
481
+ 0))
482
+
483
+ #
484
+ # Test how non-editable composite strings appear
485
+ pid = Wx::PG::StringProperty.new("wxRuby Traits", Wx::PG::PG_LABEL, "<composed>")
486
+ pg.set_property_read_only(pid)
487
+
488
+ #
489
+ # For testing purposes, combine two methods of adding children
490
+ #
491
+
492
+ pid.append_child(Wx::PG::StringProperty.new("Latest Release",
493
+ Wx::PG::PG_LABEL,
494
+ "3.0.0"))
495
+ pid.append_child(Wx::PG::BoolProperty.new("Win API",
496
+ Wx::PG::PG_LABEL,
497
+ true))
498
+
499
+ pg.append(pid)
500
+
501
+ pg.append_in(pid, Wx::PG::BoolProperty.new("QT", Wx::PG::PG_LABEL, true))
502
+ pg.append_in(pid, Wx::PG::BoolProperty.new("Cocoa", Wx::PG::PG_LABEL, true))
503
+ pg.append_in(pid, Wx::PG::BoolProperty.new("Haiku", Wx::PG::PG_LABEL, false))
504
+ pg.append_in(pid, Wx::PG::StringProperty.new("Trunk Version", Wx::PG::PG_LABEL, Wx::WXRUBY_VERSION))
505
+ pg.append_in(pid, Wx::PG::BoolProperty.new("GTK+", Wx::PG::PG_LABEL, true))
506
+ pg.append_in(pid, Wx::PG::BoolProperty.new("Android", Wx::PG::PG_LABEL, false))
507
+ end
508
+
509
+ def create_grid(style, extraStyle)
510
+ # This function creates the property grid in tests
511
+
512
+ style = # default style
513
+ Wx::PG::PG_BOLD_MODIFIED |
514
+ Wx::PG::PG_SPLITTER_AUTO_CENTER |
515
+ Wx::PG::PG_AUTO_SORT |
516
+ Wx::PG::PG_TOOLBAR if style == -1
517
+
518
+
519
+ # default extra style
520
+ extraStyle = Wx::PG::PG_EX_MODE_BUTTONS |
521
+ Wx::PG::PG_EX_MULTIPLE_SELECTION if extraStyle == -1
522
+
523
+ pg_manager = Wx::PG::PropertyGridManager.new(frame_win, Wx::ID_ANY, style: style)
524
+ pg_manager.set_size(frame_win.get_client_size)
525
+ pg_manager.set_extra_style(extraStyle)
526
+
527
+ # This is the default validation failure behaviour
528
+ pg_manager.set_validation_failure_behavior(Wx::PG::PGVFBFlags::MarkCell |
529
+ Wx::PG::PGVFBFlags::ShowMessageBox)
530
+
531
+ pg = pg_manager.get_grid
532
+ # Set somewhat different unspecified value appearance
533
+ cell = Wx::PG::PGCell.new
534
+ cell.set_text("Unspecified")
535
+ cell.set_fg_col(Wx::LIGHT_GREY)
536
+ pg.set_unspecified_value_appearance(cell)
537
+
538
+ # Populate grid
539
+ pg_manager.add_page("Standard Items")
540
+ populate_with_standard_items(pg_manager)
541
+ pg_manager.add_page("Examples")
542
+ populate_with_examples(pg_manager)
543
+
544
+ pg_manager.refresh
545
+ pg_manager.update
546
+ # Wait for update to be done
547
+ yield_for_a_while(200)
548
+
549
+ pg_manager
550
+ end
551
+
552
+ def setup
553
+ super
554
+ frame_win.raise_window
555
+ @pg_manager = create_grid(-1, -1)
556
+ end
557
+
558
+ def cleanup
559
+ @pg_manager.destroy
560
+ super
561
+ end
562
+
563
+ def test_iterate
564
+ @pg_manager.each_property(Wx::PG::PG_ITERATE_PROPERTIES) do |prop|
565
+ assert_false(prop.is_category, "'#{prop.get_label}' is a category (non-private child property expected)")
566
+ assert_false(prop.get_parent.has_flag(Wx::PG::PGFlags::Aggregate), "'#{prop.get_label}' is a private child (non-private child property expected)")
567
+ end
568
+ @pg_manager.each_property(Wx::PG::PG_ITERATE_CATEGORIES) do |prop|
569
+ assert_true(prop.is_category, "'#{prop.get_label}' is not a category (only categories expected)")
570
+ end
571
+ @pg_manager.each_property(Wx::PG::PG_ITERATE_PROPERTIES|Wx::PG::PG_ITERATE_CATEGORIES) do |prop|
572
+ assert_false(prop.get_parent.has_flag(Wx::PG::PGFlags::Aggregate), "'#{prop.get_label}' is a private child (non-private child property or category expected)")
573
+ end
574
+ @pg_manager.each_property(Wx::PG::PG_ITERATE_VISIBLE) do |prop|
575
+ assert_true(prop.parent == @pg_manager.grid.root || prop.parent.expanded?, "'#{prop.get_label}' had collapsed parent (only visible properties expected)")
576
+ assert_false(prop.has_flag(Wx::PG::PGFlags::Hidden), "'#{prop.get_label}' was hidden (only visible properties expected)")
577
+ end
578
+ end
579
+
580
+ def test_iterate_delete_first_page_then_last
581
+ # Get all properties from first page
582
+ pageFirst = @pg_manager.get_page(0)
583
+ properties_page_first_init = pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
584
+ # Get all properties from last page
585
+ pageLast = @pg_manager.get_page(@pg_manager.get_page_count - 1)
586
+ properties_page_last_init = pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
587
+
588
+ countAllPropertiesInit = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
589
+
590
+ # Delete all properties from first page
591
+ pageFirst.clear
592
+
593
+ assert_true(pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
594
+
595
+ properties_page_last = pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
596
+ assert_equal(properties_page_last_init, properties_page_last)
597
+
598
+ countAllProperties = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
599
+ assert_equal(countAllPropertiesInit-properties_page_first_init.size, countAllProperties)
600
+
601
+ # Delete all properties from last page
602
+ pageLast.clear
603
+
604
+ assert_true(pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
605
+
606
+ assert_true(pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
607
+
608
+ countAllProperties = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
609
+ assert_equal(countAllPropertiesInit-properties_page_first_init.size-properties_page_last_init.size, countAllProperties)
610
+ end
611
+
612
+ def test_iterate_delete_last_page_then_first
613
+ # Get all properties from first page
614
+ pageFirst = @pg_manager.get_page(0)
615
+ properties_page_first_init = pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
616
+ # Get all properties from last page
617
+ pageLast = @pg_manager.get_page(@pg_manager.get_page_count - 1)
618
+ properties_page_last_init = pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
619
+
620
+ countAllPropertiesInit = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
621
+
622
+ # Delete all properties from last page
623
+ pageLast.clear
624
+
625
+ assert_true(pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
626
+
627
+ properties_page_first = pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).collect { |prop| prop.get_name }
628
+ assert_equal(properties_page_first_init, properties_page_first)
629
+
630
+ countAllProperties = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
631
+ assert_equal(countAllPropertiesInit-properties_page_last_init.size, countAllProperties)
632
+
633
+ # Delete all properties from first page
634
+ pageFirst.clear
635
+
636
+ assert_true(pageLast.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
637
+
638
+ assert_true(pageFirst.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count == 0)
639
+
640
+ countAllProperties = @pg_manager.each_property(Wx::PG::PG_ITERATOR_FLAGS_ALL | Wx::PG.PG_IT_CHILDREN(Wx::PG::PG_ITERATOR_FLAGS_ALL)).count
641
+ assert_equal(countAllPropertiesInit-properties_page_first_init.size-properties_page_last_init.size, countAllProperties)
642
+ end
643
+
644
+ unless is_ci_build?
645
+
646
+ def test_select_property
647
+ # Test that setting focus to properties does not crash things
648
+ @pg_manager.page_count.times do |pc|
649
+ page = @pg_manager.page(pc)
650
+ @pg_manager.select_page(page)
651
+
652
+ page.each_property(Wx::PG::PG_ITERATE_VISIBLE) do |prop|
653
+ @pg_manager.grid.select_property(prop, true)
654
+ sleep(0.150)
655
+ frame_win.update
656
+ end
657
+ end
658
+ end
659
+
660
+ end
661
+
662
+ def test_delete_property
663
+ # delete everything in reverse order
664
+
665
+ array = @pg_manager.each_property(Wx::PG::PG_ITERATE_ALL & ~(Wx::PG.PG_IT_CHILDREN(Wx::PG::PGFlags::Aggregate))).to_a
666
+ array.reverse_each { |prop| @pg_manager.delete_property(prop) }
667
+
668
+ assert_true(@pg_manager.each_property(Wx::PG::PG_ITERATE_ALL & ~(Wx::PG.PG_IT_CHILDREN(Wx::PG::PGFlags::Aggregate))).count == 0, "Not all properties are deleted")
669
+
670
+ @pg_manager.refresh
671
+ @pg_manager.update
672
+ # Wait for update to be done
673
+ yield_for_a_while(100)
674
+ end
675
+
676
+ def test_default_values
677
+ @pg_manager.each_property(Wx::PG::PG_ITERATE_PROPERTIES) do |prop|
678
+ @pg_manager.set_property_value(prop, prop.default_value)
679
+ end
680
+ end
681
+
682
+ def test_set_get_property_values
683
+ test_arrstr_1 = %w[Apple Orange Lemon]
684
+
685
+ test_arrstr_2 = %w[Potato Cabbage Cucumber]
686
+
687
+ test_arrint_1 = [1,2,3]
688
+
689
+ test_arrint_2 = [0,1,4]
690
+
691
+ if Wx.has_feature? :USE_DATETIME
692
+ dt1 = Time.now
693
+ dt1 = Time.new(dt1.year, dt1.month, 28) if dt1.month == 2 && dt1.day == 29
694
+
695
+ dt2 = Time.new(dt1.year-10, dt1.month, dt1.day)
696
+ dt1 = Time.new(dt1.year-1, dt1.month, dt1.day)
697
+ end
698
+
699
+ @pg_manager.set_property_value("StringProperty", "Text1")
700
+ @pg_manager.set_property_value("IntProperty", 1024)
701
+ @pg_manager.set_property_value("FloatProperty", 1024.0000000001)
702
+ @pg_manager.set_property_value("BoolProperty", false)
703
+ @pg_manager.set_property_value("EnumProperty", 120)
704
+ @pg_manager.set_property_value("ArrayStringProperty", test_arrstr_1)
705
+ @pg_manager.set_property_value("ColourProperty", Wx::Colour.new)
706
+ @pg_manager.set_property_value("ColourProperty", Wx::BLACK)
707
+ @pg_manager.set_property_value("MultiChoiceProperty", test_arrint_1)
708
+ if Wx.has_feature? :USE_DATETIME
709
+ @pg_manager.set_property_value("DateProperty", dt1)
710
+ end
711
+
712
+ @pg_manager.select_page(1)
713
+ pg = @pg_manager.grid
714
+
715
+ assert_equal("Text1", pg.get_property_value_as_string("StringProperty"))
716
+ assert_equal(1024, pg.get_property_value_as_int("IntProperty"))
717
+ assert_equal(1024.0000000001, pg.get_property_value_as_double("FloatProperty"))
718
+ assert_false(pg.get_property_value_as_bool("BoolProperty"))
719
+ assert_equal(120, pg.get_property_value_as_long("EnumProperty"))
720
+ assert_equal(test_arrstr_1, pg.get_property_value_as_array_string("ArrayStringProperty"))
721
+ col = @pg_manager.get_property_value("ColourProperty").get_colour
722
+ assert_equal(Wx::BLACK, col)
723
+ assert_equal(test_arrint_1, pg.get_property_value_as_array_int("MultiChoiceProperty"))
724
+ if Wx.has_feature? :USE_DATETIME
725
+ assert_equal(dt1, pg.get_property_value_as_date_time("DateProperty"))
726
+ end
727
+
728
+ @pg_manager.set_property_value("IntProperty", 10000000000)
729
+ assert_equal(10000000000, pg.get_property_value_as_long_long("IntProperty"))
730
+
731
+ pg.set_property_value("StringProperty", "Text2")
732
+ pg.set_property_value("IntProperty", 512)
733
+ pg.set_property_value("FloatProperty", 512.0)
734
+ pg.set_property_value("BoolProperty", true)
735
+ pg.set_property_value("EnumProperty", 80)
736
+ pg.set_property_value("ArrayStringProperty", test_arrstr_2)
737
+ pg.set_property_value("ColourProperty", Wx::WHITE)
738
+ pg.set_property_value("MultiChoiceProperty", test_arrint_2)
739
+ if Wx.has_feature? :USE_DATETIME
740
+ pg.set_property_value("DateProperty", dt2)
741
+ end
742
+
743
+ @pg_manager.select_page(0)
744
+
745
+ assert_equal("Text2", @pg_manager.get_property_value_as_string("StringProperty"))
746
+ assert_equal(512, @pg_manager.get_property_value_as_int("IntProperty"))
747
+ assert_equal(512.0, @pg_manager.get_property_value_as_double("FloatProperty"))
748
+ assert_true(@pg_manager.get_property_value_as_bool("BoolProperty"))
749
+ assert_equal(80, @pg_manager.get_property_value_as_long("EnumProperty"))
750
+ assert_equal(test_arrstr_2, @pg_manager.get_property_value_as_array_string("ArrayStringProperty"))
751
+ col = @pg_manager.get_property_value("ColourProperty").colour
752
+ assert_equal(Wx::WHITE, col)
753
+ assert_equal(test_arrint_2, @pg_manager.get_property_value_as_array_int("MultiChoiceProperty"))
754
+ if Wx.has_feature? :USE_DATETIME
755
+ assert_equal(dt2, @pg_manager.get_property_value_as_date_time("DateProperty"))
756
+ end
757
+
758
+ @pg_manager.set_property_value("IntProperty", -80000000000)
759
+ assert_equal(-80000000000, @pg_manager.get_property_value_as_long_long("IntProperty"))
760
+
761
+ nvs = 'Lamborghini Diablo XYZ; 5707; [100; 3.9; 8.6] 3000002; Convertible'
762
+ @pg_manager.set_property_value("Car", nvs)
763
+ assert_equal("Lamborghini Diablo XYZ", @pg_manager.get_property_value_as_string("Car.Model"))
764
+ assert_equal(100, @pg_manager.get_property_value_as_int("Car.Speeds.Max. Speed (mph)"))
765
+ assert_equal(3000002, @pg_manager.get_property_value_as_int("Car.Price ($)"))
766
+ assert_true(@pg_manager.get_property_value_as_bool("Car.Convertible"))
767
+
768
+ # SetPropertyValueString for special cases such as wxColour
769
+ @pg_manager.set_property_value_string("ColourProperty", "(123,4,255)")
770
+ col = @pg_manager.get_property_value("ColourProperty").colour
771
+ assert_equal(Wx::Colour.new(123, 4, 255), col)
772
+ @pg_manager.set_property_value_string("ColourProperty", "#FE860B")
773
+ col = @pg_manager.get_property_value("ColourProperty").colour
774
+ assert_equal(Wx::Colour.new("#FE860B"), col)
775
+
776
+ @pg_manager.set_property_value_string("ColourPropertyWithAlpha", "(10, 20, 30, 128)")
777
+ col = @pg_manager.get_property_value("ColourPropertyWithAlpha").colour
778
+ assert_equal(Wx::Colour.new(10, 20, 30, 128), col)
779
+ assert_equal("(10,20,30,128)", @pg_manager.get_property_value_as_string("ColourPropertyWithAlpha"))
780
+ end
781
+
782
+ def test_set_property_value_unspecified
783
+ # Null variant setter tests
784
+ @pg_manager.set_property_value_unspecified("StringProperty")
785
+ @pg_manager.set_property_value_unspecified("IntProperty")
786
+ @pg_manager.set_property_value_unspecified("FloatProperty")
787
+ @pg_manager.set_property_value_unspecified("BoolProperty")
788
+ @pg_manager.set_property_value_unspecified("EnumProperty")
789
+ @pg_manager.set_property_value_unspecified("ArrayStringProperty")
790
+ @pg_manager.set_property_value_unspecified("ColourProperty")
791
+ @pg_manager.set_property_value_unspecified("MultiChoiceProperty")
792
+ if Wx.has_feature? :USE_DATETIME
793
+ @pg_manager.set_property_value_unspecified("DateProperty")
794
+ end
795
+ end
796
+
797
+ def replace_grid(style, extraStyle)
798
+ @pg_manager.destroy # First destroy previous instance
799
+ @pg_manager = create_grid(style, extraStyle)
800
+ @pg_manager.set_focus
801
+ end
802
+
803
+ def test_multiple_selection
804
+ replace_grid(-1, Wx::PG::PG_EX_MULTIPLE_SELECTION) unless @pg_manager.get_extra_style & Wx::PG::PG_EX_MULTIPLE_SELECTION
805
+
806
+ pg = @pg_manager.grid
807
+
808
+ prop1 = pg.get_property("Label")
809
+ prop2 = pg.get_property("Cell Text Colour")
810
+ prop3 = pg.get_property("Height")
811
+ catProp = pg.get_property("Appearance")
812
+
813
+ assert_not_nil(prop1)
814
+ assert_not_nil(prop2)
815
+ assert_not_nil(prop3)
816
+
817
+ pg.clear_selection
818
+ pg.add_to_selection(prop1)
819
+ pg.add_to_selection(prop2)
820
+ pg.add_to_selection(prop3)
821
+
822
+ # Adding category to selection should fail silently
823
+ pg.add_to_selection(catProp)
824
+
825
+ selectedProperties = pg.get_selected_properties
826
+
827
+ assert_equal(3, selectedProperties.size)
828
+ assert_true(pg.is_property_selected(prop1))
829
+ assert_true(pg.is_property_selected(prop2))
830
+ assert_true(pg.is_property_selected(prop3))
831
+ assert_false(pg.is_property_selected(catProp))
832
+
833
+ pg.remove_from_selection(prop1)
834
+ selectedProperties2 = pg.get_selected_properties
835
+
836
+ assert_equal(2, selectedProperties2.size)
837
+ assert_false(pg.is_property_selected(prop1))
838
+ assert_true(pg.is_property_selected(prop2))
839
+ assert_true(pg.is_property_selected(prop3))
840
+
841
+ pg.clear_selection
842
+
843
+ selectedProperties3 = pg.get_selected_properties
844
+
845
+ assert_equal(0, selectedProperties3.size)
846
+ assert_false(pg.is_property_selected(prop1))
847
+ assert_false(pg.is_property_selected(prop2))
848
+ assert_false(pg.is_property_selected(prop3))
849
+
850
+ pg.select_property(prop2)
851
+
852
+ assert_false(pg.is_property_selected(prop1))
853
+ assert_true(pg.is_property_selected(prop2))
854
+ assert_false(pg.is_property_selected(prop3))
855
+ end
856
+
857
+ end