wxruby3 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/wxruby3/include/wxruby-Config.h +23 -5
- data/ext/wxruby3/include/wxruby-Persistence.h +79 -0
- data/ext/wxruby3/swig/memory_management.i +6 -0
- data/lib/wx/core/book_ctrl_base.rb +16 -0
- data/lib/wx/core/config.rb +454 -83
- data/lib/wx/core/notebook.rb +10 -8
- data/lib/wx/core/peristent_object.rb +15 -0
- data/lib/wx/core/persistence_manager.rb +39 -0
- data/lib/wx/core/persistent_window.rb +16 -0
- data/lib/wx/core/top_level_window.rb +16 -0
- data/lib/wx/core/treebook.rb +18 -0
- data/lib/wx/core.rb +4 -0
- data/lib/wx/doc/book_ctrl_base.rb +19 -0
- data/lib/wx/doc/config.rb +101 -41
- data/lib/wx/doc/extra/14_config.md +101 -0
- data/lib/wx/doc/extra/15_persistence.md +148 -0
- data/lib/wx/doc/persistence_manager.rb +36 -0
- data/lib/wx/doc/persistent_object.rb +27 -0
- data/lib/wx/doc/top_level_window.rb +19 -0
- data/lib/wx/doc/treebook.rb +6 -1
- data/lib/wx/version.rb +1 -1
- data/rakelib/build.rb +1 -1
- data/rakelib/lib/core/package.rb +22 -1
- data/rakelib/lib/core/spec.rb +10 -0
- data/rakelib/lib/core/spec_helper.rb +1 -1
- data/rakelib/lib/director/config_base.rb +490 -19
- data/rakelib/lib/director/event_filter.rb +1 -1
- data/rakelib/lib/director/event_loop.rb +1 -1
- data/rakelib/lib/director/file_dialog_customize_hook.rb +2 -2
- data/rakelib/lib/director/grid_cell_attr.rb +1 -1
- data/rakelib/lib/director/grid_cell_editor.rb +1 -1
- data/rakelib/lib/director/grid_cell_renderer.rb +1 -1
- data/rakelib/lib/director/header_ctrl.rb +3 -0
- data/rakelib/lib/director/html_listbox.rb +2 -1
- data/rakelib/lib/director/persistence_manager.rb +410 -0
- data/rakelib/lib/director/persistent_object.rb +70 -0
- data/rakelib/lib/director/persistent_window.rb +73 -0
- data/rakelib/lib/director/static_bitmap.rb +4 -0
- data/rakelib/lib/director/text_entry.rb +1 -1
- data/rakelib/lib/generate/analyzer.rb +43 -43
- data/rakelib/lib/generate/doc.rb +1 -1
- data/rakelib/lib/specs/interfaces.rb +3 -0
- data/rakelib/lib/typemap/config.rb +8 -0
- data/samples/widgets/widgets.rb +5 -9
- data/tests/test_config.rb +207 -42
- data/tests/test_persistence.rb +142 -0
- metadata +19 -2
@@ -0,0 +1,410 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
###
|
6
|
+
# wxRuby3 wxWidgets interface director
|
7
|
+
###
|
8
|
+
|
9
|
+
module WXRuby3
|
10
|
+
|
11
|
+
class Director
|
12
|
+
|
13
|
+
class PersistenceManager < Director
|
14
|
+
|
15
|
+
include Typemap::ConfigBase
|
16
|
+
|
17
|
+
def setup
|
18
|
+
super
|
19
|
+
spec.gc_as_marked
|
20
|
+
spec.use_class_implementation 'wxPersistenceManager', 'WxRubyPersistenceManager'
|
21
|
+
spec.ignore 'wxPersistenceManager::Register',
|
22
|
+
'wxPersistenceManager::Find',
|
23
|
+
'wxPersistenceManager::Unregister',
|
24
|
+
'wxPersistenceManager::Save',
|
25
|
+
'wxPersistenceManager::Restore',
|
26
|
+
'wxPersistenceManager::SaveAndUnregister',
|
27
|
+
'wxPersistenceManager::RegisterAndRestore',
|
28
|
+
ignore_doc: false
|
29
|
+
# doc gen only
|
30
|
+
spec.map 'void *obj' => 'Object', swig: false do
|
31
|
+
map_in code: ''
|
32
|
+
end
|
33
|
+
spec.map 'T *obj' => 'Object', swig: false do
|
34
|
+
map_in code: ''
|
35
|
+
end
|
36
|
+
spec.regard 'wxPersistenceManager::wxPersistenceManager',
|
37
|
+
'wxPersistenceManager::GetConfig',
|
38
|
+
'wxPersistenceManager::GetKey'
|
39
|
+
spec.suppress_warning 473, 'wxPersistenceManager::GetConfig'
|
40
|
+
spec.ignore %w[wxCreatePersistentObject wxPersistentRegisterAndRestore]
|
41
|
+
spec.add_header_code <<~__HEREDOC
|
42
|
+
#include "wxruby-Persistence.h"
|
43
|
+
|
44
|
+
// default global wxRuby persistence manager
|
45
|
+
static WxRubyPersistenceManager s_wxruby_persistence_manager {};
|
46
|
+
|
47
|
+
static WxRuby_ID to_f_id("to_f");
|
48
|
+
static WxRuby_ID to_i_id("to_i");
|
49
|
+
static WxRuby_ID to_s_id("to_s");
|
50
|
+
static WxRuby_ID save_value_id("save_value");
|
51
|
+
static WxRuby_ID restore_value_id("save_value");
|
52
|
+
static WxRuby_ID create_po_id("create_persistent_object");
|
53
|
+
|
54
|
+
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
55
|
+
#define PO_LONG wxLongLong_t
|
56
|
+
#define PO_NUM2LONG(n) NUM2LL(n)
|
57
|
+
#define PO_LONG2NUM(l) LL2NUM(l)
|
58
|
+
#else
|
59
|
+
#define PO_LONG long
|
60
|
+
#define PO_NUM2LONG(n) NUM2LONG(n)
|
61
|
+
#define PO_LONG2NUM(l) LONG2NUM(l)
|
62
|
+
#endif
|
63
|
+
|
64
|
+
bool WxRubyPersistenceManager::SaveRubyValue(const wxPersistentObject& who, const wxString& name, VALUE value)
|
65
|
+
{
|
66
|
+
Swig::Director* dir = dynamic_cast<Swig::Director*> (this);
|
67
|
+
// is this a user defined Ruby persistence manager with overridden #save_value?
|
68
|
+
if (dir && !wxRuby_IsNativeMethod(dir->swig_get_self(), save_value_id()))
|
69
|
+
{
|
70
|
+
VALUE rb_who = SWIG_NewPointerObj(SWIG_as_voidptr(&who), SWIGTYPE_p_wxPersistentObject, 0 );
|
71
|
+
return wxRuby_Funcall(dir->swig_get_self(), save_value_id(), 3, rb_who, WXSTR_TO_RSTR(name), value);
|
72
|
+
}
|
73
|
+
else
|
74
|
+
{
|
75
|
+
// just call C++ base implementation
|
76
|
+
return DoSaveRubyValue(who, name, value);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
VALUE WxRubyPersistenceManager::RestoreRubyValue(const wxPersistentObject& who, const wxString& name)
|
81
|
+
{
|
82
|
+
Swig::Director* dir = dynamic_cast<Swig::Director*> (this);
|
83
|
+
// is this a user defined Ruby persistence manager with overridden #restore_value?
|
84
|
+
if (dir && !wxRuby_IsNativeMethod(dir->swig_get_self(), restore_value_id()))
|
85
|
+
{
|
86
|
+
VALUE rb_who = SWIG_NewPointerObj(SWIG_as_voidptr(&who), SWIGTYPE_p_wxPersistentObject, 0 );
|
87
|
+
return wxRuby_Funcall(dir->swig_get_self(), restore_value_id(), 3, rb_who, WXSTR_TO_RSTR(name));
|
88
|
+
}
|
89
|
+
else
|
90
|
+
{
|
91
|
+
// just call C++ base implementation
|
92
|
+
return DoRestoreRubyValue(who, name);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
bool WxRubyPersistenceManager::DoSaveRubyValue(const wxPersistentObject& who, const wxString& name, VALUE value)
|
97
|
+
{
|
98
|
+
wxConfigBase* cfg = this->GetConfig();
|
99
|
+
if (!cfg)
|
100
|
+
return false;
|
101
|
+
wxString key = this->GetKey(who, name);
|
102
|
+
switch(TYPE(value))
|
103
|
+
{
|
104
|
+
case T_TRUE:
|
105
|
+
case T_FALSE:
|
106
|
+
return cfg->Write(key, value == Qtrue);
|
107
|
+
|
108
|
+
case T_FIXNUM:
|
109
|
+
case T_BIGNUM:
|
110
|
+
return cfg->Write(key, PO_NUM2LONG(value));
|
111
|
+
|
112
|
+
case T_FLOAT:
|
113
|
+
return cfg->Write(key, NUM2DBL(value));
|
114
|
+
|
115
|
+
case T_STRING:
|
116
|
+
return cfg->Write(key, RSTR_TO_WXSTR(value));
|
117
|
+
|
118
|
+
default:
|
119
|
+
if (rb_respond_to(value, to_i_id()))
|
120
|
+
{
|
121
|
+
VALUE ival = rb_funcall(value, to_i_id(), 0);
|
122
|
+
return cfg->Write(key, PO_NUM2LONG(ival));
|
123
|
+
}
|
124
|
+
else if (rb_respond_to(value, to_f_id()))
|
125
|
+
{
|
126
|
+
VALUE fval = rb_funcall(value, to_f_id(), 0);
|
127
|
+
return cfg->Write(key, NUM2DBL(fval));
|
128
|
+
}
|
129
|
+
break;
|
130
|
+
}
|
131
|
+
VALUE sval = rb_funcall(value, to_s_id(), 0);
|
132
|
+
return cfg->Write(key, RSTR_TO_WXSTR(sval));
|
133
|
+
}
|
134
|
+
|
135
|
+
VALUE WxRubyPersistenceManager::DoRestoreRubyValue(const wxPersistentObject& who, const wxString& name)
|
136
|
+
{
|
137
|
+
wxConfigBase* cfg = this->GetConfig();
|
138
|
+
if (!cfg)
|
139
|
+
return Qnil;
|
140
|
+
wxString key = this->GetKey(who, name);
|
141
|
+
wxConfigBase::EntryType vtype = cfg->GetEntryType(key);
|
142
|
+
switch(vtype)
|
143
|
+
{
|
144
|
+
case wxConfigBase::Type_Boolean:
|
145
|
+
{
|
146
|
+
bool v;
|
147
|
+
if (cfg->Read(key, &v))
|
148
|
+
{
|
149
|
+
return v ? Qtrue : Qfalse;
|
150
|
+
}
|
151
|
+
break;
|
152
|
+
}
|
153
|
+
case wxConfigBase::Type_Integer:
|
154
|
+
{
|
155
|
+
PO_LONG v;
|
156
|
+
if (cfg->Read(key, &v))
|
157
|
+
{
|
158
|
+
return PO_LONG2NUM(v);
|
159
|
+
}
|
160
|
+
break;
|
161
|
+
}
|
162
|
+
case wxConfigBase::Type_Float:
|
163
|
+
{
|
164
|
+
double v;
|
165
|
+
if (cfg->Read(key, &v))
|
166
|
+
{
|
167
|
+
return DBL2NUM(v);
|
168
|
+
}
|
169
|
+
break;
|
170
|
+
}
|
171
|
+
case wxConfigBase::Type_String:
|
172
|
+
{
|
173
|
+
wxString v;
|
174
|
+
if (cfg->Read(key, &v))
|
175
|
+
{
|
176
|
+
return WXSTR_TO_RSTR(v);
|
177
|
+
}
|
178
|
+
break;
|
179
|
+
}
|
180
|
+
default:
|
181
|
+
break;
|
182
|
+
}
|
183
|
+
return Qnil;
|
184
|
+
}
|
185
|
+
|
186
|
+
void WxRubyPersistenceManager::UnregisterPersistentObject(VALUE rb_obj)
|
187
|
+
{
|
188
|
+
WxRubyPersistenceManager* wxrb_pm =
|
189
|
+
dynamic_cast<WxRubyPersistenceManager*> (&wxPersistenceManager::Get());
|
190
|
+
if (wxrb_pm) wxrb_pm->UnregisterRbPO(rb_obj);
|
191
|
+
}
|
192
|
+
|
193
|
+
void WxRubyPersistenceManager::GC_markPO()
|
194
|
+
{
|
195
|
+
rb_object_to_rb_po_map_t::iterator it;
|
196
|
+
for( it = rb_object_po_map_.begin(); it != rb_object_po_map_.end(); ++it )
|
197
|
+
{
|
198
|
+
rb_gc_mark(it->first);
|
199
|
+
rb_gc_mark(it->second);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
static void wxRuby_markPersistentObjects()
|
204
|
+
{
|
205
|
+
WxRubyPersistenceManager* wxrb_pm =
|
206
|
+
dynamic_cast<WxRubyPersistenceManager*> (&wxPersistenceManager::Get());
|
207
|
+
if (wxrb_pm) wxrb_pm->GC_markPO();
|
208
|
+
}
|
209
|
+
__HEREDOC
|
210
|
+
spec.add_extend_code 'wxPersistenceManager', <<~__HEREDOC
|
211
|
+
VALUE Register(VALUE obj)
|
212
|
+
{
|
213
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
214
|
+
VALUE rb_po = rb_funcall(obj, create_po_id(), 0);
|
215
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
216
|
+
{
|
217
|
+
void* ptr;
|
218
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, SWIG_POINTER_DISOWN);
|
219
|
+
if (!SWIG_IsOK(res))
|
220
|
+
{
|
221
|
+
rb_raise(rb_eRuntimeError, "Unable to create Wx::PersistentObject for object");
|
222
|
+
}
|
223
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
224
|
+
if ($self->Register(po->GetObject(), po))
|
225
|
+
{
|
226
|
+
wxrb_pm->RegisterRbPO(obj, rb_po);
|
227
|
+
return rb_po;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
return Qnil;
|
231
|
+
}
|
232
|
+
|
233
|
+
VALUE Register(VALUE obj, VALUE rb_po)
|
234
|
+
{
|
235
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
236
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
237
|
+
{
|
238
|
+
void* ptr;
|
239
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, SWIG_POINTER_DISOWN);
|
240
|
+
if (!SWIG_IsOK(res))
|
241
|
+
{
|
242
|
+
rb_raise(rb_eRuntimeError, "Unable to create Wx::PersistentObject for object");
|
243
|
+
}
|
244
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
245
|
+
if ($self->Register(po->GetObject(), po))
|
246
|
+
{
|
247
|
+
wxrb_pm->RegisterRbPO(obj, rb_po);
|
248
|
+
return rb_po;
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return Qnil;
|
252
|
+
}
|
253
|
+
|
254
|
+
VALUE Find(VALUE obj)
|
255
|
+
{
|
256
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
257
|
+
VALUE rb_po = wxrb_pm ? wxrb_pm->FindRbPO(obj) : Qnil;
|
258
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
259
|
+
{
|
260
|
+
void* ptr;
|
261
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, 0);
|
262
|
+
if (!SWIG_IsOK(res))
|
263
|
+
{
|
264
|
+
rb_raise(rb_eRuntimeError, "Invalid Wx::PersistentObject for object");
|
265
|
+
}
|
266
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
267
|
+
if ($self->Find(po->GetObject()))
|
268
|
+
return rb_po;
|
269
|
+
}
|
270
|
+
return Qnil;
|
271
|
+
}
|
272
|
+
|
273
|
+
void Unregister(VALUE obj)
|
274
|
+
{
|
275
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
276
|
+
VALUE rb_po = wxrb_pm ? wxrb_pm->FindRbPO(obj) : Qnil;
|
277
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
278
|
+
{
|
279
|
+
void* ptr;
|
280
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, 0);
|
281
|
+
if (!SWIG_IsOK(res))
|
282
|
+
{
|
283
|
+
rb_raise(rb_eRuntimeError, "Invalid Wx::PersistentObject for object");
|
284
|
+
}
|
285
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
286
|
+
$self->Unregister(po->GetObject());
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
void Save(VALUE obj)
|
291
|
+
{
|
292
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
293
|
+
VALUE rb_po = wxrb_pm ? wxrb_pm->FindRbPO(obj) : Qnil;
|
294
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
295
|
+
{
|
296
|
+
void* ptr;
|
297
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, 0);
|
298
|
+
if (!SWIG_IsOK(res))
|
299
|
+
{
|
300
|
+
rb_raise(rb_eRuntimeError, "Invalid Wx::PersistentObject for object");
|
301
|
+
}
|
302
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
303
|
+
$self->Save(po->GetObject());
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
bool Restore(VALUE obj)
|
308
|
+
{
|
309
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
310
|
+
VALUE rb_po = wxrb_pm ? wxrb_pm->FindRbPO(obj) : Qnil;
|
311
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
312
|
+
{
|
313
|
+
void* ptr;
|
314
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, 0);
|
315
|
+
if (!SWIG_IsOK(res))
|
316
|
+
{
|
317
|
+
rb_raise(rb_eRuntimeError, "Invalid Wx::PersistentObject for object");
|
318
|
+
}
|
319
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
320
|
+
return $self->Restore(po->GetObject());
|
321
|
+
}
|
322
|
+
return false;
|
323
|
+
}
|
324
|
+
|
325
|
+
void SaveAndUnregister(VALUE obj)
|
326
|
+
{
|
327
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
328
|
+
VALUE rb_po = wxrb_pm ? wxrb_pm->FindRbPO(obj) : Qnil;
|
329
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
330
|
+
{
|
331
|
+
void* ptr;
|
332
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, 0);
|
333
|
+
if (!SWIG_IsOK(res))
|
334
|
+
{
|
335
|
+
rb_raise(rb_eRuntimeError, "Invalid Wx::PersistentObject for object");
|
336
|
+
}
|
337
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
338
|
+
$self->Save(po->GetObject());
|
339
|
+
$self->Unregister(po->GetObject());
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
343
|
+
bool RegisterAndRestore(VALUE obj)
|
344
|
+
{
|
345
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
346
|
+
VALUE rb_po = rb_funcall(obj, create_po_id(), 0);
|
347
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
348
|
+
{
|
349
|
+
void* ptr;
|
350
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, SWIG_POINTER_DISOWN);
|
351
|
+
if (!SWIG_IsOK(res))
|
352
|
+
{
|
353
|
+
rb_raise(rb_eRuntimeError, "Unable to create Wx::PersistentObject for object");
|
354
|
+
}
|
355
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
356
|
+
if ($self->Register(po->GetObject(), po))
|
357
|
+
{
|
358
|
+
wxrb_pm->RegisterRbPO(obj, rb_po);
|
359
|
+
return $self->Restore(po->GetObject());
|
360
|
+
}
|
361
|
+
}
|
362
|
+
return false;
|
363
|
+
}
|
364
|
+
|
365
|
+
bool RegisterAndRestore(VALUE obj, VALUE rb_po)
|
366
|
+
{
|
367
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
368
|
+
if (!NIL_P(rb_po) && wxrb_pm)
|
369
|
+
{
|
370
|
+
void* ptr;
|
371
|
+
int res = SWIG_ConvertPtr(rb_po, &ptr, SWIGTYPE_p_wxPersistentObject, SWIG_POINTER_DISOWN);
|
372
|
+
if (!SWIG_IsOK(res))
|
373
|
+
{
|
374
|
+
rb_raise(rb_eRuntimeError, "Unable to create Wx::PersistentObject for object");
|
375
|
+
}
|
376
|
+
wxPersistentObject* po = reinterpret_cast< wxPersistentObject * >(ptr);
|
377
|
+
if ($self->Register(po->GetObject(), po))
|
378
|
+
{
|
379
|
+
wxrb_pm->RegisterRbPO(obj, rb_po);
|
380
|
+
return $self->Restore(po->GetObject());
|
381
|
+
}
|
382
|
+
}
|
383
|
+
return false;
|
384
|
+
}
|
385
|
+
|
386
|
+
bool SaveValue(const wxPersistentObject& who, const wxString& name, VALUE value)
|
387
|
+
{
|
388
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
389
|
+
return wxrb_pm ? wxrb_pm->DoSaveRubyValue(who, name, value) : false;
|
390
|
+
}
|
391
|
+
|
392
|
+
VALUE RestoreValue(const wxPersistentObject& who, const wxString& name)
|
393
|
+
{
|
394
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> ($self);
|
395
|
+
return wxrb_pm ? wxrb_pm->DoRestoreRubyValue(who, name) : Qnil;
|
396
|
+
}
|
397
|
+
__HEREDOC
|
398
|
+
spec.add_init_code <<~__HEREDOC
|
399
|
+
// install the default global wxRuby persistence manager
|
400
|
+
wxPersistenceManager::Set(s_wxruby_persistence_manager);
|
401
|
+
// and the persistent object marker
|
402
|
+
wxRuby_AppendMarker(wxRuby_markPersistentObjects);
|
403
|
+
__HEREDOC
|
404
|
+
end
|
405
|
+
|
406
|
+
end # class PersistenceManager
|
407
|
+
|
408
|
+
end # class Director
|
409
|
+
|
410
|
+
end # module WXRuby3
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
###
|
6
|
+
# wxRuby3 wxWidgets interface director
|
7
|
+
###
|
8
|
+
|
9
|
+
module WXRuby3
|
10
|
+
|
11
|
+
class Director
|
12
|
+
|
13
|
+
class PersistentObject < Director
|
14
|
+
|
15
|
+
def setup
|
16
|
+
super
|
17
|
+
spec.gc_as_marked
|
18
|
+
spec.add_header_code <<~__HEREDOC
|
19
|
+
#include "wxruby-Persistence.h"
|
20
|
+
|
21
|
+
WxRubyPersistentObject::WxRubyPersistentObject(VALUE rb_obj)
|
22
|
+
: wxPersistentObject((void*)rb_obj)
|
23
|
+
{}
|
24
|
+
|
25
|
+
WxRubyPersistentObject::~WxRubyPersistentObject()
|
26
|
+
{
|
27
|
+
if (this->GetObject())
|
28
|
+
WxRubyPersistenceManager::UnregisterPersistentObject(
|
29
|
+
reinterpret_cast<VALUE> (this->GetObject()));
|
30
|
+
}
|
31
|
+
__HEREDOC
|
32
|
+
spec.use_class_implementation 'wxPersistentObject', 'WxRubyPersistentObject'
|
33
|
+
spec.ignore %w[wxPersistentObject::GetObject wxPersistentObject::wxPersistentObject]
|
34
|
+
spec.ignore %w[wxCreatePersistentObject wxPersistentRegisterAndRestore]
|
35
|
+
spec.extend_interface 'wxPersistentObject',
|
36
|
+
'wxPersistentObject(VALUE rb_obj)',
|
37
|
+
visibility: 'protected'
|
38
|
+
spec.add_extend_code 'wxPersistentObject', <<~__HEREDOC
|
39
|
+
bool SaveValue(const wxString& name, VALUE value)
|
40
|
+
{
|
41
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> (&wxPersistenceManager::Get());
|
42
|
+
return wxrb_pm ? wxrb_pm->SaveRubyValue(*$self, name, value) : false;
|
43
|
+
}
|
44
|
+
VALUE RestoreValue(const wxString& name)
|
45
|
+
{
|
46
|
+
WxRubyPersistenceManager* wxrb_pm = dynamic_cast<WxRubyPersistenceManager*> (&wxPersistenceManager::Get());
|
47
|
+
return wxrb_pm ? wxrb_pm->RestoreRubyValue(*$self, name) : Qnil;
|
48
|
+
}
|
49
|
+
__HEREDOC
|
50
|
+
spec.add_extend_code 'wxPersistentObject', <<~__HEREDOC
|
51
|
+
VALUE GetObject()
|
52
|
+
{
|
53
|
+
WxRubyPersistentObject* rpo = dynamic_cast<WxRubyPersistentObject*> ($self);
|
54
|
+
if (rpo)
|
55
|
+
{
|
56
|
+
return reinterpret_cast<VALUE> (rpo->GetObject());
|
57
|
+
}
|
58
|
+
else
|
59
|
+
{
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
__HEREDOC
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end # class PersistentObject
|
67
|
+
|
68
|
+
end # class Director
|
69
|
+
|
70
|
+
end # module WXRuby3
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
###
|
6
|
+
# wxRuby3 wxWidgets interface director
|
7
|
+
###
|
8
|
+
|
9
|
+
module WXRuby3
|
10
|
+
|
11
|
+
class Director
|
12
|
+
|
13
|
+
class PersistentWindow < Director
|
14
|
+
|
15
|
+
def setup
|
16
|
+
spec.items << 'wxPersistentTLW' << 'wxPersistentBookCtrl' << 'wxPersistentTreeBookCtrl'
|
17
|
+
if Config.instance.wx_version >= '3.3.0'
|
18
|
+
# before 3.3.0 this was not properly available
|
19
|
+
spec.items << 'wxPersistentComboBox'
|
20
|
+
end
|
21
|
+
super
|
22
|
+
spec.gc_as_marked
|
23
|
+
spec.use_template_as_class('wxPersistentWindow', 'wxPersistentWindowBase')
|
24
|
+
spec.override_inheritance_chain('wxPersistentWindow', %w[wxPersistentObject])
|
25
|
+
spec.ignore 'wxPersistentWindow::wxPersistentWindow',
|
26
|
+
'wxPersistentWindow::Get',
|
27
|
+
ignore_doc: false
|
28
|
+
# make ctor protected because of pure virt methods
|
29
|
+
spec.extend_interface 'wxPersistentWindow',
|
30
|
+
'wxPersistentWindowBase(wxWindow *win)',
|
31
|
+
visibility: 'protected'
|
32
|
+
spec.add_header_code 'typedef wxWindow WindowType;'
|
33
|
+
spec.add_swig_code 'typedef wxWindow WindowType;'
|
34
|
+
spec.map 'WindowType *' => 'Wx::Window', swig: false do
|
35
|
+
map_in code: ''
|
36
|
+
map_out code: ''
|
37
|
+
end
|
38
|
+
spec.add_extend_code 'wxPersistentWindowBase', <<~__HEREDOC
|
39
|
+
wxWindow * GetObject()
|
40
|
+
{
|
41
|
+
return reinterpret_cast<wxWindow*> ($self->GetObject());
|
42
|
+
}
|
43
|
+
__HEREDOC
|
44
|
+
# wxPersistentTLW
|
45
|
+
spec.override_inheritance_chain('wxPersistentTLW', [{ 'wxPersistentWindowBase' => 'wxPersistentWindow' }, 'wxPersistentObject'])
|
46
|
+
# add method override missing from docs
|
47
|
+
spec.extend_interface 'wxPersistentTLW',
|
48
|
+
'virtual wxString GetKind() const override'
|
49
|
+
# wxPersistentBookCtrl
|
50
|
+
spec.override_inheritance_chain('wxPersistentBookCtrl', [{ 'wxPersistentWindowBase' => 'wxPersistentWindow' }, 'wxPersistentObject'])
|
51
|
+
# add method override missing from docs
|
52
|
+
spec.extend_interface 'wxPersistentBookCtrl',
|
53
|
+
'virtual wxString GetKind() const override'
|
54
|
+
# wxPersistentTreeBookCtrl
|
55
|
+
spec.override_inheritance_chain('wxPersistentTreeBookCtrl', ['wxPersistentBookCtrl', { 'wxPersistentWindowBase' => 'wxPersistentWindow' }, 'wxPersistentObject'])
|
56
|
+
# add method override missing from docs
|
57
|
+
spec.extend_interface 'wxPersistentTreeBookCtrl',
|
58
|
+
'virtual wxString GetKind() const override'
|
59
|
+
spec.do_not_generate :functions, :defines, :typedefs, :variables, :enums
|
60
|
+
if Config.instance.wx_version >= '3.0.0'
|
61
|
+
# wxPersistentComboBox
|
62
|
+
spec.override_inheritance_chain('wxPersistentComboBox', [{ 'wxPersistentWindowBase' => 'wxPersistentWindow' }, 'wxPersistentObject'])
|
63
|
+
# add method override missing from docs
|
64
|
+
spec.extend_interface 'wxPersistentComboBox',
|
65
|
+
'virtual wxString GetKind() const override'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -45,6 +45,10 @@ module WXRuby3
|
|
45
45
|
spec.add_swig_code %Q{typedef wxStaticBitmap::ScaleMode ScaleMode; }
|
46
46
|
spec.add_header_code %Q{typedef wxStaticBitmap::ScaleMode ScaleMode; }
|
47
47
|
defmod.items << def_genstatbmp
|
48
|
+
# as we already called super before adding wxGenericStaticBitmap the no_proxy settings from the
|
49
|
+
# base Window director are missing; just copy all those set for wxStaticBitmap
|
50
|
+
list = spec.no_proxies.select { |name| name.start_with?('wxStaticBitmap::') }
|
51
|
+
spec.no_proxy(*list.collect { |name| name.sub(/\AwxStaticBitmap::/, 'wxGenericStaticBitmap::')})
|
48
52
|
defmod
|
49
53
|
end
|
50
54
|
|
@@ -15,7 +15,7 @@ module WXRuby3
|
|
15
15
|
def setup
|
16
16
|
super
|
17
17
|
spec.items << 'wxTextCompleter' << 'wxTextCompleterSimple'
|
18
|
-
spec.
|
18
|
+
spec.gc_as_marked 'wxTextCompleter', 'wxTextCompleterSimple' # untracked but cached in Ruby
|
19
19
|
spec.gc_as_untracked 'wxTextEntry' # actually no GC control necessary as this is a mixin only
|
20
20
|
# turn wxTextEntry into a mixin module
|
21
21
|
spec.make_mixin 'wxTextEntry'
|
@@ -540,53 +540,53 @@ module WXRuby3
|
|
540
540
|
# check the preprocessed definitions
|
541
541
|
errors = []
|
542
542
|
warnings = []
|
543
|
-
|
544
|
-
|
543
|
+
# select eligible ClassDef
|
544
|
+
cls_items = def_items.select do |item|
|
545
|
+
Extractor::ClassDef === item && !item_ignored(item, doc_gen) &&
|
545
546
|
(!item.is_template? || template_as_class?(item.name)) &&
|
546
547
|
!is_folded_base?(item.name)
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
end
|
548
|
+
end
|
549
|
+
cls_items.each do |item|
|
550
|
+
intf_class_name = if item.is_template? || template_as_class?(item.name)
|
551
|
+
template_class_name(item.name)
|
552
|
+
else
|
553
|
+
item.name
|
554
|
+
end
|
555
|
+
# this should not happen
|
556
|
+
raise "Missing preprocessed data for class #{intf_class_name}" unless has_class_interface(intf_class_name)
|
557
|
+
# get the class's method registry
|
558
|
+
cls_mtdreg = class_interface_methods(intf_class_name)
|
559
|
+
# check all directly inherited generated methods
|
560
|
+
mtdlist = ::Set.new # remember handled signatures
|
561
|
+
base_list(item).each do |base_name|
|
562
|
+
# make sure the base class has been preprocessed
|
563
|
+
get_class_interface(package, base_name, doc_gen) unless has_class_interface(base_name)
|
564
|
+
# generate any required enum typemaps for inherited virtuals
|
565
|
+
gen_base_class_enum_typemaps(base_name, enum_maps)
|
566
|
+
# iterate the base class's method registrations
|
567
|
+
class_interface_methods(base_name).each_pair do |mtdsig, mtdreg|
|
568
|
+
# only check on methods we have not handled yet
|
569
|
+
if !mtdlist.include?(mtdsig)
|
570
|
+
# did we inherit a virtual method that was not proxied in the base
|
571
|
+
if mtdreg[:virtual] && !mtdreg[:proxy]
|
572
|
+
# # if we did NOT generate a wrapper override and we do not have the proxy suppressed we're in trouble
|
573
|
+
# if !cls_mtdreg.has_key?(mtdsig) && has_method_proxy?(item.name, mtdreg[:method])
|
574
|
+
# warnings << "* WARNING: disabling proxy for virtual method #{mtdreg[:method].signature} without wrapper implementation in class #{item.name} since it is NOT proxied in base class #{base_name}!"
|
575
|
+
# els
|
576
|
+
if cls_mtdreg.has_key?(mtdsig) && !cls_mtdreg[mtdsig][:extension] && !has_method_proxy?(item.name, cls_mtdreg[mtdsig][:method])
|
577
|
+
# if this is not a custom extension and we do have an override wrapper and no proxy this is unnecessary code bloat
|
578
|
+
warnings << " * WARNING: Unnecessary override #{mtdreg[:method].signature} in class #{item.name} for non-proxied base in #{base_name}. Ignoring."
|
579
|
+
cls_mtdreg[mtdsig][:ignore] = true
|
580
|
+
end
|
581
|
+
# or did we inherit a virtual method that was proxied in the base
|
582
|
+
# for which we DO generate a wrapper override
|
583
|
+
elsif mtdreg[:virtual] && mtdreg[:proxy] && cls_mtdreg.has_key?(mtdsig)
|
584
|
+
# if we do not have a proxy as well we're in trouble
|
585
|
+
if !has_method_proxy?(item, mtdreg[:method])
|
586
|
+
errors << "* ERROR: method #{mtdreg[:method].signature} is NOT proxied with an overriden wrapper implementation in class #{item.name} but is also implemented and proxied in base class #{base_name}!"
|
587
587
|
end
|
588
|
-
mtdlist << mtdsig
|
589
588
|
end
|
589
|
+
mtdlist << mtdsig
|
590
590
|
end
|
591
591
|
end
|
592
592
|
end
|