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