wxruby3 0.9.0.pre.beta.9 → 0.9.0.pre.beta.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce9e7bb6763fb08e50024b77b709a9cc94032933960dbdaee1b3a5f90acad71d
4
- data.tar.gz: 3d39f6499828d222e038a1bd4880af58befe24f887d2d73534213107f024bf46
3
+ metadata.gz: 392d24963cded73bac9b253b83e6206ed8c1841ea697d6ec0af4d54faaabd79a
4
+ data.tar.gz: 9715c643d176e5da3c2540f84a2698d551a3cff4d6f28488644d5d9e3d929da3
5
5
  SHA512:
6
- metadata.gz: a2a56a03af8da3b6fe6dc57192cf151218cd6f6bf2dca613cdfccae1851451fc7ecb75080cb530050e30f438bee6c8990106795218e6cc5601a033517b92b445
7
- data.tar.gz: 02b8069fda0d2c3a0237747650f081b1824787d72c9aaad98ce8ef78cbd6cb5a1752bda5e98539ba092bc786854b86e26141fa935c3cd58817290931d0f7c836
6
+ metadata.gz: a833c65595d26722ada2368508ed654861f12bb5936fd3b65d29a5a72ce5dcbbc052930bc7a198e4aaba9547d0d3e73facd4a8f995f4cb65ea051c0817c47335
7
+ data.tar.gz: f95957c8734b5f02f69977b8b937ec304946b4a8f171d40b25c8be7d70b4eae667878d541b76d49b4f2c8895bbebf191ac7e2b813877a3c67ff47f8687c7288f
@@ -340,38 +340,4 @@ WXRUBY_EXPORT void GC_mark_wxEvent(void *ptr)
340
340
  std::wcout << "< GC_mark_wxEvent : " << ptr << std::endl;
341
341
  #endif
342
342
  }
343
-
344
- // Prevents Ruby's GC sweeping up items that are stored as client data
345
- // Checks whether the C++ object is still around first...
346
- WXRUBY_EXPORT void GC_mark_wxControlWithItems(void* ptr)
347
- {
348
- #ifdef __WXRB_DEBUG__
349
- if (wxRuby_TraceLevel()>1)
350
- std::wcout << "> GC_mark_wxControlWithItems : " << ptr << std::endl;
351
- #endif
352
-
353
- if ( GC_IsWindowDeleted(ptr) )
354
- return;
355
-
356
- GC_mark_wxWindow(ptr);
357
-
358
- wxControlWithItems* wx_cwi = (wxControlWithItems*) ptr;
359
- int count = wx_cwi->GetCount();
360
- if ( count == 0 )
361
- return; // Empty control
362
- if ( ! wx_cwi->HasClientObjectData() && ! wx_cwi->HasClientUntypedData() )
363
- return; // Control containing only strings
364
-
365
- for (int i = 0; i < count; ++i)
366
- {
367
- VALUE object = (VALUE) wx_cwi->GetClientData(i);
368
- if ( object && object != Qnil )
369
- rb_gc_mark(object);
370
- }
371
-
372
- #ifdef __WXRB_DEBUG__
373
- if (wxRuby_TraceLevel()>1)
374
- std::wcout << "< GC_mark_wxControlWithItems : " << ptr << std::endl;
375
- #endif
376
- }
377
343
  %}
@@ -263,7 +263,7 @@ const int wxrb_trace_level = 0;
263
263
  #ifdef __WXRB_DEBUG__
264
264
  WXRUBY_EXPORT int wxRuby_TraceLevel()
265
265
  {
266
- return _wxrb_trace_level;
266
+ return wxrb_trace_level;
267
267
  }
268
268
  #endif
269
269
  %}
@@ -25,6 +25,13 @@ class Wx::Bitmap
25
25
  new(img, depth)
26
26
  end
27
27
 
28
+ # Create a new bitmap from an icon
29
+ def self.from_icon(icon)
30
+ bmp = self.new
31
+ bmp.copy_from_icon(icon)
32
+ bmp
33
+ end
34
+
28
35
  # Ruby methods that switch class are conventionally named to_foo
29
36
  alias :to_image :convert_to_image
30
37
 
@@ -1,3 +1,6 @@
1
+
2
+ require_relative './controlwithitems'
3
+
1
4
  class Wx::Choice
2
5
  alias :get_item_data :get_client_data
3
6
  alias :set_item_data :set_client_data
@@ -1,3 +1,6 @@
1
+
2
+ require_relative './controlwithitems'
3
+
1
4
  class Wx::ComboBox
2
5
  alias :get_item_data :get_client_data
3
6
  alias :set_item_data :set_client_data
@@ -1,10 +1,106 @@
1
1
  # Superclass of a variety of controls that display lists of items (eg
2
2
  # Choice, ListBox, CheckListBox)
3
3
  class Wx::ControlWithItems
4
- # Make these ruby enumerables so find, find_all, map etc are available
4
+
5
+ # Make these Ruby enumerables so find, find_all, map etc are available
5
6
  include Enumerable
7
+
6
8
  # Passes each valid item index into the passed block
7
9
  def each
8
- 0.upto(get_count - 1) { | i | yield i }
10
+ get_count.times { | i | yield i }
11
+ end
12
+
13
+ # We need to cache client data in Ruby variables as we cannot access items
14
+ # during the GC mark phase as for some platforms (WXMSW at least) that would
15
+ # involve calling methods that would break in that phase.
16
+
17
+ def client_data_store
18
+ @client_data ||= []
19
+ end
20
+ private :client_data_store
21
+
22
+ wx_set_client_data = instance_method :set_client_data
23
+ define_method :set_client_data do |item, data|
24
+ item = item.to_i
25
+ wx_set_client_data.bind(self).call(item, data)
26
+ client_data_store[item] = data
27
+ end
28
+
29
+ def get_client_data(item)
30
+ client_data_store[item.to_i]
31
+ end
32
+
33
+ wx_append = instance_method :append
34
+ define_method :append do |item, data=nil|
35
+ if data
36
+ if ::Array === item
37
+ if !(::Array === data)
38
+ ::Kernel.raise ::TypeError.new("Expected Array for argument 3")
39
+ elsif data.size != item.size
40
+ ::Kernel.raise ::ArgumentError.new("item and data array must be equal size")
41
+ end
42
+ offs = get_count
43
+ wx_append.bind(self).call(item)
44
+ item.size.times { |ix| set_client_data(offs+ix, data[ix]) }
45
+ else
46
+ wx_append.bind(self).call(item, data)
47
+ client_data_store[get_count-1] = data
48
+ end
49
+ else
50
+ wx_append.bind(self).call(item)
51
+ # no changes to data store
52
+ end
53
+ end
54
+
55
+ wx_insert = instance_method :insert
56
+ define_method :insert do |item, pos, data=nil|
57
+ if data
58
+ if ::Array === item
59
+ if !(::Array === data)
60
+ ::Kernel.raise ::TypeError.new("Expected Array for argument 3")
61
+ elsif data.size != item.size
62
+ ::Kernel.raise ::ArgumentError.new("item and data array must be equal size")
63
+ end
64
+ wx_insert.bind(self).call(item, pos)
65
+ client_data_store.insert(pos, *::Array.new(item.size))
66
+ item.size.times { |ix| set_client_data(pos+ix, data[ix]) }
67
+ else
68
+ wx_insert.bind(self).call(item, pos, data)
69
+ client_data_store.insert(pos, data)
70
+ end
71
+ else
72
+ wx_insert.bind(self).call(item, pos)
73
+ if ::Array === item
74
+ client_data_store.insert(pos, *::Array.new(item.size))
75
+ else
76
+ client_data_store.insert(pos, nil)
77
+ end
78
+ end
79
+ end
80
+
81
+ wx_set = instance_method :set
82
+ define_method :set do |items, data=nil|
83
+ if data
84
+ if !(::Array === data)
85
+ ::Kernel.raise ::TypeError.new("Expected Array for argument 2")
86
+ elsif data.size != items.size
87
+ ::Kernel.raise ::ArgumentError.new("items and data array must be equal size")
88
+ end
89
+ end
90
+ wx_set.bind(self).call(items)
91
+ client_data_store.clear
92
+ items.each_with_index { |item, ix| set_client_data(item, data[ix]) }
93
+ end
94
+
95
+ wx_clear = instance_method :clear
96
+ define_method :clear do
97
+ wx_clear.bind(self).call
98
+ client_data_store.clear
99
+ end
100
+
101
+ wx_delete = instance_method :delete
102
+ define_method :delete do |item|
103
+ wx_delete.bind(self).call(item.to_i)
104
+ client_data_store.slice!(item.to_i)
9
105
  end
10
106
  end
data/lib/wx/core/icon.rb CHANGED
@@ -14,12 +14,18 @@ class Wx::Icon
14
14
 
15
15
  def to_bitmap
16
16
  # for WXMSW platform Icon is not derived from Bitmap
17
- return self unless Wx::PLATFORM == 'WXMSW'
17
+ return self unless Wx::PLATFORM == 'WXMSW' || Wx::PLATFORM == 'WXOSX'
18
18
  bm = Wx::Bitmap.new
19
19
  bm.copy_from_icon(self)
20
20
  bm
21
21
  end
22
22
 
23
+ if Wx::PLATFORM == 'WXMSW' || Wx::PLATFORM == 'WXOSX'
24
+ def convert_to_image
25
+ to_bitmap.convert_to_image
26
+ end
27
+ end
28
+
23
29
  # Redefine the initialize method so it raises an exception if a
24
30
  # non-existent file is given to the constructor; otherwise, wx Widgets
25
31
  # just carries on with an empty icon, which may cause faults
@@ -1,3 +1,14 @@
1
+
1
2
  class Wx::ImageList
3
+
4
+ # provide seamless support for adding icons on all platforms
5
+ wx_add = instance_method :add
6
+ define_method :add do |*args|
7
+ if Wx::Icon === args.first
8
+ args[0] = args.first.to_bitmap
9
+ end
10
+ wx_add.bind(self).call(*args)
11
+ end
12
+
2
13
  alias :<< :add
3
14
  end
@@ -1,3 +1,6 @@
1
+
2
+ require_relative './controlwithitems'
3
+
1
4
  class Wx::ListBox
2
5
  alias :get_item_data :get_client_data
3
6
  alias :set_item_data :set_client_data
@@ -0,0 +1,37 @@
1
+
2
+ class Wx::ProgressDialog
3
+
4
+ # Updates the dialog, setting the progress bar to the new value and updating the message if new one is specified.
5
+ #
6
+ # Returns <code>false</code> if the "Cancel" button has been pressed, <code>true</code> if neither "Cancel" nor
7
+ # "Skip" has been pressed and <code>:skipped</code> if "Skip" has been pressed.
8
+ #
9
+ # If false is returned, the application can either immediately destroy the dialog or ask the user for the confirmation
10
+ # and if the abort is not confirmed the dialog may be resumed with #resume method.
11
+ #
12
+ # If value is the maximum value for the dialog, the behaviour of the function depends on whether Wx::PD_AUTO_HIDE was
13
+ # used when the dialog was created. If it was, the dialog is hidden and the function returns immediately. If it was
14
+ # not, the dialog becomes a modal dialog and waits for the user to dismiss it, meaning that this function does not
15
+ # return until this happens.
16
+ #
17
+ # Notice that if newmsg is longer than the currently shown message, the dialog will be automatically made wider to
18
+ # account for it. However if the new message is shorter than the previous one, the dialog doesn't shrink back to
19
+ # avoid constant resizes if the message is changed often. To do this and fit the dialog to its current contents you
20
+ # may call fit explicitly. An alternative would be to keep the number of lines of text constant in order to avoid
21
+ # jarring dialog size changes. You may also want to make the initial message, specified when creating the dialog,
22
+ # wide enough to avoid having to resize the dialog later, e.g. by appending a long string of unbreakable spaces
23
+ # (wxString(L'\u00a0', 100)) to it.
24
+ # @param [Integer] value The new value of the progress meter. It should be less than or equal to the maximum value given to the constructor.
25
+ # @param [String] newmsg The new messages for the progress dialog text, if it is empty (which is the default) the message is not changed.
26
+ # @return [Boolean,:skipped]
27
+ def update(value, newmsg = '') end
28
+
29
+ # Like #update but makes the gauge control run in indeterminate mode.
30
+ #
31
+ # In indeterminate mode the remaining and the estimated time labels (if present) are set to "Unknown" or to newmsg
32
+ # (if it's non-empty). Each call to this function moves the progress bar a bit to indicate that some progress was done.
33
+ # @param [String] newmsg
34
+ # @return [Boolean,:skipped]
35
+ def pulse(newmsg = '') end
36
+
37
+ end
data/lib/wx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Wx
2
- WXRUBY_VERSION = '0.9.0-beta.9'
2
+ WXRUBY_VERSION = '0.9.0-beta.10'
3
3
  end
@@ -122,6 +122,9 @@ module WXRuby3
122
122
  @rescomp << ' --define __WXMSW__ --define wxUSE_DPI_AWARE_MANIFEST=2 --define wxUSE_RC_MANIFEST=1 --define ISOLATION_AWARE_ENABLED'
123
123
  @rescomp << ' --define WXUSINGDLL'
124
124
  @extra_cflags << '-DISOLATION_AWARE_ENABLED'
125
+ if @wx_version >= '3.3.0'
126
+ @extra_cflags << '-D_UNICODE' << '-DUNICODE'
127
+ end
125
128
  end
126
129
  end
127
130
  private :init_platform
@@ -70,7 +70,7 @@ static void wxRuby_SetActivationContext()
70
70
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
71
71
  (LPTSTR) &lpMsgBuf,
72
72
  0, NULL );
73
- ::fprintf(stderr, "Error in CreateActCtx : %s\n", lpMsgBuf);
73
+ std::wcerr << "Error in CreateActCtx : " << lpMsgBuf << std::endl;
74
74
  return;
75
75
  }
76
76
 
@@ -88,7 +88,7 @@ static void wxRuby_SetActivationContext()
88
88
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
89
89
  (LPTSTR) &lpMsgBuf,
90
90
  0, NULL );
91
- ::fprintf(stderr, "Error in ActivateActCtx : %s\n", lpMsgBuf);
91
+ std::wcerr << "Error in ActivateActCtx : " << lpMsgBuf << std::endl;
92
92
  }
93
93
  }
94
94
 
@@ -22,23 +22,40 @@ module WXRuby3
22
22
  wxEvtHandler
23
23
  wxObject])
24
24
  spec.ignore([
25
+ 'wxItemContainer::Append(const wxString &, wxClientData *)',
26
+ 'wxItemContainer::Append(const std::vector< wxString > &)',
27
+ 'wxItemContainer::Append(const wxArrayString &, wxClientData **)',
28
+ 'wxItemContainer::Append(unsigned int, const wxString *)',
29
+ 'wxItemContainer::Append(unsigned int, const wxString *, void **)',
30
+ 'wxItemContainer::Append(unsigned int, const wxString *, wxClientData **)',
31
+ 'wxItemContainer::Insert(const wxString &, unsigned int, wxClientData *)',
25
32
  'wxItemContainer::Insert(const std::vector< wxString > &)',
33
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)',
34
+ 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int)',
35
+ 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, void **)',
36
+ 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, wxClientData **)',
37
+ 'wxItemContainer::Set(const std::vector< wxString > &)',
38
+ 'wxItemContainer::Set(const wxArrayString &, wxClientData **)',
39
+ 'wxItemContainer::Set(unsigned int, const wxString *)',
40
+ 'wxItemContainer::Set(unsigned int, const wxString *, void **)',
41
+ 'wxItemContainer::Set(unsigned int, const wxString *, wxClientData **)',
42
+ 'wxItemContainer::DetachClientObject',
43
+ 'wxItemContainer::HasClientObjectData',
26
44
  'wxItemContainer::GetClientObject',
27
45
  'wxItemContainer::SetClientObject'])
46
+ spec.ignore([
47
+ 'wxItemContainer::Append(const wxArrayString &, void **)',
48
+ 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)',
49
+ 'wxItemContainer::Set(const wxArrayString &, void **)'], ignore_doc: false)
50
+ # for doc only
51
+ spec.map 'void** clientData' => 'Array', swig: false do
52
+ map_in code: ''
53
+ end
28
54
  spec.ignore(%w[wxItemContainer::GetClientData wxItemContainer::SetClientData], ignore_doc: false) # keep docs
29
- # Replace the old Wx definitions of these methods - which segfault
55
+ # Replace the old Wx definition of this method (which segfaults)
56
+ # Only need the setter as we cache data in Ruby and the getter
57
+ # therefor can be pure Ruby
30
58
  spec.add_extend_code('wxControlWithItems', <<~__HEREDOC
31
- VALUE get_client_data(int n) {
32
- // Avoid an assert failure if no data previously set
33
- if ( ! self->HasClientUntypedData() )
34
- return Qnil;
35
-
36
- VALUE returnVal = (VALUE) self->GetClientData(n);
37
- if ( ! returnVal )
38
- return Qnil;
39
- return returnVal;
40
- }
41
-
42
59
  VALUE set_client_data(int n, VALUE item_data) {
43
60
  self->SetClientData(n, (void *)item_data);
44
61
  return item_data;
@@ -51,13 +68,8 @@ module WXRuby3
51
68
  def setup_ctrl_with_items(clsnm)
52
69
  # used in GC phase so DO NOT trigger Ruby redirection
53
70
  spec.no_proxy "#{clsnm}::GetCount"
54
- spec.add_swig_code <<~__HEREDOC
55
- // adjust GC marker
56
- %markfunc #{clsnm} "GC_mark_wxControlWithItems";
57
- __HEREDOC
58
71
  spec.add_header_code <<~__HEREDOC
59
72
  extern swig_class cWxControlWithItems;
60
- WXRUBY_EXPORT void GC_mark_wxControlWithItems(void* ptr);
61
73
  __HEREDOC
62
74
  spec.no_proxy "#{clsnm}::GetStringSelection"
63
75
  end
@@ -107,72 +107,48 @@ module WXRuby3
107
107
  spec.do_not_generate(:functions, :enums, :defines)
108
108
  when 'wxDirDialog'
109
109
  when 'wxProgressDialog'
110
- # These two have problematic arguments; they accept a bool pointer
111
- # which will be set to true if "skip" was pressed since the last
112
- # update. Dealt with below.
113
110
  spec.make_concrete 'wxProgressDialog'
114
111
  spec.items << 'wxGenericProgressDialog'
115
112
  spec.fold_bases('wxProgressDialog' => 'wxGenericProgressDialog')
116
- spec.ignore(%w[wxGenericProgressDialog::Pulse wxGenericProgressDialog::Update], ignore_doc: false) # keep docs
117
- # TODO : add docs for Ruby specials
113
+ if Config.instance.windows?
114
+ # The native dialog implementation for WXMSW is not usable with wxRuby because
115
+ # of it's multi-threaded nature so we explicitly use the generic implementation here
116
+ # (on most or all other platforms that is implicitly so).
117
+ spec.use_class_implementation 'wxProgressDialog', 'wxGenericProgressDialog'
118
+ end
119
+ # These two have problematic arguments; they accept a bool pointer
120
+ # which will be set to true if "skip" was pressed since the last
121
+ # update. Dealt with below.
122
+ spec.ignore(%w[wxGenericProgressDialog::Pulse wxGenericProgressDialog::Update])
118
123
  spec.add_extend_code 'wxProgressDialog', <<~__HEREDOC
119
- // In wxRuby there are two versions of each of these methods, the
120
- // standard one which returns just true/false depending on whether it
121
- // has been aborted, and a special one which returns a pair of values,
122
- // true/false for "aborted" and then true/false for "skipped"
124
+ // In wxRuby we change the return value for these methods to be either:
125
+ // - false if canceled
126
+ // - true if not canceled nor skipped
127
+ // - :skipped if skipped
123
128
  VALUE pulse(VALUE rb_msg = Qnil)
124
129
  {
130
+ static WxRuby_ID skipped_id("skipped");
131
+
125
132
  wxString new_msg;
126
133
  if ( rb_msg == Qnil )
127
134
  new_msg = wxEmptyString;
128
135
  else
129
136
  new_msg = wxString( StringValuePtr(rb_msg), wxConvUTF8 );
130
137
 
131
- if ( $self->Pulse(new_msg) )
132
- return Qtrue;
133
- else
134
- return Qfalse;
135
- }
136
-
137
- VALUE pulse_and_check(VALUE rb_msg = Qnil)
138
- {
139
- VALUE ret = rb_ary_new();
140
-
141
- wxString new_msg;
142
- if ( rb_msg == Qnil )
143
- new_msg = wxEmptyString;
144
- else
145
- new_msg = wxString( StringValuePtr(rb_msg), wxConvUTF8 );
146
-
147
138
  bool skip = false;
148
139
  if ( $self->Pulse(new_msg, &skip) )
149
- rb_ary_push(ret, Qtrue);
150
- else
151
- rb_ary_push(ret, Qfalse);
152
-
153
- rb_ary_push(ret, ( skip ? Qtrue : Qfalse) );
154
-
155
- return ret;
156
- }
157
-
158
- VALUE update(int value, VALUE rb_msg = Qnil)
159
- {
160
- wxString new_msg;
161
- if ( rb_msg == Qnil )
162
- new_msg = wxEmptyString;
163
- else
164
- new_msg = wxString( StringValuePtr(rb_msg), wxConvUTF8 );
165
-
166
- if ( $self->Update(value, new_msg) )
167
- return Qtrue;
140
+ {
141
+ if (skip) return ID2SYM(skipped_id());
142
+ else return Qtrue;
143
+ }
168
144
  else
169
145
  return Qfalse;
170
146
  }
171
147
 
172
- VALUE update_and_check(int value, VALUE rb_msg = Qnil)
148
+ VALUE update(int value, VALUE rb_msg = Qnil)
173
149
  {
174
- VALUE ret = rb_ary_new();
175
-
150
+ static WxRuby_ID skipped_id("skipped");
151
+
176
152
  wxString new_msg;
177
153
  if ( rb_msg == Qnil )
178
154
  new_msg = wxEmptyString;
@@ -181,13 +157,12 @@ module WXRuby3
181
157
 
182
158
  bool skip = false;
183
159
  if ( $self->Update(value, new_msg, &skip) )
184
- rb_ary_push(ret, Qtrue);
185
- else
186
- rb_ary_push(ret, Qfalse);
187
-
188
- rb_ary_push(ret, ( skip ? Qtrue : Qfalse) );
189
-
190
- return ret;
160
+ {
161
+ if (skip) return ID2SYM(skipped_id());
162
+ else return Qtrue;
163
+ }
164
+ else
165
+ return Qfalse;
191
166
  }
192
167
  __HEREDOC
193
168
  when 'wxWizard'
@@ -11,7 +11,9 @@ module WXRuby3
11
11
 
12
12
  def setup
13
13
  spec.require_app 'wxImageList'
14
- spec.rename_for_ruby('AddIcon' => 'wxImageList::Add(const wxIcon &)')
14
+ if Config.instance.windows? || Config.instance.macosx?
15
+ spec.ignore('wxImageList::Add(const wxIcon &)', ignore_doc: false)
16
+ end
15
17
  super
16
18
  end
17
19
  end # class ImageList
@@ -13,6 +13,47 @@ module WXRuby3
13
13
 
14
14
  def setup
15
15
  super
16
+ # we need access to the wxPrintPreview maintained in the frame
17
+ # for GC marking so define a derived class for that.
18
+ spec.add_header_code <<~__HEREDOC
19
+ class WxRubyPreviewFrame : public wxPreviewFrame
20
+ {
21
+ public:
22
+ WxRubyPreviewFrame(wxPrintPreviewBase *preview,
23
+ wxWindow *parent,
24
+ const wxString& title = wxGetTranslation(wxASCII_STR("Print Preview")),
25
+ const wxPoint& pos = wxDefaultPosition,
26
+ const wxSize& size = wxDefaultSize,
27
+ long style = wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT,
28
+ const wxString& name = wxASCII_STR(wxFrameNameStr))
29
+ : wxPreviewFrame(preview, parent, title, pos, size, style, name)
30
+ {}
31
+ virtual ~WxRubyPreviewFrame() {}
32
+
33
+ const wxPrintPreview* get_print_preview() const
34
+ {
35
+ return dynamic_cast<const wxPrintPreview*> (this->m_printPreview);
36
+ }
37
+ };
38
+
39
+ static void GC_mark_wxPreviewFrame(void *ptr)
40
+ {
41
+ if ( GC_IsWindowDeleted(ptr) )
42
+ return;
43
+
44
+ // Do standard marking routines as for all wxWindows
45
+ GC_mark_wxWindow(ptr);
46
+
47
+ WxRubyPreviewFrame* preview_frame = dynamic_cast<WxRubyPreviewFrame*>((wxPreviewFrame*)ptr);
48
+ if (preview_frame)
49
+ {
50
+ const void* ptr = (const void*)preview_frame->get_print_preview();
51
+ rb_gc_mark(SWIG_RubyInstanceFor(const_cast<void*> (ptr)));
52
+ }
53
+ }
54
+ __HEREDOC
55
+ spec.use_class_implementation 'wxPreviewFrame', 'WxRubyPreviewFrame'
56
+ spec.add_swig_code '%markfunc wxPreviewFrame "GC_mark_wxPreviewFrame";'
16
57
  spec.rename_for_ruby('init' => 'wxPreviewFrame::Initialize')
17
58
  # We do not wrap the (undocumented) wxPrintPreviewBase so map this to wxPrintPreview what
18
59
  # in all cases will be the actual base being used.
@@ -15,15 +15,13 @@ module WXRuby3
15
15
  spec.disable_proxies # fixed and final data structures
16
16
  spec.items << 'wxPrintDialogData' << 'wxPageSetupDialogData'
17
17
  spec.ignore 'wxPrintDialogData::SetSetupDialog' # deprecated since 2.5.4
18
- # make wxPrintDialogData GC-safe
19
- spec.ignore 'wxPrintDialogData::GetPrintData'
20
- spec.add_extend_code 'wxPrintDialogData', <<~__HEREDOC
21
- wxPrintData* GetPrintData()
22
- { return new wxPrintData(self->GetPrintData()); }
23
- __HEREDOC
24
- spec.new_object 'wxPrintDialogData::GetPrintData'
18
+ # only keep the const version
25
19
  spec.ignore 'wxPageSetupDialogData::GetPrintData'
26
20
  spec.regard 'wxPageSetupDialogData::GetPrintData() const'
21
+ # for GetPrintData methods
22
+ spec.map 'wxPrintData&' => 'Wx::PrintData' do
23
+ map_out code: '$result = SWIG_NewPointerObj(SWIG_as_voidptr(new wxPrintData(*$1)), SWIGTYPE_p_wxPrintData, SWIG_POINTER_OWN);'
24
+ end
27
25
  spec.swig_import 'swig/classes/include/wxDefs.h'
28
26
  end
29
27
  end # class PrintData
@@ -36,6 +36,7 @@ DIALOGS_STYLED_BUSYINFO = 25
36
36
  DIALOGS_FIND = 26
37
37
  DIALOGS_REPLACE = 27
38
38
  DIALOGS_PREFS = 28
39
+ DIALOGS_PREFS_TOOLBOOK = 29
39
40
 
40
41
  class MyTipProvider < TipProvider
41
42
  TIPS = [
@@ -147,16 +148,18 @@ end
147
148
  # PropertySheetDialog is specialised for doing preferences dialogs; it
148
149
  # contains a BookCtrl of some sort
149
150
  class MyPrefsDialog < Wx::PropertySheetDialog
150
- def initialize(parent)
151
+ def initialize(parent, pref_type)
151
152
  # Using Book type other than Notebook needs two-step construction
152
153
  super()
153
- self.sheet_style = Wx::PROPSHEET_BUTTONTOOLBOOK
154
- self.sheet_outer_border = 1
155
- self.sheet_inner_border = 2
156
- img_list = Wx::ImageList.new(32, 32)
157
- img_list << std_bitmap(Wx::ART_NORMAL_FILE)
158
- img_list << std_bitmap(Wx::ART_CDROM)
159
- img_list << std_bitmap(Wx::ART_REPORT_VIEW)
154
+ if pref_type == DIALOGS_PREFS_TOOLBOOK
155
+ self.sheet_style = Wx::PROPSHEET_BUTTONTOOLBOOK
156
+ self.sheet_outer_border = 1
157
+ self.sheet_inner_border = 2
158
+ img_list = Wx::ImageList.new(32, 32)
159
+ img_list << std_bitmap(Wx::ART_NORMAL_FILE)
160
+ img_list << std_bitmap(Wx::ART_CDROM)
161
+ img_list << std_bitmap(Wx::ART_REPORT_VIEW)
162
+ end
160
163
 
161
164
  create(parent, -1, "Preferences")
162
165
  create_buttons(Wx::ID_OK|Wx::ID_CANCEL)
@@ -247,40 +250,41 @@ class MyFrame < Frame
247
250
  @index = -1
248
251
  @index_2 = -1
249
252
 
250
- @max = 10
253
+ @max = 100
251
254
 
252
255
  create_status_bar()
253
256
 
254
- evt_menu(DIALOGS_CHOOSE_COLOUR) {|event| on_choose_colour(event) }
255
- evt_menu(DIALOGS_CHOOSE_FONT) {|event| on_choose_font(event) }
256
- evt_menu(DIALOGS_LOG_DIALOG) {|event| on_log_dialog(event) }
257
- evt_menu(DIALOGS_MESSAGE_BOX) {|event| on_message_box(event) }
258
- evt_menu(DIALOGS_TEXT_ENTRY) {|event| on_text_entry(event) }
259
- evt_menu(DIALOGS_PASSWORD_ENTRY) {|event| on_password_entry(event) }
260
- evt_menu(DIALOGS_NUM_ENTRY) {|event| on_numeric_entry(event) }
261
- evt_menu(DIALOGS_SINGLE_CHOICE) {|event| on_single_choice(event) }
262
- evt_menu(DIALOGS_MULTI_CHOICE) {|event| on_multi_choice(event) }
263
- evt_menu(DIALOGS_FILE_OPEN) {|event| on_file_open(event) }
264
- evt_menu(DIALOGS_FILE_OPEN2) {|event| on_file_open2(event) }
265
- evt_menu(DIALOGS_FILES_OPEN) {|event| on_files_open(event) }
266
- evt_menu(DIALOGS_FILE_SAVE) {|event| on_file_save(event) }
267
- evt_menu(DIALOGS_DIR_CHOOSE) {|event| on_dir_choose(event) }
268
- evt_menu(DIALOGS_MODAL) {|event| on_modal_dlg(event) }
269
- evt_menu(DIALOGS_MODELESS) {|event| on_modeless_dlg(event) }
270
- evt_menu(DIALOGS_TIP) {|event| on_show_tip(event) }
271
- evt_menu(DIALOGS_CUSTOM_TIP) {|event| on_show_custom_tip(event) }
272
- evt_menu(DIALOGS_PROGRESS) {|event| on_show_progress(event) }
273
- evt_menu(DIALOGS_BUSYINFO) {|event| on_show_busy_info(event) }
274
- evt_menu(DIALOGS_STYLED_BUSYINFO) {|event| on_show_styled_busy_info(event) }
275
- evt_menu(DIALOGS_PREFS) {|event| on_show_prefs(event) }
276
- evt_menu(DIALOGS_FIND) {|event| on_show_find_dialog(event) }
277
- evt_menu(DIALOGS_REPLACE) {|event| on_show_replace_dialog(event) }
278
- evt_find(-1) {|event| on_find_dialog(event) }
279
- evt_find_next(-1) {|event| on_find_dialog(event) }
280
- evt_find_replace(-1) {|event| on_find_dialog(event) }
281
- evt_find_replace_all(-1) {|event| on_find_dialog(event) }
282
- evt_find_close(-1) {|event| on_find_dialog(event) }
283
- evt_menu(ID_EXIT) {|event| on_exit(event) }
257
+ evt_menu(DIALOGS_CHOOSE_COLOUR, :on_choose_colour)
258
+ evt_menu(DIALOGS_CHOOSE_FONT, :on_choose_font)
259
+ evt_menu(DIALOGS_LOG_DIALOG, :on_log_dialog)
260
+ evt_menu(DIALOGS_MESSAGE_BOX, :on_message_box)
261
+ evt_menu(DIALOGS_TEXT_ENTRY, :on_text_entry)
262
+ evt_menu(DIALOGS_PASSWORD_ENTRY, :on_password_entry)
263
+ evt_menu(DIALOGS_NUM_ENTRY, :on_numeric_entry)
264
+ evt_menu(DIALOGS_SINGLE_CHOICE, :on_single_choice)
265
+ evt_menu(DIALOGS_MULTI_CHOICE, :on_multi_choice)
266
+ evt_menu(DIALOGS_FILE_OPEN, :on_file_open)
267
+ evt_menu(DIALOGS_FILE_OPEN2, :on_file_open2)
268
+ evt_menu(DIALOGS_FILES_OPEN, :on_files_open)
269
+ evt_menu(DIALOGS_FILE_SAVE, :on_file_save)
270
+ evt_menu(DIALOGS_DIR_CHOOSE, :on_dir_choose)
271
+ evt_menu(DIALOGS_MODAL, :on_modal_dlg)
272
+ evt_menu(DIALOGS_MODELESS, :on_modeless_dlg)
273
+ evt_menu(DIALOGS_TIP, :on_show_tip)
274
+ evt_menu(DIALOGS_CUSTOM_TIP, :on_show_custom_tip)
275
+ evt_menu(DIALOGS_PROGRESS, :on_show_progress)
276
+ evt_menu(DIALOGS_BUSYINFO, :on_show_busy_info)
277
+ evt_menu(DIALOGS_STYLED_BUSYINFO, :on_show_styled_busy_info)
278
+ evt_menu(DIALOGS_PREFS, :on_show_prefs)
279
+ evt_menu(DIALOGS_PREFS_TOOLBOOK,:on_show_prefs)
280
+ evt_menu(DIALOGS_FIND, :on_show_find_dialog)
281
+ evt_menu(DIALOGS_REPLACE, :on_show_replace_dialog)
282
+ evt_find(-1, :on_find_dialog)
283
+ evt_find_next(-1, :on_find_dialog)
284
+ evt_find_replace(-1, :on_find_dialog)
285
+ evt_find_replace_all(-1, :on_find_dialog)
286
+ evt_find_close(-1, :on_find_dialog)
287
+ evt_menu(ID_EXIT, :on_exit)
284
288
 
285
289
  end
286
290
 
@@ -614,26 +618,37 @@ class MyFrame < Frame
614
618
 
615
619
 
616
620
  def on_show_prefs(event)
617
- MyPrefsDialog(self)
621
+ MyPrefsDialog(self, event.id)
618
622
  end
619
623
 
620
624
  def on_show_progress(event)
621
625
  cont = false
622
626
  Wx::ProgressDialog("Progress dialog example",
623
- "An informative message",
627
+ "An informative message\n"+"#{' '*100}\n\n\n\n",
624
628
  @max, # range
625
629
  self, # parent
626
- PD_CAN_ABORT | PD_APP_MODAL |
630
+ PD_CAN_ABORT | PD_CAN_SKIP | PD_APP_MODAL |
627
631
  PD_ELAPSED_TIME | PD_ESTIMATED_TIME |
628
632
  PD_REMAINING_TIME) do |dialog|
629
633
  cont = true
630
- (@max+1).times do |i|
631
- if i == @max
632
- cont = dialog.update(i, "That's all, folks!")
633
- elsif i == @max / 2
634
- cont = dialog.update(i, "Only half of it left (very long message)!")
635
- else
634
+ i = 0
635
+ while i <= @max
636
+ if i == 0
636
637
  cont = dialog.update(i)
638
+ elsif i == @max
639
+ cont = dialog.update(i, "That's all, folks!\n\nNothing more to see here any more.")
640
+ elsif i <= (@max / 2)
641
+ cont = dialog.pulse("Testing indeterminate mode\n" +
642
+ "\n" +
643
+ "This mode allows you to show to the user\n" +
644
+ "that something is going on even if you don't know\n" +
645
+ "when exactly will you finish.")
646
+ else
647
+ cont = dialog.update(i, "Now in standard determinate mode\n" +
648
+ "\n" +
649
+ "This is the standard usage mode in which you\n" +
650
+ "update the dialog after performing each new step of work.\n" +
651
+ "It requires knowing the total number of steps in advance.")
637
652
  end
638
653
 
639
654
  if !cont
@@ -644,8 +659,12 @@ class MyFrame < Frame
644
659
  break
645
660
  end
646
661
  dialog.resume
662
+ elsif cont == :skipped
663
+ i += (@max / 4)
664
+ i = @max-1 if i >= @max
647
665
  end
648
- sleep(1)
666
+ sleep(i == 0 ? 1 : 0.15)
667
+ i += 1
649
668
  end
650
669
  end
651
670
 
@@ -831,7 +850,8 @@ class MyApp < App
831
850
  file_menu.append(DIALOGS_PROGRESS, "Pro&gress dialog\tCtrl-G")
832
851
  file_menu.append(DIALOGS_BUSYINFO, "&Busy info dialog\tCtrl-B")
833
852
  file_menu.append(DIALOGS_STYLED_BUSYINFO, "Styled BusyInfo dialog")
834
- file_menu.append(DIALOGS_PREFS, "Propert&y sheet dialog\tCtrl-Y")
853
+ file_menu.append(DIALOGS_PREFS, "Standard propert&y sheet dialog\tCtrl-Y")
854
+ file_menu.append(DIALOGS_PREFS_TOOLBOOK, "&Toolbook property sheet dialog\tShift-Ctrl-Y")
835
855
  file_menu.append(DIALOGS_FIND, "&Find dialog\tCtrl-F", "", ITEM_CHECK)
836
856
  file_menu.append(DIALOGS_REPLACE, "Find and &replace dialog\tShift-Ctrl-F", "", ITEM_CHECK)
837
857
 
@@ -211,7 +211,7 @@ class MathsPanel < Panel
211
211
  # Display a dialog to save the image to a file
212
212
  def on_save
213
213
  SaveImageDialog(parent) do |dlg|
214
- if dlg.show_modal == ID_OK
214
+ if dlg.show_modal == Wx::ID_OK
215
215
  if dlg.image_type == Wx::BITMAP_TYPE_PNG
216
216
  # test writing to IO
217
217
  File.open(dlg.path, 'w') do |f|
@@ -38,12 +38,12 @@ end
38
38
  # otherwise samples using 'include Wx' (or other modules) will fail on referencing
39
39
  # a (module) method unscoped from one of these included modules
40
40
  module ::Kernel
41
- def method_missing(name, *args)
41
+ def method_missing(name, *args, &block)
42
42
  if self.class.name.start_with?('WxRuby::Sample::SampleLoader_') && (scope = self.class.name.split('::')).size > 3
43
43
  top_mod = Object.const_get(scope[0,3].join('::'))
44
- return top_mod.__send__(name, *args) if top_mod.respond_to?(name)
44
+ return top_mod.__send__(name, *args, &block) if top_mod.respond_to?(name)
45
45
  top_mod.included_modules.each do |imod|
46
- return imod.__send__(name, *args) if imod.respond_to?(name)
46
+ return imod.__send__(name, *args, &block) if imod.respond_to?(name)
47
47
  end
48
48
  end
49
49
  super
@@ -117,21 +117,21 @@ module WxRuby
117
117
  style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::BLACK);
118
118
  style_set_background(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE);
119
119
  style_clear_all
120
- style_set_foreground(Wx::STC::STC_STYLE_LINENUMBER, Wx::Colour.new('SlateGray'))
120
+ style_set_foreground(Wx::STC::STC_STYLE_LINENUMBER, Wx::Colour.new('Dark Grey'))
121
121
  style_set_background(Wx::STC::STC_STYLE_LINENUMBER, Wx::WHITE);
122
122
  style_set_foreground(Wx::STC::STC_STYLE_INDENTGUIDE, Wx::LIGHT_GREY);
123
- set_whitespace_background(false, Wx::Colour.new('DarkSlateGray'))
124
- style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('DARKGREEN'))
123
+ set_whitespace_background(false, Wx::Colour.new('Dark Slate Grey'))
124
+ style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('Dark Green'))
125
125
  style_set_bold(SCE_RB_COMMENTLINE, true)
126
126
  style_set_foreground(SCE_RB_WORD, Wx::BLACK)
127
127
  style_set_bold(SCE_RB_WORD, true)
128
- style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('Teal'))
128
+ style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('Dark Olive Green'))
129
129
  style_set_bold(SCE_RB_OPERATOR, true)
130
- style_set_foreground(SCE_RB_POD, Wx::Colour.new('GREY'))
130
+ style_set_foreground(SCE_RB_POD, Wx::Colour.new('Grey'))
131
131
  style_set_foreground(SCE_RB_NUMBER, Wx::BLUE)
132
132
  style_set_foreground(SCE_RB_STRING, c_maroon)
133
133
  style_set_foreground(SCE_RB_CHARACTER, Wx::RED)
134
- style_set_foreground(SCE_RB_SYMBOL, Wx::Colour.new('DARKBLUE'))
134
+ style_set_foreground(SCE_RB_SYMBOL, Wx::Colour.new('Navy'))
135
135
  style_set_bold(SCE_RB_SYMBOL, true)
136
136
  if Wx::WXWIDGETS_VERSION >= '3.3.0'
137
137
  style_set_foreground(SCE_RB_HERE_DELIM, Wx::BLACK)
@@ -145,8 +145,8 @@ module WxRuby
145
145
  style_set_foreground(SCE_RB_STRING_QR, c_maroon)
146
146
  style_set_foreground(SCE_RB_STRING_QW, c_maroon)
147
147
  end
148
- bg = Wx::Colour.new('LightGray')
149
- fg = Wx::Colour.new('DarkCyan')
148
+ bg = Wx::Colour.new('Light Grey')
149
+ fg = Wx::Colour.new('Cadet Blue')
150
150
  set_fold_margin_colour(true, bg)
151
151
  set_fold_margin_hi_colour(true, bg)
152
152
  marker_set_foreground(Wx::STC::STC_MARKNUM_FOLDER, fg)
@@ -156,8 +156,8 @@ module WxRuby
156
156
  end
157
157
 
158
158
  def dark_theme
159
- bg = Wx::Colour.new('DarkSlateGray')
160
- c_str = Wx::Colour.new('LimeGreen')
159
+ bg = Wx::Colour.new('Dark Slate Grey')
160
+ c_str = Wx::Colour.new('Lime Green')
161
161
  style_set_background(Wx::STC::STC_STYLE_DEFAULT, bg)
162
162
  style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE)
163
163
  style_clear_all
@@ -166,28 +166,28 @@ module WxRuby
166
166
  style_set_foreground(Wx::STC::STC_STYLE_INDENTGUIDE, bg);
167
167
  set_whitespace_background(true, bg)
168
168
  style_set_eol_filled(SCE_RB_DEFAULT, true)
169
- style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('Silver'))
169
+ style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('Light Grey'))
170
170
  style_set_background(SCE_RB_COMMENTLINE, bg)
171
171
  style_set_bold(SCE_RB_COMMENTLINE, true)
172
- style_set_foreground(SCE_RB_WORD, Wx::Colour.new('Chocolate'))
172
+ style_set_foreground(SCE_RB_WORD, Wx::Colour.new('Coral'))
173
173
  style_set_background(SCE_RB_WORD, bg)
174
174
  style_set_bold(SCE_RB_WORD, true)
175
- style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('LightCyan'))
175
+ style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('Light Grey'))
176
176
  style_set_background(SCE_RB_OPERATOR, bg)
177
177
  style_set_bold(SCE_RB_OPERATOR, true)
178
- style_set_foreground(SCE_RB_POD, Wx::Colour.new('Gray'))
178
+ style_set_foreground(SCE_RB_POD, Wx::Colour.new('Grey'))
179
179
  style_set_background(SCE_RB_POD, bg)
180
- style_set_foreground(SCE_RB_NUMBER, Wx::Colour.new('DeepSkyBlue'))
180
+ style_set_foreground(SCE_RB_NUMBER, Wx::Colour.new('Cyan'))
181
181
  style_set_background(SCE_RB_NUMBER, bg)
182
182
  style_set_foreground(SCE_RB_STRING, c_str)
183
183
  style_set_background(SCE_RB_STRING, bg)
184
- style_set_foreground(SCE_RB_CHARACTER, Wx::Colour.new('YellowGreen'))
184
+ style_set_foreground(SCE_RB_CHARACTER, Wx::Colour.new('Yellow Green'))
185
185
  style_set_background(SCE_RB_CHARACTER, bg)
186
186
  style_set_foreground(SCE_RB_SYMBOL, Wx::Colour.new('Gold'))
187
187
  style_set_background(SCE_RB_SYMBOL, bg)
188
188
  style_set_bold(SCE_RB_SYMBOL, true)
189
189
  if Wx::WXWIDGETS_VERSION >= '3.3.0'
190
- style_set_foreground(SCE_RB_HERE_DELIM, Wx::Colour.new('Chocolate'))
190
+ style_set_foreground(SCE_RB_HERE_DELIM, Wx::Colour.new('Coral'))
191
191
  style_set_bold(SCE_RB_HERE_DELIM, true)
192
192
  style_set_foreground(SCE_RB_HERE_Q, c_str)
193
193
  style_set_foreground(SCE_RB_HERE_QQ, c_str)
@@ -198,8 +198,8 @@ module WxRuby
198
198
  style_set_foreground(SCE_RB_STRING_QR, c_str)
199
199
  style_set_foreground(SCE_RB_STRING_QW, c_str)
200
200
  end
201
- bg = Wx::Colour.new('CadetBlue')
202
- fg = Wx::Colour.new('Chocolate')
201
+ bg = Wx::Colour.new('Cadet Blue')
202
+ fg = Wx::Colour.new('Coral')
203
203
  set_fold_margin_colour(true, bg)
204
204
  set_fold_margin_hi_colour(true, bg)
205
205
  marker_set_foreground(Wx::STC::STC_MARKNUM_FOLDER, fg)
@@ -35,9 +35,9 @@ module WxRuby
35
35
  end
36
36
 
37
37
  def dark_theme
38
- self.background_colour = Wx::Colour.new('DarkSlateGray')
38
+ self.background_colour = Wx::Colour.new('Dark Slate Grey')
39
39
  self.foreground_colour = Wx::WHITE
40
- self.set_default_style(txtatt = Wx::TextAttr.new(Wx::WHITE, Wx::Colour.new('DarkSlateGray'), self.font))
40
+ self.set_default_style(txtatt = Wx::TextAttr.new(Wx::WHITE, Wx::Colour.new('Dark Slate Grey'), self.font))
41
41
  self.set_style(0, self.get_last_position, txtatt)
42
42
  end
43
43
 
@@ -262,39 +262,41 @@ class MyTreeCtrl < Wx::TreeCtrl
262
262
  end
263
263
 
264
264
  def create_buttons_image_list(size)
265
- if size < 0
266
- self.buttons_image_list = nil
267
- return
268
- end
269
-
270
- # Make an image list containing small icons
271
- images = Wx::ImageList.new(size, size, true)
265
+ unless Wx::PLATFORM == 'WXMSW'
266
+ if size < 0
267
+ self.buttons_image_list = nil
268
+ return
269
+ end
272
270
 
273
- # should correspond to TreeCtrlIcon_xxx enum
274
- Wx::BusyCursor.busy do
275
- icons = if @alternate_images
276
- [Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon3.xpm'), Wx::BITMAP_TYPE_XPM),
277
- Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon3.xpm'), Wx::BITMAP_TYPE_XPM),
278
- Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon5.xpm'), Wx::BITMAP_TYPE_XPM),
279
- Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon5.xpm'), Wx::BITMAP_TYPE_XPM)
280
- ]
281
- else
282
- icon_size = Wx::Size.new(@image_size, @image_size)
283
- ic1 = Wx::ArtProvider::get_icon(Wx::ART_FOLDER, Wx::ART_LIST, icon_size)
284
- ic2 = Wx::ArtProvider::get_icon(Wx::ART_FOLDER_OPEN, Wx::ART_LIST, icon_size)
285
- [ic1, ic1, ic2, ic2]
286
- end
271
+ # Make an image list containing small icons
272
+ images = Wx::ImageList.new(size, size, true)
287
273
 
288
- icons.each do |ic|
289
- if ic.width == size
290
- images.add(ic)
291
- else
292
- resized = ic.convert_to_image.rescale(size, size)
293
- images.add(Wx::Bitmap.new(resized))
274
+ # should correspond to TreeCtrlIcon_xxx enum
275
+ Wx::BusyCursor.busy do
276
+ icons = if @alternate_images
277
+ [Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon3.xpm'), Wx::BITMAP_TYPE_XPM),
278
+ Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon3.xpm'), Wx::BITMAP_TYPE_XPM),
279
+ Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon5.xpm'), Wx::BITMAP_TYPE_XPM),
280
+ Wx::Icon.new(File.join(File.dirname(__FILE__), 'icon5.xpm'), Wx::BITMAP_TYPE_XPM)
281
+ ]
282
+ else
283
+ icon_size = Wx::Size.new(@image_size, @image_size)
284
+ ic1 = Wx::ArtProvider::get_icon(Wx::ART_FOLDER, Wx::ART_LIST, icon_size)
285
+ ic2 = Wx::ArtProvider::get_icon(Wx::ART_FOLDER_OPEN, Wx::ART_LIST, icon_size)
286
+ [ic1, ic1, ic2, ic2]
287
+ end
288
+
289
+ icons.each do |ic|
290
+ if ic.width == size
291
+ images.add(ic)
292
+ else
293
+ resized = ic.convert_to_image.rescale(size, size)
294
+ images.add(Wx::Bitmap.new(resized))
295
+ end
294
296
  end
295
- end
296
297
 
297
- self.buttons_image_list = images
298
+ self.buttons_image_list = images
299
+ end
298
300
  end
299
301
  end
300
302
 
@@ -1454,7 +1456,7 @@ class MyFrame < Wx::Frame
1454
1456
  end
1455
1457
 
1456
1458
  def on_toggle_buttons(event)
1457
- unless Wx.has_feature?(:WXMSW)
1459
+ unless Wx::PLATFORM == 'WXMSW'
1458
1460
  if Wx::THE_APP.show_buttons
1459
1461
  @treectrl.create_buttons_image_list(-1)
1460
1462
  Wx::get_app.show_buttons = false
@@ -31,6 +31,73 @@ class TestItemData < Test::Unit::TestCase
31
31
  assert_retrievable_data(f.control, 0, { 'b' => 'B' })
32
32
  assert_retrievable_data(f.control, 1, 'string item data')
33
33
  assert_retrievable_data(f.control, 2, 42.3)
34
+
35
+ GC.start
36
+
37
+ # single item append; no data
38
+ f.control.append('integer')
39
+ assert_equal(4, f.control.count)
40
+ assert_equal('integer', f.control.get_string(3))
41
+ assert_equal(nil, f.control.get_item_data(3))
42
+
43
+ # single item append; with data
44
+ f.control.append('array', 110)
45
+ assert_equal(5, f.control.count)
46
+ assert_equal('array', f.control.get_string(4))
47
+ assert_equal(110, f.control.get_item_data(4))
48
+
49
+ # array item append; no data
50
+ f.control.append(%w[set tree bag])
51
+ assert_equal(8, f.control.count)
52
+ assert_equal(nil, f.control.get_item_data(5))
53
+ assert_equal(nil, f.control.get_item_data(7))
54
+
55
+ # array item append; with data
56
+ f.control.append(%w[object module class], ['O', 'M', 'C'])
57
+ assert_equal(11, f.control.count)
58
+ assert_equal('O', f.control.get_item_data(8))
59
+ assert_equal('C', f.control.get_item_data(10))
60
+
61
+ GC.start
62
+
63
+ # single item insert; no data
64
+ f.control.insert('integer2', 3)
65
+ assert_equal(12, f.control.count)
66
+ assert_equal('integer2', f.control.get_string(3))
67
+ assert_equal(nil, f.control.get_item_data(3))
68
+
69
+ # single item insert; with data
70
+ f.control.insert('array2', 4, 110)
71
+ assert_equal(13, f.control.count)
72
+ assert_equal('array2', f.control.get_string(4))
73
+ assert_equal(110, f.control.get_item_data(4))
74
+
75
+ # array item insert; no data
76
+ f.control.insert(%w[set2 tree2 bag2], 5)
77
+ assert_equal(16, f.control.count)
78
+ assert_equal(nil, f.control.get_item_data(5))
79
+ assert_equal(nil, f.control.get_item_data(7))
80
+
81
+ # array item insert; with data
82
+ f.control.insert(%w[object2 module2 class2], 8, ['O', 'M', 'C'])
83
+ assert_equal(19, f.control.count)
84
+ assert_equal('O', f.control.get_item_data(8))
85
+ assert_equal('C', f.control.get_item_data(10))
86
+
87
+ GC.start
88
+
89
+ # item delete
90
+ f.control.delete(8)
91
+ assert_equal(18, f.control.count)
92
+ assert_equal('M', f.control.get_item_data(8))
93
+
94
+ GC.start
95
+
96
+ # clear all
97
+ f.control.clear
98
+ assert_equal(0, f.control.count)
99
+
100
+ GC.start
34
101
  end
35
102
 
36
103
  def test_treectrl_itemdata
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wxruby3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.pre.beta.9
4
+ version: 0.9.0.pre.beta.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Corino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-28 00:00:00.000000000 Z
11
+ date: 2023-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -190,6 +190,7 @@ files:
190
190
  - lib/wx/doc/pg/pgeditor.rb
191
191
  - lib/wx/doc/pg/property_grid.rb
192
192
  - lib/wx/doc/pg/property_grid_interface.rb
193
+ - lib/wx/doc/progress_dialog.rb
193
194
  - lib/wx/doc/prt/page_setup_dialog.rb
194
195
  - lib/wx/doc/prt/print_data.rb
195
196
  - lib/wx/doc/prt/print_dialog.rb