]> git.saurik.com Git - wxWidgets.git/blame_incremental - wxPython/demo/Main.py
Fixed setup.h logic again
[wxWidgets.git] / wxPython / demo / Main.py
... / ...
CommitLineData
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
14import sys, os, time
15
16import wx # This module uses the new wx namespace
17import wx.html
18
19import images
20
21# For debugging
22##wx.Trap();
23##print os.getpid(); raw_input("Press a key...")
24
25
26#---------------------------------------------------------------------------
27
28
29_treeList = [
30 # new stuff
31 ('Recent Additions', [
32 'VListBox',
33 'Listbook',
34 'MaskedNumCtrl',
35 'FloatCanvas',
36 'XmlResourceSubclass',
37 'GridBagSizer',
38 'Cursor',
39 'PyPlot',
40 ]),
41
42 # managed windows == things with a (optional) caption you can close
43 ('Base Frames and Dialogs', [
44 'Dialog',
45 'Frame',
46 'MDIWindows',
47 'MiniFrame',
48 'Wizard',
49 ]),
50
51 # the common dialogs
52 ('Common Dialogs', [
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',
65 ]),
66
67 # dialogs from libraries
68 ('More Dialogs', [
69 'ErrorDialogs',
70 'ImageBrowser',
71 'MultipleChoiceDialog',
72 'ScrolledMessageDialog',
73 ]),
74
75 # core controls
76 ('Core Windows/Controls', [
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',
91 'PopupMenu',
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',
109 ]),
110
111 ('Custom Controls', [
112 'AnalogClockWindow',
113 'ColourSelect',
114 'Editor',
115 'GenericButtons',
116 'GenericDirCtrl',
117 'LEDNumberCtrl',
118 'MultiSash',
119 'PopupControl',
120 'PyColourChooser',
121 'TreeListCtrl',
122 ]),
123
124 # controls coming from other libraries
125 ('More Windows/Controls', [
126 #'RightTextCtrl', deprecated as we have wxTE_RIGHT now.
127 'Calendar',
128 'CalendarCtrl',
129 'ContextHelp',
130 'DynamicSashWindow',
131 'EditableListBox',
132 'FancyText',
133 'FileBrowseButton',
134 'FloatBar',
135 'FloatCanvas',
136 'HtmlWindow',
137 'IEHtmlWin',
138 'IntCtrl',
139 'MVCTree',
140 'MaskedEditControls',
141 'MaskedNumCtrl',
142 'MimeTypesManager',
143 'PyCrust',
144 'PyPlot',
145 'PyShell',
146 'ScrolledPanel',
147 'SplitTree',
148 'StyledTextCtrl_1',
149 'StyledTextCtrl_2',
150 'TablePrint',
151 'Throbber',
152 'TimeCtrl',
153 'VListBox',
154 ]),
155
156 # How to lay out the controls in a frame/dialog
157 ('Window Layout', [
158 'GridBagSizer',
159 'LayoutAnchors',
160 'LayoutConstraints',
161 'Layoutf',
162 'RowColSizer',
163 'ScrolledPanel',
164 'Sizers',
165 'XmlResource',
166 'XmlResourceHandler',
167 'XmlResourceSubclass',
168 ]),
169
170 # ditto
171 ('Process and Events', [
172 'EventManager',
173 'KeyEvents',
174 'OOR',
175 'Process',
176 'PythonEvents',
177 'Threads',
178 'Timer',
179 'infoframe',
180 ]),
181
182 # Clipboard and DnD
183 ('Clipboard and DnD', [
184 'CustomDragAndDrop',
185 'DragAndDrop',
186 'URLDragAndDrop',
187 ]),
188
189 # Images
190 ('Using Images', [
191 'ArtProvider',
192 'Cursor',
193 'DragImage',
194 'Image',
195 'ImageFromStream',
196 'Mask',
197 'Throbber',
198 ]),
199
200 # Other stuff
201 ('Miscellaneous', [
202 'ColourDB',
203 'DialogUnits',
204 'DrawXXXList',
205 'FileHistory',
206 'FontEnumerator',
207 'Joystick',
208 'NewNamespace',
209 'OGL',
210 'PrintFramework',
211 'ShapedWindow',
212 'Unicode',
213 'Wave',
214 ]),
215
216 # need libs not coming with the demo
217 ('Objects using an external library', [
218 'ActiveXWrapper_Acrobat',
219 'ActiveXWrapper_IE',
220 'GLCanvas',
221 #'PlotCanvas', # deprecated, use PyPlot
222 ]),
223
224
225 ('Check out the samples dir too', [
226 ]),
227
228]
229
230
231
232#---------------------------------------------------------------------------
233# Show how to derive a custom wxLog class
234
235class MyLog(wx.PyLog):
236 def __init__(self, textCtrl, logTime=0):
237 wx.PyLog.__init__(self)
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
245 if self.tc:
246 self.tc.AppendText(message + '\n')
247
248
249class MyTP(wx.PyTipProvider):
250 def GetTip(self):
251 return "This is my tip"
252
253#---------------------------------------------------------------------------
254# A class to be used to display source code in the demo. Try using the
255# wxSTC in the StyledTextCtrl_2 sample first, fall back to wxTextCtrl
256# if there is an error, such as the stc module not being present.
257#
258
259try:
260 ##raise ImportError
261 from wx import stc
262 from StyledTextCtrl_2 import PythonSTC
263 class DemoCodeViewer(PythonSTC):
264 def __init__(self, parent, ID):
265 PythonSTC.__init__(self, parent, ID)
266 self.SetUpEditor()
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
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
379 self.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, 'fore:#008000,back:#F0FFF0')
380 self.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
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
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
418#---------------------------------------------------------------------------
419
420def opj(path):
421 """Convert paths to the platform-specific separator"""
422 return apply(os.path.join, tuple(path.split('/')))
423
424
425#---------------------------------------------------------------------------
426
427class wxPythonDemo(wx.Frame):
428 overviewText = "wxPython Overview"
429
430 def __init__(self, parent, id, title):
431 wx.Frame.__init__(self, parent, -1, title, size = (800, 600),
432 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
433
434 self.cwd = os.getcwd()
435 self.curOverview = ""
436 self.window = None
437
438 icon = images.getMondrianIcon()
439 self.SetIcon(icon)
440
441 if wx.Platform != '__WXMAC__':
442 # setup a taskbar icon, and catch some events from it
443 icon = wx.IconFromBitmap(
444 images.getMondrianImage().Scale(16,16).ConvertToBitmap() )
445 self.tbicon = wx.TaskBarIcon()
446 self.tbicon.SetIcon(icon, "wxPython Demo")
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)
451
452 wx.CallAfter(self.ShowTip)
453
454 self.otherWin = None
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)
459
460 self.Centre(wx.BOTH)
461 self.CreateStatusBar(1, wx.ST_SIZEGRIP)
462
463 splitter = wx.SplitterWindow(self, -1)
464 splitter2 = wx.SplitterWindow(splitter, -1)
465
466 # Set up a log on the View Log Notebook page
467 self.log = wx.TextCtrl(splitter2, -1,
468 style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
469
470 # Set the wxWindows log target to be this textctrl
471 #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))
472
473 # But instead of the above we want to show how to use our own wx.Log class
474 wx.Log_SetActiveTarget(MyLog(self.log))
475
476 # for serious debugging
477 #wx.Log_SetActiveTarget(wx.LogStderr())
478 #wx.Log_SetTraceMask(wx.TraceMessages)
479
480
481
482 def EmptyHandler(evt): pass
483 #splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
484 #splitter2.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
485
486 # Prevent TreeCtrl from displaying all items after destruction when True
487 self.dying = False
488
489 # Make a File menu
490 self.mainmenu = wx.MenuBar()
491 menu = wx.Menu()
492 exitID = wx.NewId()
493 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
494 self.Bind(wx.EVT_MENU, self.OnFileExit, id=exitID)
495 wx.App_SetMacExitMenuItemId(exitID)
496 self.mainmenu.Append(menu, '&File')
497
498 # Make a Demo menu
499 menu = wx.Menu()
500 for item in _treeList:
501 submenu = wx.Menu()
502 for childItem in item[1]:
503 mID = wx.NewId()
504 submenu.Append(mID, childItem)
505 self.Bind(wx.EVT_MENU, self.OnDemoMenu, id=mID)
506 menu.AppendMenu(wx.NewId(), item[0], submenu)
507 self.mainmenu.Append(menu, '&Demo')
508
509
510 # Make a Help menu
511 helpID = wx.NewId()
512 findID = wx.NewId()
513 findnextID = wx.NewId()
514 menu = wx.Menu()
515 menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code')
516 menu.Append(findnextID, 'Find &Next\tF3', 'Find Next')
517 menu.AppendSeparator()
518 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
519 wx.App_SetMacAboutMenuItemId(helpID)
520 self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=helpID)
521 self.Bind(wx.EVT_MENU, self.OnHelpFind, id=findID)
522 self.Bind(wx.EVT_MENU, self.OnFindNext, id=findnextID)
523 self.Bind(wx.EVT_COMMAND_FIND, self.OnFind)
524 self.Bind(wx.EVT_COMMAND_FIND_NEXT, self.OnFind)
525 self.Bind(wx.EVT_COMMAND_FIND_CLOSE, self.OnFindClose)
526 self.mainmenu.Append(menu, '&Help')
527 self.SetMenuBar(self.mainmenu)
528
529 self.finddata = wx.FindReplaceData()
530
531 if 0:
532 # This is another way to set Accelerators, in addition to
533 # using the '\t<key>' syntax in the menu items.
534 aTable = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), exitID),
535 (wx.ACCEL_CTRL, ord('H'), helpID),
536 (wx.ACCEL_CTRL, ord('F'), findID),
537 (wx.ACCEL_NORMAL, WXK_F3, findnextID)
538 ])
539 self.SetAcceleratorTable(aTable)
540
541
542 # Create a TreeCtrl
543 tID = wx.NewId()
544 self.treeMap = {}
545 self.tree = wx.TreeCtrl(splitter, tID, style =
546 wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
547 )
548
549 root = self.tree.AddRoot("wxPython Overview")
550 firstChild = None
551 for item in _treeList:
552 child = self.tree.AppendItem(root, item[0])
553 if not firstChild: firstChild = child
554 for childItem in item[1]:
555 theDemo = self.tree.AppendItem(child, childItem)
556 self.treeMap[childItem] = theDemo
557
558 self.tree.Expand(root)
559 self.tree.Expand(firstChild)
560 self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, id=tID)
561 self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, id=tID)
562 self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=tID)
563 self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
564
565 # Create a Notebook
566 self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)
567
568 # Set up a wx.html.HtmlWindow on the Overview Notebook page
569 # we put it in a panel first because there seems to be a
570 # refresh bug of some sort (wxGTK) when it is directly in
571 # the notebook...
572 if 0: # the old way
573 self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
574 self.nb.AddPage(self.ovr, self.overviewText)
575
576 else: # hopefully I can remove this hacky code soon, see SF bug #216861
577 panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
578 self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
579 self.nb.AddPage(panel, self.overviewText)
580
581 def OnOvrSize(evt, ovr=self.ovr):
582 ovr.SetSize(evt.GetSize())
583
584 panel.Bind(wx.EVT_SIZE, OnOvrSize)
585 panel.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
586
587
588 self.SetOverview(self.overviewText, overview)
589
590
591 # Set up a notebook page for viewing the source code of each sample
592 self.txt = DemoCodeViewer(self.nb, -1)
593 self.nb.AddPage(self.txt, "Demo Code")
594 self.LoadDemoSource('Main.py')
595
596
597 # add the windows to the splitter and split it.
598 splitter2.SplitHorizontally(self.nb, self.log, -120)
599 splitter.SplitVertically(self.tree, splitter2, 180)
600
601 splitter.SetMinimumPaneSize(20)
602 splitter2.SetMinimumPaneSize(20)
603
604
605 # Make the splitter on the right expand the top wind when resized
606 def SplitterOnSize(evt):
607 splitter = evt.GetEventObject()
608 sz = splitter.GetSize()
609 splitter.SetSashPosition(sz.height - 120, False)
610 evt.Skip()
611
612 splitter2.Bind(wx.EVT_SIZE, SplitterOnSize)
613
614
615 # select initial items
616 self.nb.SetSelection(0)
617 self.tree.SelectItem(root)
618
619 if len(sys.argv) == 2:
620 try:
621 selectedDemo = self.treeMap[sys.argv[1]]
622 except:
623 selectedDemo = None
624 if selectedDemo:
625 self.tree.SelectItem(selectedDemo)
626 self.tree.EnsureVisible(selectedDemo)
627
628
629 wx.LogMessage('window handle: %s' % self.GetHandle())
630
631
632 #---------------------------------------------
633 def WriteText(self, text):
634 if text[-1:] == '\n':
635 text = text[:-1]
636 wx.LogMessage(text)
637
638
639 def write(self, txt):
640 self.WriteText(txt)
641
642 #---------------------------------------------
643 def OnItemExpanded(self, event):
644 item = event.GetItem()
645 wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
646 event.Skip()
647
648 #---------------------------------------------
649 def OnItemCollapsed(self, event):
650 item = event.GetItem()
651 wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
652 event.Skip()
653
654 #---------------------------------------------
655 def OnTreeLeftDown(self, event):
656 pt = event.GetPosition();
657 item, flags = self.tree.HitTest(pt)
658 if item == self.tree.GetSelection():
659 self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
660 event.Skip()
661
662 #---------------------------------------------
663 def OnSelChanged(self, event):
664 if self.dying:
665 return
666
667 item = event.GetItem()
668 itemText = self.tree.GetItemText(item)
669 self.RunDemo(itemText)
670
671
672 #---------------------------------------------
673 def RunDemo(self, itemText):
674 os.chdir(self.cwd)
675 if self.nb.GetPageCount() == 3:
676 if self.nb.GetSelection() == 2:
677 self.nb.SetSelection(0)
678 # inform the window that it's time to quit if it cares
679 if self.window is not None:
680 if hasattr(self.window, "ShutdownDemo"):
681 self.window.ShutdownDemo()
682 wx.SafeYield() # in case the page has pending events
683 self.nb.DeletePage(2)
684
685 if itemText == self.overviewText:
686 self.LoadDemoSource('Main.py')
687 self.SetOverview(self.overviewText, overview)
688 self.nb.Refresh();
689 self.window = None
690
691 else:
692 if os.path.exists(itemText + '.py'):
693 wx.BeginBusyCursor()
694 wx.LogMessage("Running demo %s.py..." % itemText)
695 try:
696 self.LoadDemoSource(itemText + '.py')
697
698 if (sys.modules.has_key(itemText)):
699 reload(sys.modules[itemText])
700
701 module = __import__(itemText, globals())
702 self.SetOverview(itemText + " Overview", module.overview)
703 finally:
704 wx.EndBusyCursor()
705 self.tree.Refresh()
706
707 # in case runTest is modal, make sure things look right...
708 self.nb.Refresh();
709 wx.SafeYield()
710
711 self.window = module.runTest(self, self.nb, self) ###
712 if self.window is not None:
713 self.nb.AddPage(self.window, 'Demo')
714 self.nb.SetSelection(2)
715 self.nb.Refresh() # without this wxMac has troubles showing the just added page
716
717 else:
718 self.ovr.SetPage("")
719 self.txt.Clear()
720 self.window = None
721
722
723
724 #---------------------------------------------
725 # Get the Demo files
726 def LoadDemoSource(self, filename):
727 self.txt.Clear()
728 try:
729 self.txt.SetValue(open(filename).read())
730 except IOError:
731 self.txt.SetValue("Cannot open %s file." % filename)
732
733 self.txt.SetInsertionPoint(0)
734 self.txt.ShowPosition(0)
735
736 #---------------------------------------------
737 def SetOverview(self, name, text):
738 self.curOverview = text
739 lead = text[:6]
740 if lead != '<html>' and lead != '<HTML>':
741 text = '<br>'.join(text.split('\n'))
742 self.ovr.SetPage(text)
743 self.nb.SetPageText(0, name)
744
745 #---------------------------------------------
746 # Menu methods
747 def OnFileExit(self, *event):
748 self.Close()
749
750 def OnHelpAbout(self, event):
751 from About import MyAboutBox
752 about = MyAboutBox(self)
753 about.ShowModal()
754 about.Destroy()
755
756 def OnHelpFind(self, event):
757 self.nb.SetSelection(1)
758 self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
759 wx.FR_NOUPDOWN |
760 wx.FR_NOMATCHCASE |
761 wx.FR_NOWHOLEWORD)
762 self.finddlg.Show(True)
763
764 def OnFind(self, event):
765 self.nb.SetSelection(1)
766 end = self.txt.GetLastPosition()
767 textstring = self.txt.GetRange(0, end).lower()
768 start = self.txt.GetSelection()[1]
769 findstring = self.finddata.GetFindString().lower()
770 loc = textstring.find(findstring, start)
771 if loc == -1 and start != 0:
772 # string not found, start at beginning
773 start = 0
774 loc = textstring.find(findstring, start)
775 if loc == -1:
776 dlg = wx.MessageDialog(self, 'Find String Not Found',
777 'Find String Not Found in Demo File',
778 wx.OK | wx.ICON_INFORMATION)
779 dlg.ShowModal()
780 dlg.Destroy()
781 if self.finddlg:
782 if loc == -1:
783 self.finddlg.SetFocus()
784 return
785 else:
786 self.finddlg.Destroy()
787 self.txt.ShowPosition(loc)
788 self.txt.SetSelection(loc, loc + len(findstring))
789
790
791
792 def OnFindNext(self, event):
793 if self.finddata.GetFindString():
794 self.OnFind(event)
795 else:
796 self.OnHelpFind(event)
797
798 def OnFindClose(self, event):
799 event.GetDialog().Destroy()
800
801
802 #---------------------------------------------
803 def OnCloseWindow(self, event):
804 self.dying = True
805 self.window = None
806 self.mainmenu = None
807 if hasattr(self, "tbicon"):
808 del self.tbicon
809 self.Destroy()
810
811
812 #---------------------------------------------
813 def OnIdle(self, event):
814 if self.otherWin:
815 self.otherWin.Raise()
816 self.window = self.otherWin
817 self.otherWin = None
818
819
820 #---------------------------------------------
821 def ShowTip(self):
822 try:
823 showTipText = open(opj("data/showTips")).read()
824 showTip, index = eval(showTipText)
825 except IOError:
826 showTip, index = (1, 0)
827 if showTip:
828 tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
829 ##tp = MyTP(0)
830 showTip = wx.ShowTip(self, tp)
831 index = tp.GetCurrentTip()
832 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
833
834
835 #---------------------------------------------
836 def OnDemoMenu(self, event):
837 try:
838 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
839 except:
840 selectedDemo = None
841 if selectedDemo:
842 self.tree.SelectItem(selectedDemo)
843 self.tree.EnsureVisible(selectedDemo)
844
845
846 #---------------------------------------------
847 def OnTaskBarActivate(self, evt):
848 if self.IsIconized():
849 self.Iconize(False)
850 if not self.IsShown():
851 self.Show(True)
852 self.Raise()
853
854 #---------------------------------------------
855
856 TBMENU_RESTORE = 1000
857 TBMENU_CLOSE = 1001
858
859 def OnTaskBarMenu(self, evt):
860 menu = wx.Menu()
861 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
862 menu.Append(self.TBMENU_CLOSE, "Close")
863 self.tbicon.PopupMenu(menu)
864 menu.Destroy()
865
866 #---------------------------------------------
867 def OnTaskBarClose(self, evt):
868 self.Close()
869
870 # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
871 # prod the main idle handler a bit to get the window to actually close
872 wx.GetApp().ProcessIdle()
873
874
875 #---------------------------------------------
876 def OnIconfiy(self, evt):
877 wx.LogMessage("OnIconfiy")
878 evt.Skip()
879
880 #---------------------------------------------
881 def OnMaximize(self, evt):
882 wx.LogMessage("OnMaximize")
883 evt.Skip()
884
885
886
887
888#---------------------------------------------------------------------------
889#---------------------------------------------------------------------------
890
891class MySplashScreen(wx.SplashScreen):
892 def __init__(self):
893 bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
894 wx.SplashScreen.__init__(self, bmp,
895 wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
896 3000, None, -1)
897 self.Bind(wx.EVT_CLOSE, self.OnClose)
898
899 def OnClose(self, evt):
900 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
901 frame.Show()
902 evt.Skip() # Make sure the default handler runs too...
903
904
905class MyApp(wx.App):
906 def OnInit(self):
907 """
908 Create and show the splash screen. It will then create and show
909 the main frame when it is time to do so.
910 """
911
912 wx.InitAllImageHandlers()
913
914 # Normally when using a SplashScreen you would create it, show
915 # it and then continue on with the applicaiton's
916 # initialization, finally creating and showing the main
917 # application window(s). In this case we have nothing else to
918 # do so we'll delay showing the main frame until later (see
919 # OnClose above) so the users can see the SplashScrren effect.
920 splash = MySplashScreen()
921 splash.Show()
922
923 return True
924
925
926
927#---------------------------------------------------------------------------
928
929def main():
930 try:
931 demoPath = os.path.dirname(__file__)
932 os.chdir(demoPath)
933 except:
934 pass
935 app = MyApp(0) #wx.Platform == "__WXMAC__")
936 app.MainLoop()
937
938
939#---------------------------------------------------------------------------
940
941
942
943overview = """<html><body>
944<h2>wxPython</h2>
945
946<p> wxPython is a <b>GUI toolkit</b> for the <a
947href="http://www.python.org/">Python</a> programming language. It
948allows Python programmers to create programs with a robust, highly
949functional graphical user interface, simply and easily. It is
950implemented as a Python extension module (native code) that wraps the
951popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
952platform GUI library, which is written in C++.
953
954<p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
955means that it is free for anyone to use and the source code is
956available for anyone to look at and modify. Or anyone can contribute
957fixes or enhancements to the project.
958
959<p> wxPython is a <b>cross-platform</b> toolkit. This means that the
960same program will run on multiple platforms without modification.
961Currently supported platforms are 32-bit Microsoft Windows, most Unix
962or unix-like systems, and Macintosh OS X. Since the language is
963Python, wxPython programs are <b>simple, easy</b> to write and easy to
964understand.
965
966<p> <b>This demo</b> is not only a collection of test cases for
967wxPython, but is also designed to help you learn about and how to use
968wxPython. Each sample is listed in the tree control on the left.
969When a sample is selected in the tree then a module is loaded and run
970(usually in a tab of this notebook,) and the source code of the module
971is loaded in another tab for you to browse and learn from.
972
973"""
974
975
976#----------------------------------------------------------------------------
977#----------------------------------------------------------------------------
978
979if __name__ == '__main__':
980 main()
981
982#----------------------------------------------------------------------------
983
984
985
986
987
988
989