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