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