wxruby3 0.9.2 → 0.9.3

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.
Files changed (347) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +35 -29
  3. data/README.md +24 -15
  4. data/ext/wxruby3/include/wxruby-ClientData.h +48 -0
  5. data/ext/wxruby3/include/wxruby-Validator.h +39 -0
  6. data/ext/wxruby3/include/wxruby-ValidatorBinding.h +64 -0
  7. data/ext/wxruby3/swig/custom/director.swg +8 -0
  8. data/ext/wxruby3/swig/mark_free_impl.i +0 -33
  9. data/lib/wx/core/bitmap_combobox.rb +17 -21
  10. data/lib/wx/core/combobox.rb +13 -3
  11. data/lib/wx/core/controlwithitems.rb +40 -130
  12. data/lib/wx/core/enum.rb +17 -1
  13. data/lib/wx/core/event.rb +6 -1
  14. data/lib/wx/core/evthandler.rb +8 -2
  15. data/lib/wx/core/generic_validator.rb +312 -0
  16. data/lib/wx/core/listbox.rb +2 -2
  17. data/lib/wx/core/log.rb +1 -1
  18. data/lib/wx/core/owner_drawn_combobox.rb +45 -0
  19. data/lib/wx/core/size.rb +4 -0
  20. data/lib/wx/core/sizer.rb +1 -2
  21. data/lib/wx/core/standard_paths.rb +22 -0
  22. data/lib/wx/core/text_entry.rb +4 -1
  23. data/lib/wx/core/validator.rb +70 -5
  24. data/lib/wx/core/window.rb +3 -7
  25. data/lib/wx/doc/art_locator.rb +1 -0
  26. data/lib/wx/doc/comboctrl.rb +18 -0
  27. data/lib/wx/doc/controlwithitems.rb +16 -0
  28. data/lib/wx/doc/date_picker_ctrl.rb +23 -0
  29. data/lib/wx/doc/editable_listbox.rb +44 -0
  30. data/lib/wx/doc/enum.rb +15 -0
  31. data/lib/wx/doc/event.rb +12 -0
  32. data/lib/wx/doc/extra/12_client_data.md +89 -0
  33. data/lib/wx/doc/extra/13_validators.md +139 -0
  34. data/lib/wx/doc/gdi_common.rb +4 -0
  35. data/lib/wx/doc/generic_validator.rb +95 -0
  36. data/lib/wx/doc/html/simple_html_listbox.rb +22 -0
  37. data/lib/wx/doc/num_validator.rb +387 -0
  38. data/lib/wx/doc/owner_drawn_combobox.rb +96 -0
  39. data/lib/wx/doc/pg/numeric_property_validator.rb +33 -0
  40. data/lib/wx/doc/static_bitmap.rb +25 -0
  41. data/lib/wx/doc/text_validator.rb +10 -0
  42. data/lib/wx/doc/validator.rb +113 -0
  43. data/lib/wx/doc/window.rb +30 -0
  44. data/lib/wx/html/simple_html_listbox.rb +24 -91
  45. data/lib/wx/keyword_defs.rb +34 -2
  46. data/lib/wx/rbn/ribbon_gallery.rb +0 -21
  47. data/lib/wx/version.rb +1 -1
  48. data/rakelib/lib/config/mingw.rb +12 -0
  49. data/rakelib/lib/core/include/client_data.inc +65 -0
  50. data/rakelib/lib/core/include/funcall.inc +1 -1
  51. data/rakelib/lib/core/package.rb +17 -2
  52. data/rakelib/lib/core/parameter.rb +1 -1
  53. data/rakelib/lib/core/spec_helper.rb +7 -1
  54. data/rakelib/lib/director/app.rb +18 -0
  55. data/rakelib/lib/director/app_traits.rb +3 -1
  56. data/rakelib/lib/director/bitmap_combobox.rb +2 -2
  57. data/rakelib/lib/director/combobox.rb +22 -0
  58. data/rakelib/lib/director/comboctrl.rb +1 -55
  59. data/rakelib/lib/director/ctrl_with_items.rb +88 -21
  60. data/rakelib/lib/director/date_picker_ctrl.rb +8 -6
  61. data/rakelib/lib/director/editable_listbox.rb +30 -0
  62. data/rakelib/lib/director/event.rb +102 -12
  63. data/rakelib/lib/director/event_handler.rb +3 -2
  64. data/rakelib/lib/director/functions.rb +4 -2
  65. data/rakelib/lib/director/generic_dirctrl.rb +17 -0
  66. data/rakelib/lib/director/grid_cell_attr.rb +0 -2
  67. data/rakelib/lib/director/grid_cell_editor.rb +0 -2
  68. data/rakelib/lib/director/grid_cell_renderer.rb +0 -2
  69. data/rakelib/lib/director/header_ctrl.rb +6 -1
  70. data/rakelib/lib/director/html_listbox.rb +96 -22
  71. data/rakelib/lib/director/num_validator.rb +495 -0
  72. data/rakelib/lib/director/numeric_property_validator.rb +131 -6
  73. data/rakelib/lib/director/owner_drawn_combobox.rb +192 -0
  74. data/rakelib/lib/director/pgproperty.rb +3 -29
  75. data/rakelib/lib/director/ribbon_button_bar.rb +3 -3
  76. data/rakelib/lib/director/ribbon_gallery.rb +3 -5
  77. data/rakelib/lib/director/sizer.rb +15 -4
  78. data/rakelib/lib/director/sizer_item.rb +13 -0
  79. data/rakelib/lib/director/static_bitmap.rb +28 -0
  80. data/rakelib/lib/director/text_entry.rb +4 -0
  81. data/rakelib/lib/director/text_validator.rb +124 -13
  82. data/rakelib/lib/director/toggle_button.rb +1 -0
  83. data/rakelib/lib/director/top_level_window.rb +0 -2
  84. data/rakelib/lib/director/tree_ctrl.rb +35 -0
  85. data/rakelib/lib/director/utils.rb +16 -2
  86. data/rakelib/lib/director/validator.rb +196 -21
  87. data/rakelib/lib/director/window.rb +16 -2
  88. data/rakelib/lib/extractor/function.rb +2 -1
  89. data/rakelib/lib/generate/analyzer.rb +1 -1
  90. data/rakelib/lib/generate/doc.rb +10 -4
  91. data/rakelib/lib/specs/interfaces.rb +2 -0
  92. data/rakelib/lib/swig_runner.rb +55 -9
  93. data/rakelib/lib/typemap/client_data.rb +67 -0
  94. data/rakelib/lib/typemap/common.rb +3 -3
  95. data/rakelib/lib/typemap/datetime.rb +1 -1
  96. data/rakelib/lib/typemap/tree_itemid.rb +2 -2
  97. data/samples/aui/aui.rb +1237 -1233
  98. data/samples/calendar/calendar.rb +293 -289
  99. data/samples/controls/get_item_sample.rb +83 -79
  100. data/samples/controls/htlbox.rb +331 -327
  101. data/samples/dialogs/dialogs.rb +682 -694
  102. data/samples/dialogs/wizard.rb +52 -55
  103. data/samples/dragdrop/dragdrop.rb +146 -142
  104. data/samples/drawing/bitmap.rb +29 -26
  105. data/samples/drawing/bitmap_image.rb +84 -80
  106. data/samples/drawing/graphics_drawing.rb +209 -205
  107. data/samples/drawing/image_prt.rb +344 -340
  108. data/samples/drawing/maths_images.rb +18 -1
  109. data/samples/drawing/rmagic_bitmap_image.rb +88 -84
  110. data/samples/etc/caret.rb +306 -0
  111. data/samples/etc/miniframe.rb +65 -60
  112. data/samples/etc/sash.rb +109 -105
  113. data/samples/etc/scrollwin.rb +86 -80
  114. data/samples/etc/system_settings.rb +216 -209
  115. data/samples/event/activation.rb +72 -67
  116. data/samples/event/event.rb +160 -153
  117. data/samples/event/threaded.rb +8 -1
  118. data/samples/event/update_ui_event.rb +67 -60
  119. data/samples/grid/grid.rb +188 -181
  120. data/samples/grid/gridtablebase.rb +136 -129
  121. data/samples/html/html.rb +208 -204
  122. data/samples/mdi/mdi.rb +59 -54
  123. data/samples/minimal/minimal.rb +54 -51
  124. data/samples/minimal/nothing.rb +1 -0
  125. data/samples/printing/printing.rb +367 -377
  126. data/samples/printing/printing2.rb +203 -198
  127. data/samples/propgrid/propgrid.rb +2312 -2308
  128. data/samples/propgrid/propgrid_minimal.rb +57 -50
  129. data/samples/ribbon/ribbon.rb +780 -774
  130. data/samples/sampler/ext.rb +0 -33
  131. data/samples/sampler/sample.rb +4 -9
  132. data/samples/sampler.rb +1 -1
  133. data/samples/splash/splash.rb +118 -116
  134. data/samples/text/rich_textctrl.rb +207 -201
  135. data/samples/text/richtext.rb +1409 -1405
  136. data/samples/text/scintilla.rb +137 -128
  137. data/samples/text/textctrl.rb +89 -83
  138. data/samples/text/unicode.rb +175 -168
  139. data/samples/treectrl/treectrl.rb +1430 -1426
  140. data/samples/widgets/activityindicator.rb +95 -0
  141. data/samples/widgets/art/widgets/activityindicator.xpm +278 -0
  142. data/samples/widgets/art/widgets/bmpbtn.xpm +37 -0
  143. data/samples/widgets/art/widgets/bmpcombobox.xpm +54 -0
  144. data/samples/widgets/art/widgets/button.xpm +54 -0
  145. data/samples/widgets/art/widgets/checkbox.xpm +54 -0
  146. data/samples/{bigdemo/icons → widgets/art/widgets}/choice.xpm +1 -1
  147. data/samples/widgets/art/widgets/choicebk.xpm +54 -0
  148. data/samples/widgets/art/widgets/clrpicker.xpm +193 -0
  149. data/samples/widgets/art/widgets/combobox.xpm +54 -0
  150. data/samples/widgets/art/widgets/datepick.xpm +200 -0
  151. data/samples/widgets/art/widgets/dirctrl.xpm +54 -0
  152. data/samples/widgets/art/widgets/dirpicker.xpm +213 -0
  153. data/samples/widgets/art/widgets/filepicker.xpm +214 -0
  154. data/samples/widgets/art/widgets/fontpicker.xpm +185 -0
  155. data/samples/widgets/art/widgets/gauge.xpm +54 -0
  156. data/samples/widgets/art/widgets/header.xpm +54 -0
  157. data/samples/widgets/art/widgets/hyperlnk.xpm +54 -0
  158. data/samples/widgets/art/widgets/listbook.xpm +54 -0
  159. data/samples/widgets/art/widgets/listbox.xpm +54 -0
  160. data/samples/widgets/art/widgets/native.xpm +81 -0
  161. data/samples/widgets/art/widgets/notebook.xpm +54 -0
  162. data/samples/widgets/art/widgets/odcombobox.xpm +54 -0
  163. data/samples/widgets/art/widgets/radiobox.xpm +54 -0
  164. data/samples/widgets/art/widgets/scrolbar.xpm +54 -0
  165. data/samples/widgets/art/widgets/slider.xpm +54 -0
  166. data/samples/widgets/art/widgets/spinbtn.xpm +40 -0
  167. data/samples/widgets/art/widgets/statbmp.xpm +40 -0
  168. data/samples/widgets/art/widgets/statbox.xpm +54 -0
  169. data/samples/widgets/art/widgets/stattext.xpm +54 -0
  170. data/samples/widgets/art/widgets/text.xpm +54 -0
  171. data/samples/widgets/art/widgets/timepick.xpm +207 -0
  172. data/samples/widgets/art/widgets/toggle.xpm +54 -0
  173. data/samples/widgets/art/widgets/toucan.png +0 -0
  174. data/samples/widgets/bmpcombobox.rb +651 -0
  175. data/samples/widgets/button.rb +462 -0
  176. data/samples/widgets/checkbox.rb +211 -0
  177. data/samples/widgets/choice.rb +287 -0
  178. data/samples/widgets/clrpicker.rb +156 -0
  179. data/samples/widgets/combobox.rb +516 -0
  180. data/samples/widgets/datepick.rb +215 -0
  181. data/samples/widgets/dirctrl.rb +265 -0
  182. data/samples/widgets/dirpicker.rb +158 -0
  183. data/samples/widgets/editlbox.rb +122 -0
  184. data/samples/widgets/filectrl.rb +216 -0
  185. data/samples/widgets/filepicker.rb +214 -0
  186. data/samples/widgets/fontpicker.rb +135 -0
  187. data/samples/widgets/gauge.rb +311 -0
  188. data/samples/widgets/headerctrl.rb +236 -0
  189. data/samples/widgets/hyperlink.rb +203 -0
  190. data/samples/widgets/itemcontainer.rb +185 -0
  191. data/samples/widgets/listbox.rb +473 -0
  192. data/samples/widgets/notebook.rb +488 -0
  193. data/samples/widgets/odcombobox.rb +608 -0
  194. data/samples/widgets/radiobox.rb +328 -0
  195. data/samples/widgets/searchctrl.rb +159 -0
  196. data/samples/widgets/slider.rb +594 -0
  197. data/samples/widgets/spinbtn.rb +443 -0
  198. data/samples/widgets/statbmp.rb +130 -0
  199. data/samples/widgets/static.rb +436 -0
  200. data/samples/widgets/textctrl.rb +700 -0
  201. data/samples/widgets/timepick.rb +148 -0
  202. data/samples/widgets/tn_widgets.png +0 -0
  203. data/samples/widgets/toggle.rb +385 -0
  204. data/samples/widgets/widgets.rb +1233 -0
  205. data/samples/xrc/custom_xrc_sample.rb +47 -41
  206. data/samples/xrc/xrc_sample.rb +53 -47
  207. data/tests/test_event_handling.rb +52 -34
  208. data/tests/test_events.rb +7 -0
  209. data/tests/test_item_data.rb +24 -0
  210. data/tests/test_sizer.rb +44 -1
  211. data/tests/test_validators.rb +805 -0
  212. metadata +92 -138
  213. data/lib/wx/core/choice.rb +0 -14
  214. data/lib/wx/core/combo_ctrl.rb +0 -110
  215. data/rakelib/lib/typemap/grid_client_data.rb +0 -58
  216. data/samples/bigdemo/About.rbw +0 -39
  217. data/samples/bigdemo/ColorPanel.rbw +0 -23
  218. data/samples/bigdemo/GridSimple.rbw +0 -78
  219. data/samples/bigdemo/MDIDemo.rbw +0 -57
  220. data/samples/bigdemo/PopupMenu.rbw +0 -146
  221. data/samples/bigdemo/ShapedWindow.rbw +0 -128
  222. data/samples/bigdemo/Sizers.rbw +0 -541
  223. data/samples/bigdemo/bigdemo.rb +0 -817
  224. data/samples/bigdemo/demoTemplate.rbw +0 -33
  225. data/samples/bigdemo/helpfile.htb +0 -0
  226. data/samples/bigdemo/icons/Test 015.jpg +0 -0
  227. data/samples/bigdemo/icons/Test 015.png +0 -0
  228. data/samples/bigdemo/icons/choice.bmp +0 -0
  229. data/samples/bigdemo/icons/combo.bmp +0 -0
  230. data/samples/bigdemo/icons/combo.xpm +0 -27
  231. data/samples/bigdemo/icons/copy.xpm +0 -25
  232. data/samples/bigdemo/icons/cut.xpm +0 -24
  233. data/samples/bigdemo/icons/gauge.bmp +0 -0
  234. data/samples/bigdemo/icons/gauge.xpm +0 -27
  235. data/samples/bigdemo/icons/help.xpm +0 -25
  236. data/samples/bigdemo/icons/list.bmp +0 -0
  237. data/samples/bigdemo/icons/list.xpm +0 -27
  238. data/samples/bigdemo/icons/mondrian.ico +0 -0
  239. data/samples/bigdemo/icons/mondrian.xpm +0 -44
  240. data/samples/bigdemo/icons/new.xpm +0 -24
  241. data/samples/bigdemo/icons/ogl.ico +0 -0
  242. data/samples/bigdemo/icons/ogl.xpm +0 -45
  243. data/samples/bigdemo/icons/open.xpm +0 -26
  244. data/samples/bigdemo/icons/paste.bmp +0 -0
  245. data/samples/bigdemo/icons/paste.xpm +0 -38
  246. data/samples/bigdemo/icons/pointy.png +0 -0
  247. data/samples/bigdemo/icons/preview.xpm +0 -26
  248. data/samples/bigdemo/icons/print.xpm +0 -26
  249. data/samples/bigdemo/icons/radio.bmp +0 -0
  250. data/samples/bigdemo/icons/radio.xpm +0 -27
  251. data/samples/bigdemo/icons/robert.xpm +0 -415
  252. data/samples/bigdemo/icons/sashtest.ico +0 -0
  253. data/samples/bigdemo/icons/save.xpm +0 -25
  254. data/samples/bigdemo/icons/smiles.bmp +0 -0
  255. data/samples/bigdemo/icons/smiles.xpm +0 -39
  256. data/samples/bigdemo/icons/smiley.ico +0 -0
  257. data/samples/bigdemo/icons/smiley.xpm +0 -42
  258. data/samples/bigdemo/icons/stattext.xpm +0 -24
  259. data/samples/bigdemo/icons/test2.bmp +0 -0
  260. data/samples/bigdemo/icons/test2.png +0 -0
  261. data/samples/bigdemo/icons/test2.xpm +0 -79
  262. data/samples/bigdemo/icons/text.bmp +0 -0
  263. data/samples/bigdemo/icons/text.xpm +0 -27
  264. data/samples/bigdemo/icons/tog1.bmp +0 -0
  265. data/samples/bigdemo/icons/tog1.xpm +0 -38
  266. data/samples/bigdemo/icons/tog2.bmp +0 -0
  267. data/samples/bigdemo/icons/tog2.xpm +0 -38
  268. data/samples/bigdemo/icons/wxruby-128x128.png +0 -0
  269. data/samples/bigdemo/icons/wxwin.ico +0 -0
  270. data/samples/bigdemo/icons/wxwin16x16.png +0 -0
  271. data/samples/bigdemo/icons/wxwin16x16.xpm +0 -25
  272. data/samples/bigdemo/icons/wxwin32x32.png +0 -0
  273. data/samples/bigdemo/icons/wxwin48x48.png +0 -0
  274. data/samples/bigdemo/run.rb +0 -98
  275. data/samples/bigdemo/tips.txt +0 -7
  276. data/samples/bigdemo/utils.rb +0 -20
  277. data/samples/bigdemo/wxArtProvider.rbw +0 -282
  278. data/samples/bigdemo/wxBitmapButton.rbw +0 -65
  279. data/samples/bigdemo/wxButton.rbw +0 -64
  280. data/samples/bigdemo/wxCalendarCtrl.rbw +0 -59
  281. data/samples/bigdemo/wxCheckBox.rbw +0 -50
  282. data/samples/bigdemo/wxCheckListBox.rbw +0 -65
  283. data/samples/bigdemo/wxChoice.rbw +0 -47
  284. data/samples/bigdemo/wxChoicebook.rbw +0 -78
  285. data/samples/bigdemo/wxColourDialog.rbw +0 -33
  286. data/samples/bigdemo/wxComboBox.rbw +0 -77
  287. data/samples/bigdemo/wxCursor.rbw +0 -136
  288. data/samples/bigdemo/wxDialog.rbw +0 -74
  289. data/samples/bigdemo/wxDirDialog.rbw +0 -29
  290. data/samples/bigdemo/wxDragImage.rbw +0 -70
  291. data/samples/bigdemo/wxFileDialog.rbw +0 -37
  292. data/samples/bigdemo/wxFileDialog_Save.rbw +0 -35
  293. data/samples/bigdemo/wxFindReplaceDialog.rbw +0 -82
  294. data/samples/bigdemo/wxFontDialog.rbw +0 -200
  295. data/samples/bigdemo/wxFrame.rbw +0 -53
  296. data/samples/bigdemo/wxGauge.rbw +0 -65
  297. data/samples/bigdemo/wxGenericDirCtrl.rbw +0 -74
  298. data/samples/bigdemo/wxGrid.rbw +0 -66
  299. data/samples/bigdemo/wxHtmlHelpController.rbw +0 -52
  300. data/samples/bigdemo/wxListBox.rbw +0 -140
  301. data/samples/bigdemo/wxListCtrl_virtual.rbw +0 -112
  302. data/samples/bigdemo/wxMDIWindows.rbw +0 -50
  303. data/samples/bigdemo/wxMenu.rbw +0 -247
  304. data/samples/bigdemo/wxMessageDialog.rbw +0 -27
  305. data/samples/bigdemo/wxMiniFrame.rbw +0 -70
  306. data/samples/bigdemo/wxMultipleChoiceDialog.rbw +0 -29
  307. data/samples/bigdemo/wxNotebook.rbw +0 -136
  308. data/samples/bigdemo/wxProgressDialog.rbw +0 -43
  309. data/samples/bigdemo/wxRadioBox.rbw +0 -72
  310. data/samples/bigdemo/wxRadioButton.rbw +0 -125
  311. data/samples/bigdemo/wxSashWindow.rbw +0 -141
  312. data/samples/bigdemo/wxScrolledMessageDialog.rbw +0 -57
  313. data/samples/bigdemo/wxScrolledWindow.rbw +0 -199
  314. data/samples/bigdemo/wxSingleChoiceDialog.rbw +0 -33
  315. data/samples/bigdemo/wxSlider.rbw +0 -42
  316. data/samples/bigdemo/wxSpinButton.rbw +0 -50
  317. data/samples/bigdemo/wxSpinCtrl.rbw +0 -51
  318. data/samples/bigdemo/wxSplitterWindow.rbw +0 -63
  319. data/samples/bigdemo/wxStaticBitmap.rbw +0 -47
  320. data/samples/bigdemo/wxStaticText.rbw +0 -55
  321. data/samples/bigdemo/wxStatusBar.rbw +0 -126
  322. data/samples/bigdemo/wxTextCtrl.rbw +0 -149
  323. data/samples/bigdemo/wxTextEntryDialog.rbw +0 -31
  324. data/samples/bigdemo/wxToggleButton.rbw +0 -49
  325. data/samples/bigdemo/wxToolBar.rbw +0 -131
  326. data/samples/bigdemo/wxTreeCtrl.rbw +0 -191
  327. data/samples/caret/caret.rb +0 -298
  328. data/samples/caret/mondrian.xpm +0 -44
  329. data/samples/controls/books.rb +0 -189
  330. data/samples/controls/choice.xpm +0 -27
  331. data/samples/controls/combo.xpm +0 -27
  332. data/samples/controls/controls.rb +0 -1099
  333. data/samples/controls/gauge.xpm +0 -27
  334. data/samples/controls/list.xpm +0 -27
  335. data/samples/controls/mondrian.ico +0 -0
  336. data/samples/controls/mondrian.xpm +0 -44
  337. data/samples/controls/radio.xpm +0 -27
  338. data/samples/controls/stattext.xpm +0 -24
  339. data/samples/controls/test2.bmp +0 -0
  340. data/samples/controls/text.xpm +0 -27
  341. data/samples/controls/tn_books.png +0 -0
  342. data/samples/controls/tn_controls.png +0 -0
  343. data/samples/etc/choice.rb +0 -87
  344. data/samples/etc/tn_choice.png +0 -0
  345. data/samples/text/mondrian.ico +0 -0
  346. data/samples/text/mondrian.xpm +0 -44
  347. /data/samples/{caret → etc}/tn_caret.png +0 -0
@@ -0,0 +1,805 @@
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 ValidatorTests < WxRuby::Test::GUITests
8
+
9
+ def setup
10
+ super
11
+ @text = Wx::TextCtrl.new(frame_win, name: 'Text')
12
+ end
13
+
14
+ def cleanup
15
+ @text.destroy if @text
16
+ @text = nil
17
+ super
18
+ end
19
+
20
+ def teardown
21
+ @text.destroy if @text
22
+ @text = nil
23
+ super
24
+ end
25
+
26
+ attr_accessor :text
27
+
28
+ class MyTextValidator < Wx::Validator
29
+
30
+ # overload for customized functionality
31
+ def do_transfer_from_window
32
+ get_window.get_value
33
+ end
34
+
35
+ # overload for customized functionality
36
+ def do_transfer_to_window(val)
37
+ get_window.set_value(val)
38
+ true
39
+ end
40
+
41
+ def validate(parent)
42
+ get_window && get_window.value != 'F*ck!'
43
+ end
44
+
45
+ end
46
+
47
+ def test_my_text_validator
48
+ data = 'hello'
49
+ val = MyTextValidator.new
50
+
51
+ val.on_transfer_to_window { data }
52
+ val.on_transfer_from_window { |v| data = v }
53
+ text.set_validator(val)
54
+
55
+ assert_true(text.empty?)
56
+
57
+ assert_true(text.transfer_data_to_window)
58
+
59
+ assert_equal('hello', text.value)
60
+ assert_true(frame_win.validate)
61
+
62
+ text.value = 'F*ck!'
63
+ assert_false(frame_win.validate)
64
+
65
+ text.value = 'OMG!'
66
+ assert_true(frame_win.validate)
67
+
68
+ assert_true(text.transfer_data_from_window)
69
+ assert_equal('OMG!', data)
70
+ end
71
+
72
+ end
73
+
74
+ class TextValidatorTests < WxRuby::Test::GUITests
75
+
76
+ def setup
77
+ super
78
+ @text = nil
79
+ end
80
+
81
+ def cleanup
82
+ @text.destroy if @text
83
+ @text = nil
84
+ super
85
+ end
86
+
87
+ def teardown
88
+ @text.destroy if @text
89
+ @text = nil
90
+ super
91
+ end
92
+
93
+ attr_accessor :text
94
+
95
+ def test_basic
96
+ val = Wx::TextValidator.new(Wx::TextValidatorStyle::FILTER_NONE)
97
+
98
+ assert_empty(val.value)
99
+
100
+ assert_empty(val.valid?("wx-90.?! @_~E+{"))
101
+
102
+ val.set_style(Wx::TextValidatorStyle::FILTER_EMPTY)
103
+ assert_not_empty(val.valid?(''))
104
+ assert_empty(val.valid?(' '))
105
+
106
+ val.set_style(Wx::TextValidatorStyle::FILTER_ASCII)
107
+ assert_empty(val.valid?("wx-90.?! @_~E+{"))
108
+
109
+ val.set_style(Wx::TextValidatorStyle::FILTER_ALPHA)
110
+
111
+ assert_empty(val.valid?("wx"))
112
+ assert_not_empty(val.valid?("wx_")) # _ is not alpha
113
+
114
+ val.set_style(Wx::TextValidatorStyle::FILTER_ALPHANUMERIC)
115
+
116
+ assert_empty(val.valid?("wx01"))
117
+ assert_not_empty(val.valid?("wx 01")) # 'space' is not alphanumeric
118
+
119
+ val.set_style(Wx::TextValidatorStyle::FILTER_DIGITS)
120
+
121
+ assert_empty(val.valid?("97"))
122
+ assert_not_empty(val.valid?("9.7")) # . is not digit
123
+
124
+ val.set_style(Wx::TextValidatorStyle::FILTER_XDIGITS)
125
+
126
+ assert_empty(val.valid?("90AEF"))
127
+ assert_not_empty(val.valid?("90GEF")) # G is not xdigit
128
+
129
+ val.set_style(Wx::TextValidatorStyle::FILTER_NUMERIC)
130
+
131
+ assert_empty(val.valid?("+90.e-2"))
132
+ assert_not_empty(val.valid?("-8.5#0")) # # is not numeric
133
+
134
+ val.set_style(Wx::TextValidatorStyle::FILTER_INCLUDE_LIST)
135
+
136
+ val.set_includes(%w[wxMSW wxGTK wxOSX])
137
+
138
+ assert_empty(val.valid?("wxGTK"))
139
+ assert_not_empty(val.valid?("wxQT")) # wxQT is not included
140
+
141
+ val.set_excludes(%w[wxGTK])
142
+
143
+ assert_empty(val.valid?("wxOSX"))
144
+ assert_not_empty(val.valid?("wxGTK")) # wxGTK now excluded
145
+
146
+ val.set_style(Wx::TextValidatorStyle::FILTER_EXCLUDE_LIST)
147
+
148
+ val.set_excludes(%w[wxMSW wxGTK wxOSX])
149
+
150
+ assert_empty(val.valid?("wxQT & wxUNIV"))
151
+ assert_not_empty(val.valid?("wxMSW")) # wxMSW is excluded
152
+
153
+ val.set_includes(%w[wxMSW]) # exclusion takes priority over inclusion.
154
+
155
+ assert_empty(val.valid?("wxUNIV"))
156
+ assert_not_empty(val.valid?("wxMSW")) # wxMSW still excluded
157
+
158
+ val.set_style(Wx::TextValidatorStyle::FILTER_INCLUDE_CHAR_LIST)
159
+ val.set_char_includes("tuvwxyz.012+-")
160
+
161
+ assert_empty(val.valid?("0.2t+z-1"))
162
+ assert_not_empty(val.valid?("x*y")); # * is not included
163
+
164
+ val.add_char_includes("*")
165
+
166
+ assert_empty(val.valid?("x*y")) # * now included
167
+ assert_not_empty(val.valid?("x%y")) # % is not included
168
+
169
+ val.add_char_excludes("*") # exclusion takes priority over inclusion.
170
+
171
+ assert_not_empty(val.valid?("x*y")) # * now excluded
172
+
173
+ val.set_style(Wx::TextValidatorStyle::FILTER_EXCLUDE_CHAR_LIST)
174
+ val.set_char_excludes("tuvwxyz.012+-")
175
+
176
+ assert_empty(val.valid?("A*B=?"))
177
+ assert_not_empty(val.valid?("0.6/t")) # t is excluded
178
+
179
+ val.add_char_includes("t") # exclusion takes priority over inclusion.
180
+
181
+ assert_not_empty(val.valid?("0.6/t")) # t still excluded
182
+ end
183
+
184
+ def test_text_ctrl_validate
185
+ self.text = Wx::TextCtrl.new(frame_win, name: 'Text')
186
+
187
+ val = Wx::TextValidator.new(Wx::TextValidatorStyle::FILTER_ALPHA)
188
+ text.set_validator(val)
189
+
190
+ assert_empty(text)
191
+ assert_empty(text.validator.value)
192
+
193
+ text.validator.value = 'wxwidgets'
194
+
195
+ assert_true(text.transfer_data_to_window)
196
+
197
+ assert_equal('wxwidgets', text.value)
198
+
199
+ assert_equal('wxwidgets', text.validator.value)
200
+ text.value = 'wxRuby'
201
+ assert_true(text.transfer_data_from_window)
202
+ assert_equal('wxRuby', text.validator.value)
203
+ end
204
+
205
+ def test_text_ctrl_validate_transfer
206
+ self.text = Wx::TextCtrl.new(frame_win, name: 'Text')
207
+
208
+ data = 'wxwidgets'
209
+ val = Wx::TextValidator.new(Wx::TextValidatorStyle::FILTER_ALPHA)
210
+ val.on_transfer_to_window { data }
211
+ val.on_transfer_from_window { |v| data = v }
212
+ text.set_validator(val)
213
+
214
+ assert_empty(text)
215
+ assert_empty(text.validator.value)
216
+
217
+ assert_true(text.transfer_data_to_window)
218
+
219
+ assert_equal('wxwidgets', text.value)
220
+ assert_equal('wxwidgets', text.validator.value)
221
+
222
+ assert_equal('wxwidgets', data)
223
+ text.value = 'wxRuby'
224
+ assert_true(text.transfer_data_from_window)
225
+ assert_equal('wxRuby', text.validator.value)
226
+ assert_equal('wxRuby', data)
227
+ end
228
+
229
+ class CustomTextValidator < Wx::TextValidator
230
+
231
+ def initialize(arg)
232
+ if arg.is_a?(self.class)
233
+ super(arg)
234
+ @value_owner = arg.value_owner
235
+ else
236
+ super(Wx::TextValidatorStyle::FILTER_NONE)
237
+ @value_owner = arg
238
+ self.on_transfer_to_window :handle_get_data
239
+ self.on_transfer_from_window :handle_set_data
240
+ end
241
+ end
242
+
243
+ attr_reader :value_owner
244
+
245
+ def clone
246
+ self.class.new(self)
247
+ end
248
+
249
+ protected
250
+
251
+ def handle_set_data(data)
252
+ @value_owner.value = data
253
+ end
254
+
255
+ def handle_get_data
256
+ @value_owner.value
257
+ end
258
+
259
+ end
260
+
261
+ class ModelData
262
+
263
+ def initialize(val = '123')
264
+ @value = val
265
+ end
266
+
267
+ attr_accessor :value
268
+
269
+ end
270
+
271
+ def test_custom_validator
272
+ self.text = Wx::TextCtrl.new(frame_win, name: 'Text')
273
+
274
+ mod = ModelData.new
275
+
276
+ assert_equal('123', mod.value)
277
+
278
+ val = CustomTextValidator.new(mod)
279
+ text.set_validator(val)
280
+
281
+ assert_true(text.empty?)
282
+
283
+ assert_true(text.transfer_data_to_window)
284
+
285
+ assert_equal('123', text.value)
286
+
287
+ text.value = '456'
288
+
289
+ assert_true(text.transfer_data_from_window)
290
+
291
+ assert_equal('456', mod.value)
292
+ end
293
+
294
+ end
295
+
296
+ class IntegerValidatorTests < WxRuby::Test::GUITests
297
+
298
+ def setup
299
+ super
300
+ @text = Wx::TextCtrl.new(frame_win, name: 'Text')
301
+ end
302
+
303
+ def cleanup
304
+ @text.destroy if @text
305
+ @text = nil
306
+ super
307
+ end
308
+
309
+ def teardown
310
+ @text.destroy if @text
311
+ @text = nil
312
+ super
313
+ end
314
+
315
+ attr_accessor :text
316
+
317
+ def test_no_custom_transfer
318
+ valInt = Wx::IntegerValidator.new
319
+ text.validator = valInt
320
+
321
+ assert_equal(0, text.validator.value)
322
+ assert_true(text.transfer_data_to_window)
323
+ assert_equal('0', text.value)
324
+
325
+ text.validator.value = 17
326
+ assert_true(text.transfer_data_to_window)
327
+ assert_equal('17', text.value)
328
+
329
+ text.change_value("foobar")
330
+ assert_false(text.transfer_data_from_window)
331
+ assert_equal(17, text.validator.value)
332
+
333
+ text.change_value('-234')
334
+ assert_true(text.transfer_data_from_window)
335
+ assert_equal(-234, text.validator.value)
336
+
337
+ text.change_value('9223372036854775808') # == LLONG_MAX + 1
338
+ assert_false(text.transfer_data_from_window)
339
+ assert_equal(-234, text.validator.value)
340
+
341
+ text.clear
342
+ assert_false(text.transfer_data_from_window)
343
+ end
344
+
345
+ def test_transfer
346
+ data = 0
347
+ valInt = Wx::IntegerValidator.new
348
+ valInt.on_transfer_to_window { data }
349
+ valInt.on_transfer_from_window { |v| data = v }
350
+ text.validator = valInt
351
+
352
+ assert_true(text.transfer_data_to_window)
353
+ assert_equal('0', text.value)
354
+
355
+ data = 17
356
+ assert_true(text.transfer_data_to_window)
357
+ assert_equal('17', text.value)
358
+
359
+ text.change_value("foobar")
360
+ assert_false(text.transfer_data_from_window)
361
+
362
+ text.change_value('-234')
363
+ assert_true(text.transfer_data_from_window)
364
+ assert_equal(-234, data)
365
+
366
+ text.change_value('9223372036854775808') # == LLONG_MAX + 1
367
+ assert_false(text.transfer_data_from_window)
368
+
369
+ text.clear
370
+ assert_false(text.transfer_data_from_window)
371
+ end
372
+
373
+ def test_transfer_range
374
+ data = 0
375
+ valInt = Wx::IntegerValidator.new(-20, 20, Wx::NumValidatorStyle::NUM_VAL_ZERO_AS_BLANK)
376
+ valInt.on_transfer_to_window { data }
377
+ valInt.on_transfer_from_window { |v| data = v }
378
+ text.validator = valInt
379
+
380
+ assert_true(text.transfer_data_to_window)
381
+ assert_equal('', text.value) # Wx::NumValidatorStyle::NUM_VAL_ZERO_AS_BLANK
382
+
383
+ data = 17
384
+ assert_true(text.transfer_data_to_window)
385
+ assert_equal('17', text.value)
386
+
387
+ text.change_value('-234')
388
+ assert_false(text.transfer_data_from_window)
389
+
390
+ text.change_value('-20')
391
+ assert_true(text.transfer_data_from_window)
392
+ assert_equal(-20, data)
393
+
394
+ text.change_value('21') # == max + 1
395
+ assert_false(text.transfer_data_from_window)
396
+
397
+ text.clear
398
+ assert_true(text.transfer_data_from_window)
399
+ assert_equal(0, data) # Wx::NumValidatorStyle::NUM_VAL_ZERO_AS_BLANK
400
+ end
401
+
402
+ end
403
+
404
+ class UnsignedValidatorTests < WxRuby::Test::GUITests
405
+
406
+ def setup
407
+ super
408
+ @text = Wx::TextCtrl.new(frame_win, name: 'Text')
409
+ end
410
+
411
+ def cleanup
412
+ @text.destroy if @text
413
+ @text = nil
414
+ super
415
+ end
416
+
417
+ def teardown
418
+ @text.destroy if @text
419
+ @text = nil
420
+ super
421
+ end
422
+
423
+ attr_accessor :text
424
+
425
+ def test_no_custom_transfer
426
+ valInt = Wx::UnsignedValidator.new
427
+ text.validator = valInt
428
+
429
+ assert_equal(0, text.validator.value)
430
+ assert_true(text.transfer_data_to_window)
431
+ assert_equal('0', text.value)
432
+
433
+ text.validator.value = 17
434
+ assert_true(text.transfer_data_to_window)
435
+ assert_equal('17', text.value)
436
+
437
+ text.change_value('-1')
438
+ assert_false(text.transfer_data_from_window)
439
+ assert_equal(17, text.validator.value)
440
+
441
+ text.change_value('234')
442
+ assert_true(text.transfer_data_from_window)
443
+ assert_equal(234, text.validator.value)
444
+
445
+ text.change_value((2*64).to_s) # == ULLONG_MAX
446
+ assert_true(text.transfer_data_from_window)
447
+ assert_equal(2*64, text.validator.value)
448
+
449
+ text.clear
450
+ assert_false(text.transfer_data_from_window)
451
+ end
452
+
453
+ def test_transfer
454
+ data = 0
455
+ valInt = Wx::UnsignedValidator.new
456
+ valInt.on_transfer_to_window { data }
457
+ valInt.on_transfer_from_window { |v| data = v }
458
+ text.validator = valInt
459
+
460
+ assert_true(text.transfer_data_to_window)
461
+ assert_equal('0', text.value)
462
+
463
+ data = 17
464
+ assert_true(text.transfer_data_to_window)
465
+ assert_equal('17', text.value)
466
+
467
+ text.change_value('-1')
468
+ assert_false(text.transfer_data_from_window)
469
+
470
+ text.change_value('234')
471
+ assert_true(text.transfer_data_from_window)
472
+ assert_equal(234, data)
473
+
474
+ text.change_value((2*64).to_s) # == ULLONG_MAX
475
+ assert_true(text.transfer_data_from_window)
476
+
477
+ text.clear
478
+ assert_false(text.transfer_data_from_window)
479
+ end
480
+
481
+ def test_transfer_range
482
+ data = 1
483
+ valInt = Wx::UnsignedValidator.new(1, 20)
484
+ valInt.on_transfer_to_window { data }
485
+ valInt.on_transfer_from_window { |v| data = v }
486
+ text.validator = valInt
487
+
488
+ assert_true(text.transfer_data_to_window)
489
+ assert_equal('1', text.value)
490
+
491
+ data = 17
492
+ assert_true(text.transfer_data_to_window)
493
+ assert_equal('17', text.value)
494
+
495
+ text.change_value('0')
496
+ assert_false(text.transfer_data_from_window)
497
+
498
+ text.change_value('234')
499
+ assert_false(text.transfer_data_from_window)
500
+
501
+ text.change_value('20')
502
+ assert_true(text.transfer_data_from_window)
503
+ assert_equal(20, data)
504
+
505
+ text.change_value('1')
506
+ assert_true(text.transfer_data_from_window)
507
+ assert_equal(1, data)
508
+
509
+ text.clear
510
+ assert_false(text.transfer_data_from_window)
511
+ end
512
+
513
+ end
514
+
515
+ class FloatValidatorTests < WxRuby::Test::GUITests
516
+
517
+ def setup
518
+ super
519
+ @text = Wx::TextCtrl.new(frame_win, name: 'Text')
520
+ end
521
+
522
+ def cleanup
523
+ @text.destroy if @text
524
+ @text = nil
525
+ super
526
+ end
527
+
528
+ def teardown
529
+ @text.destroy if @text
530
+ @text = nil
531
+ super
532
+ end
533
+
534
+ attr_accessor :text
535
+
536
+ def test_no_custom_transfer
537
+ valFlt = Wx::FloatValidator.new(3, Wx::NumValidatorStyle::NUM_VAL_DEFAULT)
538
+ text.validator = valFlt
539
+
540
+ assert_equal(0.0, text.validator.value)
541
+ assert_true(text.transfer_data_to_window)
542
+ assert_match(/\A0(\.|,)000\Z/, text.value)
543
+
544
+ text.validator.style = Wx::NumValidatorStyle::NUM_VAL_NO_TRAILING_ZEROES
545
+
546
+ assert_true(text.transfer_data_to_window)
547
+ assert_equal('0', text.value)
548
+
549
+ text.validator.value = 17.123
550
+ assert_true(text.transfer_data_to_window)
551
+ assert_match(/\A17(\.|,)123\Z/, text.value)
552
+
553
+ text.validator.value = 17.1236
554
+ assert_true(text.transfer_data_to_window)
555
+ assert_match(/\A17(\.|,)124\Z/, text.value)
556
+
557
+ text.change_value("foobar")
558
+ assert_false(text.transfer_data_from_window)
559
+ assert_equal(17.1236, text.validator.value)
560
+
561
+ text.change_value('-234')
562
+ assert_true(text.transfer_data_from_window)
563
+ assert_equal(-234, text.validator.value)
564
+
565
+ text.clear
566
+ assert_false(text.transfer_data_from_window)
567
+ end
568
+
569
+ def test_transfer
570
+ data = 0.0
571
+ valFlt = Wx::FloatValidator.new(3, Wx::NumValidatorStyle::NUM_VAL_DEFAULT)
572
+ valFlt.on_transfer_to_window { data }
573
+ valFlt.on_transfer_from_window { |v| data = v }
574
+ text.validator = valFlt
575
+
576
+ assert_true(text.transfer_data_to_window)
577
+ assert_match(/\A0(\.|,)000\Z/, text.value)
578
+
579
+ text.validator.style = Wx::NumValidatorStyle::NUM_VAL_NO_TRAILING_ZEROES
580
+
581
+ assert_true(text.transfer_data_to_window)
582
+ assert_equal('0', text.value)
583
+
584
+ data = 17.123
585
+ assert_true(text.transfer_data_to_window)
586
+ assert_match(/\A17(\.|,)123\Z/, text.value)
587
+
588
+ data = 17.1236
589
+ assert_true(text.transfer_data_to_window)
590
+ assert_match(/\A17(\.|,)124\Z/, text.value)
591
+
592
+ text.change_value("foobar")
593
+ assert_false(text.transfer_data_from_window)
594
+
595
+ text.change_value('-234')
596
+ assert_true(text.transfer_data_from_window)
597
+ assert_equal(-234, data)
598
+
599
+ text.clear
600
+ assert_false(text.transfer_data_from_window)
601
+ end
602
+
603
+ def test_transfer_range
604
+ data = 0
605
+ valFlt = Wx::FloatValidator.new(3, Wx::NumValidatorStyle::NUM_VAL_NO_TRAILING_ZEROES)
606
+ valFlt.set_range(-0.500, 0.500)
607
+ valFlt.on_transfer_to_window { data }
608
+ valFlt.on_transfer_from_window { |v| data = v }
609
+ text.validator = valFlt
610
+
611
+ assert_true(text.transfer_data_to_window)
612
+ assert_equal('0', text.value)
613
+
614
+ data = 0.123
615
+ assert_true(text.transfer_data_to_window)
616
+ assert_match(/\A0(\.|,)123\Z/, text.value)
617
+
618
+ text.change_value('-0.734')
619
+ assert_false(text.transfer_data_from_window)
620
+
621
+ text.change_value('-0.234')
622
+ assert_true(text.transfer_data_from_window)
623
+ assert_equal(-0.234, data)
624
+
625
+ text.change_value('0.501') # == max + 0.001
626
+ assert_false(text.transfer_data_from_window)
627
+
628
+ text.clear
629
+ assert_false(text.transfer_data_from_window)
630
+ end
631
+
632
+ end
633
+
634
+ class GenericValidatorTests < WxRuby::Test::GUITests
635
+
636
+ def setup
637
+ super
638
+ @control = nil
639
+ end
640
+
641
+ def cleanup
642
+ @control.destroy if @control
643
+ @control = nil
644
+ super
645
+ end
646
+
647
+ def teardown
648
+ @control.destroy if @control
649
+ @control = nil
650
+ super
651
+ end
652
+
653
+ attr_accessor :control
654
+
655
+ def test_text_ctrl
656
+ self.control = Wx::TextCtrl.new(frame_win, name: 'Text', validator: Wx::GenericValidator.new)
657
+
658
+ assert_equal('', control.value)
659
+ assert_nil(control.validator.value)
660
+
661
+ control.validator.value = 'Hello'
662
+ assert_true(control.transfer_data_to_window)
663
+ assert_equal('Hello', control.value)
664
+
665
+ control.change_value('Bye')
666
+ assert_true(control.transfer_data_from_window)
667
+ assert_equal('Bye', control.validator.value)
668
+ end
669
+
670
+ def test_boolean_ctrl
671
+ self.control = Wx::CheckBox.new(frame_win, name: 'Check', validator: Wx::GenericValidator.new)
672
+
673
+ assert_false(control.checked?)
674
+ assert_nil(control.validator.value)
675
+
676
+ control.validator.value = true
677
+ assert_true(control.transfer_data_to_window)
678
+ assert_true(control.checked?)
679
+
680
+ control.set_value(false)
681
+ assert_true(control.transfer_data_from_window)
682
+ assert_false(control.validator.value)
683
+ end
684
+
685
+ def test_integer_ctrl
686
+ self.control = Wx::Gauge.new(frame_win, range: 100, name: 'Gauge', validator: Wx::GenericValidator.new)
687
+
688
+ assert_equal(0, control.value)
689
+ assert_nil(control.validator.value)
690
+
691
+ control.validator.value = 10
692
+ assert_true(control.transfer_data_to_window)
693
+ assert_equal(10, control.value)
694
+
695
+ control.set_value(75)
696
+ assert_true(control.transfer_data_from_window)
697
+ assert_equal(75, control.validator.value)
698
+ end
699
+
700
+ def test_integer_ctrl_binding
701
+ integer_store = 0
702
+ self.control = Wx::Gauge.new(frame_win, range: 100, name: 'Gauge', validator: Wx::GenericValidator.new)
703
+ control.validator.on_transfer_to_window { integer_store }
704
+ control.validator.on_transfer_from_window { |data| integer_store = data }
705
+
706
+ assert_equal(0, control.value)
707
+ assert_nil(control.validator.value)
708
+
709
+ integer_store = 10
710
+ assert_true(control.transfer_data_to_window)
711
+ assert_equal(10, control.value)
712
+ assert_equal(10, control.validator.value)
713
+
714
+ control.set_value(75)
715
+ assert_true(control.transfer_data_from_window)
716
+ assert_equal(75, control.validator.value)
717
+ assert_equal(75, integer_store)
718
+ end
719
+
720
+ def test_single_list_ctrl
721
+ self.control = Wx::ListBox.new(frame_win, choices: %w[First Second Third Fourth Fifth], name: 'List', validator: Wx::GenericValidator.new)
722
+
723
+ assert_equal(0, control.selections.size)
724
+ assert_nil(control.validator.value)
725
+
726
+ control.validator.value = 1
727
+ assert_true(control.transfer_data_to_window)
728
+ assert_equal(1, control.selection)
729
+
730
+ control.deselect(1)
731
+ control.set_selection(3)
732
+ assert_true(control.transfer_data_from_window)
733
+ assert_equal(3, control.validator.value)
734
+ end
735
+
736
+ def test_array_ctrl
737
+ self.control = Wx::ListBox.new(frame_win, choices: %w[First Second Third Fourth Fifth], style: Wx::LB_MULTIPLE, name: 'List', validator: Wx::GenericValidator.new)
738
+
739
+ assert_equal(0, control.selections.size)
740
+ assert_nil(control.validator.value)
741
+
742
+ control.validator.value = [1, 3]
743
+ assert_true(control.transfer_data_to_window)
744
+ assert_equal([1,3], control.selections)
745
+
746
+ control.count.times { |i| control.deselect(i) }
747
+ [0, 2, 4].each { |i| control.set_selection(i) }
748
+ assert_true(control.transfer_data_from_window)
749
+ assert_equal([0, 2, 4], control.validator.value)
750
+ end
751
+
752
+ class Model
753
+
754
+ def initialize
755
+ @value = nil
756
+ end
757
+
758
+ attr_accessor :value
759
+
760
+ def load
761
+ @value
762
+ end
763
+
764
+ def store(v)
765
+ @value = v
766
+ end
767
+
768
+ end
769
+
770
+ class GenericModelValidator < Wx::GenericValidator
771
+
772
+ def initialize(arg)
773
+ if arg.is_a?(self.class)
774
+ super
775
+ @model = arg.model
776
+ else
777
+ super()
778
+ @model = arg
779
+ on_transfer_to_window { @model.load }
780
+ on_transfer_from_window { |data| @model.store(data) }
781
+ end
782
+ end
783
+
784
+ attr_reader :model
785
+
786
+ end
787
+
788
+ def test_custom_array_ctrl_validate
789
+ model = Model.new
790
+ self.control = Wx::ListBox.new(frame_win, choices: %w[First Second Third Fourth Fifth], style: Wx::LB_MULTIPLE, name: 'List', validator: GenericModelValidator.new(model))
791
+
792
+ assert_equal(0, control.selections.size)
793
+ assert_nil(model.value)
794
+
795
+ model.value = [1, 3]
796
+ assert_true(control.transfer_data_to_window)
797
+ assert_equal([1,3], control.selections)
798
+
799
+ control.count.times { |i| control.deselect(i) }
800
+ [0, 2, 4].each { |i| control.set_selection(i) }
801
+ assert_true(control.transfer_data_from_window)
802
+ assert_equal([0, 2, 4], model.value)
803
+ end
804
+
805
+ end