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.
- checksums.yaml +4 -4
- data/INSTALL.md +85 -0
- data/README.md +2 -0
- data/assets/logo.png +0 -0
- data/assets/logo.svg +170 -0
- data/assets/logo.xcf +0 -0
- data/ext/wxruby3/include/wxruby-ScaledDC.h +549 -0
- data/ext/wxruby3/swig/wx.i +1 -1
- data/lib/wx/core/array_ext.rb +26 -0
- data/lib/wx/core/art_locator.rb +92 -0
- data/lib/wx/core/artprovider.rb +1 -1
- data/lib/wx/core/bitmap.rb +90 -53
- data/lib/wx/core/cursor.rb +12 -0
- data/lib/wx/core/data_object.rb +74 -6
- data/lib/wx/core/dataformat.rb +3 -1
- data/lib/wx/core/dc.rb +76 -52
- data/lib/wx/core/enum.rb +4 -0
- data/lib/wx/core/event.rb +38 -5
- data/lib/wx/core/evthandler.rb +64 -23
- data/lib/wx/core/icon.rb +50 -35
- data/lib/wx/core/id_helper.rb +32 -0
- data/lib/wx/core/image.rb +63 -53
- data/lib/wx/core/point.rb +35 -10
- data/lib/wx/core/real_point.rb +35 -10
- data/lib/wx/core/rect.rb +44 -9
- data/lib/wx/core/region_iterator.rb +37 -0
- data/lib/wx/core/size.rb +32 -5
- data/lib/wx/core/window.rb +8 -31
- data/lib/wx/doc/array_ext.rb +27 -0
- data/lib/wx/doc/art_locator.rb +57 -0
- data/lib/wx/doc/bitmap.rb +27 -0
- data/lib/wx/doc/clipboard.rb +12 -0
- data/lib/wx/doc/const.rb +77 -0
- data/lib/wx/doc/cursor.rb +16 -0
- data/lib/wx/doc/data_object.rb +103 -0
- data/lib/wx/doc/dc.rb +63 -46
- data/lib/wx/doc/event.rb +24 -0
- data/lib/wx/doc/events.rb +14 -0
- data/lib/wx/doc/evthandler.rb +24 -3
- data/lib/wx/doc/extra/00_starting.md +1 -1
- data/lib/wx/doc/extra/06_geometry.md +10 -4
- data/lib/wx/doc/extra/10_art.md +105 -0
- data/lib/wx/doc/gc_dc.rb +21 -0
- data/lib/wx/doc/gdi_common.rb +155 -6
- data/lib/wx/doc/graphics_context.rb +42 -0
- data/lib/wx/doc/icon.rb +18 -0
- data/lib/wx/doc/id_helper.rb +25 -0
- data/lib/wx/doc/image.rb +33 -0
- data/lib/wx/doc/region_iterator.rb +31 -0
- data/lib/wx/doc/scaled_dc.rb +17 -0
- data/lib/wx/doc/window.rb +18 -0
- data/lib/wx/global_const.rb +4 -3
- data/lib/wx/version.rb +1 -1
- data/lib/wx/wxruby/cmd/sampler.rb +3 -21
- data/rakelib/lib/config.rb +4 -4
- data/rakelib/lib/core/package.rb +6 -6
- data/rakelib/lib/core/spec.rb +2 -0
- data/rakelib/lib/director/art_provider.rb +2 -2
- data/rakelib/lib/director/busy_info.rb +9 -7
- data/rakelib/lib/director/clipboard.rb +1 -1
- data/rakelib/lib/director/colour_picker_ctrl.rb +1 -0
- data/rakelib/lib/director/data_object.rb +162 -0
- data/rakelib/lib/director/data_object_simple_base.rb +123 -0
- data/rakelib/lib/director/derived_dc.rb +134 -2
- data/rakelib/lib/director/dir_picker_ctrl.rb +1 -0
- data/rakelib/lib/director/event.rb +73 -8
- data/rakelib/lib/director/events.rb +19 -1
- data/rakelib/lib/director/file_picker_ctrl.rb +1 -0
- data/rakelib/lib/director/font_picker_ctrl.rb +1 -0
- data/rakelib/lib/director/gdicommon.rb +1 -3
- data/rakelib/lib/director/graphics_context.rb +89 -0
- data/rakelib/lib/director/help_controller.rb +2 -2
- data/rakelib/lib/director/html_data_object.rb +37 -0
- data/rakelib/lib/director/image.rb +55 -0
- data/rakelib/lib/director/region_iterator.rb +48 -0
- data/rakelib/lib/director/richtext_buffer.rb +1 -1
- data/rakelib/lib/director/richtext_buffer_data_object.rb +45 -0
- data/rakelib/lib/director/scroll_bar.rb +39 -0
- data/rakelib/lib/director/slider.rb +39 -0
- data/rakelib/lib/director/window.rb +36 -5
- data/rakelib/lib/director/window_disabler.rb +0 -7
- data/rakelib/lib/extractor/class.rb +1 -1
- data/rakelib/lib/extractor/function.rb +1 -1
- data/rakelib/lib/generate/doc.rb +26 -6
- data/rakelib/lib/specs/interfaces.rb +8 -1
- data/rakelib/lib/typemap/common.rb +1 -1
- data/rakelib/lib/typemap/data_object_data.rb +13 -4
- data/rakelib/lib/util/string.rb +29 -8
- data/samples/art/wxruby-128x128.png +0 -0
- data/samples/art/wxruby-256x256.png +0 -0
- data/samples/art/wxruby-64x64.png +0 -0
- data/samples/art/wxruby.ico +0 -0
- data/samples/art/wxruby.png +0 -0
- data/samples/drawing/graphics_drawing.rb +1 -2
- data/samples/propgrid/propgrid.rb +65 -65
- data/samples/sample.xpm +246 -470
- data/samples/treectrl/treectrl.rb +1 -1
- data/tests/art/my_art/sample.xpm +251 -0
- data/tests/art/sample3.xpm +251 -0
- data/tests/art/test_art/bitmap/sample.xpm +251 -0
- data/tests/art/test_art/bitmap/wxruby.bmp +0 -0
- data/tests/art/test_art/bitmap/wxruby.png +0 -0
- data/tests/art/test_art/bitmap/wxruby.xpm +251 -0
- data/tests/art/test_art/cursor/wxruby.bmp +0 -0
- data/tests/art/test_art/icon/sample.xpm +251 -0
- data/tests/art/test_art/icon/wxruby.ico +0 -0
- data/tests/art/test_art/icon/wxruby.png +0 -0
- data/tests/art/test_art/image/sample.xpm +251 -0
- data/tests/art/test_art/image/wxruby.jpg +0 -0
- data/tests/art/test_art/image/wxruby.png +0 -0
- data/tests/art/test_art/sample2.xpm +251 -0
- data/tests/lib/wxapp_runner.rb +64 -0
- data/tests/test_art.rb +91 -0
- data/tests/test_basic.rb +0 -5
- data/tests/test_clipboard.rb +149 -17
- data/tests/test_dc.rb +70 -0
- data/tests/test_dialog.rb +2 -13
- data/tests/test_event_handling.rb +2 -13
- data/tests/test_events.rb +14 -6
- data/tests/test_geometry.rb +67 -17
- data/tests/test_intl.rb +2 -15
- data/tests/test_item_data.rb +2 -15
- data/tests/test_variant.rb +1 -15
- data/tests/testapp.rb +0 -5
- data/tests/testapp_noframe.rb +0 -5
- metadata +56 -5
@@ -13,7 +13,7 @@ module WXRuby3
|
|
13
13
|
|
14
14
|
def setup
|
15
15
|
super
|
16
|
-
spec.
|
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
|
@@ -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
|
-
|
30
|
+
rc = rb_yield(rb_dc);
|
31
|
+
SWIG_RubyRemoveTracking((void *)dc_ptr);
|
32
|
+
DATA_PTR(rb_dc) = NULL;
|
29
33
|
}
|
30
|
-
return
|
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
|
@@ -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.
|
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
|
-
|
89
|
-
spec.
|
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.
|
149
|
-
|
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
|
-
|
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' =>
|
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
|
@@ -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
|