]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
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();
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
d56cebe7 466 def EmptyHandler(evt): pass
80b27b4e
RD
467 #splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
468 #splitter2.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
cf694132 469
1e4a197e
RD
470 # Prevent TreeCtrl from displaying all items after destruction when True
471 self.dying = False
cf694132
RD
472
473 # Make a File menu
1fded56b
RD
474 self.mainmenu = wx.MenuBar()
475 menu = wx.Menu()
476 exitID = wx.NewId()
f0261a72 477 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
80b27b4e 478 self.Bind(wx.EVT_MENU, self.OnFileExit, id=exitID)
1fded56b 479 wx.App_SetMacExitMenuItemId(exitID)
cf694132
RD
480 self.mainmenu.Append(menu, '&File')
481
ec3e670f 482 # Make a Demo menu
1fded56b 483 menu = wx.Menu()
ec3e670f 484 for item in _treeList:
1fded56b 485 submenu = wx.Menu()
ec3e670f 486 for childItem in item[1]:
1fded56b 487 mID = wx.NewId()
ec3e670f 488 submenu.Append(mID, childItem)
80b27b4e 489 self.Bind(wx.EVT_MENU, self.OnDemoMenu, id=mID)
1fded56b 490 menu.AppendMenu(wx.NewId(), item[0], submenu)
ec3e670f
RD
491 self.mainmenu.Append(menu, '&Demo')
492
493
cf694132 494 # Make a Help menu
1fded56b
RD
495 helpID = wx.NewId()
496 findID = wx.NewId()
497 findnextID = wx.NewId()
498 menu = wx.Menu()
1e4a197e
RD
499 menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code')
500 menu.Append(findnextID, 'Find &Next\tF3', 'Find Next')
501 menu.AppendSeparator()
2f90df85 502 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
1fded56b 503 wx.App_SetMacAboutMenuItemId(helpID)
80b27b4e
RD
504 self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=helpID)
505 self.Bind(wx.EVT_MENU, self.OnHelpFind, id=findID)
506 self.Bind(wx.EVT_MENU, self.OnFindNext, id=findnextID)
507 self.Bind(wx.EVT_COMMAND_FIND, self.OnFind)
508 self.Bind(wx.EVT_COMMAND_FIND_NEXT, self.OnFind)
509 self.Bind(wx.EVT_COMMAND_FIND_CLOSE, self.OnFindClose)
cf694132
RD
510 self.mainmenu.Append(menu, '&Help')
511 self.SetMenuBar(self.mainmenu)
512
1fded56b 513 self.finddata = wx.FindReplaceData()
1e4a197e
RD
514
515 if 0:
516 # This is another way to set Accelerators, in addition to
517 # using the '\t<key>' syntax in the menu items.
1fded56b
RD
518 aTable = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), exitID),
519 (wx.ACCEL_CTRL, ord('H'), helpID),
520 (wx.ACCEL_CTRL, ord('F'), findID),
521 (wx.ACCEL_NORMAL, WXK_F3, findnextID)
522 ])
1e4a197e 523 self.SetAcceleratorTable(aTable)
2f90df85 524
bb0054cd 525
cf694132 526 # Create a TreeCtrl
1fded56b 527 tID = wx.NewId()
f6bcfd97 528 self.treeMap = {}
3628e088
RD
529 self.tree = wx.TreeCtrl(splitter, tID, style =
530 wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
eb0f373c 531 )
afb810d9 532
e9159fe8 533 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
534 firstChild = None
535 for item in _treeList:
536 child = self.tree.AppendItem(root, item[0])
537 if not firstChild: firstChild = child
538 for childItem in item[1]:
539 theDemo = self.tree.AppendItem(child, childItem)
540 self.treeMap[childItem] = theDemo
541
542 self.tree.Expand(root)
543 self.tree.Expand(firstChild)
80b27b4e
RD
544 self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, id=tID)
545 self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, id=tID)
546 self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=tID)
547 self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
cf694132 548
cf694132 549 # Create a Notebook
1fded56b 550 self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)
cf694132 551
1fded56b 552 # Set up a wx.html.HtmlWindow on the Overview Notebook page
0bdca46d
RD
553 # we put it in a panel first because there seems to be a
554 # refresh bug of some sort (wxGTK) when it is directly in
555 # the notebook...
556 if 0: # the old way
1fded56b 557 self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
0bdca46d
RD
558 self.nb.AddPage(self.ovr, self.overviewText)
559
1fded56b
RD
560 else: # hopefully I can remove this hacky code soon, see SF bug #216861
561 panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
562 self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
0bdca46d
RD
563 self.nb.AddPage(panel, self.overviewText)
564
565 def OnOvrSize(evt, ovr=self.ovr):
566 ovr.SetSize(evt.GetSize())
567
80b27b4e
RD
568 panel.Bind(wx.EVT_SIZE, OnOvrSize)
569 panel.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
0bdca46d 570
c368d904 571
e9159fe8 572 self.SetOverview(self.overviewText, overview)
cf694132
RD
573
574
1fded56b
RD
575 # Set up a notebook page for viewing the source code of each sample
576 self.txt = DemoCodeViewer(self.nb, -1)
cf694132 577 self.nb.AddPage(self.txt, "Demo Code")
80b27b4e 578 self.LoadDemoSource('Main.py')
cf694132
RD
579
580
cf694132 581 # Set up a log on the View Log Notebook page
1fded56b
RD
582 self.log = wx.TextCtrl(splitter2, -1,
583 style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
342639eb 584
f6bcfd97 585 # Set the wxWindows log target to be this textctrl
1fded56b 586 #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))
342639eb 587
1fded56b
RD
588 # But instead of the above we want to show how to use our own wx.Log class
589 wx.Log_SetActiveTarget(MyLog(self.log))
cf694132 590
f9b24f07 591 # for serious debugging
1fded56b
RD
592 #wx.Log_SetActiveTarget(wx.LogStderr())
593 #wx.Log_SetTraceMask(wx.TraceMessages)
5a7823f5 594
f9b24f07 595
f6bcfd97 596 # add the windows to the splitter and split it.
2f0f3b0f 597 splitter2.SplitHorizontally(self.nb, self.log, -120)
1e4a197e 598 splitter.SplitVertically(self.tree, splitter2, 180)
afb810d9 599
f6bcfd97 600 splitter.SetMinimumPaneSize(20)
afb810d9
RD
601 splitter2.SetMinimumPaneSize(20)
602
cf694132 603
2f0f3b0f
RD
604 # Make the splitter on the right expand the top wind when resized
605 def SplitterOnSize(evt):
606 splitter = evt.GetEventObject()
607 sz = splitter.GetSize()
608 splitter.SetSashPosition(sz.height - 120, False)
609 evt.Skip()
80b27b4e
RD
610
611 splitter2.Bind(wx.EVT_SIZE, SplitterOnSize)
2f0f3b0f 612
cf694132 613
bb0054cd
RD
614 # select initial items
615 self.nb.SetSelection(0)
f6bcfd97 616 self.tree.SelectItem(root)
ec3e670f
RD
617
618 if len(sys.argv) == 2:
619 try:
620 selectedDemo = self.treeMap[sys.argv[1]]
621 except:
622 selectedDemo = None
f6bcfd97 623 if selectedDemo:
ec3e670f
RD
624 self.tree.SelectItem(selectedDemo)
625 self.tree.EnsureVisible(selectedDemo)
626
bb0054cd 627
1fded56b 628 wx.LogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
629
630
cf694132
RD
631 #---------------------------------------------
632 def WriteText(self, text):
f6bcfd97
BP
633 if text[-1:] == '\n':
634 text = text[:-1]
1fded56b 635 wx.LogMessage(text)
f6bcfd97 636
cf694132
RD
637
638 def write(self, txt):
639 self.WriteText(txt)
640
641 #---------------------------------------------
642 def OnItemExpanded(self, event):
643 item = event.GetItem()
1fded56b 644 wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 645 event.Skip()
cf694132
RD
646
647 #---------------------------------------------
648 def OnItemCollapsed(self, event):
649 item = event.GetItem()
1fded56b 650 wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 651 event.Skip()
f6bcfd97
BP
652
653 #---------------------------------------------
654 def OnTreeLeftDown(self, event):
655 pt = event.GetPosition();
656 item, flags = self.tree.HitTest(pt)
657 if item == self.tree.GetSelection():
d975da9b 658 self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
185d7c3e 659 event.Skip()
cf694132
RD
660
661 #---------------------------------------------
662 def OnSelChanged(self, event):
663 if self.dying:
664 return
665
5a7823f5
RD
666 item = event.GetItem()
667 itemText = self.tree.GetItemText(item)
668 self.RunDemo(itemText)
669
670
671 #---------------------------------------------
672 def RunDemo(self, itemText):
694759cf 673 os.chdir(self.cwd)
cf694132
RD
674 if self.nb.GetPageCount() == 3:
675 if self.nb.GetSelection() == 2:
676 self.nb.SetSelection(0)
1e4a197e
RD
677 # inform the window that it's time to quit if it cares
678 if self.window is not None:
679 if hasattr(self.window, "ShutdownDemo"):
680 self.window.ShutdownDemo()
1fded56b 681 wx.SafeYield() # in case the page has pending events
cf694132
RD
682 self.nb.DeletePage(2)
683
e9159fe8 684 if itemText == self.overviewText:
80b27b4e 685 self.LoadDemoSource('Main.py')
e9159fe8 686 self.SetOverview(self.overviewText, overview)
cf694132 687 self.nb.Refresh();
e91a9dfc 688 self.window = None
cf694132
RD
689
690 else:
691 if os.path.exists(itemText + '.py'):
1fded56b
RD
692 wx.BeginBusyCursor()
693 wx.LogMessage("Running demo %s.py..." % itemText)
f6bcfd97 694 try:
80b27b4e
RD
695 self.LoadDemoSource(itemText + '.py')
696
697 if (sys.modules.has_key(itemText)):
698 reload(sys.modules[itemText])
699
f6bcfd97 700 module = __import__(itemText, globals())
e9159fe8 701 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97 702 finally:
1fded56b 703 wx.EndBusyCursor()
5a1eefc7 704 self.tree.Refresh()
cf694132
RD
705
706 # in case runTest is modal, make sure things look right...
707 self.nb.Refresh();
1fded56b 708 wx.SafeYield()
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)
eb28fd47 714 self.nb.Refresh() # without this wxMac has troubles showing the just added page
cf694132
RD
715
716 else:
f6bcfd97 717 self.ovr.SetPage("")
cf694132 718 self.txt.Clear()
e91a9dfc 719 self.window = None
cf694132 720
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'))
f6bcfd97 741 self.ovr.SetPage(text)
cf694132 742 self.nb.SetPageText(0, name)
cf694132
RD
743
744 #---------------------------------------------
745 # Menu methods
c368d904 746 def OnFileExit(self, *event):
cf694132
RD
747 self.Close()
748
cf694132 749 def OnHelpAbout(self, event):
e166644c 750 from About import MyAboutBox
ec3e670f 751 about = MyAboutBox(self)
cf694132
RD
752 about.ShowModal()
753 about.Destroy()
754
1e4a197e
RD
755 def OnHelpFind(self, event):
756 self.nb.SetSelection(1)
1fded56b
RD
757 self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
758 wx.FR_NOUPDOWN |
759 wx.FR_NOMATCHCASE |
760 wx.FR_NOWHOLEWORD)
1e4a197e
RD
761 self.finddlg.Show(True)
762
763 def OnFind(self, event):
764 self.nb.SetSelection(1)
765 end = self.txt.GetLastPosition()
766 textstring = self.txt.GetRange(0, end).lower()
767 start = self.txt.GetSelection()[1]
768 findstring = self.finddata.GetFindString().lower()
769 loc = textstring.find(findstring, start)
770 if loc == -1 and start != 0:
771 # string not found, start at beginning
772 start = 0
773 loc = textstring.find(findstring, start)
774 if loc == -1:
1fded56b 775 dlg = wx.MessageDialog(self, 'Find String Not Found',
1e4a197e 776 'Find String Not Found in Demo File',
1fded56b 777 wx.OK | wx.ICON_INFORMATION)
1e4a197e
RD
778 dlg.ShowModal()
779 dlg.Destroy()
780 if self.finddlg:
781 if loc == -1:
782 self.finddlg.SetFocus()
783 return
784 else:
785 self.finddlg.Destroy()
1e4a197e 786 self.txt.ShowPosition(loc)
1fded56b 787 self.txt.SetSelection(loc, loc + len(findstring))
1e4a197e
RD
788
789
790
791 def OnFindNext(self, event):
792 if self.finddata.GetFindString():
793 self.OnFind(event)
794 else:
795 self.OnHelpFind(event)
796
797 def OnFindClose(self, event):
798 event.GetDialog().Destroy()
799
cf694132
RD
800
801 #---------------------------------------------
802 def OnCloseWindow(self, event):
1e4a197e 803 self.dying = True
e91a9dfc 804 self.window = None
26197023 805 self.mainmenu = None
c368d904
RD
806 if hasattr(self, "tbicon"):
807 del self.tbicon
cf694132
RD
808 self.Destroy()
809
c368d904 810
cf694132
RD
811 #---------------------------------------------
812 def OnIdle(self, event):
813 if self.otherWin:
814 self.otherWin.Raise()
e91a9dfc 815 self.window = self.otherWin
cf694132
RD
816 self.otherWin = None
817
ccf691a4
RD
818
819 #---------------------------------------------
820 def ShowTip(self):
821 try:
822 showTipText = open(opj("data/showTips")).read()
823 showTip, index = eval(showTipText)
824 except IOError:
825 showTip, index = (1, 0)
826 if showTip:
1fded56b 827 tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
861a0196 828 ##tp = MyTP(0)
1fded56b 829 showTip = wx.ShowTip(self, tp)
ccf691a4
RD
830 index = tp.GetCurrentTip()
831 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
832
833
ec3e670f
RD
834 #---------------------------------------------
835 def OnDemoMenu(self, event):
f6bcfd97
BP
836 try:
837 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
838 except:
839 selectedDemo = None
840 if selectedDemo:
841 self.tree.SelectItem(selectedDemo)
842 self.tree.EnsureVisible(selectedDemo)
ec3e670f 843
c368d904
RD
844
845 #---------------------------------------------
846 def OnTaskBarActivate(self, evt):
847 if self.IsIconized():
1e4a197e 848 self.Iconize(False)
c368d904 849 if not self.IsShown():
1e4a197e 850 self.Show(True)
c368d904
RD
851 self.Raise()
852
853 #---------------------------------------------
854
855 TBMENU_RESTORE = 1000
856 TBMENU_CLOSE = 1001
857
858 def OnTaskBarMenu(self, evt):
1fded56b 859 menu = wx.Menu()
c368d904
RD
860 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
861 menu.Append(self.TBMENU_CLOSE, "Close")
862 self.tbicon.PopupMenu(menu)
863 menu.Destroy()
864
865 #---------------------------------------------
866 def OnTaskBarClose(self, evt):
867 self.Close()
868
1fded56b 869 # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
c368d904 870 # prod the main idle handler a bit to get the window to actually close
1fded56b 871 wx.GetApp().ProcessIdle()
c368d904
RD
872
873
f3d9dc1d
RD
874 #---------------------------------------------
875 def OnIconfiy(self, evt):
1fded56b 876 wx.LogMessage("OnIconfiy")
f3d9dc1d
RD
877 evt.Skip()
878
879 #---------------------------------------------
880 def OnMaximize(self, evt):
1fded56b 881 wx.LogMessage("OnMaximize")
f3d9dc1d
RD
882 evt.Skip()
883
884
885
886
cf694132
RD
887#---------------------------------------------------------------------------
888#---------------------------------------------------------------------------
889
1fded56b 890class MySplashScreen(wx.SplashScreen):
b5a5d647 891 def __init__(self):
1fded56b
RD
892 bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
893 wx.SplashScreen.__init__(self, bmp,
a253aa20
RD
894 wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
895 3000, None, -1)
80b27b4e 896 self.Bind(wx.EVT_CLOSE, self.OnClose)
b5a5d647
RD
897
898 def OnClose(self, evt):
9fb56e0c 899 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
1e4a197e 900 frame.Show()
ccf691a4 901 evt.Skip() # Make sure the default handler runs too...
cf694132 902
b5a5d647 903
1fded56b 904class MyApp(wx.App):
b5a5d647
RD
905 def OnInit(self):
906 """
68320e40 907 Create and show the splash screen. It will then create and show
b5a5d647
RD
908 the main frame when it is time to do so.
909 """
1e4a197e 910
1fded56b 911 wx.InitAllImageHandlers()
a253aa20
RD
912
913 # Normally when using a SplashScreen you would create it, show
914 # it and then continue on with the applicaiton's
915 # initialization, finally creating and showing the main
916 # application window(s). In this case we have nothing else to
917 # do so we'll delay showing the main frame until later (see
918 # OnClose above) so the users can see the SplashScrren effect.
b5a5d647
RD
919 splash = MySplashScreen()
920 splash.Show()
a253aa20 921
1e4a197e 922 return True
b5a5d647
RD
923
924
925
cf694132
RD
926#---------------------------------------------------------------------------
927
928def main():
e02c03a4 929 try:
d56cebe7 930 demoPath = os.path.dirname(__file__)
e02c03a4
RD
931 os.chdir(demoPath)
932 except:
933 pass
d14a1e28 934 app = MyApp(0) #wx.Platform == "__WXMAC__")
cf694132
RD
935 app.MainLoop()
936
937
938#---------------------------------------------------------------------------
939
940
941
f6bcfd97 942overview = """<html><body>
1fded56b
RD
943<h2>wxPython</h2>
944
945<p> wxPython is a <b>GUI toolkit</b> for the <a
946href="http://www.python.org/">Python</a> programming language. It
947allows Python programmers to create programs with a robust, highly
948functional graphical user interface, simply and easily. It is
949implemented as a Python extension module (native code) that wraps the
950popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
951platform GUI library, which is written in C++.
952
953<p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
954means that it is free for anyone to use and the source code is
955available for anyone to look at and modify. Or anyone can contribute
8b9a4190 956fixes or enhancements to the project.
1fded56b
RD
957
958<p> wxPython is a <b>cross-platform</b> toolkit. This means that the
959same program will run on multiple platforms without modification.
960Currently supported platforms are 32-bit Microsoft Windows, most Unix
961or unix-like systems, and Macintosh OS X. Since the language is
962Python, wxPython programs are <b>simple, easy</b> to write and easy to
963understand.
964
965<p> <b>This demo</b> is not only a collection of test cases for
966wxPython, but is also designed to help you learn about and how to use
967wxPython. Each sample is listed in the tree control on the left.
968When a sample is selected in the tree then a module is loaded and run
969(usually in a tab of this notebook,) and the source code of the module
970is loaded in another tab for you to browse and learn from.
971
972"""
cf694132
RD
973
974
975#----------------------------------------------------------------------------
976#----------------------------------------------------------------------------
977
978if __name__ == '__main__':
979 main()
980
981#----------------------------------------------------------------------------
982
983
984
985
986
987
988