]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/Main.py
Other doc updates
[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 'ActiveX_FlashWindow',
43 'ActiveX_IEHtmlWindow',
44 'ActiveX_PDFWindow',
45 ]),
46
47 # managed windows == things with a (optional) caption you can close
48 ('Base Frames and Dialogs', [
49 'Dialog',
50 'Frame',
51 'MDIWindows',
52 'MiniFrame',
53 'Wizard',
54 ]),
55
56 # the common dialogs
57 ('Common Dialogs', [
58 'ColourDialog',
59 'DirDialog',
60 'FileDialog',
61 'FileDialog_Save',
62 'FindReplaceDialog',
63 'FontDialog',
64 'MessageDialog',
65 'PageSetupDialog',
66 'PrintDialog',
67 'ProgressDialog',
68 'SingleChoiceDialog',
69 'TextEntryDialog',
70 ]),
71
72 # dialogs from libraries
73 ('More Dialogs', [
74 'ImageBrowser',
75 'MultipleChoiceDialog',
76 'ScrolledMessageDialog',
77 ]),
78
79 # core controls
80 ('Core Windows/Controls', [
81 'BitmapButton',
82 'Button',
83 'CheckBox',
84 'CheckListBox',
85 'Choice',
86 'ComboBox',
87 'Gauge',
88 'Grid',
89 'Grid_MegaExample',
90 'ListBox',
91 'ListCtrl',
92 'ListCtrl_virtual',
93 'Listbook',
94 'Menu',
95 'Notebook',
96 'PopupMenu',
97 'PopupWindow',
98 'RadioBox',
99 'RadioButton',
100 'SashWindow',
101 'ScrolledWindow',
102 'Slider',
103 'SpinButton',
104 'SpinCtrl',
105 'SplitterWindow',
106 'StaticBitmap',
107 'StaticText',
108 'StatusBar',
109 'TextCtrl',
110 'ToggleButton',
111 'ToolBar',
112 'TreeCtrl',
113 'Validator',
114 ]),
115
116 ('Custom Controls', [
117 'AnalogClockWindow',
118 'ColourSelect',
119 'Editor',
120 'GenericButtons',
121 'GenericDirCtrl',
122 'LEDNumberCtrl',
123 'MultiSash',
124 'PopupControl',
125 'PyColourChooser',
126 'TreeListCtrl',
127 ]),
128
129 # controls coming from other libraries
130 ('More Windows/Controls', [
131 'ActiveX_FlashWindow',
132 'ActiveX_IEHtmlWindow',
133 'ActiveX_PDFWindow',
134 #'RightTextCtrl', deprecated as we have wxTE_RIGHT now.
135 'Calendar',
136 'CalendarCtrl',
137 'ContextHelp',
138 'DynamicSashWindow',
139 'EditableListBox',
140 'FancyText',
141 'FileBrowseButton',
142 'FloatBar',
143 'FloatCanvas',
144 'HtmlWindow',
145 'IntCtrl',
146 'MVCTree',
147 'MaskedEditControls',
148 'MaskedNumCtrl',
149 'MimeTypesManager',
150 'PyCrust',
151 'PyPlot',
152 'PyShell',
153 'ScrolledPanel',
154 'SplitTree',
155 'StyledTextCtrl_1',
156 'StyledTextCtrl_2',
157 'TablePrint',
158 'Throbber',
159 'TimeCtrl',
160 'VListBox',
161 ]),
162
163 # How to lay out the controls in a frame/dialog
164 ('Window Layout', [
165 'GridBagSizer',
166 'LayoutAnchors',
167 'LayoutConstraints',
168 'Layoutf',
169 'RowColSizer',
170 'ScrolledPanel',
171 'Sizers',
172 'XmlResource',
173 'XmlResourceHandler',
174 'XmlResourceSubclass',
175 ]),
176
177 # ditto
178 ('Process and Events', [
179 'EventManager',
180 'KeyEvents',
181 'Process',
182 'PythonEvents',
183 'Threads',
184 'Timer',
185 'infoframe',
186 ]),
187
188 # Clipboard and DnD
189 ('Clipboard and DnD', [
190 'CustomDragAndDrop',
191 'DragAndDrop',
192 'URLDragAndDrop',
193 ]),
194
195 # Images
196 ('Using Images', [
197 'ArtProvider',
198 'Cursor',
199 'DragImage',
200 'Image',
201 'ImageAlpha',
202 'ImageFromStream',
203 'Mask',
204 'Throbber',
205 ]),
206
207 # Other stuff
208 ('Miscellaneous', [
209 'ColourDB',
210 'DialogUnits',
211 'DrawXXXList',
212 'FileHistory',
213 'FontEnumerator',
214 'Joystick',
215 'OGL',
216 'PrintFramework',
217 'ShapedWindow',
218 'Sound',
219 'Unicode',
220 ]),
221
222 # need libs not coming with the demo
223 ('Objects using an external library', [
224 'GLCanvas',
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 self.tree.SetFocus()
725
726
727 #---------------------------------------------
728 # Get the Demo files
729 def LoadDemoSource(self, filename):
730 self.txt.Clear()
731 try:
732 self.txt.SetValue(open(filename).read())
733 except IOError:
734 self.txt.SetValue("Cannot open %s file." % filename)
735
736 self.txt.SetInsertionPoint(0)
737 self.txt.ShowPosition(0)
738
739 #---------------------------------------------
740 def SetOverview(self, name, text):
741 self.curOverview = text
742 lead = text[:6]
743 if lead != '<html>' and lead != '<HTML>':
744 text = '<br>'.join(text.split('\n'))
745 self.ovr.SetPage(text)
746 self.nb.SetPageText(0, name)
747
748 #---------------------------------------------
749 # Menu methods
750 def OnFileExit(self, *event):
751 self.Close()
752
753 def OnToggleRedirect(self, event):
754 app = wx.GetApp()
755 if event.Checked():
756 app.RedirectStdio()
757 print "Print statements and other standard output will now be directed to this window."
758 else:
759 app.RestoreStdio()
760 print "Print statements and other standard output will now be sent to the usual location."
761
762 def OnHelpAbout(self, event):
763 from About import MyAboutBox
764 about = MyAboutBox(self)
765 about.ShowModal()
766 about.Destroy()
767
768 def OnHelpFind(self, event):
769 self.nb.SetSelection(1)
770 self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
771 wx.FR_NOUPDOWN |
772 wx.FR_NOMATCHCASE |
773 wx.FR_NOWHOLEWORD)
774 self.finddlg.Show(True)
775
776 def OnFind(self, event):
777 self.nb.SetSelection(1)
778 end = self.txt.GetLastPosition()
779 textstring = self.txt.GetRange(0, end).lower()
780 start = self.txt.GetSelection()[1]
781 findstring = self.finddata.GetFindString().lower()
782 loc = textstring.find(findstring, start)
783 if loc == -1 and start != 0:
784 # string not found, start at beginning
785 start = 0
786 loc = textstring.find(findstring, start)
787 if loc == -1:
788 dlg = wx.MessageDialog(self, 'Find String Not Found',
789 'Find String Not Found in Demo File',
790 wx.OK | wx.ICON_INFORMATION)
791 dlg.ShowModal()
792 dlg.Destroy()
793 if self.finddlg:
794 if loc == -1:
795 self.finddlg.SetFocus()
796 return
797 else:
798 self.finddlg.Destroy()
799 self.txt.ShowPosition(loc)
800 self.txt.SetSelection(loc, loc + len(findstring))
801
802
803
804 def OnFindNext(self, event):
805 if self.finddata.GetFindString():
806 self.OnFind(event)
807 else:
808 self.OnHelpFind(event)
809
810 def OnFindClose(self, event):
811 event.GetDialog().Destroy()
812
813
814 #---------------------------------------------
815 def OnCloseWindow(self, event):
816 self.dying = True
817 self.window = None
818 self.mainmenu = None
819 self.Destroy()
820
821
822 #---------------------------------------------
823 def OnIdle(self, event):
824 if self.otherWin:
825 self.otherWin.Raise()
826 self.window = self.otherWin
827 self.otherWin = None
828
829
830 #---------------------------------------------
831 def ShowTip(self):
832 try:
833 showTipText = open(opj("data/showTips")).read()
834 showTip, index = eval(showTipText)
835 except IOError:
836 showTip, index = (1, 0)
837 if showTip:
838 tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
839 ##tp = MyTP(0)
840 showTip = wx.ShowTip(self, tp)
841 index = tp.GetCurrentTip()
842 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
843
844
845 #---------------------------------------------
846 def OnDemoMenu(self, event):
847 try:
848 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
849 except:
850 selectedDemo = None
851 if selectedDemo:
852 self.tree.SelectItem(selectedDemo)
853 self.tree.EnsureVisible(selectedDemo)
854
855
856 #---------------------------------------------
857 def OnTaskBarActivate(self, evt):
858 if self.IsIconized():
859 self.Iconize(False)
860 if not self.IsShown():
861 self.Show(True)
862 self.Raise()
863
864 #---------------------------------------------
865
866 TBMENU_RESTORE = 1000
867 TBMENU_CLOSE = 1001
868
869 def OnTaskBarMenu(self, evt):
870 menu = wx.Menu()
871 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
872 menu.Append(self.TBMENU_CLOSE, "Close")
873 self.tbicon.PopupMenu(menu)
874 menu.Destroy()
875
876 #---------------------------------------------
877 def OnTaskBarClose(self, evt):
878 self.Close()
879
880 # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
881 # prod the main idle handler a bit to get the window to actually close
882 wx.GetApp().ProcessIdle()
883
884
885 #---------------------------------------------
886 def OnIconfiy(self, evt):
887 wx.LogMessage("OnIconfiy")
888 evt.Skip()
889
890 #---------------------------------------------
891 def OnMaximize(self, evt):
892 wx.LogMessage("OnMaximize")
893 evt.Skip()
894
895
896
897
898 #---------------------------------------------------------------------------
899 #---------------------------------------------------------------------------
900
901 class MySplashScreen(wx.SplashScreen):
902 def __init__(self):
903 bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
904 wx.SplashScreen.__init__(self, bmp,
905 wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
906 3000, None, -1)
907 self.Bind(wx.EVT_CLOSE, self.OnClose)
908
909 def OnClose(self, evt):
910 self.Hide()
911 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
912 frame.Show()
913 evt.Skip() # Make sure the default handler runs too...
914
915
916 class MyApp(wx.App):
917 def OnInit(self):
918 """
919 Create and show the splash screen. It will then create and show
920 the main frame when it is time to do so.
921 """
922
923 wx.InitAllImageHandlers()
924
925 # Normally when using a SplashScreen you would create it, show
926 # it and then continue on with the applicaiton's
927 # initialization, finally creating and showing the main
928 # application window(s). In this case we have nothing else to
929 # do so we'll delay showing the main frame until later (see
930 # OnClose above) so the users can see the SplashScrren effect.
931 splash = MySplashScreen()
932 splash.Show()
933
934 return True
935
936
937
938 #---------------------------------------------------------------------------
939
940 def main():
941 try:
942 demoPath = os.path.dirname(__file__)
943 os.chdir(demoPath)
944 except:
945 pass
946 app = MyApp(0) ##wx.Platform == "__WXMAC__")
947 app.MainLoop()
948
949
950 #---------------------------------------------------------------------------
951
952
953
954 overview = """<html><body>
955 <h2>wxPython</h2>
956
957 <p> wxPython is a <b>GUI toolkit</b> for the <a
958 href="http://www.python.org/">Python</a> programming language. It
959 allows Python programmers to create programs with a robust, highly
960 functional graphical user interface, simply and easily. It is
961 implemented as a Python extension module (native code) that wraps the
962 popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
963 platform GUI library, which is written in C++.
964
965 <p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
966 means that it is free for anyone to use and the source code is
967 available for anyone to look at and modify. Or anyone can contribute
968 fixes or enhancements to the project.
969
970 <p> wxPython is a <b>cross-platform</b> toolkit. This means that the
971 same program will run on multiple platforms without modification.
972 Currently supported platforms are 32-bit Microsoft Windows, most Unix
973 or unix-like systems, and Macintosh OS X. Since the language is
974 Python, wxPython programs are <b>simple, easy</b> to write and easy to
975 understand.
976
977 <p> <b>This demo</b> is not only a collection of test cases for
978 wxPython, but is also designed to help you learn about and how to use
979 wxPython. Each sample is listed in the tree control on the left.
980 When a sample is selected in the tree then a module is loaded and run
981 (usually in a tab of this notebook,) and the source code of the module
982 is loaded in another tab for you to browse and learn from.
983
984 """
985
986
987 #----------------------------------------------------------------------------
988 #----------------------------------------------------------------------------
989
990 if __name__ == '__main__':
991 main()
992
993 #----------------------------------------------------------------------------
994
995
996
997
998
999
1000