wxruby 1.9.2-i386-mswin32 → 1.9.3-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/LICENSE +53 -53
  2. data/README +299 -299
  3. data/lib/wx/classes/app.rb +6 -0
  4. data/lib/wx/classes/checklistbox.rb +45 -30
  5. data/lib/wx/classes/clipboard.rb +16 -0
  6. data/lib/wx/classes/event.rb +5 -0
  7. data/lib/wx/classes/evthandler.rb +20 -10
  8. data/lib/wx/classes/grid.rb +38 -39
  9. data/lib/wx/classes/listctrl.rb +12 -0
  10. data/lib/wx/classes/mediactrl.rb +22 -0
  11. data/lib/wx/classes/menu.rb +6 -6
  12. data/lib/wx/classes/sound.rb +23 -0
  13. data/lib/wx/classes/styledtextctrl.rb +2 -2
  14. data/lib/wx/classes/treectrl.rb +26 -0
  15. data/lib/wx/keyword_ctors.rb +19 -5
  16. data/lib/wx/keyword_defs.rb +20 -0
  17. data/lib/wx/version.rb +1 -1
  18. data/lib/wx.rb +42 -42
  19. data/lib/wxruby2.exp +0 -0
  20. data/lib/wxruby2.lib +0 -0
  21. data/lib/wxruby2.so +0 -0
  22. data/samples/SAMPLES-LICENSE.TXT +17 -17
  23. data/samples/aui/aui.rb +8 -1
  24. data/samples/bigdemo/About.rbw +39 -39
  25. data/samples/bigdemo/ColorPanel.rbw +25 -25
  26. data/samples/bigdemo/GridSimple.rbw +80 -80
  27. data/samples/bigdemo/MDIDemo.rbw +59 -59
  28. data/samples/bigdemo/PopupMenu.rbw +151 -151
  29. data/samples/bigdemo/Sizers.rbw +545 -545
  30. data/samples/bigdemo/bigdemo.rb +826 -826
  31. data/samples/bigdemo/demoTemplate.rbw +37 -37
  32. data/samples/bigdemo/icons/choice.xpm +27 -27
  33. data/samples/bigdemo/icons/combo.xpm +27 -27
  34. data/samples/bigdemo/icons/copy.xpm +25 -25
  35. data/samples/bigdemo/icons/cut.xpm +24 -24
  36. data/samples/bigdemo/icons/gauge.xpm +27 -27
  37. data/samples/bigdemo/icons/help.xpm +25 -25
  38. data/samples/bigdemo/icons/list.xpm +27 -27
  39. data/samples/bigdemo/icons/mondrian.xpm +44 -44
  40. data/samples/bigdemo/icons/new.xpm +24 -24
  41. data/samples/bigdemo/icons/ogl.ico +0 -0
  42. data/samples/bigdemo/icons/ogl.xpm +45 -45
  43. data/samples/bigdemo/icons/open.xpm +26 -26
  44. data/samples/bigdemo/icons/paste.xpm +38 -38
  45. data/samples/bigdemo/icons/preview.xpm +26 -26
  46. data/samples/bigdemo/icons/print.xpm +26 -26
  47. data/samples/bigdemo/icons/radio.xpm +27 -27
  48. data/samples/bigdemo/icons/robert.xpm +415 -415
  49. data/samples/bigdemo/icons/save.xpm +25 -25
  50. data/samples/bigdemo/icons/smiles.xpm +39 -39
  51. data/samples/bigdemo/icons/smiley.xpm +42 -42
  52. data/samples/bigdemo/icons/stattext.xpm +24 -24
  53. data/samples/bigdemo/icons/test2.bmp +0 -0
  54. data/samples/bigdemo/icons/test2.xpm +79 -79
  55. data/samples/bigdemo/icons/text.xpm +27 -27
  56. data/samples/bigdemo/icons/tog1.xpm +38 -38
  57. data/samples/bigdemo/icons/tog2.xpm +38 -38
  58. data/samples/bigdemo/icons/wxwin16x16.xpm +25 -25
  59. data/samples/bigdemo/tips.txt +7 -7
  60. data/samples/bigdemo/utils.rb +11 -11
  61. data/samples/bigdemo/wxButton.rbw +66 -66
  62. data/samples/bigdemo/wxCalendarCtrl.rbw +72 -72
  63. data/samples/bigdemo/wxCheckBox.rbw +52 -52
  64. data/samples/bigdemo/wxCheckListBox.rbw +77 -77
  65. data/samples/bigdemo/wxChoice.rbw +49 -49
  66. data/samples/bigdemo/wxColourDialog.rbw +34 -34
  67. data/samples/bigdemo/wxComboBox.rbw +79 -79
  68. data/samples/bigdemo/wxDialog.rbw +92 -92
  69. data/samples/bigdemo/wxDirDialog.rbw +32 -32
  70. data/samples/bigdemo/wxFileDialog.rbw +39 -39
  71. data/samples/bigdemo/wxFileDialog_Save.rbw +38 -38
  72. data/samples/bigdemo/wxFindReplaceDialog.rbw +85 -85
  73. data/samples/bigdemo/wxFontDialog.rbw +176 -176
  74. data/samples/bigdemo/wxFrame.rbw +55 -55
  75. data/samples/bigdemo/wxGauge.rbw +73 -73
  76. data/samples/bigdemo/wxGrid.rbw +68 -68
  77. data/samples/bigdemo/wxListBox.rbw +142 -142
  78. data/samples/bigdemo/wxListCtrl_virtual.rbw +109 -109
  79. data/samples/bigdemo/wxMDIWindows.rbw +52 -52
  80. data/samples/bigdemo/wxMenu.rbw +238 -238
  81. data/samples/bigdemo/wxMessageDialog.rbw +30 -30
  82. data/samples/bigdemo/wxMultipleChoiceDialog.rbw +34 -34
  83. data/samples/bigdemo/wxNotebook.rbw +138 -138
  84. data/samples/bigdemo/wxProgressDialog.rbw +45 -45
  85. data/samples/bigdemo/wxRadioBox.rbw +74 -74
  86. data/samples/bigdemo/wxRadioButton.rbw +127 -127
  87. data/samples/bigdemo/wxSashWindow.rbw +94 -104
  88. data/samples/bigdemo/wxScrolledMessageDialog.rbw +59 -59
  89. data/samples/bigdemo/wxScrolledWindow.rbw +201 -201
  90. data/samples/bigdemo/wxSingleChoiceDialog.rbw +35 -35
  91. data/samples/bigdemo/wxSlider.rbw +44 -44
  92. data/samples/bigdemo/wxSpinButton.rbw +52 -52
  93. data/samples/bigdemo/wxSpinCtrl.rbw +53 -53
  94. data/samples/bigdemo/wxSplitterWindow.rbw +65 -65
  95. data/samples/bigdemo/wxStaticBitmap.rbw +53 -53
  96. data/samples/bigdemo/wxStaticText.rbw +57 -57
  97. data/samples/bigdemo/wxStatusBar.rbw +128 -128
  98. data/samples/bigdemo/wxTextCtrl.rbw +151 -151
  99. data/samples/bigdemo/wxTextEntryDialog.rbw +34 -34
  100. data/samples/bigdemo/wxToggleButton.rbw +51 -51
  101. data/samples/bigdemo/wxToolBar.rbw +133 -133
  102. data/samples/bigdemo/wxTreeCtrl.rbw +192 -192
  103. data/samples/calendar/calendar.rb +275 -275
  104. data/samples/caret/caret.rb +286 -286
  105. data/samples/caret/mondrian.xpm +44 -44
  106. data/samples/controls/controls.rb +1140 -1140
  107. data/samples/controls/get_item_sample.rb +87 -87
  108. data/samples/controls/icons/choice.xpm +27 -27
  109. data/samples/controls/icons/combo.xpm +27 -27
  110. data/samples/controls/icons/gauge.xpm +27 -27
  111. data/samples/controls/icons/list.xpm +27 -27
  112. data/samples/controls/icons/radio.xpm +27 -27
  113. data/samples/controls/icons/stattext.xpm +24 -24
  114. data/samples/controls/icons/text.xpm +27 -27
  115. data/samples/controls/mondrian.xpm +44 -44
  116. data/samples/dialogs/dialogs.rb +724 -724
  117. data/samples/dialogs/tips.txt +18 -18
  118. data/samples/drawing/graphics_drawing.rb +232 -0
  119. data/samples/{images → drawing}/images.rb +48 -48
  120. data/samples/{images → drawing}/paperclip.png +0 -0
  121. data/samples/etc/activation.rb +108 -108
  122. data/samples/etc/choice.rb +72 -72
  123. data/samples/etc/miniframe.rb +84 -84
  124. data/samples/etc/sash.rb +135 -135
  125. data/samples/etc/scrollwin.rb +116 -116
  126. data/samples/etc/system_settings.rb +258 -258
  127. data/samples/etc/wizard.rb +79 -79
  128. data/samples/grid/grid.rb +1 -0
  129. data/samples/listbook/listbook.rb +181 -181
  130. data/samples/listbook/listbook.xrc +370 -370
  131. data/samples/mdi/mdi.rb +87 -87
  132. data/samples/media/mediactrl.rb +173 -0
  133. data/samples/minimal/minimal.rb +85 -85
  134. data/samples/minimal/nothing.rb +21 -21
  135. data/samples/opengl/cube.rb +123 -0
  136. data/samples/sockets/SocketPackets.rb +27 -0
  137. data/samples/sockets/res/message-new.png +0 -0
  138. data/samples/sockets/res/user.png +0 -0
  139. data/samples/sockets/wxClient.rb +395 -0
  140. data/samples/sockets/wxServer.rb +422 -0
  141. data/samples/sockets/wxSocketGUI.rb +97 -0
  142. data/samples/text/textctrl.rb +124 -124
  143. data/samples/text/unicode.rb +238 -238
  144. data/samples/text/utf8.txt +14 -14
  145. data/samples/treectrl/treectrl.rb +1180 -1181
  146. data/samples/xrc/samples.xrc +46 -46
  147. data/samples/xrc/xrc_sample.rb +107 -107
  148. metadata +26 -9
  149. data/samples/images/Thumbs.db +0 -0
@@ -1,826 +1,826 @@
1
- #!/usr/bin/env ruby
2
- # Demo created by Robert Carlin,
3
- # based on the wxPython demo by Robin Dunn
4
- # Modified a bit by Kevin Smith and Roy Sutton
5
-
6
- # TODO:
7
- # Finish Scintilla integration
8
- # Fix 'Find Next'
9
- # Refactor editor pane
10
- # More samples
11
- # Finish 'rubification' of source
12
- # Fix non-scintilla code viewer
13
-
14
- begin
15
- require 'wx'
16
- rescue LoadError => no_wx_err
17
- begin
18
- require 'rubygems'
19
- require 'wx'
20
- rescue LoadError
21
- raise no_wx_err
22
- end
23
- end
24
-
25
- MENU_EXIT = 100
26
- TREE_ID = 101
27
-
28
- OVR_TEXT = "This is the WxRuby Demo. It was ported from the wxPython Demo, created by Robin Dunn. Many thanks to him for all his hard work - this demo is what it is because of him. Click on any of the items in the tree control to start the demo. Don't forget to check out the Demo Code tab - you can see the source code for each demo!\nHope you like it!"
29
-
30
- $tree_list = [
31
- #new stuff
32
- #['Recent Additions', [
33
- # 'wxMaskedNumCtrl',
34
- # 'FloatCanvas',
35
- # ]],
36
-
37
- # managed windows == things with a [optional] caption you can close
38
- ['Base Frames and Dialogs', [
39
- 'wxDialog',
40
- 'wxFrame',
41
- 'wxMDIWindows',
42
- 'wxMiniFrame',
43
- #'wxWizard',
44
- ]],
45
-
46
- # the common dialogs
47
- ['Common Dialogs', [
48
- 'wxColourDialog',
49
- 'wxDirDialog',
50
- 'wxFileDialog',
51
- 'wxFileDialog_Save',
52
- 'wxFindReplaceDialog',
53
- 'wxFontDialog',
54
- 'wxMessageDialog',
55
- #'wxPageSetupDialog',
56
- #'wxPrintDialog',
57
- 'wxProgressDialog',
58
- 'wxSingleChoiceDialog',
59
- 'wxTextEntryDialog',
60
- ]],
61
-
62
- # dialogs from libraries
63
- ['More Dialogs', [
64
- # 'ErrorDialogs',
65
- # 'ImageBrowser',
66
- 'wxMultipleChoiceDialog',
67
- 'wxScrolledMessageDialog'
68
- ]],
69
-
70
- # core controls
71
- ['Core Windows/Controls', [
72
- 'PopupMenu',
73
- 'wxBitmapButton',
74
- 'wxButton',
75
- 'wxCheckBox',
76
- 'wxCheckListBox',
77
- 'wxChoice',
78
- 'wxChoicebook',
79
- 'wxComboBox',
80
- 'wxGauge',
81
- 'wxGenericDirCtrl',
82
- 'wxGrid',
83
- #'wxGrid_MegaExample',
84
- 'wxListBox',
85
- #'wxListCtrl',
86
- 'wxListCtrl_virtual',
87
- 'wxMenu',
88
- 'wxNotebook',
89
- #'wxPopupWindow',
90
- 'wxRadioBox',
91
- 'wxRadioButton',
92
- 'wxSashWindow',
93
- 'wxScrolledWindow',
94
- 'wxSlider',
95
- 'wxSpinButton',
96
- 'wxSpinCtrl',
97
- 'wxSplitterWindow',
98
- 'wxStaticBitmap',
99
- 'wxStaticText',
100
- 'wxStatusBar',
101
- 'wxTextCtrl',
102
- 'wxToggleButton',
103
- 'wxToolBar',
104
- 'wxTreeCtrl',
105
- #'wxValidator',
106
- ]],
107
-
108
- # controls coming from other libraries
109
- ['More Windows/Controls', [
110
- #'wxFloatBar', deprecated
111
- #'wxMVCTree', deprecated
112
- #'wxRightTextCtrl', deprecated as we have wxTE_RIGHT now.
113
- #'AnalogClockWindow',
114
- #'ColourSelect',
115
- #'ContextHelp',
116
- #'FancyText',
117
- #'FloatCanvas',
118
- #'FileBrowseButton',
119
- #'GenericButtons',
120
- #'MaskedEditControls',
121
- #'SplitTree',
122
- #'TablePrint',
123
- #'Throbber',
124
- #'wxCalendar',
125
- 'wxCalendarCtrl',
126
- #'wxDynamicSashWindow',
127
- #'wxEditableListBox',
128
- #'wxEditor',
129
- #'wxHtmlWindow',
130
- #'wxIEHtmlWin',
131
- #'wxIntCtrl',
132
- #'wxLEDNumberCtrl',
133
- #'wxMimeTypesManager',
134
- #'wxMaskedNumCtrl',
135
- #'wxMultiSash',
136
- #'wxPopupControl',
137
- #'wxStyledTextCtrl_1',
138
- #'wxStyledTextCtrl_2',
139
- #'wxTimeCtrl',
140
- #'wxTreeListCtrl',
141
- ]],
142
-
143
- # How to lay out the controls in a frame/dialog
144
- ['Window Layout', [
145
- # 'LayoutAnchors',
146
- # 'Layoutf',
147
- # 'RowColSizer',
148
- 'Sizers',
149
- # 'wxScrolledPanel',
150
- # 'wxXmlResource',
151
- # 'wxXmlResourceHandler',
152
- ]],
153
-
154
- # ditto
155
- #['Process and Events', [
156
- # 'EventManager',
157
- # 'infoframe',
158
- # 'OOR',
159
- # 'PythonEvents',
160
- # 'Threads',
161
- # 'wxKeyEvents',
162
- # 'wxProcess',
163
- # 'wxTimer',
164
- # ]],
165
-
166
- #~ # Clipboard and DnD
167
- #~ ['Clipboard and DnD', [
168
- #~ #'CustomDragAndDrop',
169
- #~ 'DragAndDrop',
170
- #~ 'URLDragAndDrop',
171
- #~ ]],
172
-
173
- # Images
174
- ['Using Images', [
175
- # 'Throbber',
176
- 'wxArtProvider',
177
- 'wxCursor',
178
- 'wxDragImage',
179
- # 'wxImage',
180
- # 'wxImageFromStream',
181
- # 'wxMask',
182
- ]],
183
-
184
- # Other stuff
185
- ['Miscellaneous', [
186
- # 'ColourDB',
187
- # 'DialogUnits',
188
- # 'DrawXXXList',
189
- # 'FontEnumerator',
190
- # 'PrintFramework',
191
- 'ShapedWindow',
192
- # 'Throbber',
193
- # 'Unicode',
194
- # 'wxFileHistory',
195
- # 'wxJoystick',
196
- # 'wxOGL',
197
- # 'wxWave',
198
- ]],
199
-
200
- # need libs not coming with the demo
201
- #['Objects using an external library', [
202
- # 'ActiveXWrapper_Acrobat',
203
- # 'ActiveXWrapper_IE',
204
- # 'wxGLCanvas',
205
- # 'wxPlotCanvas',
206
- # ]],
207
-
208
-
209
- ['Check out the samples dir too', [
210
- ]],
211
-
212
- ]
213
-
214
- class DemoCodeViewer < Wx::TextCtrl
215
- def intialize(parent, id)
216
- super(parent, id, OVR_TEXT, Wx::DEFAULT_POSITION, Wx::Size.new(400, 400),
217
- Wx::TE_MULTILINE|Wx::TE_READONLY|Wx::HSCROLL|
218
- Wx::TE_RICH|Wx::TE_NOHIDESEL)
219
- end
220
- end
221
-
222
- class WxRubyDemo < Wx::Frame
223
- attr_accessor :otherWin
224
-
225
- def initialize(title, pos, size, style=Wx::DEFAULT_FRAME_STYLE)
226
- super(nil,-1,title,pos,size,style)
227
- @demoID = 6000
228
- @otherWin = nil
229
-
230
- icon_file = File.join(File.dirname(__FILE__), 'icons', 'mondrian.xpm')
231
- icon = Wx::Icon.new(icon_file, Wx::BITMAP_TYPE_XPM)
232
- set_icon(icon)
233
-
234
- @tbicon = DemoTaskBarIcon.new(self)
235
-
236
- evt_idle {|event| on_idle(event)}
237
- evt_close {|event| on_close(event)}
238
- evt_iconize {|event| on_iconize(event)}
239
- evt_maximize {|event| on_maximize(event)}
240
-
241
- centre(Wx::BOTH)
242
- create_status_bar(1, Wx::ST_SIZEGRIP)
243
- set_status_text("Welcome to the WxRuby Demo!")
244
-
245
- splitter = Wx::SplitterWindow.new(self, -1)
246
- splitter2 = Wx::SplitterWindow.new(splitter, -1)
247
-
248
- # Make a File menu
249
-
250
- @mainmenu = Wx::MenuBar.new
251
- menu = Wx::Menu.new
252
- menu.append(MENU_EXIT, "E&xit\tALT-X", "Get the heck outta here!")
253
- evt_menu(MENU_EXIT) {exit}
254
- @mainmenu.append(menu, "&File")
255
-
256
- # Make a Demo menu - thanks to Kevin Smith for figuring the submenus out!
257
- menu = Wx::Menu.new
258
- $tree_list.each do |item|
259
- @submenu = Wx::Menu.new
260
- item[1].each do |childItem|
261
- mID = @demoID += 1
262
- @submenu.append(mID, childItem)
263
- evt_menu(mID) {|event| on_demo_menu(childItem)}
264
- end
265
- menuItem = Wx::MenuItem.new(menu, 500000, item[0], "", Wx::ITEM_NORMAL, @submenu)
266
- menu.append_item(menuItem)
267
- end
268
- @mainmenu.append(menu, "&Demo")
269
-
270
- # Make a Help menu
271
- helpID = Wx::ID_ABOUT
272
- findID = @demoID += 1
273
- findnextID = @demoID += 1
274
- clearID = @demoID += 1
275
- menu = Wx::Menu.new
276
- menu.append(findID, "&Find\tCtrl-F", "Find in the Demo Code")
277
- menu.append(findnextID, "Find &Next\tF3", "Find Next")
278
- menu.append_separator
279
- menu.append(helpID, "&About\tCtrl-H", "wxRuby RULES!!!")
280
- evt_menu(helpID) {|event| on_help_about(event)}
281
- evt_menu(findID) {|event| on_help_find(event)}
282
- evt_menu(findnextID) {|event| on_find_next(event)}
283
- evt_find(-1) {|event| on_find(event)}
284
- evt_find_next(-1) {|event| on_find(event)}
285
- evt_find_close(-1) {|event| on_find_close(event)}
286
- @mainmenu.append(menu, "&Help")
287
- set_menu_bar(@mainmenu)
288
-
289
- @finddata = Wx::FindReplaceData.new()
290
-
291
- @treeMap = {}
292
- @tree = Wx::TreeCtrl.new(splitter, TREE_ID, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::TR_DEFAULT_STYLE)#, Wx::TR_HAS_BUTTONS | Wx::TR_HAS_VARIABLE_ROW_HEIGHT)
293
- root = @tree.add_root("wxRuby Overview")
294
- firstChild = nil
295
-
296
- $tree_list.each do |item|
297
- child = @tree.append_item(root, item[0])
298
- if not firstChild then firstChild = child end
299
- item[1].each do |childItem|
300
- theDemo = @tree.append_item(child, childItem)
301
- @treeMap[childItem] = theDemo
302
- end
303
- end
304
- @tree.expand(root)
305
- @tree.expand(firstChild)
306
-
307
- evt_tree_item_expanded(TREE_ID) {|event| on_item_expanded(event)}
308
- evt_tree_item_collapsed(TREE_ID) {|event| on_item_collapsed(event)}
309
- evt_tree_sel_changed(TREE_ID) {|event| on_tree_sel_changed(event)}
310
- evt_tree_item_activated(TREE_ID) {|event| on_tree_sel_changed(event)}
311
- @tree.evt_left_down {|event| on_tree_left_down(event)}
312
-
313
-
314
-
315
- # Create a Notebook
316
- @nb = Wx::Notebook.new(splitter2, -1, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::CLIP_CHILDREN)
317
-
318
- @ovr = Wx::TextCtrl.new(@nb, -1, OVR_TEXT, Wx::DEFAULT_POSITION,
319
- Wx::Size.new(400,400),
320
- Wx::TE_MULTILINE|Wx::TE_READONLY|
321
- Wx::TE_RICH|Wx::TE_NOHIDESEL)
322
- @nb.add_page(@ovr, "Overview")
323
-
324
- if Wx.const_defined?(:Scintilla)
325
- panel, @txt = setup_editor(@nb)
326
- @nb.add_page(panel, "Demo Code")
327
- else
328
- # FIXME: Should use DemoCodeViewer, but when we do (on Windows) it
329
- # puts all text on one line! Can remove instance_eval
330
- # once that's resolved
331
- @txt = Wx::TextCtrl.new(@nb, -1, OVR_TEXT, Wx::DEFAULT_POSITION,
332
- Wx::Size.new(400,400),
333
- Wx::TE_MULTILINE|Wx::TE_READONLY|
334
- Wx::HSCROLL|Wx::TE_RICH|Wx::TE_NOHIDESEL)
335
- @txt.instance_eval { alias clear_all clear }
336
- @txt.set_max_length(0)
337
- @nb.add_page(@txt, "Demo Code")
338
- end
339
-
340
- get_demo_file(__FILE__)
341
-
342
- @log = Wx::TextCtrl.new(splitter2, -1, "", Wx::DEFAULT_POSITION,
343
- Wx::DEFAULT_SIZE,
344
- Wx::TE_MULTILINE|Wx::TE_READONLY|Wx::HSCROLL)
345
- # For some reason when the number of characters entered is
346
- # greater than about 10,700, the text control freezes. I know
347
- # someone mentioned this on the list a while ago...calling
348
- # set_max_length(0) with zero as the argument tells the text
349
- # control to default limit that the underlying native text
350
- # control can handle.
351
- @log.set_max_length(0)
352
- Wx::Log::set_active_target(Wx::LogTextCtrl.new(@log))
353
-
354
- splitter.split_vertically(@tree, splitter2, 190)
355
- splitter2.split_horizontally(@nb, @log, 200)
356
-
357
-
358
- splitter.set_minimum_pane_size(20)
359
- splitter2.set_minimum_pane_size(100)
360
-
361
- @nb.set_selection(0)
362
- @tree.select_item(root)
363
- show_tip()
364
- end
365
-
366
- def write_text(text)
367
- Wx::log_message(text)
368
- end
369
-
370
- def on_idle(event)
371
- if @otherWin != nil
372
- @otherWin.raise()
373
- @window = @otherWin
374
- @otherWin = nil
375
- end
376
- end
377
-
378
- def on_close(event)
379
- @tbicon.remove_icon
380
- destroy()
381
- exit()
382
- end
383
-
384
- def on_item_expanded(event)
385
- item = event.get_item()
386
- Wx::log_message("on_item_expanded: %s" % @tree.get_item_text(item))
387
- end
388
-
389
- def on_item_collapsed(event)
390
- item = event.get_item()
391
- Wx::log_message("on_item_collapsed: %s" % @tree.get_item_text(item))
392
- end
393
-
394
- def on_tree_sel_changed(event)
395
- item = event.get_item()
396
- if item.nonzero?
397
- itemText = @tree.get_item_text(item)
398
- run_demo(itemText)
399
- end
400
- end
401
-
402
- def on_tree_left_down(event)
403
- pt = Wx::Point.new(event.get_x, event.get_y)
404
- item = @tree.hit_test(pt)
405
- if item == @tree.get_selection()
406
- set_overview(@tree.get_item_text(item) + " Overview", @curOverview)
407
- Wx::log_message(@tree.get_item_text(item) + " Overview")
408
- end
409
- event.skip()
410
- end
411
-
412
- def run_demo(itemText)
413
- if @nb.get_page_count() == 3
414
- if @nb.get_selection() == 2
415
- @nb.set_selection(0)
416
- end
417
- if @window != nil
418
- @window = nil
419
- end
420
- @nb.delete_page(2)
421
- end
422
-
423
- if itemText == "wxRuby Overview"
424
- get_demo_file(__FILE__)
425
- set_overview("wxRuby Overview", OVR_TEXT)
426
- @nb.refresh()
427
- @window = nil
428
- else
429
- demo_file = File.join( File.dirname(__FILE__), itemText + '.rbw')
430
- if File.exist?(demo_file)
431
- Wx::log_message("Running Demo: " + itemText + ".rbw")
432
- get_demo_file(demo_file)
433
- # I use load() here because it allows the user to modify
434
- # the underlying file for each sample, so that each time
435
- # They run it any changes made will be reflected without
436
- # having to restart the demo.
437
- begin
438
- load demo_file
439
- set_overview(itemText + " Overview", Demo::overview)
440
- @tree.refresh()
441
- @nb.refresh()
442
- @window = Demo.run(self, @nb, self)
443
- if @window.class.ancestors.include?(Wx::Window)
444
- # Check to see if the demo returned a Wx::Window, Wx::Panel or a new class inheriting from them
445
- # if so, create a new tab in the notebook for them
446
- @nb.add_page(@window, "Demo")
447
- @nb.set_selection(2)
448
- @nb.refresh()
449
- end
450
- rescue Exception => problem
451
- dlg = Wx::MessageDialog.new(self, "A problem occurred with the %s demo:\n%s\n%s" % [itemText, problem, problem.backtrace().join("\n").to_s()],
452
- "Error!!!", Wx::OK | Wx::ICON_ERROR)
453
- dlg.show_modal()
454
- dlg.destroy()
455
- end
456
- else
457
- @ovr.set_value("")
458
- @txt.clear_all
459
- @window = nil
460
- end
461
- end
462
- @tree.set_focus()
463
- end
464
-
465
- def get_demo_file(fileName)
466
- @filename = fileName
467
- @txt.clear()
468
- @txt.load_file(fileName)
469
- if @txt.is_a?(Wx::TextCtrl)
470
- @txt.set_insertion_point(0)
471
- @txt.show_position(0)
472
- end
473
- end
474
-
475
- def set_overview(name, text)
476
- text ||= ''
477
- @curOverview = text
478
- @ovr.set_value(text)
479
- @ovr.set_style(0,text.length,Wx::TextAttr.new(Wx::BLUE, Wx::Colour.new("White"), Wx::Font.new(12, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_BOLD)))
480
- @nb.set_page_text(0, name)
481
- end
482
-
483
- # Menu Methods
484
-
485
- def on_file_exit(event)
486
- close()
487
- end
488
-
489
- def on_help_about(event)
490
- load File.join(File.dirname(__FILE__), "About.rbw")
491
- about = About::MyAboutBox.new(self)
492
- about.show_modal()
493
- about.destroy()
494
- end
495
-
496
- def on_help_find(event)
497
- @nb.set_selection(1)
498
- @finddlg = Wx::FindReplaceDialog.new(self, @finddata, "Find", Wx::FR_NOUPDOWN | Wx::FR_NOMATCHCASE | Wx::FR_NOWHOLEWORD)
499
- @finddlg.show()
500
- end
501
-
502
- def on_find(event)
503
- # FIXME: These problems are probably resolved now
504
- # Problems
505
- # 1) For some reason, the control is not properly counting EOL characters - it almost seems to be skipping them
506
- # causing the control to incorrectly set the initial insertion point for the the "found" text
507
- # 2) This also is causing problems with the amount of text that is highlighted - the length of the highlighted string
508
- # is less than it should be
509
- # 3) After doing an initial "find" operation, using the "find next" operation causes the program to crash - again, I
510
- # don't know why this is :(
511
- # Example - When I try to find "menu", the text that gets highlighted is the newline on the second line and the "ME" of
512
- # MENU_EXIT - a total of only 3 characters, when it should highlight all of "menu". I don't fully understand
513
- # this problem, but it doesn't appear until after you attempt to find text beyond the first line :(
514
- if @txt.is_a?(Wx::TextCtrl)
515
- @nb.set_selection(1)
516
- myEnd = @txt.get_last_position()
517
- write_text("Last position = %d" % myEnd)
518
- textstring = @txt.get_range(0,myEnd).downcase()
519
- if Wx::PLATFORM == "WXMSW"
520
- textstring.sub!(/\n/, "\r\n")
521
- end
522
- #write_text("textstring - %s" % textstring)
523
- start = @txt.get_insertion_point()
524
- write_text("insertion point = " + start.to_s())
525
- findstring = @finddata.get_find_string().downcase()
526
- write_text("finddata = " + findstring)
527
- loc = textstring.index(findstring, start)
528
- write_text("location = " + loc.to_s())
529
- write_text("findstring.length() = " + findstring.length().to_s())
530
- if loc == nil and start != 0
531
- # string not found, start at beginning
532
- start = 0
533
- loc = textstring.index(findstring, start)
534
- end
535
-
536
- if loc == nil
537
- dlg = Wx::MessageDialog.new(self, 'Find String Not Found', 'Find String Not Found in Demo File',
538
- Wx::OK | Wx::ICON_INFORMATION)
539
- dlg.show_modal()
540
- dlg.destroy()
541
- end
542
-
543
- if @finddlg
544
- if loc == nil
545
- @finddlg.set_focus()
546
- return
547
- else
548
- @finddlg.destroy()
549
- end
550
- end
551
- @txt.show_position(loc)
552
- @txt.set_selection(loc, loc + findstring.length())
553
- else # Scintilla
554
- # FIXME: Take into account search direction
555
- @txt.set_target_start(@txt.get_target_end)
556
- @txt.set_target_end(@txt.get_length - 1)
557
- # FIXME: get flags from find dialog
558
- @txt.set_search_flags(0)
559
- loc = @txt.search_in_target(event.get_find_string)
560
- if loc == -1
561
- dlg = Wx::MessageDialog.new(self, 'Find String Not Found', 'Find String Not Found in Demo File',
562
- Wx::OK | Wx::ICON_INFORMATION)
563
- dlg.show_modal()
564
- dlg.destroy()
565
- end
566
-
567
- if @finddlg
568
- if loc == -1
569
- @finddlg.set_focus()
570
- return
571
- end
572
- end
573
- @txt.ensure_caret_visible
574
- @txt.set_selection(loc, loc + event.get_find_string.length)
575
- end
576
- end
577
-
578
- def on_find_next(event)
579
- # FIXME: Saving an event is probably a bad idea
580
- if @finddata.get_find_string() != ""
581
- on_find(event)
582
- else
583
- on_help_find(event)
584
- end
585
- end
586
-
587
- def on_find_close(event)
588
- event.get_dialog().destroy()
589
- end
590
-
591
- def show_tip()
592
- tips_file = File.join(File.dirname(__FILE__), 'tips.txt')
593
- tp = Wx::create_file_tip_provider( tips_file, rand(6) )
594
- Wx::show_tip(self, tp)
595
- end
596
-
597
- def on_demo_menu(childItem)
598
- # Also, for some reason I haven't figured out yet either, the demo executes two times
599
- selectedDemo = @treeMap[childItem]
600
- if selectedDemo
601
- @tree.select_item(selectedDemo)
602
- @tree.ensure_visible(selectedDemo)
603
- end
604
- end
605
-
606
- def on_iconize(event)
607
- Wx::log_message("on_iconify")
608
- event.skip
609
- end
610
-
611
- def on_maximize(event)
612
- Wx::log_message("on_maximize")
613
- event.skip
614
- end
615
-
616
- # FIXME: Refactor into a class
617
- def setup_editor(parent)
618
- panel = Wx::Panel.new(parent)
619
- panel.hide
620
- sci = setup_scintilla(panel)
621
- @save_button = Wx::Button.new(panel, -1, 'Save Changes')
622
- @delete_button = Wx::Button.new(panel, -1, 'Delete Modified')
623
- @save_button.enable(false);
624
- panel.evt_button(@save_button.get_id) { on_save }
625
- panel.evt_button(@delete_button.get_id) { on_delete }
626
- panel.evt_sci_modified { on_modified }
627
-
628
- radio_buttons = {:original => Wx::RadioButton.new(panel, -1, "Original", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::RB_GROUP),
629
- :modified => Wx::RadioButton.new(panel, -1, "Modified")}
630
-
631
- @control_box = Wx::BoxSizer.new(Wx::HORIZONTAL)
632
- @control_box.add(Wx::StaticText.new(panel, -1, 'Active Version:'), 0, Wx::RIGHT | Wx::LEFT | Wx::ALIGN_CENTER_VERTICAL, 5)
633
- radio_buttons.each_pair { |id, button|
634
- @control_box.add(button, 0, Wx::EXPAND | Wx::RIGHT, 5)
635
- evt_radiobutton(button.get_id) { |event| on_radio_button(event) }
636
- }
637
- @control_box.add(@save_button, 0, Wx::RIGHT, 5)
638
- @control_box.add(@delete_button, 0)
639
-
640
- @box = Wx::BoxSizer.new(Wx::VERTICAL)
641
- @box.add(@control_box, 0, Wx::EXPAND)
642
- @box.add(Wx::StaticLine.new(panel), 0, Wx::EXPAND)
643
-
644
- @box.add(sci, 1, Wx::EXPAND)
645
- @box.fit(panel)
646
- panel.set_sizer(@box)
647
- [panel, sci]
648
- end
649
-
650
- def setup_scintilla(parent)
651
- sci = Wx::Scintilla.new(parent)
652
- font = Wx::Font.new(10, Wx::TELETYPE, Wx::NORMAL, Wx::NORMAL)
653
- sci.style_set_font(Wx::SCI_STYLE_DEFAULT, font);
654
- sci.set_edge_mode(Wx::SCI_EDGE_LINE)
655
- line_num_margin = sci.text_width(Wx::SCI_STYLE_LINENUMBER, "_99999")
656
- sci.set_margin_width(0, line_num_margin)
657
-
658
- sci.style_set_foreground(Wx::SCI_STYLE_DEFAULT, Wx::BLACK);
659
- sci.style_set_background(Wx::SCI_STYLE_DEFAULT, Wx::WHITE);
660
- sci.style_set_foreground(Wx::SCI_STYLE_LINENUMBER, Wx::LIGHT_GREY);
661
- sci.style_set_background(Wx::SCI_STYLE_LINENUMBER, Wx::WHITE);
662
- sci.style_set_foreground(Wx::SCI_STYLE_INDENTGUIDE, Wx::LIGHT_GREY);
663
-
664
- sci.set_tab_width(2)
665
- sci.set_use_tabs(false)
666
- sci.set_tab_indents(true)
667
- sci.set_back_space_un_indents(true)
668
- sci.set_indent(2)
669
- sci.set_edge_column(80)
670
-
671
- sci.set_lexer(Wx::SCI_LEX_RUBY)
672
- sci.style_clear_all
673
- sci.style_set_foreground(2, Wx::RED)
674
- sci.style_set_foreground(3, Wx::GREEN)
675
- sci.style_set_foreground(5, Wx::BLUE)
676
- sci.style_set_foreground(6, Wx::BLUE)
677
- sci.style_set_foreground(7, Wx::BLUE)
678
- sci.set_key_words(0, "begin break elsif module retry unless end case next return until class ensure nil self when def false not super while alias defined? for or then yield and do if redo true else in rescue undef")
679
-
680
- sci.set_property("fold","1")
681
- sci.set_property("fold.compact", "0")
682
- sci.set_property("fold.comment", "1")
683
- sci.set_property("fold.preprocessor", "1")
684
-
685
- sci.set_margin_width(1, 0)
686
- sci.set_margin_type(1, Wx::SCI_MARGIN_SYMBOL)
687
- sci.set_margin_mask(1, Wx::SCI_MASK_FOLDERS)
688
- sci.set_margin_width(1, 20)
689
-
690
- sci.marker_define(Wx::SCI_MARKNUM_FOLDER, Wx::SCI_MARK_PLUS)
691
- sci.marker_define(Wx::SCI_MARKNUM_FOLDEROPEN, Wx::SCI_MARK_MINUS)
692
- sci.marker_define(Wx::SCI_MARKNUM_FOLDEREND, Wx::SCI_MARK_EMPTY)
693
- sci.marker_define(Wx::SCI_MARKNUM_FOLDERMIDTAIL, Wx::SCI_MARK_EMPTY)
694
- sci.marker_define(Wx::SCI_MARKNUM_FOLDEROPENMID, Wx::SCI_MARK_EMPTY)
695
- sci.marker_define(Wx::SCI_MARKNUM_FOLDERSUB, Wx::SCI_MARK_EMPTY)
696
- sci.marker_define(Wx::SCI_MARKNUM_FOLDERTAIL, Wx::SCI_MARK_EMPTY)
697
- sci.set_fold_flags(16)
698
-
699
- sci.set_margin_sensitive(1,1)
700
- sci
701
- end
702
-
703
- def on_save
704
- if not FileTest.directory?(File.dirname(modified_filename))
705
- if not Dir.mkdir(File.dirname(modified_filename))
706
- Wx::log_message("Unable to create directory 'modified'")
707
- return
708
- end
709
- end
710
- File.open(modified_filename, "w") { |file|
711
- file.write(@txt.get_text)
712
- }
713
- # FIXME: Reload module we just saved
714
- end
715
-
716
- def on_delete
717
- if File.exists?(modified_filename)
718
- File.unlink(modified_filename)
719
- end
720
- # FIXME: Update state
721
- end
722
-
723
- def on_modified
724
- @save_button.enable(@txt.get_modify)
725
- end
726
-
727
- def on_radio_button(event)
728
- # FIXME: Can't do anything here yet
729
- end
730
-
731
- def modified_filename
732
- File.join(File.dirname(@filename), "modified", File.basename(@filename))
733
- end
734
- end
735
-
736
- class DemoTaskBarIcon < Wx::TaskBarIcon
737
- # TODO: Need a new_id function like wxPython has
738
- TBMENU_RESTORE = 6000
739
- TBMENU_CLOSE = 6001
740
- TBMENU_CHANGE = 6002
741
- TBMENU_REMOVE = 6003
742
-
743
- def initialize(frame)
744
- super()
745
-
746
- @frame = frame
747
-
748
- # starting image
749
- icon = make_icon('ruby.png')
750
- set_icon(icon, 'wxRuby Demo')
751
- @image_index = 1
752
-
753
- # events
754
- evt_taskbar_left_dclick {|evt| on_taskbar_activate(evt) }
755
-
756
- evt_menu(TBMENU_RESTORE) {|evt| on_taskbar_activate(evt) }
757
- evt_menu(TBMENU_CLOSE) { @frame.close }
758
- evt_menu(TBMENU_CHANGE) {|evt| on_taskbar_change(evt) }
759
- evt_menu(TBMENU_REMOVE) { remove_icon }
760
- end
761
-
762
- def create_popup_menu
763
- # Called by the base class when it needs to popup the menu
764
- # (the default evt_right_down event). Create and return
765
- # the menu to display.
766
- menu = Wx::Menu.new
767
- menu.append(TBMENU_RESTORE, "Restore wxRuby Demo")
768
- menu.append(TBMENU_CLOSE, "Close wxRuby Demo")
769
- menu.append_separator
770
- menu.append(TBMENU_CHANGE, "Change the TB Icon")
771
- menu.append(TBMENU_REMOVE, "Remove the TB Icon")
772
- return menu
773
- end
774
-
775
- def make_icon(imgname)
776
- # Different platforms have different requirements for the
777
- # taskbar icon size
778
- filename = File.join( File.dirname(__FILE__), 'icons', imgname )
779
- img = Wx::Image.new(filename)
780
- if Wx::PLATFORM == "WXMSW"
781
- img = img.scale(16, 16)
782
- elsif Wx::PLATFORM == "WXGTK"
783
- img = img.scale(22, 22)
784
- end
785
- # WXMAC can be any size up to 128x128, so don't scale
786
- icon = Wx::Icon.new
787
- icon.copy_from_bitmap(Wx::Bitmap.new(img))
788
- return icon
789
- end
790
-
791
- def on_taskbar_activate(evt)
792
- if @frame.is_iconized
793
- @frame.iconize(false)
794
- end
795
- if not @frame.is_shown
796
- @frame.show(true)
797
- end
798
- @frame.raise
799
- end
800
-
801
- def on_taskbar_change(evt)
802
- names = [ "ruby.png", "wxwin16x16.xpm", "smiles.xpm", "mondrian.xpm" ]
803
- name = names[@image_index]
804
- @image_index += 1
805
- if @image_index >= names.length
806
- @image_index = 0
807
- end
808
-
809
- icon = make_icon(name)
810
- set_icon(icon, 'This is a new icon: ' + name)
811
- end
812
-
813
- end
814
-
815
- class DemoApp < Wx::App
816
- def on_init
817
- frame = WxRubyDemo.new("WxRuby BIG combined demo",
818
- Wx::DEFAULT_POSITION,
819
- Wx::Size.new(750, 550))
820
-
821
- frame.show(true)
822
- end
823
- end
824
-
825
- demo = DemoApp.new
826
- demo.main_loop
1
+ #!/usr/bin/env ruby
2
+ # Demo created by Robert Carlin,
3
+ # based on the wxPython demo by Robin Dunn
4
+ # Modified a bit by Kevin Smith and Roy Sutton
5
+
6
+ # TODO:
7
+ # Finish Scintilla integration
8
+ # Fix 'Find Next'
9
+ # Refactor editor pane
10
+ # More samples
11
+ # Finish 'rubification' of source
12
+ # Fix non-scintilla code viewer
13
+
14
+ begin
15
+ require 'wx'
16
+ rescue LoadError => no_wx_err
17
+ begin
18
+ require 'rubygems'
19
+ require 'wx'
20
+ rescue LoadError
21
+ raise no_wx_err
22
+ end
23
+ end
24
+
25
+ MENU_EXIT = 100
26
+ TREE_ID = 101
27
+
28
+ OVR_TEXT = "This is the WxRuby Demo. It was ported from the wxPython Demo, created by Robin Dunn. Many thanks to him for all his hard work - this demo is what it is because of him. Click on any of the items in the tree control to start the demo. Don't forget to check out the Demo Code tab - you can see the source code for each demo!\nHope you like it!"
29
+
30
+ $tree_list = [
31
+ #new stuff
32
+ #['Recent Additions', [
33
+ # 'wxMaskedNumCtrl',
34
+ # 'FloatCanvas',
35
+ # ]],
36
+
37
+ # managed windows == things with a [optional] caption you can close
38
+ ['Base Frames and Dialogs', [
39
+ 'wxDialog',
40
+ 'wxFrame',
41
+ 'wxMDIWindows',
42
+ 'wxMiniFrame',
43
+ #'wxWizard',
44
+ ]],
45
+
46
+ # the common dialogs
47
+ ['Common Dialogs', [
48
+ 'wxColourDialog',
49
+ 'wxDirDialog',
50
+ 'wxFileDialog',
51
+ 'wxFileDialog_Save',
52
+ 'wxFindReplaceDialog',
53
+ 'wxFontDialog',
54
+ 'wxMessageDialog',
55
+ #'wxPageSetupDialog',
56
+ #'wxPrintDialog',
57
+ 'wxProgressDialog',
58
+ 'wxSingleChoiceDialog',
59
+ 'wxTextEntryDialog',
60
+ ]],
61
+
62
+ # dialogs from libraries
63
+ ['More Dialogs', [
64
+ # 'ErrorDialogs',
65
+ # 'ImageBrowser',
66
+ 'wxMultipleChoiceDialog',
67
+ 'wxScrolledMessageDialog'
68
+ ]],
69
+
70
+ # core controls
71
+ ['Core Windows/Controls', [
72
+ 'PopupMenu',
73
+ 'wxBitmapButton',
74
+ 'wxButton',
75
+ 'wxCheckBox',
76
+ 'wxCheckListBox',
77
+ 'wxChoice',
78
+ 'wxChoicebook',
79
+ 'wxComboBox',
80
+ 'wxGauge',
81
+ 'wxGenericDirCtrl',
82
+ 'wxGrid',
83
+ #'wxGrid_MegaExample',
84
+ 'wxListBox',
85
+ #'wxListCtrl',
86
+ 'wxListCtrl_virtual',
87
+ 'wxMenu',
88
+ 'wxNotebook',
89
+ #'wxPopupWindow',
90
+ 'wxRadioBox',
91
+ 'wxRadioButton',
92
+ 'wxSashWindow',
93
+ 'wxScrolledWindow',
94
+ 'wxSlider',
95
+ 'wxSpinButton',
96
+ 'wxSpinCtrl',
97
+ 'wxSplitterWindow',
98
+ 'wxStaticBitmap',
99
+ 'wxStaticText',
100
+ 'wxStatusBar',
101
+ 'wxTextCtrl',
102
+ 'wxToggleButton',
103
+ 'wxToolBar',
104
+ 'wxTreeCtrl',
105
+ #'wxValidator',
106
+ ]],
107
+
108
+ # controls coming from other libraries
109
+ ['More Windows/Controls', [
110
+ #'wxFloatBar', deprecated
111
+ #'wxMVCTree', deprecated
112
+ #'wxRightTextCtrl', deprecated as we have wxTE_RIGHT now.
113
+ #'AnalogClockWindow',
114
+ #'ColourSelect',
115
+ #'ContextHelp',
116
+ #'FancyText',
117
+ #'FloatCanvas',
118
+ #'FileBrowseButton',
119
+ #'GenericButtons',
120
+ #'MaskedEditControls',
121
+ #'SplitTree',
122
+ #'TablePrint',
123
+ #'Throbber',
124
+ #'wxCalendar',
125
+ 'wxCalendarCtrl',
126
+ #'wxDynamicSashWindow',
127
+ #'wxEditableListBox',
128
+ #'wxEditor',
129
+ #'wxHtmlWindow',
130
+ #'wxIEHtmlWin',
131
+ #'wxIntCtrl',
132
+ #'wxLEDNumberCtrl',
133
+ #'wxMimeTypesManager',
134
+ #'wxMaskedNumCtrl',
135
+ #'wxMultiSash',
136
+ #'wxPopupControl',
137
+ #'wxStyledTextCtrl_1',
138
+ #'wxStyledTextCtrl_2',
139
+ #'wxTimeCtrl',
140
+ #'wxTreeListCtrl',
141
+ ]],
142
+
143
+ # How to lay out the controls in a frame/dialog
144
+ ['Window Layout', [
145
+ # 'LayoutAnchors',
146
+ # 'Layoutf',
147
+ # 'RowColSizer',
148
+ 'Sizers',
149
+ # 'wxScrolledPanel',
150
+ # 'wxXmlResource',
151
+ # 'wxXmlResourceHandler',
152
+ ]],
153
+
154
+ # ditto
155
+ #['Process and Events', [
156
+ # 'EventManager',
157
+ # 'infoframe',
158
+ # 'OOR',
159
+ # 'PythonEvents',
160
+ # 'Threads',
161
+ # 'wxKeyEvents',
162
+ # 'wxProcess',
163
+ # 'wxTimer',
164
+ # ]],
165
+
166
+ #~ # Clipboard and DnD
167
+ #~ ['Clipboard and DnD', [
168
+ #~ #'CustomDragAndDrop',
169
+ #~ 'DragAndDrop',
170
+ #~ 'URLDragAndDrop',
171
+ #~ ]],
172
+
173
+ # Images
174
+ ['Using Images', [
175
+ # 'Throbber',
176
+ 'wxArtProvider',
177
+ 'wxCursor',
178
+ 'wxDragImage',
179
+ # 'wxImage',
180
+ # 'wxImageFromStream',
181
+ # 'wxMask',
182
+ ]],
183
+
184
+ # Other stuff
185
+ ['Miscellaneous', [
186
+ # 'ColourDB',
187
+ # 'DialogUnits',
188
+ # 'DrawXXXList',
189
+ # 'FontEnumerator',
190
+ # 'PrintFramework',
191
+ 'ShapedWindow',
192
+ # 'Throbber',
193
+ # 'Unicode',
194
+ # 'wxFileHistory',
195
+ # 'wxJoystick',
196
+ # 'wxOGL',
197
+ # 'wxWave',
198
+ ]],
199
+
200
+ # need libs not coming with the demo
201
+ #['Objects using an external library', [
202
+ # 'ActiveXWrapper_Acrobat',
203
+ # 'ActiveXWrapper_IE',
204
+ # 'wxGLCanvas',
205
+ # 'wxPlotCanvas',
206
+ # ]],
207
+
208
+
209
+ ['Check out the samples dir too', [
210
+ ]],
211
+
212
+ ]
213
+
214
+ class DemoCodeViewer < Wx::TextCtrl
215
+ def intialize(parent, id)
216
+ super(parent, id, OVR_TEXT, Wx::DEFAULT_POSITION, Wx::Size.new(400, 400),
217
+ Wx::TE_MULTILINE|Wx::TE_READONLY|Wx::HSCROLL|
218
+ Wx::TE_RICH|Wx::TE_NOHIDESEL)
219
+ end
220
+ end
221
+
222
+ class WxRubyDemo < Wx::Frame
223
+ attr_accessor :otherWin
224
+
225
+ def initialize(title, pos, size, style=Wx::DEFAULT_FRAME_STYLE)
226
+ super(nil,-1,title,pos,size,style)
227
+ @demoID = 6000
228
+ @otherWin = nil
229
+
230
+ icon_file = File.join(File.dirname(__FILE__), 'icons', 'mondrian.xpm')
231
+ icon = Wx::Icon.new(icon_file, Wx::BITMAP_TYPE_XPM)
232
+ set_icon(icon)
233
+
234
+ @tbicon = DemoTaskBarIcon.new(self)
235
+
236
+ evt_idle {|event| on_idle(event)}
237
+ evt_close {|event| on_close(event)}
238
+ evt_iconize {|event| on_iconize(event)}
239
+ evt_maximize {|event| on_maximize(event)}
240
+
241
+ centre(Wx::BOTH)
242
+ create_status_bar(1, Wx::ST_SIZEGRIP)
243
+ set_status_text("Welcome to the WxRuby Demo!")
244
+
245
+ splitter = Wx::SplitterWindow.new(self, -1)
246
+ splitter2 = Wx::SplitterWindow.new(splitter, -1)
247
+
248
+ # Make a File menu
249
+
250
+ @mainmenu = Wx::MenuBar.new
251
+ menu = Wx::Menu.new
252
+ menu.append(MENU_EXIT, "E&xit\tALT-X", "Get the heck outta here!")
253
+ evt_menu(MENU_EXIT) {exit}
254
+ @mainmenu.append(menu, "&File")
255
+
256
+ # Make a Demo menu - thanks to Kevin Smith for figuring the submenus out!
257
+ menu = Wx::Menu.new
258
+ $tree_list.each do |item|
259
+ @submenu = Wx::Menu.new
260
+ item[1].each do |childItem|
261
+ mID = @demoID += 1
262
+ @submenu.append(mID, childItem)
263
+ evt_menu(mID) {|event| on_demo_menu(childItem)}
264
+ end
265
+ menuItem = Wx::MenuItem.new(menu, 500000, item[0], "", Wx::ITEM_NORMAL, @submenu)
266
+ menu.append_item(menuItem)
267
+ end
268
+ @mainmenu.append(menu, "&Demo")
269
+
270
+ # Make a Help menu
271
+ helpID = Wx::ID_ABOUT
272
+ findID = @demoID += 1
273
+ findnextID = @demoID += 1
274
+ clearID = @demoID += 1
275
+ menu = Wx::Menu.new
276
+ menu.append(findID, "&Find\tCtrl-F", "Find in the Demo Code")
277
+ menu.append(findnextID, "Find &Next\tF3", "Find Next")
278
+ menu.append_separator
279
+ menu.append(helpID, "&About\tCtrl-H", "wxRuby RULES!!!")
280
+ evt_menu(helpID) {|event| on_help_about(event)}
281
+ evt_menu(findID) {|event| on_help_find(event)}
282
+ evt_menu(findnextID) {|event| on_find_next(event)}
283
+ evt_find(-1) {|event| on_find(event)}
284
+ evt_find_next(-1) {|event| on_find(event)}
285
+ evt_find_close(-1) {|event| on_find_close(event)}
286
+ @mainmenu.append(menu, "&Help")
287
+ set_menu_bar(@mainmenu)
288
+
289
+ @finddata = Wx::FindReplaceData.new()
290
+
291
+ @treeMap = {}
292
+ @tree = Wx::TreeCtrl.new(splitter, TREE_ID, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::TR_DEFAULT_STYLE)#, Wx::TR_HAS_BUTTONS | Wx::TR_HAS_VARIABLE_ROW_HEIGHT)
293
+ root = @tree.add_root("wxRuby Overview")
294
+ firstChild = nil
295
+
296
+ $tree_list.each do |item|
297
+ child = @tree.append_item(root, item[0])
298
+ if not firstChild then firstChild = child end
299
+ item[1].each do |childItem|
300
+ theDemo = @tree.append_item(child, childItem)
301
+ @treeMap[childItem] = theDemo
302
+ end
303
+ end
304
+ @tree.expand(root)
305
+ @tree.expand(firstChild)
306
+
307
+ evt_tree_item_expanded(TREE_ID) {|event| on_item_expanded(event)}
308
+ evt_tree_item_collapsed(TREE_ID) {|event| on_item_collapsed(event)}
309
+ evt_tree_sel_changed(TREE_ID) {|event| on_tree_sel_changed(event)}
310
+ evt_tree_item_activated(TREE_ID) {|event| on_tree_sel_changed(event)}
311
+ @tree.evt_left_down {|event| on_tree_left_down(event)}
312
+
313
+
314
+
315
+ # Create a Notebook
316
+ @nb = Wx::Notebook.new(splitter2, -1, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::CLIP_CHILDREN)
317
+
318
+ @ovr = Wx::TextCtrl.new(@nb, -1, OVR_TEXT, Wx::DEFAULT_POSITION,
319
+ Wx::Size.new(400,400),
320
+ Wx::TE_MULTILINE|Wx::TE_READONLY|
321
+ Wx::TE_RICH|Wx::TE_NOHIDESEL)
322
+ @nb.add_page(@ovr, "Overview")
323
+
324
+ if Wx.const_defined?(:Scintilla)
325
+ panel, @txt = setup_editor(@nb)
326
+ @nb.add_page(panel, "Demo Code")
327
+ else
328
+ # FIXME: Should use DemoCodeViewer, but when we do (on Windows) it
329
+ # puts all text on one line! Can remove instance_eval
330
+ # once that's resolved
331
+ @txt = Wx::TextCtrl.new(@nb, -1, OVR_TEXT, Wx::DEFAULT_POSITION,
332
+ Wx::Size.new(400,400),
333
+ Wx::TE_MULTILINE|Wx::TE_READONLY|
334
+ Wx::HSCROLL|Wx::TE_RICH|Wx::TE_NOHIDESEL)
335
+ @txt.instance_eval { alias clear_all clear }
336
+ @txt.set_max_length(0)
337
+ @nb.add_page(@txt, "Demo Code")
338
+ end
339
+
340
+ get_demo_file(__FILE__)
341
+
342
+ @log = Wx::TextCtrl.new(splitter2, -1, "", Wx::DEFAULT_POSITION,
343
+ Wx::DEFAULT_SIZE,
344
+ Wx::TE_MULTILINE|Wx::TE_READONLY|Wx::HSCROLL)
345
+ # For some reason when the number of characters entered is
346
+ # greater than about 10,700, the text control freezes. I know
347
+ # someone mentioned this on the list a while ago...calling
348
+ # set_max_length(0) with zero as the argument tells the text
349
+ # control to default limit that the underlying native text
350
+ # control can handle.
351
+ @log.set_max_length(0)
352
+ Wx::Log::set_active_target(Wx::LogTextCtrl.new(@log))
353
+
354
+ splitter.split_vertically(@tree, splitter2, 190)
355
+ splitter2.split_horizontally(@nb, @log, 200)
356
+
357
+
358
+ splitter.set_minimum_pane_size(20)
359
+ splitter2.set_minimum_pane_size(100)
360
+
361
+ @nb.set_selection(0)
362
+ @tree.select_item(root)
363
+ show_tip()
364
+ end
365
+
366
+ def write_text(text)
367
+ Wx::log_message(text)
368
+ end
369
+
370
+ def on_idle(event)
371
+ if @otherWin != nil
372
+ @otherWin.raise()
373
+ @window = @otherWin
374
+ @otherWin = nil
375
+ end
376
+ end
377
+
378
+ def on_close(event)
379
+ @tbicon.remove_icon
380
+ destroy()
381
+ exit()
382
+ end
383
+
384
+ def on_item_expanded(event)
385
+ item = event.get_item()
386
+ Wx::log_message("on_item_expanded: %s" % @tree.get_item_text(item))
387
+ end
388
+
389
+ def on_item_collapsed(event)
390
+ item = event.get_item()
391
+ Wx::log_message("on_item_collapsed: %s" % @tree.get_item_text(item))
392
+ end
393
+
394
+ def on_tree_sel_changed(event)
395
+ item = event.get_item()
396
+ if item.nonzero?
397
+ itemText = @tree.get_item_text(item)
398
+ run_demo(itemText)
399
+ end
400
+ end
401
+
402
+ def on_tree_left_down(event)
403
+ pt = Wx::Point.new(event.get_x, event.get_y)
404
+ item = @tree.hit_test(pt)
405
+ if item == @tree.get_selection()
406
+ set_overview(@tree.get_item_text(item) + " Overview", @curOverview)
407
+ Wx::log_message(@tree.get_item_text(item) + " Overview")
408
+ end
409
+ event.skip()
410
+ end
411
+
412
+ def run_demo(itemText)
413
+ if @nb.get_page_count() == 3
414
+ if @nb.get_selection() == 2
415
+ @nb.set_selection(0)
416
+ end
417
+ if @window != nil
418
+ @window = nil
419
+ end
420
+ @nb.delete_page(2)
421
+ end
422
+
423
+ if itemText == "wxRuby Overview"
424
+ get_demo_file(__FILE__)
425
+ set_overview("wxRuby Overview", OVR_TEXT)
426
+ @nb.refresh()
427
+ @window = nil
428
+ else
429
+ demo_file = File.join( File.dirname(__FILE__), itemText + '.rbw')
430
+ if File.exist?(demo_file)
431
+ Wx::log_message("Running Demo: " + itemText + ".rbw")
432
+ get_demo_file(demo_file)
433
+ # I use load() here because it allows the user to modify
434
+ # the underlying file for each sample, so that each time
435
+ # They run it any changes made will be reflected without
436
+ # having to restart the demo.
437
+ begin
438
+ load demo_file
439
+ set_overview(itemText + " Overview", Demo::overview)
440
+ @tree.refresh()
441
+ @nb.refresh()
442
+ @window = Demo.run(self, @nb, self)
443
+ if @window.class.ancestors.include?(Wx::Window)
444
+ # Check to see if the demo returned a Wx::Window, Wx::Panel or a new class inheriting from them
445
+ # if so, create a new tab in the notebook for them
446
+ @nb.add_page(@window, "Demo")
447
+ @nb.set_selection(2)
448
+ @nb.refresh()
449
+ end
450
+ rescue Exception => problem
451
+ dlg = Wx::MessageDialog.new(self, "A problem occurred with the %s demo:\n%s\n%s" % [itemText, problem, problem.backtrace().join("\n").to_s()],
452
+ "Error!!!", Wx::OK | Wx::ICON_ERROR)
453
+ dlg.show_modal()
454
+ dlg.destroy()
455
+ end
456
+ else
457
+ @ovr.set_value("")
458
+ @txt.clear_all
459
+ @window = nil
460
+ end
461
+ end
462
+ @tree.set_focus()
463
+ end
464
+
465
+ def get_demo_file(fileName)
466
+ @filename = fileName
467
+ @txt.clear()
468
+ @txt.load_file(fileName)
469
+ if @txt.is_a?(Wx::TextCtrl)
470
+ @txt.set_insertion_point(0)
471
+ @txt.show_position(0)
472
+ end
473
+ end
474
+
475
+ def set_overview(name, text)
476
+ text ||= ''
477
+ @curOverview = text
478
+ @ovr.set_value(text)
479
+ @ovr.set_style(0,text.length,Wx::TextAttr.new(Wx::BLUE, Wx::Colour.new("White"), Wx::Font.new(12, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_BOLD)))
480
+ @nb.set_page_text(0, name)
481
+ end
482
+
483
+ # Menu Methods
484
+
485
+ def on_file_exit(event)
486
+ close()
487
+ end
488
+
489
+ def on_help_about(event)
490
+ load File.join(File.dirname(__FILE__), "About.rbw")
491
+ about = About::MyAboutBox.new(self)
492
+ about.show_modal()
493
+ about.destroy()
494
+ end
495
+
496
+ def on_help_find(event)
497
+ @nb.set_selection(1)
498
+ @finddlg = Wx::FindReplaceDialog.new(self, @finddata, "Find", Wx::FR_NOUPDOWN | Wx::FR_NOMATCHCASE | Wx::FR_NOWHOLEWORD)
499
+ @finddlg.show()
500
+ end
501
+
502
+ def on_find(event)
503
+ # FIXME: These problems are probably resolved now
504
+ # Problems
505
+ # 1) For some reason, the control is not properly counting EOL characters - it almost seems to be skipping them
506
+ # causing the control to incorrectly set the initial insertion point for the the "found" text
507
+ # 2) This also is causing problems with the amount of text that is highlighted - the length of the highlighted string
508
+ # is less than it should be
509
+ # 3) After doing an initial "find" operation, using the "find next" operation causes the program to crash - again, I
510
+ # don't know why this is :(
511
+ # Example - When I try to find "menu", the text that gets highlighted is the newline on the second line and the "ME" of
512
+ # MENU_EXIT - a total of only 3 characters, when it should highlight all of "menu". I don't fully understand
513
+ # this problem, but it doesn't appear until after you attempt to find text beyond the first line :(
514
+ if @txt.is_a?(Wx::TextCtrl)
515
+ @nb.set_selection(1)
516
+ myEnd = @txt.get_last_position()
517
+ write_text("Last position = %d" % myEnd)
518
+ textstring = @txt.get_range(0,myEnd).downcase()
519
+ if Wx::PLATFORM == "WXMSW"
520
+ textstring.sub!(/\n/, "\r\n")
521
+ end
522
+ #write_text("textstring - %s" % textstring)
523
+ start = @txt.get_insertion_point()
524
+ write_text("insertion point = " + start.to_s())
525
+ findstring = @finddata.get_find_string().downcase()
526
+ write_text("finddata = " + findstring)
527
+ loc = textstring.index(findstring, start)
528
+ write_text("location = " + loc.to_s())
529
+ write_text("findstring.length() = " + findstring.length().to_s())
530
+ if loc == nil and start != 0
531
+ # string not found, start at beginning
532
+ start = 0
533
+ loc = textstring.index(findstring, start)
534
+ end
535
+
536
+ if loc == nil
537
+ dlg = Wx::MessageDialog.new(self, 'Find String Not Found', 'Find String Not Found in Demo File',
538
+ Wx::OK | Wx::ICON_INFORMATION)
539
+ dlg.show_modal()
540
+ dlg.destroy()
541
+ end
542
+
543
+ if @finddlg
544
+ if loc == nil
545
+ @finddlg.set_focus()
546
+ return
547
+ else
548
+ @finddlg.destroy()
549
+ end
550
+ end
551
+ @txt.show_position(loc)
552
+ @txt.set_selection(loc, loc + findstring.length())
553
+ else # Scintilla
554
+ # FIXME: Take into account search direction
555
+ @txt.set_target_start(@txt.get_target_end)
556
+ @txt.set_target_end(@txt.get_length - 1)
557
+ # FIXME: get flags from find dialog
558
+ @txt.set_search_flags(0)
559
+ loc = @txt.search_in_target(event.get_find_string)
560
+ if loc == -1
561
+ dlg = Wx::MessageDialog.new(self, 'Find String Not Found', 'Find String Not Found in Demo File',
562
+ Wx::OK | Wx::ICON_INFORMATION)
563
+ dlg.show_modal()
564
+ dlg.destroy()
565
+ end
566
+
567
+ if @finddlg
568
+ if loc == -1
569
+ @finddlg.set_focus()
570
+ return
571
+ end
572
+ end
573
+ @txt.ensure_caret_visible
574
+ @txt.set_selection(loc, loc + event.get_find_string.length)
575
+ end
576
+ end
577
+
578
+ def on_find_next(event)
579
+ # FIXME: Saving an event is probably a bad idea
580
+ if @finddata.get_find_string() != ""
581
+ on_find(event)
582
+ else
583
+ on_help_find(event)
584
+ end
585
+ end
586
+
587
+ def on_find_close(event)
588
+ event.get_dialog().destroy()
589
+ end
590
+
591
+ def show_tip()
592
+ tips_file = File.join(File.dirname(__FILE__), 'tips.txt')
593
+ tp = Wx::create_file_tip_provider( tips_file, rand(6) )
594
+ Wx::show_tip(self, tp)
595
+ end
596
+
597
+ def on_demo_menu(childItem)
598
+ # Also, for some reason I haven't figured out yet either, the demo executes two times
599
+ selectedDemo = @treeMap[childItem]
600
+ if selectedDemo
601
+ @tree.select_item(selectedDemo)
602
+ @tree.ensure_visible(selectedDemo)
603
+ end
604
+ end
605
+
606
+ def on_iconize(event)
607
+ Wx::log_message("on_iconify")
608
+ event.skip
609
+ end
610
+
611
+ def on_maximize(event)
612
+ Wx::log_message("on_maximize")
613
+ event.skip
614
+ end
615
+
616
+ # FIXME: Refactor into a class
617
+ def setup_editor(parent)
618
+ panel = Wx::Panel.new(parent)
619
+ panel.hide
620
+ sci = setup_scintilla(panel)
621
+ @save_button = Wx::Button.new(panel, -1, 'Save Changes')
622
+ @delete_button = Wx::Button.new(panel, -1, 'Delete Modified')
623
+ @save_button.enable(false);
624
+ panel.evt_button(@save_button.get_id) { on_save }
625
+ panel.evt_button(@delete_button.get_id) { on_delete }
626
+ panel.evt_sci_modified { on_modified }
627
+
628
+ radio_buttons = {:original => Wx::RadioButton.new(panel, -1, "Original", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::RB_GROUP),
629
+ :modified => Wx::RadioButton.new(panel, -1, "Modified")}
630
+
631
+ @control_box = Wx::BoxSizer.new(Wx::HORIZONTAL)
632
+ @control_box.add(Wx::StaticText.new(panel, -1, 'Active Version:'), 0, Wx::RIGHT | Wx::LEFT | Wx::ALIGN_CENTER_VERTICAL, 5)
633
+ radio_buttons.each_pair { |id, button|
634
+ @control_box.add(button, 0, Wx::EXPAND | Wx::RIGHT, 5)
635
+ evt_radiobutton(button.get_id) { |event| on_radio_button(event) }
636
+ }
637
+ @control_box.add(@save_button, 0, Wx::RIGHT, 5)
638
+ @control_box.add(@delete_button, 0)
639
+
640
+ @box = Wx::BoxSizer.new(Wx::VERTICAL)
641
+ @box.add(@control_box, 0, Wx::EXPAND)
642
+ @box.add(Wx::StaticLine.new(panel), 0, Wx::EXPAND)
643
+
644
+ @box.add(sci, 1, Wx::EXPAND)
645
+ @box.fit(panel)
646
+ panel.set_sizer(@box)
647
+ [panel, sci]
648
+ end
649
+
650
+ def setup_scintilla(parent)
651
+ sci = Wx::Scintilla.new(parent)
652
+ font = Wx::Font.new(10, Wx::TELETYPE, Wx::NORMAL, Wx::NORMAL)
653
+ sci.style_set_font(Wx::SCI_STYLE_DEFAULT, font);
654
+ sci.set_edge_mode(Wx::SCI_EDGE_LINE)
655
+ line_num_margin = sci.text_width(Wx::SCI_STYLE_LINENUMBER, "_99999")
656
+ sci.set_margin_width(0, line_num_margin)
657
+
658
+ sci.style_set_foreground(Wx::SCI_STYLE_DEFAULT, Wx::BLACK);
659
+ sci.style_set_background(Wx::SCI_STYLE_DEFAULT, Wx::WHITE);
660
+ sci.style_set_foreground(Wx::SCI_STYLE_LINENUMBER, Wx::LIGHT_GREY);
661
+ sci.style_set_background(Wx::SCI_STYLE_LINENUMBER, Wx::WHITE);
662
+ sci.style_set_foreground(Wx::SCI_STYLE_INDENTGUIDE, Wx::LIGHT_GREY);
663
+
664
+ sci.set_tab_width(2)
665
+ sci.set_use_tabs(false)
666
+ sci.set_tab_indents(true)
667
+ sci.set_back_space_un_indents(true)
668
+ sci.set_indent(2)
669
+ sci.set_edge_column(80)
670
+
671
+ sci.set_lexer(Wx::SCI_LEX_RUBY)
672
+ sci.style_clear_all
673
+ sci.style_set_foreground(2, Wx::RED)
674
+ sci.style_set_foreground(3, Wx::GREEN)
675
+ sci.style_set_foreground(5, Wx::BLUE)
676
+ sci.style_set_foreground(6, Wx::BLUE)
677
+ sci.style_set_foreground(7, Wx::BLUE)
678
+ sci.set_key_words(0, "begin break elsif module retry unless end case next return until class ensure nil self when def false not super while alias defined? for or then yield and do if redo true else in rescue undef")
679
+
680
+ sci.set_property("fold","1")
681
+ sci.set_property("fold.compact", "0")
682
+ sci.set_property("fold.comment", "1")
683
+ sci.set_property("fold.preprocessor", "1")
684
+
685
+ sci.set_margin_width(1, 0)
686
+ sci.set_margin_type(1, Wx::SCI_MARGIN_SYMBOL)
687
+ sci.set_margin_mask(1, Wx::SCI_MASK_FOLDERS)
688
+ sci.set_margin_width(1, 20)
689
+
690
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDER, Wx::SCI_MARK_PLUS)
691
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDEROPEN, Wx::SCI_MARK_MINUS)
692
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDEREND, Wx::SCI_MARK_EMPTY)
693
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDERMIDTAIL, Wx::SCI_MARK_EMPTY)
694
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDEROPENMID, Wx::SCI_MARK_EMPTY)
695
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDERSUB, Wx::SCI_MARK_EMPTY)
696
+ sci.marker_define(Wx::SCI_MARKNUM_FOLDERTAIL, Wx::SCI_MARK_EMPTY)
697
+ sci.set_fold_flags(16)
698
+
699
+ sci.set_margin_sensitive(1,1)
700
+ sci
701
+ end
702
+
703
+ def on_save
704
+ if not FileTest.directory?(File.dirname(modified_filename))
705
+ if not Dir.mkdir(File.dirname(modified_filename))
706
+ Wx::log_message("Unable to create directory 'modified'")
707
+ return
708
+ end
709
+ end
710
+ File.open(modified_filename, "w") { |file|
711
+ file.write(@txt.get_text)
712
+ }
713
+ # FIXME: Reload module we just saved
714
+ end
715
+
716
+ def on_delete
717
+ if File.exists?(modified_filename)
718
+ File.unlink(modified_filename)
719
+ end
720
+ # FIXME: Update state
721
+ end
722
+
723
+ def on_modified
724
+ @save_button.enable(@txt.get_modify)
725
+ end
726
+
727
+ def on_radio_button(event)
728
+ # FIXME: Can't do anything here yet
729
+ end
730
+
731
+ def modified_filename
732
+ File.join(File.dirname(@filename), "modified", File.basename(@filename))
733
+ end
734
+ end
735
+
736
+ class DemoTaskBarIcon < Wx::TaskBarIcon
737
+ # TODO: Need a new_id function like wxPython has
738
+ TBMENU_RESTORE = 6000
739
+ TBMENU_CLOSE = 6001
740
+ TBMENU_CHANGE = 6002
741
+ TBMENU_REMOVE = 6003
742
+
743
+ def initialize(frame)
744
+ super()
745
+
746
+ @frame = frame
747
+
748
+ # starting image
749
+ icon = make_icon('ruby.png')
750
+ set_icon(icon, 'wxRuby Demo')
751
+ @image_index = 1
752
+
753
+ # events
754
+ evt_taskbar_left_dclick {|evt| on_taskbar_activate(evt) }
755
+
756
+ evt_menu(TBMENU_RESTORE) {|evt| on_taskbar_activate(evt) }
757
+ evt_menu(TBMENU_CLOSE) { @frame.close }
758
+ evt_menu(TBMENU_CHANGE) {|evt| on_taskbar_change(evt) }
759
+ evt_menu(TBMENU_REMOVE) { remove_icon }
760
+ end
761
+
762
+ def create_popup_menu
763
+ # Called by the base class when it needs to popup the menu
764
+ # (the default evt_right_down event). Create and return
765
+ # the menu to display.
766
+ menu = Wx::Menu.new
767
+ menu.append(TBMENU_RESTORE, "Restore wxRuby Demo")
768
+ menu.append(TBMENU_CLOSE, "Close wxRuby Demo")
769
+ menu.append_separator
770
+ menu.append(TBMENU_CHANGE, "Change the TB Icon")
771
+ menu.append(TBMENU_REMOVE, "Remove the TB Icon")
772
+ return menu
773
+ end
774
+
775
+ def make_icon(imgname)
776
+ # Different platforms have different requirements for the
777
+ # taskbar icon size
778
+ filename = File.join( File.dirname(__FILE__), 'icons', imgname )
779
+ img = Wx::Image.new(filename)
780
+ if Wx::PLATFORM == "WXMSW"
781
+ img = img.scale(16, 16)
782
+ elsif Wx::PLATFORM == "WXGTK"
783
+ img = img.scale(22, 22)
784
+ end
785
+ # WXMAC can be any size up to 128x128, so don't scale
786
+ icon = Wx::Icon.new
787
+ icon.copy_from_bitmap(Wx::Bitmap.new(img))
788
+ return icon
789
+ end
790
+
791
+ def on_taskbar_activate(evt)
792
+ if @frame.is_iconized
793
+ @frame.iconize(false)
794
+ end
795
+ if not @frame.is_shown
796
+ @frame.show(true)
797
+ end
798
+ @frame.raise
799
+ end
800
+
801
+ def on_taskbar_change(evt)
802
+ names = [ "ruby.png", "wxwin16x16.xpm", "smiles.xpm", "mondrian.xpm" ]
803
+ name = names[@image_index]
804
+ @image_index += 1
805
+ if @image_index >= names.length
806
+ @image_index = 0
807
+ end
808
+
809
+ icon = make_icon(name)
810
+ set_icon(icon, 'This is a new icon: ' + name)
811
+ end
812
+
813
+ end
814
+
815
+ class DemoApp < Wx::App
816
+ def on_init
817
+ frame = WxRubyDemo.new("WxRuby BIG combined demo",
818
+ Wx::DEFAULT_POSITION,
819
+ Wx::Size.new(750, 550))
820
+
821
+ frame.show(true)
822
+ end
823
+ end
824
+
825
+ demo = DemoApp.new
826
+ demo.main_loop