wxruby3 1.3.1 → 1.4.2

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +16 -12
  3. data/README.md +4 -3
  4. data/ext/wxruby3/include/wxRubyApp.h +9 -9
  5. data/ext/wxruby3/swig/mark_free_impl.i +47 -11
  6. data/ext/wxruby3/swig/wx.i +30 -12
  7. data/lib/wx/aui/auifloatframe.rb +1 -1
  8. data/lib/wx/aui/auimanager.rb +5 -16
  9. data/lib/wx/aui/auinotebook.rb +1 -1
  10. data/lib/wx/aui/require.rb +0 -2
  11. data/lib/wx/core/acceleratortable.rb +1 -1
  12. data/lib/wx/core/animation.rb +2 -2
  13. data/lib/wx/core/app.rb +1 -1
  14. data/lib/wx/core/artprovider.rb +4 -4
  15. data/lib/wx/core/bitmap.rb +1 -1
  16. data/lib/wx/core/bitmap_combobox.rb +2 -2
  17. data/lib/wx/core/clientdc.rb +1 -1
  18. data/lib/wx/core/clipboard.rb +4 -4
  19. data/lib/wx/core/colour.rb +1 -1
  20. data/lib/wx/core/combobox.rb +1 -1
  21. data/lib/wx/core/config.rb +7 -7
  22. data/lib/wx/core/controlwithitems.rb +3 -3
  23. data/lib/wx/core/data_object.rb +4 -4
  24. data/lib/wx/core/dataformat.rb +9 -3
  25. data/lib/wx/core/dialog.rb +3 -2
  26. data/lib/wx/core/event.rb +3 -3
  27. data/lib/wx/core/evthandler.rb +317 -289
  28. data/lib/wx/core/file_dialog.rb +1 -1
  29. data/lib/wx/core/find_replace_dialog.rb +2 -2
  30. data/lib/wx/core/functions.rb +1 -1
  31. data/lib/wx/core/genericdirctrl.rb +1 -1
  32. data/lib/wx/core/geometry.rb +2 -2
  33. data/lib/wx/core/graphics_pen_info.rb +1 -1
  34. data/lib/wx/core/helpprovider.rb +1 -1
  35. data/lib/wx/core/icon.rb +1 -1
  36. data/lib/wx/core/image.rb +2 -2
  37. data/lib/wx/core/imagelist.rb +1 -1
  38. data/lib/wx/core/locale.rb +5 -5
  39. data/lib/wx/core/log.rb +8 -8
  40. data/lib/wx/core/menu.rb +3 -3
  41. data/lib/wx/core/module_ext.rb +16 -0
  42. data/lib/wx/core/owner_drawn_combobox.rb +3 -3
  43. data/lib/wx/core/pen_info.rb +1 -1
  44. data/lib/wx/core/persistence_manager.rb +2 -2
  45. data/lib/wx/core/rect.rb +1 -1
  46. data/lib/wx/core/secret_store.rb +1 -1
  47. data/lib/wx/core/simplehelpprovider.rb +1 -1
  48. data/lib/wx/core/sizer.rb +8 -8
  49. data/lib/wx/core/splash_screen.rb +1 -1
  50. data/lib/wx/core/standard_paths.rb +1 -1
  51. data/lib/wx/core/task_bar_button.rb +1 -1
  52. data/lib/wx/core/text_entry.rb +1 -1
  53. data/lib/wx/core/textctrl.rb +2 -2
  54. data/lib/wx/core/timer.rb +2 -2
  55. data/lib/wx/core/tree_ctrl.rb +1 -1
  56. data/lib/wx/core/v_list_box.rb +1 -1
  57. data/lib/wx/core/validator.rb +2 -2
  58. data/lib/wx/core/variant.rb +2 -2
  59. data/lib/wx/core/window.rb +48 -2
  60. data/lib/wx/core/xmlresource.rb +4 -4
  61. data/lib/wx/core.rb +2 -0
  62. data/lib/wx/doc/evthandler.rb +1 -0
  63. data/lib/wx/doc/tip_window.rb +22 -0
  64. data/lib/wx/grid/grid.rb +3 -3
  65. data/lib/wx/grid/require.rb +0 -2
  66. data/lib/wx/html/htmlhelpcontroller.rb +1 -1
  67. data/lib/wx/html/htmlwindow.rb +1 -1
  68. data/lib/wx/html/require.rb +0 -2
  69. data/lib/wx/html/simple_html_listbox.rb +3 -3
  70. data/lib/wx/keyword_ctors.rb +14 -7
  71. data/lib/wx/keyword_defs.rb +7 -7
  72. data/lib/wx/pg/pg_properties.rb +1 -1
  73. data/lib/wx/pg/pg_property.rb +3 -3
  74. data/lib/wx/pg/property_grid.rb +2 -2
  75. data/lib/wx/pg/property_grid_interface.rb +2 -2
  76. data/lib/wx/pg/require.rb +0 -2
  77. data/lib/wx/prt/previewframe.rb +1 -1
  78. data/lib/wx/prt/require.rb +0 -2
  79. data/lib/wx/rbn/ribbon_control.rb +1 -1
  80. data/lib/wx/rbn/ribbon_page.rb +1 -1
  81. data/lib/wx/rbn/ribbon_panel.rb +1 -1
  82. data/lib/wx/rtc/require.rb +0 -2
  83. data/lib/wx/rtc/rich_text_composite_object.rb +1 -1
  84. data/lib/wx/rtc/rich_text_ctrl.rb +1 -1
  85. data/lib/wx/rtc/rich_text_paragraph.rb +1 -1
  86. data/lib/wx/rtc/richtext_buffer.rb +3 -3
  87. data/lib/wx/rtc/richtext_formatting_dialog.rb +2 -2
  88. data/lib/wx/rtc/richtext_style_organiser_dialog.rb +1 -1
  89. data/lib/wx/rtc/symbol_picker_dialog.rb +1 -1
  90. data/lib/wx/stc/require.rb +0 -2
  91. data/lib/wx/stc/styled_text_ctrl.rb +1 -1
  92. data/lib/wx/version.rb +1 -1
  93. data/lib/wx/wxruby/base.rb +8 -2
  94. data/lib/wx/wxruby/cmd/setup.rb +61 -37
  95. data/rakelib/gem.rb +8 -4
  96. data/rakelib/lib/config/mingw.rb +1 -1
  97. data/rakelib/lib/director/about_dialog_info.rb +1 -0
  98. data/rakelib/lib/director/aui_manager.rb +63 -57
  99. data/rakelib/lib/director/aui_notebook.rb +7 -0
  100. data/rakelib/lib/director/colour.rb +1 -1
  101. data/rakelib/lib/director/data_format.rb +1 -1
  102. data/rakelib/lib/director/event.rb +1 -0
  103. data/rakelib/lib/director/event_handler.rb +82 -46
  104. data/rakelib/lib/director/functions.rb +0 -3
  105. data/rakelib/lib/director/list_ctrl.rb +14 -10
  106. data/rakelib/lib/director/locale.rb +2 -0
  107. data/rakelib/lib/director/num_validator.rb +7 -0
  108. data/rakelib/lib/director/tip_window.rb +34 -0
  109. data/rakelib/lib/director/window.rb +9 -1
  110. data/rakelib/lib/director.rb +0 -1
  111. data/rakelib/lib/generate/doc/evt_handler.yaml +31 -12
  112. data/rakelib/lib/specs/interfaces.rb +1 -0
  113. data/tests/test_combo_ctrl.rb +1 -0
  114. data/tests/test_event_handling.rb +158 -31
  115. metadata +6 -5
data/rakelib/gem.rb CHANGED
@@ -214,16 +214,18 @@ module WXRuby3
214
214
  end
215
215
  elsif uri.scheme == 'http' || uri.scheme == 'https'
216
216
  # download the binary release package
217
- $stdout.puts "Downloading #{uri.path}..."
217
+ $stdout.puts "Downloading #{uri}..."
218
218
  filename = File.basename(uri.path)
219
- if WXRuby3.config.download_file(uri.path, filename)
219
+ if WXRuby3.config.download_file(uri.to_s, filename)
220
220
  sha_file = File.basename(filename, '.*')+DIGEST_EXT
221
- uri.path = File.join(File.dirname(uri.path), sha_file)
222
- unless WXRuby3.config.download_file(uri.path, sha_file)
221
+ sha_uri = File.join(File.dirname(uri.to_s), sha_file)
222
+ unless WXRuby3.config.download_file(sha_uri, sha_file)
223
223
  $stderr.puts "ERROR: Unable to download digest signature for binary release package : #{package}"
224
224
  exit(1)
225
225
  end
226
226
  exit(1) unless install_bin_pkg(filename)
227
+ # cleanup, remove downloaded files
228
+ FileUtils.rm_f([filename, sha_file])
227
229
  true
228
230
  else
229
231
  $stderr.puts "ERROR: Unable to download binary release package (#{package})!"
@@ -241,6 +243,8 @@ module WXRuby3
241
243
  exit(1)
242
244
  end
243
245
  exit(1) unless install_bin_pkg(bin_pkg_name+BINPKG_EXT)
246
+ # cleanup, remove downloaded files
247
+ FileUtils.rm_f([bin_pkg_name+BINPKG_EXT, bin_pkg_name+DIGEST_EXT])
244
248
  true
245
249
  else
246
250
  if prebuilt_only
@@ -98,7 +98,7 @@ module WXRuby3
98
98
  private
99
99
 
100
100
  def wx_configure
101
- bash('./configure --prefix=`pwd`/install --disable-tests --without-subdirs --without-regex --with-expat=builtin --with-zlib=builtin --disable-debug_info')
101
+ bash('./configure --prefix=`pwd`/install --disable-tests --without-subdirs --without-regex --without-libcurl --with-expat=builtin --with-zlib=builtin --disable-debug_info')
102
102
  end
103
103
 
104
104
  def wx_make
@@ -19,6 +19,7 @@ module WXRuby3
19
19
  map_check code: ''
20
20
  end
21
21
  super
22
+ spec.ignore 'wxGenericAboutBox' # wrapped with wxGenericAboutDialog
22
23
  end
23
24
  end # class AboutDialogInfo
24
25
 
@@ -18,48 +18,53 @@ module WXRuby3
18
18
  super
19
19
  spec.gc_as_object 'wxAuiManager'
20
20
  if Config.instance.wx_version >= '3.3.0'
21
- spec.items << 'wxAuiSerializer' << 'wxAuiDockInfo' << 'wxAuiDeserializer'
22
- spec.gc_as_untracked 'wxAuiSerializer', 'wxAuiDockInfo'
23
- spec.regard 'wxAuiDockInfo::rect',
24
- 'wxAuiDockInfo::dock_direction',
25
- 'wxAuiDockInfo::dock_layer',
26
- 'wxAuiDockInfo::dock_row',
27
- 'wxAuiDockInfo::size',
28
- 'wxAuiDockInfo::min_size',
29
- 'wxAuiDockInfo::resizable',
30
- 'wxAuiDockInfo::toolbar',
31
- 'wxAuiDockInfo::fixed',
32
- 'wxAuiDockInfo::reserved1'
33
- spec.make_readonly 'wxAuiDockInfo::rect',
34
- 'wxAuiDockInfo::dock_direction',
35
- 'wxAuiDockInfo::dock_layer',
36
- 'wxAuiDockInfo::dock_row',
37
- 'wxAuiDockInfo::size',
38
- 'wxAuiDockInfo::min_size',
39
- 'wxAuiDockInfo::resizable',
40
- 'wxAuiDockInfo::toolbar',
41
- 'wxAuiDockInfo::fixed',
42
- 'wxAuiDockInfo::reserved1'
43
- spec.add_extend_code 'wxAuiDockInfo', <<~__HEREDOC
44
- VALUE each_pane()
21
+ spec.items << 'wxAuiSerializer' << 'wxAuiDockLayoutInfo' << 'wxAuiPaneLayoutInfo' << 'wxAuiTabLayoutInfo' << 'wxAuiDeserializer'
22
+ spec.gc_as_untracked 'wxAuiSerializer', 'wxAuiDeserializer', 'wxAuiDockLayoutInfo', 'wxAuiPaneLayoutInfo', 'wxAuiTabLayoutInfo'
23
+ spec.regard 'wxAuiDockLayoutInfo::dock_direction',
24
+ 'wxAuiDockLayoutInfo::dock_layer',
25
+ 'wxAuiDockLayoutInfo::dock_row',
26
+ 'wxAuiDockLayoutInfo::dock_pos',
27
+ 'wxAuiDockLayoutInfo::dock_proportion',
28
+ 'wxAuiDockLayoutInfo::dock_size',
29
+ 'wxAuiPaneLayoutInfo::name',
30
+ 'wxAuiPaneLayoutInfo::floating_pos',
31
+ 'wxAuiPaneLayoutInfo::floating_size',
32
+ 'wxAuiPaneLayoutInfo::is_maximized'
33
+ spec.add_extend_code 'wxAuiTabLayoutInfo', <<~__HEREDOC
34
+ VALUE get_pages()
45
35
  {
46
- wxAuiPaneInfoPtrArray panes = self->panes;
47
- VALUE rc = Qnil;
48
- for (wxAuiPaneInfo* pane : panes)
36
+ VALUE rc = rb_ary_new();
37
+ for (int page : self->pages)
49
38
  {
50
- VALUE r_pane = SWIG_NewPointerObj(pane, SWIGTYPE_p_wxAuiPaneInfo, 0);
51
- rc = rb_yield(r_pane);
52
- }
39
+ rb_ary_push(rc, INT2NUM(page));
40
+ }
53
41
  return rc;
54
42
  }
43
+
44
+ void set_pages(VALUE rb_pages)
45
+ {
46
+ if (TYPE(rb_pages) == T_ARRAY)
47
+ {
48
+ std::vector<int> pgs;
49
+ for (int i = 0; i < RARRAY_LEN(rb_pages); i++)
50
+ {
51
+ pgs.push_back(NUM2INT(rb_ary_entry(rb_pages, i)));
52
+ }
53
+ self->pages = pgs;
54
+ }
55
+ else
56
+ {
57
+ rb_raise(rb_eTypeError, "Expected Array of Integer for 1");
58
+ }
59
+ }
55
60
  __HEREDOC
56
- spec.map 'std::vector<wxAuiPaneInfo>' => 'Array<Wx::AuiPaneInfo>' do
61
+ spec.map 'std::vector<wxAuiPaneLayoutInfo>' => 'Array<Wx::AuiPaneLayoutInfo>' do
57
62
  map_out code: <<~__CODE
58
63
  $result = rb_ary_new();
59
- std::vector<wxAuiPaneInfo>& panes = (std::vector<wxAuiPaneInfo>&)$1;
60
- for (const wxAuiPaneInfo& pane : panes)
64
+ std::vector<wxAuiPaneLayoutInfo>& panes = (std::vector<wxAuiPaneLayoutInfo>&)$1;
65
+ for (const wxAuiPaneLayoutInfo& pane : panes)
61
66
  {
62
- VALUE r_pane = SWIG_NewPointerObj(new wxAuiPaneInfo(pane), SWIGTYPE_p_wxAuiPaneInfo, SWIG_POINTER_OWN);
67
+ VALUE r_pane = SWIG_NewPointerObj(new wxAuiPaneLayoutInfo(pane), SWIGTYPE_p_wxAuiPaneLayoutInfo, SWIG_POINTER_OWN);
63
68
  rb_ary_push($result, r_pane);
64
69
  }
65
70
  __CODE
@@ -70,24 +75,24 @@ module WXRuby3
70
75
  {
71
76
  void *ptr;
72
77
  VALUE r_pane = rb_ary_entry($input, i);
73
- int res = SWIG_ConvertPtr(r_pane, &ptr, SWIGTYPE_p_wxAuiPaneInfo, 0);
78
+ int res = SWIG_ConvertPtr(r_pane, &ptr, SWIGTYPE_p_wxAuiPaneLayoutInfo, 0);
74
79
  if (!SWIG_IsOK(res) || !ptr) {
75
- Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_panes", rb_eTypeError, "in return value. Expected Array of Wx::AuiPaneInfo");
80
+ Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_panes", rb_eTypeError, "in return value. Expected Array of Wx::AuiPaneLayoutInfo");
76
81
  }
77
- wxAuiPaneInfo *pane = reinterpret_cast< wxAuiPaneInfo * >(ptr);
82
+ wxAuiPaneLayoutInfo *pane = reinterpret_cast< wxAuiPaneLayoutInfo * >(ptr);
78
83
  $result.push_back(*pane);
79
84
  }
80
85
  }
81
86
  __CODE
82
87
  end
83
- spec.map 'std::vector<wxAuiDockInfo>' => 'Array<Wx::AuiDockInfo>' do
88
+ spec.map 'std::vector<wxAuiTabLayoutInfo>' => 'Array<Wx::AuiTabLayoutInfo>' do
84
89
  map_out code: <<~__CODE
85
90
  $result = rb_ary_new();
86
- std::vector<wxAuiDockInfo>& docks = (std::vector<wxAuiDockInfo>&)$1;
87
- for (const wxAuiDockInfo& dock : docks)
91
+ std::vector<wxAuiTabLayoutInfo>& tabs = (std::vector<wxAuiTabLayoutInfo>&)$1;
92
+ for (const wxAuiTabLayoutInfo& tab : tabs)
88
93
  {
89
- VALUE r_dock = SWIG_NewPointerObj(new wxAuiDockInfo(dock), SWIGTYPE_p_wxAuiDockInfo, SWIG_POINTER_OWN);
90
- rb_ary_push($result, r_dock);
94
+ VALUE r_tab = SWIG_NewPointerObj(new wxAuiTabLayoutInfo(tab), SWIGTYPE_p_wxAuiTabLayoutInfo, SWIG_POINTER_OWN);
95
+ rb_ary_push($result, r_tab);
91
96
  }
92
97
  __CODE
93
98
  map_directorout code: <<~__CODE
@@ -96,13 +101,13 @@ module WXRuby3
96
101
  for (int i = 0; i < RARRAY_LEN($input); i++)
97
102
  {
98
103
  void *ptr;
99
- VALUE r_dock = rb_ary_entry($input, i);
100
- int res = SWIG_ConvertPtr(r_dock, &ptr, SWIGTYPE_p_wxAuiDockInfo, 0);
104
+ VALUE r_tab = rb_ary_entry($input, i);
105
+ int res = SWIG_ConvertPtr(r_tab, &ptr, SWIGTYPE_p_wxAuiTabLayoutInfo, 0);
101
106
  if (!SWIG_IsOK(res) || !ptr) {
102
- Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_docks", rb_eTypeError, "in return value. Expected Array of Wx::AuiDockInfo");
107
+ Swig::DirectorTypeMismatchException::raise(swig_get_self(), "load_docks", rb_eTypeError, "in return value. Expected Array of Wx::AuiTabLayoutInfo");
103
108
  }
104
- wxAuiDockInfo *dock = reinterpret_cast< wxAuiDockInfo * >(ptr);
105
- $result.push_back(*dock);
109
+ wxAuiTabLayoutInfo *tab = reinterpret_cast< wxAuiTabLayoutInfo * >(ptr);
110
+ $result.push_back(*tab);
106
111
  }
107
112
  }
108
113
  __CODE
@@ -215,17 +220,18 @@ module WXRuby3
215
220
 
216
221
  def gen_class_doc_members(fdoc, clsdef, cls_members, alias_methods)
217
222
  super
218
- if Config.instance.wx_version >= '3.3.0' && clsdef.name == 'wxAuiDockInfo'
219
- fdoc.doc.puts 'Yield each pane to the given block.'
220
- fdoc.doc.puts 'If no block passed returns an Enumerator.'
221
- fdoc.doc.puts '@yieldparam [Wx::AUI::AuiPaneInfo] pane the Aui pane info yielded'
222
- fdoc.doc.puts '@return [::Object, ::Enumerator] result of last block execution or enumerator'
223
- fdoc.puts 'def each_pane; end'
223
+ if Config.instance.wx_version >= '3.3.0' && clsdef.name == 'wxAuiTabLayoutInfo'
224
+ fdoc.doc.puts 'Returns the indices of the pages in this tab control in their order on screen.'
225
+ fdoc.doc.puts 'If this array is empty, it means that the tab control contains all notebook pages in natural order.'
226
+ fdoc.doc.puts '@return [::Array<Integer>] indices of the pages in this tab control'
227
+ fdoc.puts 'def get_pages; end'
228
+ fdoc.puts 'alias :pages :get_pages'
224
229
  fdoc.puts
225
- fdoc.doc.puts 'Returns an array of Wx::AuiPaneInfo for all panes managed by the frame manager.'
226
- fdoc.doc.puts '@return [Array<Wx::AUI::AuiPaneInfo>] info for all managed panes'
227
- fdoc.puts 'def get_panes; end'
228
- fdoc.puts 'alias_method :panes, :get_panes'
230
+ fdoc.doc.puts 'Set the indices of the pages in this tab control in their order on screen.'
231
+ fdoc.doc.puts 'If this array is empty, it means that the tab control contains all notebook pages in natural order.'
232
+ fdoc.doc.puts '@param [::Array<Integer>] pages indices of the pages in this tab control'
233
+ fdoc.puts 'def set_pages(pages) end'
234
+ fdoc.puts 'alias :pages= :set_pages'
229
235
  end
230
236
  end
231
237
 
@@ -25,6 +25,13 @@ module WXRuby3
25
25
  wxAuiNotebookPage::bitmap
26
26
  wxAuiNotebookPage::rect
27
27
  wxAuiNotebookPage::active]
28
+ if Config.instance.wx_version >= '3.3.0'
29
+ spec.items << 'wxAuiNotebookPosition'
30
+ spec.regard 'wxAuiNotebookPosition::tabctrl',
31
+ 'wxAuiNotebookPosition::page'
32
+ spec.make_readonly 'wxAuiNotebookPosition::tabctrl',
33
+ 'wxAuiNotebookPosition::page'
34
+ end
28
35
  # reset type mapping done in BookCtrls as the non-const arg is used for query-ing here (FindTab)
29
36
  # (wxWidgets should have made this a const arg)
30
37
  spec.map_apply 'SWIGTYPE *' => 'wxWindow* page'
@@ -16,7 +16,7 @@ module WXRuby3
16
16
  spec.gc_as_untracked('wxColour')
17
17
  spec.require_app 'wxColour::wxColour(const wxColour&)'
18
18
  spec.ignore(%w[
19
- wxColour::GetPixel wxTransparentColour wxColour::operator!=
19
+ wxColour::GetPixel wxTransparentColour wxColour::operator!= wxColour::operator==
20
20
  wxBLACK wxBLUE wxCYAN wxGREEN wxYELLOW wxLIGHT_GREY wxRED wxWHITE
21
21
  ])
22
22
  spec.map 'unsigned char *' => 'Integer' do
@@ -15,7 +15,7 @@ module WXRuby3
15
15
  def setup
16
16
  super
17
17
  spec.gc_as_object
18
- spec.ignore 'wxDataFormat::operator ==(wxDataFormatId)'
18
+ spec.ignore 'wxDataFormat::operator=='
19
19
  if Config.platform == :mingw
20
20
  # The formal signature for these is NativeFormat; this is required on
21
21
  # MSVC as otherwise an impermissible implicit cast is tried, and so
@@ -47,6 +47,7 @@ module WXRuby3
47
47
  if (class_name == "wxEvent" || class_name == "wxCommandEvent")
48
48
  {
49
49
  // special clones for Ruby derived events are already managed and tracked
50
+ // (this also covers Wx::AsyncProcCallEvent)
50
51
  return SWIG_RubyInstanceFor((void *)wx_evt);
51
52
  }
52
53
 
@@ -29,45 +29,21 @@ module WXRuby3
29
29
  # have TryBefore and TryAfter to handle this much cleaner
30
30
  spec.no_proxy 'wxEvtHandler::ProcessEvent'
31
31
  spec.regard('wxEvtHandler::ProcessEvent', regard_doc: false) # we provide customized docs
32
+ # Do not see much use for allowing overrides for these either as wxWidgets do not either
33
+ spec.no_proxy 'wxEvtHandler::QueueEvent',
34
+ 'wxEvtHandler::AddPendingEvent'
35
+ # Do not see much point in allowing/supporting these to be overridden
36
+ spec.no_proxy 'wxEvtHandler::SetNextHandler',
37
+ 'wxEvtHandler::SetPreviousHandler'
38
+ # no doc for set_previous_handler
39
+ spec.regard('wxEvtHandler::SetPreviousHandler', regard_doc: false)
32
40
  # make SWIG aware of these
33
41
  spec.regard 'wxEvtHandler::TryBefore', 'wxEvtHandler::TryAfter'
34
42
  # Special type mapping for wxEvtHandler::QueueEvent which assumes ownership of the C++ event.
35
- # We need to create a shallow copy of the Ruby event instance (copying it's Ruby members if any),
36
- # pass linkage of the C++ event to the copy and remove it from the original (input) Ruby
37
- # instance (so it can not delete/or reference it anymore); also start tracking the copy
38
- # (which effectively removes the tracking for the original).
39
- # Queued (pending) events are cleaned up (deleted) by wxWidgets after (failing) handling
40
- # which will automatically unlink and un-track them releasing the Ruby instance to be GC-ed.
41
- spec.map 'wxEvent *event' => 'Wx::Event' do
42
- map_in code: <<~__CODE
43
- // get the wrapped wxEvent*
44
- wxEvent *wx_ev = (wxEvent*)DATA_PTR($input);
45
- // check if this a user defined event
46
- if ( wx_ev->GetEventType() > wxEVT_USER_FIRST )
47
- {
48
- // we need to preserve the Ruby state
49
- // create a shallow copy of the Ruby object
50
- VALUE r_evt_copy = rb_obj_clone($input);
51
- // pass the wxEvent* over to the copy
52
- DATA_PTR(r_evt_copy) = wx_ev;
53
- // unlink the input
54
- DATA_PTR($input) = 0;
55
- // track the copy (this overwrites the record for the
56
- // original, effectively untracking it)
57
- wxRuby_AddTracking( (void*)wx_ev, r_evt_copy);
58
- }
59
- else
60
- {
61
- // std wx event; no need to preserve the Ruby state
62
- // simply untrack and unlink the input
63
- wxRuby_RemoveTracking( (void*)wx_ev);
64
- DATA_PTR($input) = 0;
65
- // and just pass on the C++ event
66
- }
67
- // Queue the C++ event
68
- $1 = wx_ev;
69
- __CODE
70
- end
43
+ # We need to disown Ruby with respect to the C++ event object but remain tracking the pair to keep
44
+ # the Ruby event object alive.
45
+ spec.disown 'wxEvent *event'
46
+
71
47
  # add special mapping for event filters so we can accept the app instance as well
72
48
  # although Wx::App is not derived from Wx::EventFilter in wxRuby (no multiple inheritance)
73
49
  spec.map 'wxEventFilter*' => 'Wx::EventFilter,Wx::App' do
@@ -225,6 +201,10 @@ module WXRuby3
225
201
  }
226
202
  __HEREDOC
227
203
  spec.add_header_code <<~__HEREDOC
204
+ static VALUE WxRuby_GetAsyncProcCallEvent_Class();
205
+ static void GC_mark_AsyncMethodCallEvent(void *ptr);
206
+ static void free_AsyncMethodCallEvent(void *ptr);
207
+
228
208
  class RbAsyncProcCallEvent : public wxAsyncMethodCallEvent
229
209
  {
230
210
  public:
@@ -245,7 +225,14 @@ module WXRuby3
245
225
 
246
226
  virtual wxEvent *Clone() const wxOVERRIDE
247
227
  {
248
- return new RbAsyncProcCallEvent(*this);
228
+ RbAsyncProcCallEvent* wx_ev = new RbAsyncProcCallEvent(*this);
229
+ // Create a new Ruby event object (owned)
230
+ VALUE rb_evt = Data_Wrap_Struct(WxRuby_GetAsyncProcCallEvent_Class(),
231
+ VOIDFUNC(GC_mark_AsyncMethodCallEvent),
232
+ VOIDFUNC(free_AsyncMethodCallEvent),
233
+ wx_ev);
234
+ wxRuby_AddTracking( (void*)wx_ev, rb_evt);
235
+ return wx_ev;
249
236
  }
250
237
 
251
238
  virtual void Execute() wxOVERRIDE
@@ -257,12 +244,22 @@ module WXRuby3
257
244
  if (TYPE(m_rb_call) == T_ARRAY)
258
245
  {
259
246
  VALUE proc = rb_ary_entry(m_rb_call, 0);
260
- VALUE args = rb_ary_subseq(m_rb_call, 1, RARRAY_LEN(m_rb_call)-1);
261
- rc = wxRuby_Funcall(ex_caught, proc, call_id(), args);
247
+ if (RARRAY_LEN(m_rb_call) > 1)
248
+ {
249
+ VALUE args = rb_ary_subseq(m_rb_call, 1, RARRAY_LEN(m_rb_call)-1);
250
+ rc = wxRuby_Funcall(ex_caught, proc, call_id(), args);
251
+ }
252
+ else
253
+ {
254
+ rc = wxRuby_Funcall(ex_caught, proc, call_id(), (int)0);
255
+ }
262
256
  }
263
257
  else
264
258
  {
265
- rc = wxRuby_Funcall(ex_caught, m_rb_call, call_id(), (int)0);
259
+ // should never happen
260
+ VALUE ex = rb_eval_string("x = RuntimeError.new('UNEXPECTED ERROR: Asynchronous Proc Event has invalid call spec!'); x.set_backtrace(caller); x");
261
+ wxRuby_PrintException(ex);
262
+ exit(1);
266
263
  }
267
264
  if (ex_caught)
268
265
  {
@@ -276,9 +273,39 @@ module WXRuby3
276
273
  }
277
274
  }
278
275
 
276
+ void GC_Mark()
277
+ {
278
+ rb_gc_mark(m_rb_call);
279
+ }
280
+
279
281
  private:
280
282
  VALUE m_rb_call;
281
283
  };
284
+
285
+ static void GC_mark_AsyncMethodCallEvent(void *ptr)
286
+ {
287
+ if (ptr)
288
+ {
289
+ RbAsyncProcCallEvent* evt = (RbAsyncProcCallEvent*)ptr;
290
+ evt->GC_Mark();
291
+ }
292
+ }
293
+
294
+ static void free_AsyncMethodCallEvent(void *ptr)
295
+ {
296
+ RbAsyncProcCallEvent *wx_evt = (RbAsyncProcCallEvent *)ptr;
297
+ delete wx_evt;
298
+ }
299
+
300
+ static VALUE WxRuby_GetAsyncProcCallEvent_Class()
301
+ {
302
+ static VALUE WxRuby_cAsyncProcCallEvent = Qnil;
303
+ if (WxRuby_cAsyncProcCallEvent == Qnil)
304
+ {
305
+ WxRuby_cAsyncProcCallEvent = rb_eval_string("Wx::AsyncProcCallEvent");
306
+ }
307
+ return WxRuby_cAsyncProcCallEvent;
308
+ }
282
309
  __HEREDOC
283
310
  spec.add_extend_code 'wxEvtHandler', <<~__HEREDOC
284
311
  // This provides the public Ruby 'connect' method
@@ -333,18 +360,23 @@ module WXRuby3
333
360
  void call_after(VALUE call)
334
361
  {
335
362
  // valid call object?
336
- VALUE proc;
337
- if (TYPE(call) == T_ARRAY &&
338
- (rb_obj_is_kind_of(proc = rb_ary_entry(call, 0), rb_cProc)
363
+ VALUE proc = TYPE(call) == T_ARRAY ? rb_ary_entry(call, 0) : Qnil;
364
+ if (!NIL_P(proc) &&
365
+ (rb_obj_is_kind_of(proc, rb_cProc)
339
366
  ||
340
367
  rb_obj_is_kind_of(proc, rb_cMethod)))
341
368
  {
342
369
  // create C++ event
343
370
  RbAsyncProcCallEvent * evt = new RbAsyncProcCallEvent(self, call);
371
+ // Create a new Ruby event object (leave ownership to wxWidgets C++)
372
+ VALUE rb_evt = Data_Wrap_Struct(WxRuby_GetAsyncProcCallEvent_Class(),
373
+ VOIDFUNC(GC_mark_AsyncMethodCallEvent),
374
+ 0,
375
+ evt);
344
376
  // track it and the call object
345
- wxRuby_AddTracking( (void*)evt, call);
346
- // queue it
347
- self->QueueEvent(evt);
377
+ wxRuby_AddTracking( (void*)evt, rb_evt);
378
+ // queue it (wxWidgets takes ownership of C++ event object)
379
+ self->wxEvtHandler::QueueEvent(evt);
348
380
  }
349
381
  }
350
382
  __HEREDOC
@@ -371,6 +403,10 @@ module WXRuby3
371
403
  def_item = defmod.find_item(citem)
372
404
  if Extractor::ClassDef === def_item && spec.is_derived_from?(def_item, 'wxEvtHandler')
373
405
  spec.no_proxy "#{spec.class_name(citem)}::ProcessEvent"
406
+ spec.no_proxy "#{spec.class_name(citem)}::QueueEvent"
407
+ spec.no_proxy "#{spec.class_name(citem)}::AddPendingEvent"
408
+ spec.no_proxy "#{spec.class_name(citem)}::SetNextHandler"
409
+ spec.no_proxy "#{spec.class_name(citem)}::SetPreviousHandler"
374
410
  is_evt_handler = true
375
411
  end
376
412
  end
@@ -204,9 +204,6 @@ module WXRuby3
204
204
  spec.add_interface_code <<~__HEREDOC
205
205
  bool wxSafeYield(wxWindow* win = NULL, bool onlyIfNeeded = false);
206
206
 
207
- // Mouse / keyboard information
208
- wxWindow * wxGetActiveWindow();
209
-
210
207
  // Dialog shortcuts
211
208
  wxString wxFileSelector (const wxString &message,
212
209
  const wxString &default_path=wxEmptyString,
@@ -148,7 +148,7 @@ module WXRuby3
148
148
 
149
149
  wxListCtrl* wx_lc = (wxListCtrl*) ptr;
150
150
 
151
- // First check if there's ImageLists and mark if found
151
+ // First check if there are ImageLists and mark if found
152
152
  wxImageList* img_list;
153
153
  img_list= wx_lc->GetImageList(wxIMAGE_LIST_NORMAL);
154
154
  if ( img_list ) rb_gc_mark(SWIG_RubyInstanceFor(img_list));
@@ -161,18 +161,22 @@ module WXRuby3
161
161
  if ( wx_lc->GetWindowStyle() & wxLC_VIRTUAL )
162
162
  return;
163
163
 
164
- int count = wx_lc->GetItemCount();
165
- if ( count == 0 ) return;
166
-
167
- for (int i = 0; i < count; ++i)
164
+ // only mark items if window fully created
165
+ if (wx_lc->GetId() != wxID_ANY)
168
166
  {
169
- wxUIntPtr data = wx_lc->GetItemData(i);
170
- VALUE object = reinterpret_cast<VALUE> (data);
171
- if ( object && object != Qnil )
167
+ int count = wx_lc->GetItemCount();
168
+ if ( count == 0 ) return;
169
+
170
+ for (int i = 0; i < count; ++i)
172
171
  {
173
- rb_gc_mark(object);
172
+ wxUIntPtr data = wx_lc->GetItemData(i);
173
+ VALUE object = reinterpret_cast<VALUE> (data);
174
+ if ( object && object != Qnil )
175
+ {
176
+ rb_gc_mark(object);
177
+ }
174
178
  }
175
- }
179
+ }
176
180
  }
177
181
  __HEREDOC
178
182
  spec.add_extend_code 'wxListCtrl', <<~__HEREDOC
@@ -29,6 +29,8 @@ module WXRuby3
29
29
  wxLanguageInfo::LayoutDirection
30
30
  ]
31
31
  spec.ignore_unless('WXMSW', 'wxLanguageInfo::WinLang', 'wxLanguageInfo::WinSublang')
32
+ # implemented in Ruby
33
+ spec.ignore 'wxLocale::GetSystemEncodingName'
32
34
  end
33
35
  end # class Locale
34
36
 
@@ -370,6 +370,13 @@ module WXRuby3
370
370
  spec.new_object 'WXIntegerValidator::Clone',
371
371
  'WXUnsignedValidator::Clone',
372
372
  'WXFloatValidator::Clone'
373
+ %w[WXIntegerValidator WXUnsignedValidator WXFloatValidator].each do |klass|
374
+ spec.no_proxy "#{klass}::ProcessEvent"
375
+ spec.no_proxy "#{klass}::QueueEvent"
376
+ spec.no_proxy "#{klass}::AddPendingEvent"
377
+ spec.no_proxy "#{klass}::SetNextHandler"
378
+ spec.no_proxy "#{klass}::SetPreviousHandler"
379
+ end
373
380
  spec.suppress_warning(473,
374
381
  'WXIntegerValidator::Clone',
375
382
  'WXUnsignedValidator::Clone',
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2023 M.J.N. Corino, The Netherlands
2
+ #
3
+ # This software is released under the MIT license.
4
+
5
+ ###
6
+ # wxRuby3 wxWidgets interface director
7
+ ###
8
+
9
+ require_relative './window'
10
+
11
+ module WXRuby3
12
+
13
+ class Director
14
+
15
+ class TipWindow < Window
16
+
17
+ def setup
18
+ super
19
+ spec.disable_proxies
20
+ spec.ignore 'wxTipWindow::SetTipWindowPtr'
21
+ spec.ignore 'wxTipWindow::wxTipWindow'
22
+ spec.add_extend_code 'wxTipWindow', <<~__HEREDOC
23
+ wxTipWindow(wxWindow* parent, const wxString& text, wxCoord maxLength = 100)
24
+ {
25
+ return new wxTipWindow(parent, text, maxLength);
26
+ }
27
+ __HEREDOC
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -66,7 +66,6 @@ module WXRuby3
66
66
  __CODE
67
67
  end
68
68
  spec.ignore [
69
- 'wxWindow::PopEventHandler',
70
69
  'wxWindow::SetConstraints',
71
70
  'wxWindow::GetHandle',
72
71
  'wxWindow::GetSize(int *,int *) const', # no need; prefer the wxSize version
@@ -83,6 +82,15 @@ module WXRuby3
83
82
  'wxWindow::Raise',
84
83
  'wxWindow::Lower'
85
84
  ]
85
+
86
+ # Event handler chaining methods; pushed handlers always remain owned by Ruby
87
+ # wxRuby3 will automatically pop any remaining handlers when windows get deleted
88
+ # also ignore this
89
+ spec.ignore 'wxWindow::PopEventHandler', ignore_doc: false
90
+ # and instead add an argument-less version (will use default argument of C++ impl)
91
+ # as we do want C++ side to delete any popped handler
92
+ spec.extend_interface 'wxWindow', 'wxEvtHandler *PopEventHandler()'
93
+
86
94
  # no real docs and can't find actual examples of usage; ignore
87
95
  spec.ignore 'wxWindow::GetConstraints', 'wxWindow::SetConstraints'
88
96
  # redefine these so a nil parent is accepted
@@ -6,7 +6,6 @@
6
6
  # wxRuby3 interface Director class
7
7
  ###
8
8
 
9
- require 'ostruct'
10
9
  require 'set'
11
10
  require 'pathname'
12
11
  require 'tempfile'