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

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