wxruby3 0.9.0.pre.beta.10 → 0.9.0.pre.beta.13

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +85 -0
  3. data/README.md +2 -0
  4. data/assets/logo.png +0 -0
  5. data/assets/logo.svg +170 -0
  6. data/assets/logo.xcf +0 -0
  7. data/ext/wxruby3/include/wxruby-ScaledDC.h +549 -0
  8. data/ext/wxruby3/swig/wx.i +1 -1
  9. data/lib/wx/core/array_ext.rb +26 -0
  10. data/lib/wx/core/art_locator.rb +92 -0
  11. data/lib/wx/core/artprovider.rb +1 -1
  12. data/lib/wx/core/bitmap.rb +90 -53
  13. data/lib/wx/core/cursor.rb +12 -0
  14. data/lib/wx/core/data_object.rb +74 -6
  15. data/lib/wx/core/dataformat.rb +3 -1
  16. data/lib/wx/core/dc.rb +76 -52
  17. data/lib/wx/core/enum.rb +4 -0
  18. data/lib/wx/core/event.rb +38 -5
  19. data/lib/wx/core/evthandler.rb +64 -23
  20. data/lib/wx/core/icon.rb +50 -35
  21. data/lib/wx/core/id_helper.rb +32 -0
  22. data/lib/wx/core/image.rb +63 -53
  23. data/lib/wx/core/point.rb +35 -10
  24. data/lib/wx/core/real_point.rb +35 -10
  25. data/lib/wx/core/rect.rb +44 -9
  26. data/lib/wx/core/region_iterator.rb +37 -0
  27. data/lib/wx/core/size.rb +32 -5
  28. data/lib/wx/core/window.rb +8 -31
  29. data/lib/wx/doc/array_ext.rb +27 -0
  30. data/lib/wx/doc/art_locator.rb +57 -0
  31. data/lib/wx/doc/bitmap.rb +27 -0
  32. data/lib/wx/doc/clipboard.rb +12 -0
  33. data/lib/wx/doc/const.rb +77 -0
  34. data/lib/wx/doc/cursor.rb +16 -0
  35. data/lib/wx/doc/data_object.rb +103 -0
  36. data/lib/wx/doc/dc.rb +63 -46
  37. data/lib/wx/doc/event.rb +24 -0
  38. data/lib/wx/doc/events.rb +14 -0
  39. data/lib/wx/doc/evthandler.rb +24 -3
  40. data/lib/wx/doc/extra/00_starting.md +1 -1
  41. data/lib/wx/doc/extra/06_geometry.md +10 -4
  42. data/lib/wx/doc/extra/10_art.md +105 -0
  43. data/lib/wx/doc/gc_dc.rb +21 -0
  44. data/lib/wx/doc/gdi_common.rb +155 -6
  45. data/lib/wx/doc/graphics_context.rb +42 -0
  46. data/lib/wx/doc/icon.rb +18 -0
  47. data/lib/wx/doc/id_helper.rb +25 -0
  48. data/lib/wx/doc/image.rb +33 -0
  49. data/lib/wx/doc/region_iterator.rb +31 -0
  50. data/lib/wx/doc/scaled_dc.rb +17 -0
  51. data/lib/wx/doc/window.rb +18 -0
  52. data/lib/wx/global_const.rb +4 -3
  53. data/lib/wx/version.rb +1 -1
  54. data/lib/wx/wxruby/cmd/sampler.rb +3 -21
  55. data/rakelib/lib/config.rb +4 -4
  56. data/rakelib/lib/core/package.rb +6 -6
  57. data/rakelib/lib/core/spec.rb +2 -0
  58. data/rakelib/lib/director/art_provider.rb +2 -2
  59. data/rakelib/lib/director/busy_info.rb +9 -7
  60. data/rakelib/lib/director/clipboard.rb +1 -1
  61. data/rakelib/lib/director/colour_picker_ctrl.rb +1 -0
  62. data/rakelib/lib/director/data_object.rb +162 -0
  63. data/rakelib/lib/director/data_object_simple_base.rb +123 -0
  64. data/rakelib/lib/director/derived_dc.rb +134 -2
  65. data/rakelib/lib/director/dir_picker_ctrl.rb +1 -0
  66. data/rakelib/lib/director/event.rb +73 -8
  67. data/rakelib/lib/director/events.rb +19 -1
  68. data/rakelib/lib/director/file_picker_ctrl.rb +1 -0
  69. data/rakelib/lib/director/font_picker_ctrl.rb +1 -0
  70. data/rakelib/lib/director/gdicommon.rb +1 -3
  71. data/rakelib/lib/director/graphics_context.rb +89 -0
  72. data/rakelib/lib/director/help_controller.rb +2 -2
  73. data/rakelib/lib/director/html_data_object.rb +37 -0
  74. data/rakelib/lib/director/image.rb +55 -0
  75. data/rakelib/lib/director/region_iterator.rb +48 -0
  76. data/rakelib/lib/director/richtext_buffer.rb +1 -1
  77. data/rakelib/lib/director/richtext_buffer_data_object.rb +45 -0
  78. data/rakelib/lib/director/scroll_bar.rb +39 -0
  79. data/rakelib/lib/director/slider.rb +39 -0
  80. data/rakelib/lib/director/window.rb +36 -5
  81. data/rakelib/lib/director/window_disabler.rb +0 -7
  82. data/rakelib/lib/extractor/class.rb +1 -1
  83. data/rakelib/lib/extractor/function.rb +1 -1
  84. data/rakelib/lib/generate/doc.rb +26 -6
  85. data/rakelib/lib/specs/interfaces.rb +8 -1
  86. data/rakelib/lib/typemap/common.rb +1 -1
  87. data/rakelib/lib/typemap/data_object_data.rb +13 -4
  88. data/rakelib/lib/util/string.rb +29 -8
  89. data/samples/art/wxruby-128x128.png +0 -0
  90. data/samples/art/wxruby-256x256.png +0 -0
  91. data/samples/art/wxruby-64x64.png +0 -0
  92. data/samples/art/wxruby.ico +0 -0
  93. data/samples/art/wxruby.png +0 -0
  94. data/samples/drawing/graphics_drawing.rb +1 -2
  95. data/samples/propgrid/propgrid.rb +65 -65
  96. data/samples/sample.xpm +246 -470
  97. data/samples/treectrl/treectrl.rb +1 -1
  98. data/tests/art/my_art/sample.xpm +251 -0
  99. data/tests/art/sample3.xpm +251 -0
  100. data/tests/art/test_art/bitmap/sample.xpm +251 -0
  101. data/tests/art/test_art/bitmap/wxruby.bmp +0 -0
  102. data/tests/art/test_art/bitmap/wxruby.png +0 -0
  103. data/tests/art/test_art/bitmap/wxruby.xpm +251 -0
  104. data/tests/art/test_art/cursor/wxruby.bmp +0 -0
  105. data/tests/art/test_art/icon/sample.xpm +251 -0
  106. data/tests/art/test_art/icon/wxruby.ico +0 -0
  107. data/tests/art/test_art/icon/wxruby.png +0 -0
  108. data/tests/art/test_art/image/sample.xpm +251 -0
  109. data/tests/art/test_art/image/wxruby.jpg +0 -0
  110. data/tests/art/test_art/image/wxruby.png +0 -0
  111. data/tests/art/test_art/sample2.xpm +251 -0
  112. data/tests/lib/wxapp_runner.rb +64 -0
  113. data/tests/test_art.rb +91 -0
  114. data/tests/test_basic.rb +0 -5
  115. data/tests/test_clipboard.rb +149 -17
  116. data/tests/test_dc.rb +70 -0
  117. data/tests/test_dialog.rb +2 -13
  118. data/tests/test_event_handling.rb +2 -13
  119. data/tests/test_events.rb +14 -6
  120. data/tests/test_geometry.rb +67 -17
  121. data/tests/test_intl.rb +2 -15
  122. data/tests/test_item_data.rb +2 -15
  123. data/tests/test_variant.rb +1 -15
  124. data/tests/testapp.rb +0 -5
  125. data/tests/testapp_noframe.rb +0 -5
  126. metadata +56 -5
@@ -13,7 +13,7 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
- spec.gc_never
16
+ spec.gc_as_temporary # don't even track Clipboard objects
17
17
  # there is no need or support for clipboard derivatives
18
18
  # not least because wxRuby only ever allows a single global clipboard
19
19
  spec.disable_proxies
@@ -13,6 +13,7 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
+ spec.add_swig_code '%feature("notabstract") wxColourPickerCtrl;'
16
17
  spec.do_not_generate(:variables, :defines, :enums, :functions) # with ColourPickerEvent
17
18
  end
18
19
  end # class ColourPickerCtrl
@@ -56,9 +56,171 @@ module WXRuby3
56
56
  # Once a DataObject has been added, it belongs to the wxDataObjectComposite object,
57
57
  # and will be freed by it on destruction.
58
58
  spec.disown 'wxDataObjectSimple* dataObject'
59
+
60
+ # Add GC management for the DataObjectSimple instances added to a DataObjectComposite instance.
61
+ spec.add_header_code <<~__HEREDOC
62
+ #include <vector>
63
+ #include <map>
64
+
65
+ typedef std::vector<VALUE> data_object_list_t;
66
+ typedef std::map<wxDataObjectComposite*, data_object_list_t> composite_data_object_map_t;
67
+ static composite_data_object_map_t CompositeDataObject_Map;
68
+
69
+ static void GC_mark_wxCompositeDataObject(void* ptr)
70
+ {
71
+ composite_data_object_map_t::iterator it = CompositeDataObject_Map.find(static_cast<wxDataObjectComposite*> (ptr));
72
+ if (it != CompositeDataObject_Map.end())
73
+ {
74
+ data_object_list_t &do_list = it->second;
75
+ for (VALUE data_obj : do_list)
76
+ {
77
+ #ifdef __WXRB_DEBUG__
78
+ if (wxRuby_TraceLevel()>1)
79
+ {
80
+ void *c_ptr = (TYPE(data_obj) == T_DATA ? DATA_PTR(data_obj) : 0);
81
+ std::wcout << "**** wxRuby_markCompositeDataObjects : " << it->first << "|" << (void*)c_ptr << std::endl;
82
+ }
83
+ #endif
84
+ rb_gc_mark(data_obj);
85
+ }
86
+ }
87
+ }
88
+
89
+ // custom implementation for wxRuby so we can handle de-registering composites
90
+ class WxRuby_DataObjectComposite : public wxDataObjectComposite
91
+ {
92
+ public:
93
+ WxRuby_DataObjectComposite() : wxDataObjectComposite() {}
94
+ virtual ~WxRuby_DataObjectComposite()
95
+ {
96
+ CompositeDataObject_Map.erase(this);
97
+ }
98
+ };
99
+
100
+ #if wxUSE_RICHTEXT
101
+ #include <wx/richtext/richtextbuffer.h>
102
+ #endif
103
+
104
+ // Add custom object wrapper for DataObjectComposite#get_object result
105
+ static VALUE wxRuby_WrapDataObjectSimple(wxDataObjectSimple* d_obj)
106
+ {
107
+ if (!d_obj)
108
+ return Qnil;
109
+
110
+ // check if we have this object tracked
111
+ VALUE r_obj = SWIG_RubyInstanceFor(d_obj);
112
+ if (r_obj != Qnil)
113
+ {
114
+ swig_class* sklass = (swig_class *) SWIGTYPE_p_wxDataObjectSimple->clientdata;
115
+ if (rb_obj_is_kind_of(r_obj, sklass->klass))
116
+ return r_obj;
117
+ }
118
+
119
+ // Otherwise check the returned type and create a new object wrapper
120
+ void* do_ptr;
121
+ if ((do_ptr = dynamic_cast<wxBitmapDataObject*> (d_obj)))
122
+ {
123
+ return SWIG_NewPointerObj(do_ptr, SWIGTYPE_p_wxBitmapDataObject, 0);
124
+ }
125
+ if ((do_ptr = dynamic_cast<wxImageDataObject*> (d_obj)))
126
+ {
127
+ return SWIG_NewPointerObj(do_ptr, SWIGTYPE_p_wxImageDataObject, 0);
128
+ }
129
+ if ((do_ptr = dynamic_cast<wxCustomDataObject*> (d_obj)))
130
+ {
131
+ return SWIG_NewPointerObj(do_ptr, SWIGTYPE_p_wxCustomDataObject, 0);
132
+ }
133
+ if ((do_ptr = dynamic_cast<wxFileDataObject*> (d_obj)))
134
+ {
135
+ return SWIG_NewPointerObj(do_ptr, SWIGTYPE_p_wxFileDataObject, 0);
136
+ }
137
+ if ((do_ptr = dynamic_cast<wxTextDataObject*> (d_obj)))
138
+ {
139
+ return SWIG_NewPointerObj(do_ptr, SWIGTYPE_p_wxTextDataObject, 0);
140
+ }
141
+ #if wxUSE_HTML && (wxVERSION_NUMBER >= 3300)
142
+ if ((do_ptr = dynamic_cast<wxHTMLDataObject*> (d_obj)))
143
+ {
144
+ VALUE r_class = rb_eval_string("Wx::HTML::HTMLDataObject");
145
+ swig_type_info* swig_type = wxRuby_GetSwigTypeForClass(r_class);
146
+ return SWIG_NewPointerObj(do_ptr, swig_type, 0);
147
+ }
148
+ #endif
149
+ /** Leave these for now. RichText has special needs
150
+ #if wxUSE_RICHTEXT
151
+ if ((do_ptr = dynamic_cast<wxRichTextBufferDataObject*> (d_obj)))
152
+ {
153
+ VALUE r_class = rb_eval_string("Wx::RTC::RichTextBufferDataObject");
154
+ swig_type_info* swig_type = wxRuby_GetSwigTypeForClass(r_class);
155
+ return SWIG_NewPointerObj(do_ptr, swig_type, 0);
156
+ }
157
+ #endif
158
+ **/
159
+ return SWIG_NewPointerObj(SWIG_as_voidptr(d_obj), SWIGTYPE_p_wxDataObjectSimple, 0);
160
+ }
161
+ __HEREDOC
162
+ # install GC marker
163
+ spec.add_swig_code '%markfunc wxDataObjectComposite "GC_mark_wxCompositeDataObject";'
164
+
165
+ # use custom implementation class
166
+ spec.use_class_implementation 'wxDataObjectComposite', 'WxRuby_DataObjectComposite'
167
+
168
+ # make sure to return the right derived type
169
+ spec.map 'wxDataObjectSimple*' => 'Wx::DataObjectSimple' do
170
+ map_out code: '$result = wxRuby_WrapDataObjectSimple($1);'
171
+ end
172
+
173
+ # disable generating the default Add method (keep docs)
174
+ spec.ignore 'wxDataObjectComposite::Add', ignore_doc: false
175
+ # Add custom Add implementation
176
+ spec.add_extend_code 'wxDataObjectComposite', <<~__HEREDOC
177
+ void add(VALUE rb_dataObject, bool preferred=false)
178
+ {
179
+ // convert simple object
180
+ wxDataObjectSimple *simple_do;
181
+ int res = SWIG_ConvertPtr(rb_dataObject, SWIG_as_voidptrptr(&simple_do), SWIGTYPE_p_wxDataObjectSimple, SWIG_POINTER_DISOWN);
182
+ if (!SWIG_IsOK(res))
183
+ {
184
+ rb_raise(rb_eArgError, "Expected Wx::DataObjectSimple for 1");
185
+ }
186
+
187
+ // add new simple instance to registration for this composite
188
+ CompositeDataObject_Map[$self].push_back(rb_dataObject);
189
+
190
+ // add to composite
191
+ $self->Add(simple_do);
192
+ }
193
+ __HEREDOC
194
+
59
195
  end
60
196
  end # class DataObject
61
197
 
198
+ def doc_generator
199
+ DataObjectDocGenerator.new(self)
200
+ end
201
+
62
202
  end # class Director
63
203
 
204
+ class DataObjectDocGenerator < DocGenerator
205
+
206
+ def get_class_doc(clsdef)
207
+ if clsdef.name == 'wxDataObjectSimple'
208
+ []
209
+ else
210
+ super
211
+ end
212
+ end
213
+ protected :get_class_doc
214
+
215
+ def get_method_doc(mtd)
216
+ if Extractor::MethodDef === mtd && mtd.class_name == 'wxDataObject' && mtd.name == 'GetDataSize'
217
+ {}
218
+ else
219
+ super
220
+ end
221
+ end
222
+ protected :get_method_doc
223
+
224
+ end
225
+
64
226
  end # module WXRuby3
@@ -0,0 +1,123 @@
1
+ ###
2
+ # wxRuby3 wxWidgets interface director
3
+ # Copyright (c) M.J.N. Corino, The Netherlands
4
+ ###
5
+
6
+ module WXRuby3
7
+
8
+ class Director
9
+
10
+ class DataObjectSimpleBase < Director
11
+
12
+ include Typemap::DataFormat
13
+ include Typemap::DataObjectData
14
+
15
+ def setup
16
+ super
17
+ spec.items.clear
18
+ # insert literal code as #gc_as_xx does not work without parsed class items
19
+ spec.add_swig_code 'GC_MANAGE_AS_OBJECT(wxDataObjectSimpleBase);'
20
+ spec.initialize_at_end = true
21
+
22
+ spec.swig_import 'ext/wxruby3/swig/classes/include/wxDataObject.h'
23
+
24
+ spec.add_header_code <<~__HEREDOC
25
+ class wxDataObjectSimpleBase : public wxDataObjectSimple
26
+ {
27
+ public:
28
+ wxDataObjectSimpleBase(const wxDataFormat &format=wxFormatInvalid)
29
+ : wxDataObjectSimple(format) {}
30
+ virtual ~wxDataObjectSimpleBase() { }
31
+
32
+ virtual size_t GetDataSize() const { return _GetDataSize(); }
33
+ virtual size_t GetDataSize(const wxDataFormat &) const { return _GetDataSize(); }
34
+ virtual bool GetDataHere(const wxDataFormat &, void *buf) const { return _GetData(buf); }
35
+ virtual bool GetDataHere(void *data_buffer) const { return _GetData(data_buffer); }
36
+ virtual bool SetData(const wxDataFormat &, size_t len, const void *buf) { return _SetData(len, buf); }
37
+ virtual bool SetData(size_t len, const void *buf) { return _SetData(len, buf); }
38
+
39
+ protected:
40
+ virtual size_t _GetDataSize() const { return 0; }
41
+ virtual bool _GetData(void *data_buffer) const { return false; }
42
+ virtual bool _SetData(size_t len, const void *buf) { return false; }
43
+ };
44
+ __HEREDOC
45
+
46
+ spec.add_interface_code <<~__HEREDOC
47
+ class wxDataObjectSimpleBase : public wxDataObjectSimple
48
+ {
49
+ public:
50
+ wxDataObjectSimpleBase(const wxDataFormat &format=wxFormatInvalid);
51
+
52
+ virtual void GetAllFormats(wxDataFormat *formats, Direction dir=Get) const;
53
+ virtual size_t GetFormatCount(Direction dir=Get) const;
54
+ virtual wxDataFormat GetPreferredFormat(Direction dir=Get) const;
55
+
56
+ protected:
57
+ virtual size_t _GetDataSize() const;
58
+ %feature("numoutputs", "0") _GetData;
59
+ virtual VOID_BOOL _GetData(void *data_buffer) const;
60
+ virtual bool _SetData(size_t len, const void *buf);
61
+ };
62
+ __HEREDOC
63
+
64
+ # For wxDataObjectSimpleBase::GetDataHere/_GetData : the ruby method should
65
+ # return either a string containing the
66
+ # data, or nil if the data cannot be provided for some reason.
67
+ spec.map 'void *data_buffer' do
68
+
69
+ map_in ignore: true, code: ''
70
+
71
+ # "misuse" the 'check' typemap to initialize the ignored argument
72
+ # since this is inserted after any non-ignored arguments have been converted we can use these
73
+ # here
74
+ map_check temp: 'std::unique_ptr<char[]> data_buf, size_t data_size', code: <<~__CODE
75
+ data_size = arg1->GetDataSize();
76
+ data_buf = std::make_unique<char[]>(data_size);
77
+ $1 = data_buf.get ();
78
+ __CODE
79
+
80
+ # ignore C defined return value entirely (also affects directorout)
81
+ map_out ignore: 'bool'
82
+
83
+ map_argout as: {type: 'String', index: 1}, code: <<~__CODE
84
+ if (result)
85
+ {
86
+ $result = rb_utf8_str_new( (const char*)data_buf$argnum.get(), data_size$argnum);
87
+ }
88
+ else
89
+ $result = Qnil;
90
+ __CODE
91
+
92
+ # ignore the buffer pointer for now
93
+ map_directorin code: ''
94
+
95
+ map_directorargout code: <<~__CODE
96
+ if (RTEST(result))
97
+ {
98
+ if (TYPE(result) == T_STRING)
99
+ {
100
+ memcpy(data_buffer, StringValuePtr(result), RSTRING_LEN(result) );
101
+ c_result = true;
102
+ }
103
+ else
104
+ {
105
+ Swig::DirectorTypeMismatchException::raise(rb_eTypeError,
106
+ "get_data_here should return a string, or nil on failure");
107
+ }
108
+ }
109
+ else
110
+ c_result = false;
111
+ __CODE
112
+
113
+ end
114
+
115
+ # Once a DataObject has been added, it belongs to the wxDataObjectComposite object,
116
+ # and will be freed by it on destruction.
117
+ # spec.disown 'wxDataObjectSimple* dataObject'
118
+ end
119
+ end # class DataObject
120
+
121
+ end # class Director
122
+
123
+ end # module WXRuby3
@@ -14,20 +14,24 @@ module WXRuby3
14
14
  spec.disable_proxies
15
15
  if spec.module_name == 'wxScreenDC'
16
16
  spec.make_abstract 'wxScreenDC'
17
+ spec.gc_never 'wxScreenDC'
17
18
  # as a ScreenDC should always be a temporary stack object
18
19
  # we do not allow creation in Ruby but rather provide a class
19
20
  # method for block execution on a temp dc
20
21
  spec.add_extend_code 'wxScreenDC', <<~__HEREDOC
21
22
  static VALUE paint(VALUE proc)
22
23
  {
24
+ VALUE rc = Qnil;
23
25
  if (rb_block_given_p ())
24
26
  {
25
27
  wxScreenDC screen_dc;
26
28
  wxDC* dc_ptr = &screen_dc;
27
29
  VALUE rb_dc = SWIG_NewPointerObj(SWIG_as_voidptr(dc_ptr), SWIGTYPE_p_wxScreenDC, 0);
28
- return rb_yield(rb_dc);
30
+ rc = rb_yield(rb_dc);
31
+ SWIG_RubyRemoveTracking((void *)dc_ptr);
32
+ DATA_PTR(rb_dc) = NULL;
29
33
  }
30
- return Qnil;
34
+ return rc;
31
35
  }
32
36
  __HEREDOC
33
37
  # not relevant anymore
@@ -51,7 +55,135 @@ module WXRuby3
51
55
  'wxSVGFileDC::StartPage',
52
56
  'wxSVGFileDC::EndPage'
53
57
  elsif spec.module_name == 'wxGCDC'
58
+ spec.make_abstract 'wxGCDC'
59
+ spec.gc_never 'wxGCDC'
60
+ # as a GCDC should always be a temporary stack object
61
+ # we do not allow creation in Ruby but rather provide class
62
+ # methods for block execution on a temp dc
63
+ spec.add_extend_code 'wxGCDC', <<~__HEREDOC
64
+ static VALUE draw_on(const wxWindowDC& dc)
65
+ {
66
+ VALUE rc = Qnil;
67
+ if (rb_block_given_p ())
68
+ {
69
+ // Somehow there seems to be a problem with the Ruby GCDC value
70
+ // being GC-ed unless we block GC for the duration of the block
71
+ // execution. Unclear why. We have similar code for other objects
72
+ // where this issue does not come up.
73
+ VALUE gc_on = rb_gc_disable();
74
+ wxGCDC gc_dc(dc);
75
+ wxGCDC* dc_ptr = &gc_dc;
76
+ VALUE rb_dc = SWIG_NewPointerObj(SWIG_as_voidptr(dc_ptr), SWIGTYPE_p_wxGCDC, 0);
77
+ rc = rb_yield(rb_dc);
78
+ SWIG_RubyRemoveTracking((void *)dc_ptr);
79
+ DATA_PTR(rb_dc) = NULL;
80
+ if (gc_on == Qtrue) rb_gc_enable();
81
+ }
82
+ return rc;
83
+ }
84
+ static VALUE draw_on(const wxMemoryDC& dc)
85
+ {
86
+ VALUE rc = Qnil;
87
+ if (rb_block_given_p ())
88
+ {
89
+ // Somehow there seems to be a problem with the Ruby GCDC value
90
+ // being GC-ed unless we block GC for the duration of the block
91
+ // execution. Unclear why. We have similar code for other objects
92
+ // where this issue does not come up.
93
+ VALUE gc_on = rb_gc_disable();
94
+ wxGCDC gc_dc(dc);
95
+ wxGCDC* dc_ptr = &gc_dc;
96
+ VALUE rb_dc = SWIG_NewPointerObj(SWIG_as_voidptr(dc_ptr), SWIGTYPE_p_wxGCDC, 0);
97
+ rc = rb_yield(rb_dc);
98
+ SWIG_RubyRemoveTracking((void *)dc_ptr);
99
+ DATA_PTR(rb_dc) = NULL;
100
+ if (gc_on == Qtrue) rb_gc_enable();
101
+ }
102
+ return rc;
103
+ }
104
+ static VALUE draw_on(const wxPrinterDC& dc)
105
+ {
106
+ VALUE rc = Qnil;
107
+ if (rb_block_given_p ())
108
+ {
109
+ // Somehow there seems to be a problem with the Ruby GCDC value
110
+ // being GC-ed unless we block GC for the duration of the block
111
+ // execution. Unclear why. We have similar code for other objects
112
+ // where this issue does not come up.
113
+ VALUE gc_on = rb_gc_disable();
114
+ wxGCDC gc_dc(dc);
115
+ wxGCDC* dc_ptr = &gc_dc;
116
+ VALUE rb_dc = SWIG_NewPointerObj(SWIG_as_voidptr(dc_ptr), SWIGTYPE_p_wxGCDC, 0);
117
+ rc = rb_yield(rb_dc);
118
+ SWIG_RubyRemoveTracking((void *)dc_ptr);
119
+ DATA_PTR(rb_dc) = NULL;
120
+ if (gc_on == Qtrue) rb_gc_enable();
121
+ }
122
+ return rc;
123
+ }
124
+ static VALUE draw_on(wxGraphicsContext* gc)
125
+ {
126
+ VALUE rc = Qnil;
127
+ if (rb_block_given_p ())
128
+ {
129
+ // Somehow there seems to be a problem with the Ruby GCDC value
130
+ // being GC-ed unless we block GC for the duration of the block
131
+ // execution. Unclear why. We have similar code for other objects
132
+ // where this issue does not come up.
133
+ VALUE gc_on = rb_gc_disable();
134
+ wxGCDC gc_dc(gc);
135
+ wxGCDC* dc_ptr = &gc_dc;
136
+ VALUE rb_dc = SWIG_NewPointerObj(SWIG_as_voidptr(dc_ptr), SWIGTYPE_p_wxGCDC, 0);
137
+ rc = rb_yield(rb_dc);
138
+ SWIG_RubyRemoveTracking((void *)dc_ptr);
139
+ DATA_PTR(rb_dc) = NULL;
140
+ if (gc_on == Qtrue) rb_gc_enable();
141
+ }
142
+ return rc;
143
+ }
144
+ __HEREDOC
54
145
  spec.ignore 'wxGCDC::wxGCDC(const wxEnhMetaFileDC &)'
146
+ elsif spec.module_name == 'wxScaledDC'
147
+ spec.items.clear # wxRuby extension; no XML docs
148
+ spec.override_inheritance_chain('wxScaledDC', %w[wxDC wxObject])
149
+ # as there are no dependencies parsed from XML make sure we're initialized after Wx::DC
150
+ spec.initialize_at_end = true
151
+ spec.gc_never 'wxScaledDC'
152
+ spec.no_proxy 'wxScaledDC'
153
+ spec.include 'wxruby-ScaledDC.h'
154
+ # wxScaledDc should ever only be used in a restricted scope
155
+ # to be destructed directly after use therefor we make it abstract
156
+ # and provide a class factory method #draw_on with accepts a block.
157
+ # (as we there no classes defined in XML we cannot use add_extend_code
158
+ # so we use a workaround here)
159
+ spec.add_swig_code <<~__HEREDOC
160
+ %extend wxScaledDC {
161
+ static VALUE draw_on(wxDC& target, double scale)
162
+ {
163
+ VALUE rc = Qnil;
164
+ if (rb_block_given_p())
165
+ {
166
+ wxScaledDC scaled_dc(target, scale);
167
+ wxScaledDC* p_scaled_dc = &scaled_dc;
168
+ VALUE rb_scaled_dc = SWIG_NewPointerObj(SWIG_as_voidptr(p_scaled_dc), SWIGTYPE_p_wxScaledDC, 0);
169
+ rc = rb_yield(rb_scaled_dc);
170
+ SWIG_RubyRemoveTracking((void *)p_scaled_dc);
171
+ DATA_PTR(rb_scaled_dc) = NULL;
172
+ }
173
+ return rc;
174
+ }
175
+ };
176
+ __HEREDOC
177
+ spec.swig_import %w[ext/wxruby3/swig/classes/include/wxObject.h
178
+ ext/wxruby3/swig/classes/include/wxDC.h]
179
+ spec.add_interface_code <<~__HEREDOC
180
+ class wxScaledDC : public wxDC
181
+ {
182
+ public:
183
+ wxScaledDC(wxDC& target, double scale);
184
+ virtual ~wxScaledDC() = 0;
185
+ };
186
+ __HEREDOC
55
187
  else
56
188
  # ctors of all other derived DC require a running App
57
189
  spec.require_app spec.module_name
@@ -13,6 +13,7 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
+ spec.add_swig_code '%feature("notabstract") wxDirPickerCtrl;'
16
17
  spec.do_not_generate(:variables, :defines, :enums, :functions) # with FileDirPickerEvent
17
18
  end
18
19
  end # class DirPickerCtrl
@@ -24,11 +24,68 @@ module WXRuby3
24
24
  # make Ruby director and wrappers use custom implementation
25
25
  spec.use_class_implementation('wxEvent', 'wxRubyEvent')
26
26
  spec.extend_interface('wxEvent', 'wxEvent(wxEventType commandType = wxEVT_NULL, int id = 0, int prop_level = wxEVENT_PROPAGATE_NONE)')
27
- spec.extend_interface('wxEvent', 'virtual wxEvent* Clone() const')
28
- spec.ignore %w[wxEvent::Clone wxEvent::GetEventUserData]
27
+ spec.ignore %w[wxEvent::GetEventUserData]
29
28
  spec.ignore 'wxEvent::wxEvent(int,wxEventType)'
30
29
  spec.no_proxy 'wxEvent::Clone'
30
+ spec.regard 'wxEvent::Clone', regard_doc: false # need updated doc
31
+ # need this to force alloc func
32
+ spec.add_swig_code '%feature("notabstract") wxEvent;'
33
+ # type mapping for result #clone
34
+ spec.map 'wxEvent*' => 'Wx::Event' do
35
+ map_out code: <<~__CODE
36
+ $result = wxRuby_WrapClonedWxEvent($1);
37
+ __CODE
38
+ end
31
39
  spec.add_header_code <<~__HEREDOC
40
+ static VALUE Evt_Type_Map = NULL;
41
+ static VALUE wxRuby_WrapClonedWxEvent(wxEvent* wx_evt)
42
+ {
43
+ wxString class_name( wx_evt->GetClassInfo()->GetClassName() );
44
+ if (class_name == "wxEvent" || class_name == "wxCommandEvent")
45
+ {
46
+ // special clones for Ruby derived events are already managed and tracked
47
+ return SWIG_RubyInstanceFor((void *)wx_evt);
48
+ }
49
+
50
+ // otherwise
51
+
52
+ // Get the mapping of event types to classes
53
+ if ( ! Evt_Type_Map )
54
+ {
55
+ Evt_Type_Map = wxRuby_GetEventTypeClassMap ();
56
+ }
57
+
58
+ // Then, look up the event type in this hash (MUCH faster than calling
59
+ // EvtHandler.evt_class_for_type method)
60
+ VALUE rb_event_type_id = INT2NUM( wx_evt->GetEventType() );
61
+ VALUE rb_event_class = rb_hash_aref(Evt_Type_Map, rb_event_type_id);
62
+
63
+ if ( NIL_P(rb_event_class) )
64
+ {
65
+ rb_event_class = wxRuby_GetDefaultEventClass();
66
+ rb_warning("Unmapped event type %i (%s)", wx_evt->GetEventType(), (const char *)class_name.mb_str());
67
+ }
68
+
69
+ // Wrap as owned object as this is a user code factory function.
70
+ swig_type_info* type = wxRuby_GetSwigTypeForClass(rb_event_class);
71
+ swig_class* class_info = (swig_class*)type->clientdata;
72
+ // Create a new (owned) Ruby event object
73
+ VALUE rb_evt = Data_Wrap_Struct(class_info->klass, VOIDFUNC(class_info->mark),
74
+ VOIDFUNC(class_info->destroy),
75
+ wx_evt);
76
+ // track new event object
77
+ SWIG_RubyAddTracking(wx_evt, rb_evt);
78
+ // do not forget to mark the instance with the mangled swig type name
79
+ rb_iv_set(rb_evt, "@__swigtype__", rb_str_new2(type->name));
80
+
81
+ #if __WXRB_DEBUG__
82
+ if (wxRuby_TraceLevel()>1)
83
+ std::wcout << "* wxRuby_WrapClonedWxEvent - wrapped cloned event " << wx_evt << "{" << type->name << "}" << std::endl;
84
+ #endif
85
+
86
+ return rb_evt;
87
+ }
88
+
32
89
  // Custom subclass implementation. Provide a constructor, destructor and
33
90
  // clone functions to allow proper linking to a Ruby object.
34
91
  class WXRUBY_EXPORT wxRubyEvent : public wxEvent
@@ -85,8 +142,8 @@ module WXRuby3
85
142
  wxCommandEvent::SetClientObject
86
143
  wxCommandEvent::GetExtraLong
87
144
  }
88
- spec.extend_interface('wxCommandEvent', 'virtual wxCommandEvent* Clone() const')
89
- spec.no_proxy 'wxCommandEvent::Clone'
145
+ # need this to force alloc func
146
+ spec.add_swig_code '%feature("notabstract") wxCommandEvent;'
90
147
  spec.add_header_code <<~__HEREDOC
91
148
  // Cf wxEvent - has to be written as a C+++ subclass to ensure correct
92
149
  // GC/thread protection of Ruby instance variables when user-written
@@ -129,7 +186,8 @@ module WXRuby3
129
186
  };
130
187
  __HEREDOC
131
188
  spec.add_wrapper_code <<~__HEREDOC
132
- extern VALUE wxRuby_GetDefaultEventClass () {
189
+ extern VALUE wxRuby_GetDefaultEventClass()
190
+ {
133
191
  return SwigClassWxEvent.klass;
134
192
  }
135
193
  __HEREDOC
@@ -145,8 +203,8 @@ module WXRuby3
145
203
 
146
204
  def process(gendoc: false)
147
205
  defmod = super
148
- spec.items.each do |citem|
149
- unless citem == 'wxEvent'
206
+ unless spec.module_name == 'wxEvent'
207
+ spec.items.each do |citem|
150
208
  def_item = defmod.find_item(citem)
151
209
  if Extractor::ClassDef === def_item
152
210
  if def_item.hierarchy.has_key?('wxEvent')
@@ -158,7 +216,14 @@ module WXRuby3
158
216
  elsif def_item.hierarchy.has_key?('wxNotifyEvent')
159
217
  spec.override_inheritance_chain(citem, {'wxNotifyEvent' => 'wxEvents'}, {'wxCommandEvent' => 'wxEvent'}, 'wxEvent', 'wxObject')
160
218
  end
161
- spec.make_abstract(citem) if citem == 'wxPaintEvent' # doc flaw
219
+ case citem
220
+ when 'wxNotifyEvent', 'wxPaintEvent'
221
+ # keep these abstract in wxRuby
222
+ spec.make_abstract(citem)
223
+ else
224
+ # need this to force alloc func
225
+ spec.add_swig_code "%feature(\"notabstract\") #{citem};"
226
+ end
162
227
  end
163
228
  end
164
229
  end
@@ -24,7 +24,7 @@ module WXRuby3
24
24
  wxPaletteChangedEvent wxQueryNewPaletteEvent wxNavigationKeyEvent wxWindowCreateEvent
25
25
  wxWindowDestroyEvent wxHelpEvent wxClipboardTextEvent wxContextMenuEvent wxChildFocusEvent
26
26
  ])
27
- spec.fold_bases('wxMouseEvent' => 'wxMouseState', 'wxKeyEvent' => 'wxKeyboardState')
27
+ spec.fold_bases('wxMouseEvent' => %w[wxMouseState wxKeyboardState], 'wxKeyEvent' => 'wxKeyboardState')
28
28
  spec.set_only_for 'WXWIN_COMPATIBILITY_2_8', 'wxShowEvent::GetShow', 'wxIconizeEvent::Iconized'
29
29
  spec.ignore 'wxKeyEvent::GetPosition(wxCoord *,wxCoord *) const'
30
30
  spec.ignore 'wxMouseState::GetPosition(int *,int *)'
@@ -32,6 +32,24 @@ module WXRuby3
32
32
  spec.do_not_generate(:variables, :defines, :enums, :functions)
33
33
  end
34
34
 
35
+ def process(gendoc: false)
36
+ defmod = super
37
+ # fix documentation errors for wxScrollEvent
38
+ def_item = defmod.find_item('wxScrollEvent')
39
+ if def_item
40
+ def_item.event_types.each do |evt_spec|
41
+ case evt_spec.first
42
+ when 'EVT_COMMAND_SCROLL_THUMBRELEASE', 'EVT_COMMAND_SCROLL_CHANGED'
43
+ if evt_spec[2] == 0
44
+ evt_spec[2] = 1 # incorrectly documented without 'id' argument
45
+ evt_spec[4] = true # ignore extracted docs
46
+ end
47
+ end
48
+ end
49
+ end
50
+ defmod
51
+ end
52
+
35
53
  end # class Events
36
54
 
37
55
  end # class Director
@@ -13,6 +13,7 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
+ spec.add_swig_code '%feature("notabstract") wxFilePickerCtrl;'
16
17
  spec.do_not_generate(:variables, :defines, :enums, :functions) # with FileDirPickerEvent
17
18
  end
18
19
  end # class FilePickerCtrl
@@ -13,6 +13,7 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
+ spec.add_swig_code '%feature("notabstract") wxFontPickerCtrl;'
16
17
  spec.do_not_generate(:variables, :defines, :enums, :functions) # with FontPickerEvent
17
18
  end
18
19
  end # class FontPickerCtrl
@@ -23,14 +23,12 @@ module WXRuby3
23
23
  'wxClientDisplayRect(int *,int *,int *,int *)',
24
24
  'wxDisplaySize(int *,int *)',
25
25
  'wxDisplaySizeMM(int *,int *)',
26
- 'wxRect::Inflate(wxCoord,wxCoord)',
27
26
  'wxRect::Inflate(wxCoord,wxCoord) const',
28
- 'wxRect::Deflate(wxCoord,wxCoord)',
29
27
  'wxRect::Deflate(wxCoord,wxCoord) const',
30
- 'wxRect::Offset(wxCoord,wxCoord)',
31
28
  'wxRect::Intersect(const wxRect &)',
32
29
  'wxRect::Union(const wxRect &)'
33
30
  ]
31
+ spec.regard 'wxRect::Offset', regard_doc: false
34
32
  # overrule common wxPoint mapping for wxRect ctor to fix ctor ambiguities here wrt wxSize
35
33
  spec.map 'const wxPoint& topLeft', 'const wxPoint& bottomRight', as: 'Wx::Point' do
36
34
  map_in code: <<~__CODE