]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Fixed setup.h logic again
[wxWidgets.git] / wxPython / demo / Main.py
CommitLineData
cf694132
RD
1#!/bin/env python
2#----------------------------------------------------------------------------
3# Name: Main.py
4# Purpose: Testing lots of stuff, controls, window types, etc.
5#
f6bcfd97 6# Author: Robin Dunn
cf694132 7#
f6bcfd97 8# Created: A long time ago, in a galaxy far, far away...
cf694132
RD
9# RCS-ID: $Id$
10# Copyright: (c) 1999 by Total Control Software
11# Licence: wxWindows license
12#----------------------------------------------------------------------------
13
1e4a197e 14import sys, os, time
cf694132 15
1fded56b
RD
16import wx # This module uses the new wx namespace
17import wx.html
606d919c 18
96bfd053
RD
19import images
20
d14a1e28
RD
21# For debugging
22##wx.Trap();
23##print os.getpid(); raw_input("Press a key...")
6fa68946 24
1e4a197e 25
cf694132
RD
26#---------------------------------------------------------------------------
27
28
29_treeList = [
9c67cbec 30 # new stuff
1e4a197e 31 ('Recent Additions', [
299647ac
RD
32 'VListBox',
33 'Listbook',
34 'MaskedNumCtrl',
8b9a4190 35 'FloatCanvas',
299647ac
RD
36 'XmlResourceSubclass',
37 'GridBagSizer',
76343679 38 'Cursor',
80b27b4e 39 'PyPlot',
9c67cbec
RD
40 ]),
41
1e4a197e 42 # managed windows == things with a (optional) caption you can close
9c67cbec 43 ('Base Frames and Dialogs', [
299647ac
RD
44 'Dialog',
45 'Frame',
46 'MDIWindows',
47 'MiniFrame',
48 'Wizard',
9c67cbec
RD
49 ]),
50
51 # the common dialogs
52 ('Common Dialogs', [
299647ac
RD
53 'ColourDialog',
54 'DirDialog',
55 'FileDialog',
56 'FileDialog_Save',
57 'FindReplaceDialog',
58 'FontDialog',
59 'MessageDialog',
60 'PageSetupDialog',
61 'PrintDialog',
62 'ProgressDialog',
63 'SingleChoiceDialog',
64 'TextEntryDialog',
9c67cbec
RD
65 ]),
66
af83019e 67 # dialogs from libraries
9c67cbec
RD
68 ('More Dialogs', [
69 'ErrorDialogs',
70 'ImageBrowser',
299647ac
RD
71 'MultipleChoiceDialog',
72 'ScrolledMessageDialog',
9c67cbec
RD
73 ]),
74
75 # core controls
76 ('Core Windows/Controls', [
299647ac
RD
77 'Button',
78 'CheckBox',
79 'CheckListBox',
80 'Choice',
81 'ComboBox',
82 'Gauge',
83 'Grid',
84 'Grid_MegaExample',
85 'ListBox',
86 'ListCtrl',
87 'ListCtrl_virtual',
88 'Listbook',
89 'Menu',
90 'Notebook',
1fded56b 91 'PopupMenu',
299647ac
RD
92 'PopupWindow',
93 'RadioBox',
94 'RadioButton',
95 'SashWindow',
96 'ScrolledWindow',
97 'Slider',
98 'SpinButton',
99 'SpinCtrl',
100 'SplitterWindow',
101 'StaticBitmap',
102 'StaticText',
103 'StatusBar',
104 'TextCtrl',
105 'ToggleButton',
106 'ToolBar',
107 'TreeCtrl',
108 'Validator',
9c67cbec
RD
109 ]),
110
d14a1e28
RD
111 ('Custom Controls', [
112 'AnalogClockWindow',
113 'ColourSelect',
299647ac 114 'Editor',
d14a1e28 115 'GenericButtons',
299647ac
RD
116 'GenericDirCtrl',
117 'LEDNumberCtrl',
118 'MultiSash',
119 'PopupControl',
120 'PyColourChooser',
121 'TreeListCtrl',
d14a1e28
RD
122 ]),
123
8b9a4190 124 # controls coming from other libraries
9c67cbec 125 ('More Windows/Controls', [
299647ac
RD
126 #'RightTextCtrl', deprecated as we have wxTE_RIGHT now.
127 'Calendar',
128 'CalendarCtrl',
9c67cbec 129 'ContextHelp',
299647ac
RD
130 'DynamicSashWindow',
131 'EditableListBox',
9c67cbec
RD
132 'FancyText',
133 'FileBrowseButton',
299647ac
RD
134 'FloatBar',
135 'FloatCanvas',
136 'HtmlWindow',
137 'IEHtmlWin',
138 'IntCtrl',
139 'MVCTree',
1fded56b 140 'MaskedEditControls',
299647ac
RD
141 'MaskedNumCtrl',
142 'MimeTypesManager',
9c67cbec 143 'PyCrust',
80b27b4e 144 'PyPlot',
299647ac
RD
145 'PyShell',
146 'ScrolledPanel',
9c67cbec 147 'SplitTree',
299647ac
RD
148 'StyledTextCtrl_1',
149 'StyledTextCtrl_2',
9c67cbec 150 'TablePrint',
1e4a197e 151 'Throbber',
299647ac
RD
152 'TimeCtrl',
153 'VListBox',
9c67cbec
RD
154 ]),
155
156 # How to lay out the controls in a frame/dialog
157 ('Window Layout', [
299647ac 158 'GridBagSizer',
9c67cbec 159 'LayoutAnchors',
299647ac 160 'LayoutConstraints',
9c67cbec
RD
161 'Layoutf',
162 'RowColSizer',
299647ac 163 'ScrolledPanel',
9c67cbec 164 'Sizers',
299647ac
RD
165 'XmlResource',
166 'XmlResourceHandler',
167 'XmlResourceSubclass',
9c67cbec
RD
168 ]),
169
170 # ditto
171 ('Process and Events', [
1e4a197e 172 'EventManager',
299647ac 173 'KeyEvents',
9c67cbec 174 'OOR',
299647ac 175 'Process',
9c67cbec
RD
176 'PythonEvents',
177 'Threads',
299647ac
RD
178 'Timer',
179 'infoframe',
9c67cbec
RD
180 ]),
181
182 # Clipboard and DnD
183 ('Clipboard and DnD', [
184 'CustomDragAndDrop',
185 'DragAndDrop',
186 'URLDragAndDrop',
187 ]),
188
189 # Images
1e4a197e 190 ('Using Images', [
299647ac 191 'ArtProvider',
76343679 192 'Cursor',
299647ac
RD
193 'DragImage',
194 'Image',
195 'ImageFromStream',
196 'Mask',
1e4a197e 197 'Throbber',
9c67cbec
RD
198 ]),
199
200 # Other stuff
201 ('Miscellaneous', [
202 'ColourDB',
203 'DialogUnits',
204 'DrawXXXList',
299647ac 205 'FileHistory',
9c67cbec 206 'FontEnumerator',
299647ac 207 'Joystick',
3628e088 208 'NewNamespace',
299647ac 209 'OGL',
9c67cbec 210 'PrintFramework',
3628e088 211 'ShapedWindow',
9c67cbec 212 'Unicode',
299647ac 213 'Wave',
9c67cbec
RD
214 ]),
215
216 # need libs not coming with the demo
217 ('Objects using an external library', [
218 'ActiveXWrapper_Acrobat',
219 'ActiveXWrapper_IE',
299647ac
RD
220 'GLCanvas',
221 #'PlotCanvas', # deprecated, use PyPlot
9c67cbec
RD
222 ]),
223
70a357c2 224
9c67cbec
RD
225 ('Check out the samples dir too', [
226 ]),
227
9c67cbec
RD
228]
229
230
cf694132
RD
231
232#---------------------------------------------------------------------------
8b9a4190 233# Show how to derive a custom wxLog class
cf694132 234
1fded56b 235class MyLog(wx.PyLog):
76bfdc78 236 def __init__(self, textCtrl, logTime=0):
1fded56b 237 wx.PyLog.__init__(self)
76bfdc78
RD
238 self.tc = textCtrl
239 self.logTime = logTime
240
241 def DoLogString(self, message, timeStamp):
242 if self.logTime:
243 message = time.strftime("%X", time.localtime(timeStamp)) + \
244 ": " + message
1e4a197e
RD
245 if self.tc:
246 self.tc.AppendText(message + '\n')
76bfdc78
RD
247
248
1fded56b 249class MyTP(wx.PyTipProvider):
861a0196
RD
250 def GetTip(self):
251 return "This is my tip"
252
1fded56b
RD
253#---------------------------------------------------------------------------
254# A class to be used to display source code in the demo. Try using the
299647ac 255# wxSTC in the StyledTextCtrl_2 sample first, fall back to wxTextCtrl
1fded56b 256# if there is an error, such as the stc module not being present.
8b9a4190 257#
1fded56b
RD
258
259try:
260 ##raise ImportError
261 from wx import stc
299647ac 262 from StyledTextCtrl_2 import PythonSTC
1fded56b
RD
263 class DemoCodeViewer(PythonSTC):
264 def __init__(self, parent, ID):
265 PythonSTC.__init__(self, parent, ID)
80b27b4e 266 self.SetUpEditor()
1fded56b
RD
267
268 # Some methods to make it compatible with how the wxTextCtrl is used
269 def SetValue(self, value):
270 self.SetReadOnly(False)
271 self.SetText(value)
272 self.SetReadOnly(True)
273
274 def Clear(self):
275 self.ClearAll()
276
277 def SetInsertionPoint(self, pos):
278 self.SetCurrentPos(pos)
279
280 def ShowPosition(self, pos):
281 self.GotoPos(pos)
282
283 def GetLastPosition(self):
284 return self.GetLength()
285
286 def GetRange(self, start, end):
287 return self.GetTextRange(start, end)
288
289 def GetSelection(self):
290 return self.GetAnchor(), self.GetCurrentPos()
291
292 def SetSelection(self, start, end):
293 self.SetSelectionStart(start)
294 self.SetSelectionEnd(end)
295
80b27b4e
RD
296 def SetUpEditor(self):
297 """
298 This method carries out the work of setting up the demo editor.
299 It's seperate so as not to clutter up the init code.
300 """
301 import keyword
302
303 self.SetLexer(stc.STC_LEX_PYTHON)
304 self.SetKeyWords(0, " ".join(keyword.kwlist))
305
306 # Enable folding
307 self.SetProperty("fold", "1" )
308
309 # Highlight tab/space mixing (shouldn't be any)
310 self.SetProperty("tab.timmy.whinge.level", "1")
311
312 # Set left and right margins
313 self.SetMargins(2,2)
314
315 # Set up the numbers in the margin for margin #1
316 self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
317 # Reasonable value for, say, 4-5 digits using a mono font (40 pix)
318 self.SetMarginWidth(1, 40)
319
320 # Indentation and tab stuff
321 self.SetIndent(4) # Proscribed indent size for wx
322 self.SetIndentationGuides(True) # Show indent guides
323 self.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
324 self.SetTabIndents(True) # Tab key indents
325 self.SetTabWidth(4) # Proscribed tab size for wx
326 self.SetUseTabs(False) # Use spaces rather than tabs, or
327 # TabTimmy will complain!
328 # White space
329 self.SetViewWhiteSpace(False) # Don't view white space
330
331 # EOL
332 #self.SetEOLMode(wx.stc.STC_EOL_CRLF) # Just leave it at the default (autosense)
333 self.SetViewEOL(False)
334 # No right-edge mode indicator
335 self.SetEdgeMode(stc.STC_EDGE_NONE)
336
337 # Setup a margin to hold fold markers
338 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
339 self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
340 self.SetMarginSensitive(2, True)
341 self.SetMarginWidth(2, 12)
342
343 # and now set up the fold markers
344 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "black")
345 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "black")
346 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "black")
347 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "black")
348 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "black")
349 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "black")
350 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "black")
351
352 # Global default style
353 if wx.Platform == '__WXMSW__':
354 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
355 'fore:#000000,back:#FFFFFF,face:Courier New,size:9')
356 else:
357 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
358 'fore:#000000,back:#FFFFFF,face:Courier,size:12')
359
360 # Clear styles and revert to default.
361 self.StyleClearAll()
362
363 # Following style specs only indicate differences from default.
364 # The rest remains unchanged.
365
366 # Line numbers in margin
367 self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')
368
369 # Highlighted brace
370 self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
371 # Unmatched brace
372 self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
373 # Indentation guide
374 self.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
375
376 # Python styles
377 self.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
378 # Comments
a253aa20
RD
379 self.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, 'fore:#008000,back:#F0FFF0')
380 self.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
80b27b4e
RD
381 # Numbers
382 self.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
383 # Strings and characters
384 self.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
385 self.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
386 # Keywords
387 self.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
388 # Triple quotes
389 self.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
390 self.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
391 # Class names
392 self.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
393 # Function names
394 self.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
395 # Operators
396 self.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
397 # Identifiers. I leave this as not bold because everything seems
398 # to be an identifier if it doesn't match the above criterae
399 self.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
400
401 # Caret color
402 self.SetCaretForeground("BLUE")
403 # Selection background
404 self.SetSelBackground(1, '#66CCFF')
405
406 self.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
407 self.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
408
1fded56b
RD
409
410except ImportError:
411 class DemoCodeViewer(wx.TextCtrl):
412 def __init__(self, parent, ID):
413 wx.TextCtrl.__init__(self, parent, ID, style =
414 wx.TE_MULTILINE | wx.TE_READONLY |
415 wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL)
416
417
6c5ae2d2
RD
418#---------------------------------------------------------------------------
419
420def opj(path):
421 """Convert paths to the platform-specific separator"""
1e4a197e 422 return apply(os.path.join, tuple(path.split('/')))
6c5ae2d2
RD
423
424
76bfdc78
RD
425#---------------------------------------------------------------------------
426
1fded56b 427class wxPythonDemo(wx.Frame):
e9159fe8 428 overviewText = "wxPython Overview"
c368d904 429
cf694132 430 def __init__(self, parent, id, title):
1fded56b 431 wx.Frame.__init__(self, parent, -1, title, size = (800, 600),
a253aa20 432 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
2f90df85 433
694759cf 434 self.cwd = os.getcwd()
3ca6a5f0 435 self.curOverview = ""
1e4a197e 436 self.window = None
694759cf 437
afb810d9 438 icon = images.getMondrianIcon()
96bfd053 439 self.SetIcon(icon)
c368d904 440
4a9067b9 441 if wx.Platform != '__WXMAC__':
c368d904 442 # setup a taskbar icon, and catch some events from it
4a9067b9
RD
443 icon = wx.IconFromBitmap(
444 images.getMondrianImage().Scale(16,16).ConvertToBitmap() )
1fded56b 445 self.tbicon = wx.TaskBarIcon()
c368d904 446 self.tbicon.SetIcon(icon, "wxPython Demo")
80b27b4e
RD
447 self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate)
448 self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.OnTaskBarMenu)
449 self.tbicon.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE)
450 self.tbicon.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
c368d904 451
1fded56b 452 wx.CallAfter(self.ShowTip)
cf694132
RD
453
454 self.otherWin = None
80b27b4e
RD
455 self.Bind(wx.EVT_IDLE, self.OnIdle)
456 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
457 self.Bind(wx.EVT_ICONIZE, self.OnIconfiy)
458 self.Bind(wx.EVT_MAXIMIZE, self.OnMaximize)
cf694132 459
1fded56b
RD
460 self.Centre(wx.BOTH)
461 self.CreateStatusBar(1, wx.ST_SIZEGRIP)
5a7823f5 462
8a12f92d
RD
463 splitter = wx.SplitterWindow(self, -1)
464 splitter2 = wx.SplitterWindow(splitter, -1)
5a7823f5 465
8edf1c75
RD
466 # Set up a log on the View Log Notebook page
467 self.log = wx.TextCtrl(splitter2, -1,
468 style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
469
470 # Set the wxWindows log target to be this textctrl
471 #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))
472
473 # But instead of the above we want to show how to use our own wx.Log class
474 wx.Log_SetActiveTarget(MyLog(self.log))
475
476 # for serious debugging
477 #wx.Log_SetActiveTarget(wx.LogStderr())
478 #wx.Log_SetTraceMask(wx.TraceMessages)
479
480
481
d56cebe7 482 def EmptyHandler(evt): pass
80b27b4e
RD
483 #splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
484 #splitter2.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
cf694132 485
1e4a197e
RD
486 # Prevent TreeCtrl from displaying all items after destruction when True
487 self.dying = False
cf694132
RD
488
489 # Make a File menu
1fded56b
RD
490 self.mainmenu = wx.MenuBar()
491 menu = wx.Menu()
492 exitID = wx.NewId()
f0261a72 493 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
80b27b4e 494 self.Bind(wx.EVT_MENU, self.OnFileExit, id=exitID)
1fded56b 495 wx.App_SetMacExitMenuItemId(exitID)
cf694132
RD
496 self.mainmenu.Append(menu, '&File')
497
ec3e670f 498 # Make a Demo menu
1fded56b 499 menu = wx.Menu()
ec3e670f 500 for item in _treeList:
1fded56b 501 submenu = wx.Menu()
ec3e670f 502 for childItem in item[1]:
1fded56b 503 mID = wx.NewId()
ec3e670f 504 submenu.Append(mID, childItem)
80b27b4e 505 self.Bind(wx.EVT_MENU, self.OnDemoMenu, id=mID)
1fded56b 506 menu.AppendMenu(wx.NewId(), item[0], submenu)
ec3e670f
RD
507 self.mainmenu.Append(menu, '&Demo')
508
509
cf694132 510 # Make a Help menu
1fded56b
RD
511 helpID = wx.NewId()
512 findID = wx.NewId()
513 findnextID = wx.NewId()
514 menu = wx.Menu()
1e4a197e
RD
515 menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code')
516 menu.Append(findnextID, 'Find &Next\tF3', 'Find Next')
517 menu.AppendSeparator()
2f90df85 518 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
1fded56b 519 wx.App_SetMacAboutMenuItemId(helpID)
80b27b4e
RD
520 self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=helpID)
521 self.Bind(wx.EVT_MENU, self.OnHelpFind, id=findID)
522 self.Bind(wx.EVT_MENU, self.OnFindNext, id=findnextID)
523 self.Bind(wx.EVT_COMMAND_FIND, self.OnFind)
524 self.Bind(wx.EVT_COMMAND_FIND_NEXT, self.OnFind)
525 self.Bind(wx.EVT_COMMAND_FIND_CLOSE, self.OnFindClose)
cf694132
RD
526 self.mainmenu.Append(menu, '&Help')
527 self.SetMenuBar(self.mainmenu)
528
1fded56b 529 self.finddata = wx.FindReplaceData()
1e4a197e
RD
530
531 if 0:
532 # This is another way to set Accelerators, in addition to
533 # using the '\t<key>' syntax in the menu items.
1fded56b
RD
534 aTable = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), exitID),
535 (wx.ACCEL_CTRL, ord('H'), helpID),
536 (wx.ACCEL_CTRL, ord('F'), findID),
537 (wx.ACCEL_NORMAL, WXK_F3, findnextID)
538 ])
1e4a197e 539 self.SetAcceleratorTable(aTable)
2f90df85 540
bb0054cd 541
cf694132 542 # Create a TreeCtrl
1fded56b 543 tID = wx.NewId()
f6bcfd97 544 self.treeMap = {}
3628e088
RD
545 self.tree = wx.TreeCtrl(splitter, tID, style =
546 wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
eb0f373c 547 )
afb810d9 548
e9159fe8 549 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
550 firstChild = None
551 for item in _treeList:
552 child = self.tree.AppendItem(root, item[0])
553 if not firstChild: firstChild = child
554 for childItem in item[1]:
555 theDemo = self.tree.AppendItem(child, childItem)
556 self.treeMap[childItem] = theDemo
557
558 self.tree.Expand(root)
559 self.tree.Expand(firstChild)
80b27b4e
RD
560 self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, id=tID)
561 self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, id=tID)
562 self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=tID)
563 self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
cf694132 564
cf694132 565 # Create a Notebook
1fded56b 566 self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)
cf694132 567
1fded56b 568 # Set up a wx.html.HtmlWindow on the Overview Notebook page
0bdca46d
RD
569 # we put it in a panel first because there seems to be a
570 # refresh bug of some sort (wxGTK) when it is directly in
571 # the notebook...
572 if 0: # the old way
1fded56b 573 self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
0bdca46d
RD
574 self.nb.AddPage(self.ovr, self.overviewText)
575
1fded56b
RD
576 else: # hopefully I can remove this hacky code soon, see SF bug #216861
577 panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
578 self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
0bdca46d
RD
579 self.nb.AddPage(panel, self.overviewText)
580
581 def OnOvrSize(evt, ovr=self.ovr):
582 ovr.SetSize(evt.GetSize())
583
80b27b4e
RD
584 panel.Bind(wx.EVT_SIZE, OnOvrSize)
585 panel.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
0bdca46d 586
c368d904 587
e9159fe8 588 self.SetOverview(self.overviewText, overview)
cf694132
RD
589
590
1fded56b
RD
591 # Set up a notebook page for viewing the source code of each sample
592 self.txt = DemoCodeViewer(self.nb, -1)
cf694132 593 self.nb.AddPage(self.txt, "Demo Code")
80b27b4e 594 self.LoadDemoSource('Main.py')
cf694132
RD
595
596
f6bcfd97 597 # add the windows to the splitter and split it.
2f0f3b0f 598 splitter2.SplitHorizontally(self.nb, self.log, -120)
1e4a197e 599 splitter.SplitVertically(self.tree, splitter2, 180)
afb810d9 600
f6bcfd97 601 splitter.SetMinimumPaneSize(20)
afb810d9
RD
602 splitter2.SetMinimumPaneSize(20)
603
cf694132 604
2f0f3b0f
RD
605 # Make the splitter on the right expand the top wind when resized
606 def SplitterOnSize(evt):
607 splitter = evt.GetEventObject()
608 sz = splitter.GetSize()
609 splitter.SetSashPosition(sz.height - 120, False)
610 evt.Skip()
80b27b4e
RD
611
612 splitter2.Bind(wx.EVT_SIZE, SplitterOnSize)
2f0f3b0f 613
cf694132 614
bb0054cd
RD
615 # select initial items
616 self.nb.SetSelection(0)
f6bcfd97 617 self.tree.SelectItem(root)
ec3e670f
RD
618
619 if len(sys.argv) == 2:
620 try:
621 selectedDemo = self.treeMap[sys.argv[1]]
622 except:
623 selectedDemo = None
f6bcfd97 624 if selectedDemo:
ec3e670f
RD
625 self.tree.SelectItem(selectedDemo)
626 self.tree.EnsureVisible(selectedDemo)
627
bb0054cd 628
1fded56b 629 wx.LogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
630
631
cf694132
RD
632 #---------------------------------------------
633 def WriteText(self, text):
f6bcfd97
BP
634 if text[-1:] == '\n':
635 text = text[:-1]
1fded56b 636 wx.LogMessage(text)
f6bcfd97 637
cf694132
RD
638
639 def write(self, txt):
640 self.WriteText(txt)
641
642 #---------------------------------------------
643 def OnItemExpanded(self, event):
644 item = event.GetItem()
1fded56b 645 wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 646 event.Skip()
cf694132
RD
647
648 #---------------------------------------------
649 def OnItemCollapsed(self, event):
650 item = event.GetItem()
1fded56b 651 wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 652 event.Skip()
f6bcfd97
BP
653
654 #---------------------------------------------
655 def OnTreeLeftDown(self, event):
656 pt = event.GetPosition();
657 item, flags = self.tree.HitTest(pt)
658 if item == self.tree.GetSelection():
d975da9b 659 self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
185d7c3e 660 event.Skip()
cf694132
RD
661
662 #---------------------------------------------
663 def OnSelChanged(self, event):
664 if self.dying:
665 return
666
5a7823f5
RD
667 item = event.GetItem()
668 itemText = self.tree.GetItemText(item)
669 self.RunDemo(itemText)
670
671
672 #---------------------------------------------
673 def RunDemo(self, itemText):
694759cf 674 os.chdir(self.cwd)
cf694132
RD
675 if self.nb.GetPageCount() == 3:
676 if self.nb.GetSelection() == 2:
677 self.nb.SetSelection(0)
1e4a197e
RD
678 # inform the window that it's time to quit if it cares
679 if self.window is not None:
680 if hasattr(self.window, "ShutdownDemo"):
681 self.window.ShutdownDemo()
1fded56b 682 wx.SafeYield() # in case the page has pending events
cf694132
RD
683 self.nb.DeletePage(2)
684
e9159fe8 685 if itemText == self.overviewText:
80b27b4e 686 self.LoadDemoSource('Main.py')
e9159fe8 687 self.SetOverview(self.overviewText, overview)
cf694132 688 self.nb.Refresh();
e91a9dfc 689 self.window = None
cf694132
RD
690
691 else:
692 if os.path.exists(itemText + '.py'):
1fded56b
RD
693 wx.BeginBusyCursor()
694 wx.LogMessage("Running demo %s.py..." % itemText)
f6bcfd97 695 try:
80b27b4e
RD
696 self.LoadDemoSource(itemText + '.py')
697
698 if (sys.modules.has_key(itemText)):
699 reload(sys.modules[itemText])
700
f6bcfd97 701 module = __import__(itemText, globals())
e9159fe8 702 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97 703 finally:
1fded56b 704 wx.EndBusyCursor()
5a1eefc7 705 self.tree.Refresh()
cf694132
RD
706
707 # in case runTest is modal, make sure things look right...
708 self.nb.Refresh();
1fded56b 709 wx.SafeYield()
cf694132 710
f6bcfd97 711 self.window = module.runTest(self, self.nb, self) ###
1e4a197e 712 if self.window is not None:
e91a9dfc 713 self.nb.AddPage(self.window, 'Demo')
cf694132 714 self.nb.SetSelection(2)
eb28fd47 715 self.nb.Refresh() # without this wxMac has troubles showing the just added page
cf694132
RD
716
717 else:
f6bcfd97 718 self.ovr.SetPage("")
cf694132 719 self.txt.Clear()
e91a9dfc 720 self.window = None
cf694132 721
2f90df85 722
cf694132
RD
723
724 #---------------------------------------------
725 # Get the Demo files
80b27b4e 726 def LoadDemoSource(self, filename):
cf694132 727 self.txt.Clear()
bb0054cd
RD
728 try:
729 self.txt.SetValue(open(filename).read())
8bf5d46e 730 except IOError:
1fded56b 731 self.txt.SetValue("Cannot open %s file." % filename)
cf694132
RD
732
733 self.txt.SetInsertionPoint(0)
734 self.txt.ShowPosition(0)
735
736 #---------------------------------------------
737 def SetOverview(self, name, text):
f6bcfd97
BP
738 self.curOverview = text
739 lead = text[:6]
740 if lead != '<html>' and lead != '<HTML>':
1e4a197e 741 text = '<br>'.join(text.split('\n'))
f6bcfd97 742 self.ovr.SetPage(text)
cf694132 743 self.nb.SetPageText(0, name)
cf694132
RD
744
745 #---------------------------------------------
746 # Menu methods
c368d904 747 def OnFileExit(self, *event):
cf694132
RD
748 self.Close()
749
cf694132 750 def OnHelpAbout(self, event):
e166644c 751 from About import MyAboutBox
ec3e670f 752 about = MyAboutBox(self)
cf694132
RD
753 about.ShowModal()
754 about.Destroy()
755
1e4a197e
RD
756 def OnHelpFind(self, event):
757 self.nb.SetSelection(1)
1fded56b
RD
758 self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
759 wx.FR_NOUPDOWN |
760 wx.FR_NOMATCHCASE |
761 wx.FR_NOWHOLEWORD)
1e4a197e
RD
762 self.finddlg.Show(True)
763
764 def OnFind(self, event):
765 self.nb.SetSelection(1)
766 end = self.txt.GetLastPosition()
767 textstring = self.txt.GetRange(0, end).lower()
768 start = self.txt.GetSelection()[1]
769 findstring = self.finddata.GetFindString().lower()
770 loc = textstring.find(findstring, start)
771 if loc == -1 and start != 0:
772 # string not found, start at beginning
773 start = 0
774 loc = textstring.find(findstring, start)
775 if loc == -1:
1fded56b 776 dlg = wx.MessageDialog(self, 'Find String Not Found',
1e4a197e 777 'Find String Not Found in Demo File',
1fded56b 778 wx.OK | wx.ICON_INFORMATION)
1e4a197e
RD
779 dlg.ShowModal()
780 dlg.Destroy()
781 if self.finddlg:
782 if loc == -1:
783 self.finddlg.SetFocus()
784 return
785 else:
786 self.finddlg.Destroy()
1e4a197e 787 self.txt.ShowPosition(loc)
1fded56b 788 self.txt.SetSelection(loc, loc + len(findstring))
1e4a197e
RD
789
790
791
792 def OnFindNext(self, event):
793 if self.finddata.GetFindString():
794 self.OnFind(event)
795 else:
796 self.OnHelpFind(event)
797
798 def OnFindClose(self, event):
799 event.GetDialog().Destroy()
800
cf694132
RD
801
802 #---------------------------------------------
803 def OnCloseWindow(self, event):
1e4a197e 804 self.dying = True
e91a9dfc 805 self.window = None
26197023 806 self.mainmenu = None
c368d904
RD
807 if hasattr(self, "tbicon"):
808 del self.tbicon
cf694132
RD
809 self.Destroy()
810
c368d904 811
cf694132
RD
812 #---------------------------------------------
813 def OnIdle(self, event):
814 if self.otherWin:
815 self.otherWin.Raise()
e91a9dfc 816 self.window = self.otherWin
cf694132
RD
817 self.otherWin = None
818
ccf691a4
RD
819
820 #---------------------------------------------
821 def ShowTip(self):
822 try:
823 showTipText = open(opj("data/showTips")).read()
824 showTip, index = eval(showTipText)
825 except IOError:
826 showTip, index = (1, 0)
827 if showTip:
1fded56b 828 tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
861a0196 829 ##tp = MyTP(0)
1fded56b 830 showTip = wx.ShowTip(self, tp)
ccf691a4
RD
831 index = tp.GetCurrentTip()
832 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
833
834
ec3e670f
RD
835 #---------------------------------------------
836 def OnDemoMenu(self, event):
f6bcfd97
BP
837 try:
838 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
839 except:
840 selectedDemo = None
841 if selectedDemo:
842 self.tree.SelectItem(selectedDemo)
843 self.tree.EnsureVisible(selectedDemo)
ec3e670f 844
c368d904
RD
845
846 #---------------------------------------------
847 def OnTaskBarActivate(self, evt):
848 if self.IsIconized():
1e4a197e 849 self.Iconize(False)
c368d904 850 if not self.IsShown():
1e4a197e 851 self.Show(True)
c368d904
RD
852 self.Raise()
853
854 #---------------------------------------------
855
856 TBMENU_RESTORE = 1000
857 TBMENU_CLOSE = 1001
858
859 def OnTaskBarMenu(self, evt):
1fded56b 860 menu = wx.Menu()
c368d904
RD
861 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
862 menu.Append(self.TBMENU_CLOSE, "Close")
863 self.tbicon.PopupMenu(menu)
864 menu.Destroy()
865
866 #---------------------------------------------
867 def OnTaskBarClose(self, evt):
868 self.Close()
869
1fded56b 870 # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
c368d904 871 # prod the main idle handler a bit to get the window to actually close
1fded56b 872 wx.GetApp().ProcessIdle()
c368d904
RD
873
874
f3d9dc1d
RD
875 #---------------------------------------------
876 def OnIconfiy(self, evt):
1fded56b 877 wx.LogMessage("OnIconfiy")
f3d9dc1d
RD
878 evt.Skip()
879
880 #---------------------------------------------
881 def OnMaximize(self, evt):
1fded56b 882 wx.LogMessage("OnMaximize")
f3d9dc1d
RD
883 evt.Skip()
884
885
886
887
cf694132
RD
888#---------------------------------------------------------------------------
889#---------------------------------------------------------------------------
890
1fded56b 891class MySplashScreen(wx.SplashScreen):
b5a5d647 892 def __init__(self):
1fded56b
RD
893 bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
894 wx.SplashScreen.__init__(self, bmp,
a253aa20
RD
895 wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
896 3000, None, -1)
80b27b4e 897 self.Bind(wx.EVT_CLOSE, self.OnClose)
b5a5d647
RD
898
899 def OnClose(self, evt):
9fb56e0c 900 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
1e4a197e 901 frame.Show()
ccf691a4 902 evt.Skip() # Make sure the default handler runs too...
cf694132 903
b5a5d647 904
1fded56b 905class MyApp(wx.App):
b5a5d647
RD
906 def OnInit(self):
907 """
68320e40 908 Create and show the splash screen. It will then create and show
b5a5d647
RD
909 the main frame when it is time to do so.
910 """
1e4a197e 911
1fded56b 912 wx.InitAllImageHandlers()
a253aa20
RD
913
914 # Normally when using a SplashScreen you would create it, show
915 # it and then continue on with the applicaiton's
916 # initialization, finally creating and showing the main
917 # application window(s). In this case we have nothing else to
918 # do so we'll delay showing the main frame until later (see
919 # OnClose above) so the users can see the SplashScrren effect.
b5a5d647
RD
920 splash = MySplashScreen()
921 splash.Show()
a253aa20 922
1e4a197e 923 return True
b5a5d647
RD
924
925
926
cf694132
RD
927#---------------------------------------------------------------------------
928
929def main():
e02c03a4 930 try:
d56cebe7 931 demoPath = os.path.dirname(__file__)
e02c03a4
RD
932 os.chdir(demoPath)
933 except:
934 pass
d14a1e28 935 app = MyApp(0) #wx.Platform == "__WXMAC__")
cf694132
RD
936 app.MainLoop()
937
938
939#---------------------------------------------------------------------------
940
941
942
f6bcfd97 943overview = """<html><body>
1fded56b
RD
944<h2>wxPython</h2>
945
946<p> wxPython is a <b>GUI toolkit</b> for the <a
947href="http://www.python.org/">Python</a> programming language. It
948allows Python programmers to create programs with a robust, highly
949functional graphical user interface, simply and easily. It is
950implemented as a Python extension module (native code) that wraps the
951popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
952platform GUI library, which is written in C++.
953
954<p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
955means that it is free for anyone to use and the source code is
956available for anyone to look at and modify. Or anyone can contribute
8b9a4190 957fixes or enhancements to the project.
1fded56b
RD
958
959<p> wxPython is a <b>cross-platform</b> toolkit. This means that the
960same program will run on multiple platforms without modification.
961Currently supported platforms are 32-bit Microsoft Windows, most Unix
962or unix-like systems, and Macintosh OS X. Since the language is
963Python, wxPython programs are <b>simple, easy</b> to write and easy to
964understand.
965
966<p> <b>This demo</b> is not only a collection of test cases for
967wxPython, but is also designed to help you learn about and how to use
968wxPython. Each sample is listed in the tree control on the left.
969When a sample is selected in the tree then a module is loaded and run
970(usually in a tab of this notebook,) and the source code of the module
971is loaded in another tab for you to browse and learn from.
972
973"""
cf694132
RD
974
975
976#----------------------------------------------------------------------------
977#----------------------------------------------------------------------------
978
979if __name__ == '__main__':
980 main()
981
982#----------------------------------------------------------------------------
983
984
985
986
987
988
989