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