wxruby3 0.9.0.pre.beta.8 → 0.9.0.pre.beta.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5dbc9b814f9b51ac36a537fad27a58595d41536f68eafb17b7250b70b510d2f
4
- data.tar.gz: bd80ce942bd3e37ee334d5562a7fcc4462e640ced3b49449e68e7c9e12f7c784
3
+ metadata.gz: 392d24963cded73bac9b253b83e6206ed8c1841ea697d6ec0af4d54faaabd79a
4
+ data.tar.gz: 9715c643d176e5da3c2540f84a2698d551a3cff4d6f28488644d5d9e3d929da3
5
5
  SHA512:
6
- metadata.gz: 640e90f61107db26bf3f73e76fd5cc05843cc714621773bb807c6f14a4e93b911bb3a92e54f430644843d9c0d986cf8041d9b9ab7750f09f69dbb4517ea8a982
7
- data.tar.gz: 5ce36f28a19449a0fd3f20ed5a8133b490335e359f13bb118c325c5592a65f75881f02970a2270699af7d64338d0f06d409d01bd26d4a67c61ed3685d9b71f92
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.8'
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|
@@ -175,6 +175,19 @@ module WxRuby
175
175
  @editors.each { |e| e.find_close }
176
176
  end
177
177
 
178
+ def goto
179
+ res = Wx.get_number_from_user('Enter line number to go to.',
180
+ 'Line:',
181
+ 'Goto Line',
182
+ @editors[@edt_book.selection].current_line+1,
183
+ 1,
184
+ @editors[@edt_book.selection].line_count,
185
+ @frame)
186
+ if res >= 1
187
+ @editors[@edt_book.selection].goto_line(res-1)
188
+ end
189
+ end
190
+
178
191
  def page_from_id(id)
179
192
  if id >= ID::EDT_MIN_ID && id < (ID::EDT_MIN_ID+@edt_book.page_count)
180
193
  id - ID::EDT_MIN_ID
@@ -231,6 +244,7 @@ module WxRuby
231
244
  FIND_NEXT = Wx::ID_FORWARD
232
245
  FIND_PREV = Wx::ID_BACKWARD
233
246
  REPLACE = Wx::ID_REPLACE
247
+ GOTO = Wx::ID_JUMP_TO
234
248
  %i[
235
249
  RUN
236
250
  TOGGLE_THEME
@@ -268,6 +282,8 @@ module WxRuby
268
282
  menuEdit.append(ID::FIND_NEXT, "Find Next\tF3", 'Find next occurrence of the search phrase')
269
283
  menuEdit.append(ID::FIND_PREV, "Find Previous\tShift-F3", 'Find previous occurrence of the search phrase')
270
284
  menuEdit.append(ID::REPLACE, "Replace...\tCtrl-R", 'Show Replace Dialog')
285
+ menuEdit.append_separator
286
+ menuEdit.append(ID::GOTO, "Got to line...\tCtrl-G", 'Move to line number')
271
287
 
272
288
  menuView = Wx::Menu.new
273
289
  menuView.append(ID::TOGGLE_THEME, 'Display dark theme', 'Display dark theme', Wx::ITEM_CHECK)
@@ -354,6 +370,8 @@ module WxRuby
354
370
  evt_menu(ID::FIND_NEXT, :on_find_next)
355
371
  evt_menu(ID::FIND_PREV, :on_find_prev)
356
372
 
373
+ evt_menu(ID::GOTO, :on_goto)
374
+
357
375
  layout
358
376
  end
359
377
 
@@ -555,6 +573,10 @@ module WxRuby
555
573
  set_status_text('')
556
574
  end
557
575
 
576
+ def on_goto(_evt)
577
+ @editors.goto
578
+ end
579
+
558
580
  end
559
581
 
560
582
  end
@@ -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,35 +117,36 @@ 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
- # current wxWidgets Scintilla (Ruby lexer) version does not support these correctly
137
- # style_set_foreground(SCE_RB_HERE_DELIM, Wx::BLACK)
138
- # style_set_bold(SCE_RB_HERE_DELIM, true)
139
- # style_set_foreground(SCE_RB_HERE_Q, c_maroon)
140
- # style_set_foreground(SCE_RB_HERE_QQ, c_maroon)
141
- # style_set_foreground(SCE_RB_HERE_QX, c_maroon)
142
- # style_set_foreground(SCE_RB_STRING_Q, c_maroon)
143
- # style_set_foreground(SCE_RB_STRING_QQ, c_maroon)
144
- # style_set_foreground(SCE_RB_STRING_QX, c_maroon)
145
- # style_set_foreground(SCE_RB_STRING_QR, c_maroon)
146
- # style_set_foreground(SCE_RB_STRING_QW, c_maroon)
147
- bg = Wx::Colour.new('LightGray')
148
- fg = Wx::Colour.new('DarkCyan')
136
+ if Wx::WXWIDGETS_VERSION >= '3.3.0'
137
+ style_set_foreground(SCE_RB_HERE_DELIM, Wx::BLACK)
138
+ style_set_bold(SCE_RB_HERE_DELIM, true)
139
+ style_set_foreground(SCE_RB_HERE_Q, c_maroon)
140
+ style_set_foreground(SCE_RB_HERE_QQ, c_maroon)
141
+ style_set_foreground(SCE_RB_HERE_QX, c_maroon)
142
+ style_set_foreground(SCE_RB_STRING_Q, c_maroon)
143
+ style_set_foreground(SCE_RB_STRING_QQ, c_maroon)
144
+ style_set_foreground(SCE_RB_STRING_QX, c_maroon)
145
+ style_set_foreground(SCE_RB_STRING_QR, c_maroon)
146
+ style_set_foreground(SCE_RB_STRING_QW, c_maroon)
147
+ end
148
+ bg = Wx::Colour.new('Light Grey')
149
+ fg = Wx::Colour.new('Cadet Blue')
149
150
  set_fold_margin_colour(true, bg)
150
151
  set_fold_margin_hi_colour(true, bg)
151
152
  marker_set_foreground(Wx::STC::STC_MARKNUM_FOLDER, fg)
@@ -155,7 +156,8 @@ module WxRuby
155
156
  end
156
157
 
157
158
  def dark_theme
158
- bg = Wx::Colour.new('DarkSlateGray')
159
+ bg = Wx::Colour.new('Dark Slate Grey')
160
+ c_str = Wx::Colour.new('Lime Green')
159
161
  style_set_background(Wx::STC::STC_STYLE_DEFAULT, bg)
160
162
  style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE)
161
163
  style_clear_all
@@ -164,39 +166,40 @@ module WxRuby
164
166
  style_set_foreground(Wx::STC::STC_STYLE_INDENTGUIDE, bg);
165
167
  set_whitespace_background(true, bg)
166
168
  style_set_eol_filled(SCE_RB_DEFAULT, true)
167
- style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('Silver'))
169
+ style_set_foreground(SCE_RB_COMMENTLINE, Wx::Colour.new('Light Grey'))
168
170
  style_set_background(SCE_RB_COMMENTLINE, bg)
169
171
  style_set_bold(SCE_RB_COMMENTLINE, true)
170
- style_set_foreground(SCE_RB_WORD, Wx::Colour.new('Chocolate'))
172
+ style_set_foreground(SCE_RB_WORD, Wx::Colour.new('Coral'))
171
173
  style_set_background(SCE_RB_WORD, bg)
172
174
  style_set_bold(SCE_RB_WORD, true)
173
- style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('LightCyan'))
175
+ style_set_foreground(SCE_RB_OPERATOR, Wx::Colour.new('Light Grey'))
174
176
  style_set_background(SCE_RB_OPERATOR, bg)
175
177
  style_set_bold(SCE_RB_OPERATOR, true)
176
- style_set_foreground(SCE_RB_POD, Wx::Colour.new('Gray'))
178
+ style_set_foreground(SCE_RB_POD, Wx::Colour.new('Grey'))
177
179
  style_set_background(SCE_RB_POD, bg)
178
- style_set_foreground(SCE_RB_NUMBER, Wx::Colour.new('DeepSkyBlue'))
180
+ style_set_foreground(SCE_RB_NUMBER, Wx::Colour.new('Cyan'))
179
181
  style_set_background(SCE_RB_NUMBER, bg)
180
- style_set_foreground(SCE_RB_STRING, Wx::Colour.new('LimeGreen'))
182
+ style_set_foreground(SCE_RB_STRING, c_str)
181
183
  style_set_background(SCE_RB_STRING, bg)
182
- style_set_foreground(SCE_RB_CHARACTER, Wx::Colour.new('YellowGreen'))
184
+ style_set_foreground(SCE_RB_CHARACTER, Wx::Colour.new('Yellow Green'))
183
185
  style_set_background(SCE_RB_CHARACTER, bg)
184
186
  style_set_foreground(SCE_RB_SYMBOL, Wx::Colour.new('Gold'))
185
187
  style_set_background(SCE_RB_SYMBOL, bg)
186
188
  style_set_bold(SCE_RB_SYMBOL, true)
187
- # current wxWidgets Scintilla (Ruby lexer) version does not support these correctly
188
- # style_set_foreground(SCE_RB_HERE_DELIM, Wx::BLACK)
189
- # style_set_bold(SCE_RB_HERE_DELIM, true)
190
- # style_set_foreground(SCE_RB_HERE_Q, c_maroon)
191
- # style_set_foreground(SCE_RB_HERE_QQ, c_maroon)
192
- # style_set_foreground(SCE_RB_HERE_QX, c_maroon)
193
- # style_set_foreground(SCE_RB_STRING_Q, c_maroon)
194
- # style_set_foreground(SCE_RB_STRING_QQ, c_maroon)
195
- # style_set_foreground(SCE_RB_STRING_QX, c_maroon)
196
- # style_set_foreground(SCE_RB_STRING_QR, c_maroon)
197
- # style_set_foreground(SCE_RB_STRING_QW, c_maroon)
198
- bg = Wx::Colour.new('CadetBlue')
199
- fg = Wx::Colour.new('Chocolate')
189
+ if Wx::WXWIDGETS_VERSION >= '3.3.0'
190
+ style_set_foreground(SCE_RB_HERE_DELIM, Wx::Colour.new('Coral'))
191
+ style_set_bold(SCE_RB_HERE_DELIM, true)
192
+ style_set_foreground(SCE_RB_HERE_Q, c_str)
193
+ style_set_foreground(SCE_RB_HERE_QQ, c_str)
194
+ style_set_foreground(SCE_RB_HERE_QX, c_str)
195
+ style_set_foreground(SCE_RB_STRING_Q, c_str)
196
+ style_set_foreground(SCE_RB_STRING_QQ, c_str)
197
+ style_set_foreground(SCE_RB_STRING_QX, c_str)
198
+ style_set_foreground(SCE_RB_STRING_QR, c_str)
199
+ style_set_foreground(SCE_RB_STRING_QW, c_str)
200
+ end
201
+ bg = Wx::Colour.new('Cadet Blue')
202
+ fg = Wx::Colour.new('Coral')
200
203
  set_fold_margin_colour(true, bg)
201
204
  set_fold_margin_hi_colour(true, bg)
202
205
  marker_set_foreground(Wx::STC::STC_MARKNUM_FOLDER, fg)
@@ -212,7 +215,7 @@ module WxRuby
212
215
  start_pos = current_pos
213
216
  end_pos = length-1
214
217
  else
215
- start_pos = current_pos
218
+ start_pos = [0, current_pos - (@search_indicator ? @search_indicator.last : 0)].max
216
219
  end_pos = 0
217
220
  end
218
221
  pos, end_pos = find_text(start_pos, end_pos, txt, flags)
@@ -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
 
@@ -45,6 +45,24 @@ module WxRuby
45
45
  clear
46
46
  end
47
47
 
48
+ def get_line_count
49
+ number_of_lines
50
+ end
51
+ alias :line_count :get_line_count
52
+
53
+ def get_current_line
54
+ pos = insertion_point
55
+ _, line = position_to_xy(pos)
56
+ line
57
+ end
58
+ alias :current_line :get_current_line
59
+
60
+ def goto_line(line)
61
+ pos = xy_to_position(0, line)
62
+ self.show_position(pos)
63
+ self.insertion_point = pos
64
+ end
65
+
48
66
  def do_find(txt, forward, whole_word, match_case)
49
67
  options = (match_case ? 0 : Regexp::IGNORECASE)
50
68
  pattern = if whole_word
@@ -52,7 +70,12 @@ module WxRuby
52
70
  else
53
71
  ::Regexp.new(txt, options)
54
72
  end
55
- forward ? self.value.index(pattern, self.insertion_point) : self.value.rindex(pattern, self.insertion_point)
73
+ if forward
74
+ self.value.index(pattern, insertion_point)
75
+ else
76
+ start_pos = [0, insertion_point - (@search_indicator ? @search_indicator.last+1 : 0)].max
77
+ self.value.rindex(pattern, start_pos)
78
+ end
56
79
  end
57
80
 
58
81
  def indicator_clear_range(pos, len)
@@ -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.8
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-27 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