wxruby3 1.3.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
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'