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
@@ -14,6 +14,8 @@ module WXRuby3
14
14
 
15
15
  class ControlWithItems < Window
16
16
 
17
+ include Typemap::ClientData
18
+
17
19
  def setup
18
20
  super
19
21
  if spec.module_name == 'wxControlWithItems'
@@ -26,48 +28,113 @@ module WXRuby3
26
28
  wxEvtHandler
27
29
  wxObject])
28
30
  spec.ignore([
29
- 'wxItemContainer::Append(const wxString &, wxClientData *)',
31
+ 'wxItemContainer::Append(const wxString &, void *)',
30
32
  'wxItemContainer::Append(const std::vector< wxString > &)',
31
- 'wxItemContainer::Append(const wxArrayString &, wxClientData **)',
33
+ 'wxItemContainer::Append(const wxArrayString &, void **)',
32
34
  'wxItemContainer::Append(unsigned int, const wxString *)',
33
35
  'wxItemContainer::Append(unsigned int, const wxString *, void **)',
34
36
  'wxItemContainer::Append(unsigned int, const wxString *, wxClientData **)',
35
- 'wxItemContainer::Insert(const wxString &, unsigned int, wxClientData *)',
37
+ 'wxItemContainer::Insert(const wxString &, unsigned int, void *)',
36
38
  'wxItemContainer::Insert(const std::vector< wxString > &)',
37
- 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)',
39
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)',
38
40
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int)',
39
41
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, void **)',
40
42
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, wxClientData **)',
41
43
  'wxItemContainer::Set(const std::vector< wxString > &)',
42
- 'wxItemContainer::Set(const wxArrayString &, wxClientData **)',
44
+ 'wxItemContainer::Set(const wxArrayString &, void **)',
43
45
  'wxItemContainer::Set(unsigned int, const wxString *)',
44
46
  'wxItemContainer::Set(unsigned int, const wxString *, void **)',
45
47
  'wxItemContainer::Set(unsigned int, const wxString *, wxClientData **)',
46
- 'wxItemContainer::DetachClientObject',
47
- 'wxItemContainer::HasClientObjectData',
48
- 'wxItemContainer::GetClientObject',
49
- 'wxItemContainer::SetClientObject'])
48
+ 'wxItemContainer::HasClientUntypedData',
49
+ 'wxItemContainer::GetClientData',
50
+ 'wxItemContainer::SetClientData'])
51
+ # ignore these but keep docs; will add custom versions below
50
52
  spec.ignore([
51
- 'wxItemContainer::Append(const wxArrayString &, void **)',
52
- 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)',
53
- 'wxItemContainer::Set(const wxArrayString &, void **)'], ignore_doc: false)
53
+ 'wxItemContainer::DetachClientObject',
54
+ 'wxItemContainer::Append(const wxArrayString &, wxClientData **)',
55
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)',
56
+ 'wxItemContainer::Set(const wxArrayString &, wxClientData **)'], ignore_doc: false)
54
57
  if Config.instance.wx_version < '3.3.0'
55
58
  # add undocumented method
56
59
  spec.extend_interface 'wxControlWithItems',
57
60
  'bool IsSorted() const'
58
61
  end
59
62
  # for doc only
60
- spec.map 'void** clientData' => 'Array', swig: false do
63
+ spec.map 'wxClientData** clientData' => 'Array', swig: false do
61
64
  map_in code: ''
62
65
  end
63
- spec.ignore(%w[wxItemContainer::GetClientData wxItemContainer::SetClientData], ignore_doc: false) # keep docs
64
- # Replace the old Wx definition of this method (which segfaults)
65
- # Only need the setter as we cache data in Ruby and the getter
66
- # therefor can be pure Ruby
66
+ # Replace the old Wx definitions of these methods adding
67
+ # proper checks on the data arrays.
68
+ # Also add an item enumerator.
67
69
  spec.add_extend_code 'wxControlWithItems', <<~__HEREDOC
68
- VALUE set_client_data(int n, VALUE item_data) {
69
- self->SetClientData(n, (void *)item_data);
70
- return item_data;
70
+ VALUE DetachClientObject(unsigned int n)
71
+ {
72
+ VALUE rc = Qnil;
73
+ wxClientData *wxcd = $self->DetachClientObject(n);
74
+ wxRubyClientData *rbcd = wxcd ? dynamic_cast<wxRubyClientData*> (wxcd) : nullptr;
75
+ if (rbcd)
76
+ {
77
+ rc = rbcd->GetData();
78
+ delete rbcd;
79
+ }
80
+ return rc;
81
+ }
82
+
83
+ int Append(const wxArrayString &items, VALUE rb_clientData)
84
+ {
85
+ if (TYPE(rb_clientData) != T_ARRAY ||
86
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
87
+ {
88
+ rb_raise(rb_eArgError,
89
+ TYPE(rb_clientData) == T_ARRAY ?
90
+ "expected Array for client_data" :
91
+ "client_data Array needs to be equal in size to items Array");
92
+ }
93
+
94
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
95
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
96
+ {
97
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
98
+ }
99
+ return $self->Append(items, cd_arr.get());
100
+ }
101
+
102
+ int Insert(const wxArrayString &items, unsigned int pos, VALUE rb_clientData)
103
+ {
104
+ if (TYPE(rb_clientData) != T_ARRAY ||
105
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
106
+ {
107
+ rb_raise(rb_eArgError,
108
+ TYPE(rb_clientData) == T_ARRAY ?
109
+ "expected Array for client_data" :
110
+ "client_data Array needs to be equal in size to items Array");
111
+ }
112
+
113
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
114
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
115
+ {
116
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
117
+ }
118
+ return $self->Insert(items, pos, cd_arr.get());
119
+ }
120
+
121
+ void Set(const wxArrayString &items, VALUE rb_clientData)
122
+ {
123
+ if (TYPE(rb_clientData) != T_ARRAY ||
124
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
125
+ {
126
+ rb_raise(rb_eArgError,
127
+ TYPE(rb_clientData) == T_ARRAY ?
128
+ "expected Array for client_data" :
129
+ "client_data Array needs to be equal in size to items Array");
130
+ }
131
+
132
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
133
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
134
+ {
135
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
136
+ }
137
+ $self->Set(items, cd_arr.get());
71
138
  }
72
139
 
73
140
  VALUE each_string()
@@ -81,7 +148,7 @@ module WXRuby3
81
148
  return rc;
82
149
  }
83
150
  __HEREDOC
84
- end
151
+ end
85
152
  end
86
153
 
87
154
  def setup_ctrl_with_items(clsnm)
@@ -25,13 +25,15 @@ module WXRuby3
25
25
  VALUE get_range()
26
26
  {
27
27
  wxDateTime dt1, dt2;
28
- $self->GetRange(&dt1, &dt2);
29
-
30
- VALUE items = rb_ary_new();
31
- rb_ary_push(items, wxRuby_wxDateTimeToRuby(dt1));
32
- rb_ary_push(items, wxRuby_wxDateTimeToRuby(dt2));
28
+ if ($self->GetRange(&dt1, &dt2))
29
+ {
30
+ VALUE items = rb_ary_new();
31
+ rb_ary_push(items, wxRuby_wxDateTimeToRuby(dt1));
32
+ rb_ary_push(items, wxRuby_wxDateTimeToRuby(dt2));
33
33
 
34
- return items;
34
+ return items;
35
+ }
36
+ return Qnil;
35
37
  }
36
38
  __HEREDOC
37
39
  end
@@ -16,6 +16,36 @@ module WXRuby3
16
16
 
17
17
  def setup
18
18
  super
19
+ # methods missing from docs
20
+ spec.extend_interface 'wxEditableListBox',
21
+ 'wxListCtrl* GetListCtrl()',
22
+ 'wxBitmapButton* GetDelButton()',
23
+ 'wxBitmapButton* GetNewButton()',
24
+ 'wxBitmapButton* GetUpButton()',
25
+ 'wxBitmapButton* GetDownButton()',
26
+ 'wxBitmapButton* GetEditButton()'
27
+ # redefine this
28
+ spec.ignore 'wxEditableListBox::GetStrings', ignore_doc: false
29
+ spec.add_extend_code 'wxEditableListBox', <<~__HEREDOC
30
+ VALUE GetStrings()
31
+ {
32
+ VALUE rb_list = rb_ary_new();
33
+ wxArrayString list;
34
+ $self->GetStrings(list);
35
+ for (unsigned int i=0; i<list.GetCount() ;++i)
36
+ {
37
+ rb_ary_push(rb_list, WXSTR_TO_RSTR(list.Item(i)));
38
+ }
39
+ return rb_list;
40
+ }
41
+ __HEREDOC
42
+ # map for doc gen
43
+ spec.map 'wxArrayString& strings' => 'Array<String>', swig: false do
44
+ map_in ignore: true, code: ''
45
+ map_argout code: ''
46
+ end
47
+ # make sure GetStrings uses the right typemap
48
+ spec.map_apply 'wxArrayString&' => 'const wxArrayString& strings'
19
49
  end
20
50
  end # class EditableListBox
21
51
 
@@ -138,36 +138,46 @@ module WXRuby3
138
138
  return INT2NUM(event_type_id);
139
139
  }
140
140
  __HEREDOC
141
+ spec.map 'wxObject*' => 'Wx::Object' do
142
+ map_out code: '$result = wxRuby_WrapWxObjectInRuby($1);'
143
+ end
141
144
  # make Ruby director and wrappers use custom implementation
142
145
  spec.use_class_implementation('wxCommandEvent', 'wxRubyCommandEvent')
143
146
  spec.ignore %w{
144
- wxCommandEvent::GetClientObject
145
- wxCommandEvent::SetClientObject
147
+ wxCommandEvent::GetClientData
148
+ wxCommandEvent::SetClientData
146
149
  wxCommandEvent::GetExtraLong
147
150
  }
151
+ # ignore but keep doc; will replace with custom versions
152
+ spec.ignore %w[wxCommandEvent::GetClientObject wxCommandEvent::SetClientObject], ignore_doc: false
153
+ # for doc gen only
154
+ spec.map 'wxClientData*' => 'Object', swig: false do
155
+ map_in code: ''
156
+ map_out code: ''
157
+ end
148
158
  # need this to force alloc func
149
159
  spec.make_concrete 'wxCommandEvent'
150
160
  spec.add_header_code <<~__HEREDOC
151
161
  // Cf wxEvent - has to be written as a C+++ subclass to ensure correct
152
162
  // GC/thread protection of Ruby instance variables when user-written
153
163
  // event classes are queued.
154
- //
155
- //
156
- // FIXME : intermittent errors with CommandEvent losing the tracked
157
- // object before handling - though the same code works fine with Wx::Event
158
164
  class WXRUBY_EXPORT wxRubyCommandEvent : public wxCommandEvent
159
165
  {
160
166
  public:
161
167
  wxRubyCommandEvent(wxEventType commandType = wxEVT_NULL,
162
- int id = 0) :
163
- wxCommandEvent(commandType, id) { }
164
- wxRubyCommandEvent(const wxRubyCommandEvent& cev) :
165
- wxCommandEvent(cev) { }
168
+ int id = 0)
169
+ : wxCommandEvent(commandType, id)
170
+ { }
171
+ wxRubyCommandEvent(const wxRubyCommandEvent& cev)
172
+ : wxCommandEvent(cev)
173
+ , has_ruby_data_(cev.has_ruby_data_)
174
+ { }
166
175
 
167
176
  // When the C++ side event is destroyed, unlink from the Ruby object
168
177
  // and remove that object from the tracking hash so it can be
169
178
  // collected by GC.
170
- virtual ~wxRubyCommandEvent() {
179
+ virtual ~wxRubyCommandEvent()
180
+ {
171
181
  SWIG_RubyUnlinkObjects((void*)this);
172
182
  wxRuby_RemoveTracking((void*)this);
173
183
  }
@@ -176,7 +186,8 @@ module WXRuby3
176
186
  // (often when using Threads), because a clone is queued. So copy the
177
187
  // Wx C++ event, create a shallow (dup) of the Ruby event object, and
178
188
  // add to the tracking hash so that it is GC-protected
179
- virtual wxCommandEvent* Clone() const {
189
+ virtual wxCommandEvent* Clone() const
190
+ {
180
191
  wxRubyCommandEvent* wx_ev = new wxRubyCommandEvent(*this);
181
192
 
182
193
  VALUE r_obj = SWIG_RubyInstanceFor((void *)this);
@@ -186,7 +197,86 @@ module WXRuby3
186
197
  wxRuby_AddTracking( (void*)wx_ev, r_obj_dup );
187
198
  return wx_ev;
188
199
  }
200
+
201
+ bool has_ruby_data_ {};
189
202
  };
203
+
204
+
205
+ // wxRuby must preserve ruby objects attached as the ClientData of
206
+ // command events that have been user-defined in ruby. Some of the
207
+ // standard wxWidgets CommandEvent classes also use ClientData
208
+ // for their own purposes, and this must not be marked as the data is
209
+ // not a ruby object, and will thus crash.
210
+ WXRUBY_EXPORT void GC_mark_wxEvent(void *ptr)
211
+ {
212
+ #ifdef __WXRB_DEBUG__
213
+ if (wxRuby_TraceLevel()>1)
214
+ std::wcout << "> GC_mark_wxEvent : " << ptr << std::endl;
215
+ #endif
216
+
217
+ if ( ! ptr ) return;
218
+ wxEvent* wx_event = (wxEvent*)ptr;
219
+ #ifdef __WXRB_DEBUG__
220
+ if (wxRuby_TraceLevel()>2)
221
+ std::wcout << "* GC_mark_wxEvent(" << ptr << ":{" << wx_event->GetEventType() << "})" << std::endl;
222
+ #endif
223
+ if (wx_event->IsCommandEvent())
224
+ {
225
+ wxCommandEvent* wx_cm_event = (wxCommandEvent*)ptr;
226
+ if (wx_cm_event->GetClientObject() == nullptr && wx_cm_event->GetClientData() != nullptr)
227
+ {
228
+ wxRubyCommandEvent* rbcev = dynamic_cast<wxRubyCommandEvent*> (wx_cm_event);
229
+ if (rbcev && rbcev->has_ruby_data_)
230
+ {
231
+ VALUE rb_client_data = (VALUE)wx_cm_event->GetClientData();
232
+ rb_gc_mark(rb_client_data);
233
+ }
234
+ }
235
+ }
236
+
237
+ #ifdef __WXRB_DEBUG__
238
+ if (wxRuby_TraceLevel()>1)
239
+ std::wcout << "< GC_mark_wxEvent : " << ptr << std::endl;
240
+ #endif
241
+ }
242
+ __HEREDOC
243
+ # CommandEvent requires custom handling of client data.
244
+ # As command events do not 'own' their wxClientData objects we cannot use the regular support
245
+ # for setting client data from Ruby as that would cause memory leaks by creating wxRubyClientData
246
+ # instances that would never get deleted.
247
+ # On the other hand wxWidgets library code might still set wxClientData instances propagated from
248
+ # control or item client data which needs to be used for returning client data with GetClientObject.
249
+ # As wxRuby client data always is any arbitrary Ruby Object anyway we simply combine the two approaches wxWidgets
250
+ # offers here under 1 set of methods.
251
+ spec.include 'wxruby-ClientData.h'
252
+ spec.add_extend_code 'wxCommandEvent', <<~__HEREDOC
253
+ VALUE GetClientObject()
254
+ {
255
+ VALUE rc = Qnil;
256
+ // return Ruby client data depending on what's available
257
+ if ($self->GetClientObject())
258
+ {
259
+ wxRubyClientData* rbcd = dynamic_cast<wxRubyClientData*> ($self->GetClientObject());
260
+ if (rbcd) rc = rbcd->GetData();
261
+ }
262
+ else if ($self->GetClientData() != nullptr)
263
+ {
264
+ wxRubyCommandEvent* rbcev = dynamic_cast<wxRubyCommandEvent*> ($self);
265
+ if (rbcev && rbcev->has_ruby_data_) rc = (VALUE)$self->GetClientData();
266
+ }
267
+ return rc;
268
+ }
269
+
270
+ void SetClientObject(VALUE cd)
271
+ {
272
+ wxRubyCommandEvent* rbcev = dynamic_cast<wxRubyCommandEvent*> ($self);
273
+ if (rbcev)
274
+ {
275
+ // use SetClientData as not to create memory leaks; GC marker for events will keep it alive
276
+ $self->SetClientData(NIL_P(cd) ? nullptr : (void*)cd);
277
+ rbcev->has_ruby_data_ = !NIL_P(cd);
278
+ }
279
+ }
190
280
  __HEREDOC
191
281
  spec.add_wrapper_code <<~__HEREDOC
192
282
  extern VALUE wxRuby_GetDefaultEventClass()
@@ -12,6 +12,8 @@ module WXRuby3
12
12
 
13
13
  class EvtHandler < Director
14
14
 
15
+ include Typemap::ClientData
16
+
15
17
  def setup
16
18
  super
17
19
  # update generated code for all event handlers
@@ -22,8 +24,7 @@ module WXRuby3
22
24
  'wxEvtHandler::Connect',
23
25
  'wxEvtHandler::Disconnect')
24
26
  spec.ignore(%w[wxEVT_HOTKEY])
25
- spec.ignore(%w[wxEvtHandler::SetClientData wxEvtHandler::GetClientData
26
- wxEvtHandler::SetClientObject wxEvtHandler::GetClientObject])
27
+ spec.ignore(%w[wxEvtHandler::SetClientData wxEvtHandler::GetClientData])
27
28
  # Do not see much point in allowing/supporting this to be overridden when we
28
29
  # have TryBefore and TryAfter to handle this much cleaner
29
30
  spec.no_proxy 'wxEvtHandler::ProcessEvent'
@@ -42,7 +42,7 @@ module WXRuby3
42
42
 
43
43
  // As the wxw logger will only make synchronous use of the filename, func and component pointers while
44
44
  // processing the log entry and never store them we simply gather pointers but no copies
45
- static void do_log(wxLogLevel lvl, int argc, VALUE *argv, ...)
45
+ static void do_log(wxLogLevel lvl, int argc, VALUE *argv)
46
46
  {
47
47
  const char* filename = nullptr;
48
48
  int line = 0;
@@ -66,7 +66,9 @@ module WXRuby3
66
66
  wxLog::IsLevelEnabled(lvl, wxASCII_STR(component)) )
67
67
  {
68
68
  VALUE log_msg = argc==1 ? argv[0] : rb_f_sprintf(argc, argv);
69
- wxLogger(lvl, filename, line, func, component).Log(RSTR_TO_WXSTR(log_msg));
69
+ wxLogRecordInfo info(filename, line, func, component);
70
+ info.timestampMS = wxGetUTCTimeMillis().GetValue();
71
+ wxLog::OnLog(lvl, RSTR_TO_WXSTR(log_msg), info);
70
72
  }
71
73
  }
72
74
 
@@ -20,6 +20,23 @@ module WXRuby3
20
20
  spec.do_not_generate(:variables, :defines, :enums, :functions) # already with DirFilterListCtrl
21
21
  end
22
22
 
23
+ def process(gendoc: false)
24
+ defmod = super
25
+ # fix documentation errors for generic dirctrl events
26
+ def_item = defmod.find_item('wxGenericDirCtrl')
27
+ if def_item
28
+ def_item.event_types.each do |evt_spec|
29
+ case evt_spec.first
30
+ when 'EVT_DIRCTRL_SELECTIONCHANGED', 'EVT_DIRCTRL_FILEACTIVATED'
31
+ if evt_spec[3].nil?
32
+ evt_spec[3] = 'wxTreeEvent' # missing from docs
33
+ end
34
+ end
35
+ end
36
+ end
37
+ defmod
38
+ end
39
+
23
40
  end # class GenericDirCtrl
24
41
 
25
42
  end # class Director
@@ -12,8 +12,6 @@ module WXRuby3
12
12
 
13
13
  class GridCellAttr < Director
14
14
 
15
- include Typemap::GridClientData
16
-
17
15
  def setup
18
16
  super
19
17
  # exposing the mixin wxClientDataContainer/wxSharedClientDataContainer has no real upside
@@ -12,8 +12,6 @@ module WXRuby3
12
12
 
13
13
  class GridCellEditor < Director
14
14
 
15
- include Typemap::GridClientData
16
-
17
15
  def setup
18
16
  super
19
17
  spec.gc_as_untracked
@@ -12,8 +12,6 @@ module WXRuby3
12
12
 
13
13
  class GridCellRenderer < Director
14
14
 
15
- include Typemap::GridClientData
16
-
17
15
  def setup
18
16
  super
19
17
  spec.gc_as_untracked
@@ -28,7 +28,12 @@ module WXRuby3
28
28
  visibility: 'protected'
29
29
  # handled; can be suppressed
30
30
  spec.suppress_warning(473, 'wxHeaderCtrl::GetColumn', 'wxHeaderCtrlSimple::GetColumn')
31
- spec.do_not_generate :typedefs, :variables, :enums, :defines, :functions
31
+ # ignore here as already available through HeaderCtrlEvent
32
+ spec.ignore '@.wxHD_ALLOW_REORDER',
33
+ '@.wxHD_ALLOW_HIDE',
34
+ '@.wxHD_BITMAP_ON_RIGHT',
35
+ '@.wxHD_DEFAULT_STYLE'
36
+ spec.do_not_generate :typedefs, :variables, :defines, :functions
32
37
  end
33
38
  end # class HeaderCtrl
34
39
 
@@ -14,6 +14,8 @@ module WXRuby3
14
14
 
15
15
  class HtmlListBox < Window
16
16
 
17
+ include Typemap::ClientData
18
+
17
19
  def setup
18
20
  spec.items << 'wxSimpleHtmlListBox' << 'wxItemContainer'
19
21
  super
@@ -72,47 +74,119 @@ module WXRuby3
72
74
  spec.extend_interface 'wxSimpleHtmlListBox',
73
75
  'virtual wxString GetString(unsigned int n) const',
74
76
  'virtual void SetString(unsigned int n, const wxString &string)'
75
- spec.ignore([ 'wxItemContainer::Append(const wxString &, wxClientData *)',
77
+ spec.ignore([ 'wxItemContainer::Append(const wxString &, void *)',
76
78
  'wxItemContainer::Append(const std::vector< wxString > &)',
77
- 'wxItemContainer::Append(const wxArrayString &, wxClientData **)',
79
+ 'wxItemContainer::Append(const wxArrayString &, void **)',
78
80
  'wxItemContainer::Append(unsigned int, const wxString *)',
79
81
  'wxItemContainer::Append(unsigned int, const wxString *, void **)',
80
82
  'wxItemContainer::Append(unsigned int, const wxString *, wxClientData **)',
81
- 'wxItemContainer::Insert(const wxString &, unsigned int, wxClientData *)',
83
+ 'wxItemContainer::Insert(const wxString &, unsigned int, void *)',
82
84
  'wxItemContainer::Insert(const std::vector< wxString > &)',
83
- 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)',
85
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)',
84
86
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int)',
85
87
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, void **)',
86
88
  'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, wxClientData **)',
87
89
  'wxItemContainer::Set(const std::vector< wxString > &)',
88
- 'wxItemContainer::Set(const wxArrayString &, wxClientData **)',
90
+ 'wxItemContainer::Set(const wxArrayString &, void **)',
89
91
  'wxItemContainer::Set(unsigned int, const wxString *)',
90
92
  'wxItemContainer::Set(unsigned int, const wxString *, void **)',
91
93
  'wxItemContainer::Set(unsigned int, const wxString *, wxClientData **)',
92
- 'wxItemContainer::DetachClientObject',
93
- 'wxItemContainer::HasClientObjectData',
94
- 'wxItemContainer::GetClientObject',
95
- 'wxItemContainer::SetClientObject',
94
+ 'wxItemContainer::GetClientData',
95
+ 'wxItemContainer::SetClientData',
96
96
  'wxItemContainer::HasClientUntypedData',
97
97
  'wxItemContainer::Clear'])
98
- spec.ignore([ 'wxItemContainer::Append(const wxArrayString &, void **)',
99
- 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)',
100
- 'wxItemContainer::Set(const wxArrayString &, void **)'], ignore_doc: false)
98
+ spec.ignore([ 'wxItemContainer::Append(const wxArrayString &, wxClientData **)',
99
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)',
100
+ 'wxItemContainer::Set(const wxArrayString &, wxClientData **)'], ignore_doc: false)
101
101
  # for doc only
102
102
  spec.map 'void** clientData' => 'Array', swig: false do
103
103
  map_in code: ''
104
104
  end
105
- spec.ignore(%w[wxItemContainer::GetClientData wxItemContainer::SetClientData], ignore_doc: false) # keep docs
106
- # Replace the old Wx definition of this method (which segfaults)
107
- # Only need the setter as we cache data in Ruby and the getter
108
- # therefor can be pure Ruby
109
- spec.add_extend_code('wxSimpleHtmlListBox', <<~__HEREDOC
110
- VALUE set_client_data(int n, VALUE item_data) {
111
- self->SetClientData(n, (void *)item_data);
112
- return item_data;
105
+ # Replace the old Wx definitions of these methods adding
106
+ # proper checks on the data arrays.
107
+ # Also add an item enumerator.
108
+ spec.add_extend_code 'wxSimpleHtmlListBox', <<~__HEREDOC
109
+ VALUE DetachClientObject(unsigned int n)
110
+ {
111
+ VALUE rc = Qnil;
112
+ wxClientData *wxcd = $self->DetachClientObject(n);
113
+ wxRubyClientData *rbcd = wxcd ? dynamic_cast<wxRubyClientData*> (wxcd) : nullptr;
114
+ if (rbcd)
115
+ {
116
+ rc = rbcd->GetData();
117
+ delete rbcd;
113
118
  }
114
- __HEREDOC
115
- )
119
+ return rc;
120
+ }
121
+
122
+ int Append(const wxArrayString &items, VALUE rb_clientData)
123
+ {
124
+ if (TYPE(rb_clientData) != T_ARRAY ||
125
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
126
+ {
127
+ rb_raise(rb_eArgError,
128
+ TYPE(rb_clientData) == T_ARRAY ?
129
+ "expected Array for client_data" :
130
+ "client_data Array needs to be equal in size to items Array");
131
+ }
132
+
133
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
134
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
135
+ {
136
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
137
+ }
138
+ return $self->Append(items, cd_arr.get());
139
+ }
140
+
141
+ int Insert(const wxArrayString &items, unsigned int pos, VALUE rb_clientData)
142
+ {
143
+ if (TYPE(rb_clientData) != T_ARRAY ||
144
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
145
+ {
146
+ rb_raise(rb_eArgError,
147
+ TYPE(rb_clientData) == T_ARRAY ?
148
+ "expected Array for client_data" :
149
+ "client_data Array needs to be equal in size to items Array");
150
+ }
151
+
152
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
153
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
154
+ {
155
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
156
+ }
157
+ return $self->Insert(items, pos, cd_arr.get());
158
+ }
159
+
160
+ void Set(const wxArrayString &items, VALUE rb_clientData)
161
+ {
162
+ if (TYPE(rb_clientData) != T_ARRAY ||
163
+ static_cast<unsigned int> (RARRAY_LEN(rb_clientData)) != items.GetCount())
164
+ {
165
+ rb_raise(rb_eArgError,
166
+ TYPE(rb_clientData) == T_ARRAY ?
167
+ "expected Array for client_data" :
168
+ "client_data Array needs to be equal in size to items Array");
169
+ }
170
+
171
+ std::unique_ptr<wxClientData*[]> cd_arr = std::make_unique<wxClientData*[]> (RARRAY_LEN(rb_clientData));
172
+ for (int i=0; i<RARRAY_LEN(rb_clientData) ;++i)
173
+ {
174
+ cd_arr[i] = new wxRubyClientData(rb_ary_entry(rb_clientData, i));
175
+ }
176
+ $self->Set(items, cd_arr.get());
177
+ }
178
+
179
+ VALUE each_string()
180
+ {
181
+ VALUE rc = Qnil;
182
+ for (unsigned int i=0; i<$self->GetCount() ;++i)
183
+ {
184
+ VALUE rb_s = WXSTR_TO_RSTR($self->GetString(i));
185
+ rc = rb_yield(rb_s);
186
+ }
187
+ return rc;
188
+ }
189
+ __HEREDOC
116
190
  end
117
191
  end # class HtmlListBox
118
192