]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Updated the description of wx.PopupTransientWindow
[wxWidgets.git] / wxPython / demo / Main.py
CommitLineData
cf694132
RD
1#!/bin/env python
2#----------------------------------------------------------------------------
3# Name: Main.py
4# Purpose: Testing lots of stuff, controls, window types, etc.
5#
f6bcfd97 6# Author: Robin Dunn
cf694132 7#
f6bcfd97 8# Created: A long time ago, in a galaxy far, far away...
cf694132
RD
9# RCS-ID: $Id$
10# Copyright: (c) 1999 by Total Control Software
11# Licence: wxWindows license
12#----------------------------------------------------------------------------
13
1e4a197e 14import sys, os, time
cf694132 15
1fded56b
RD
16import wx # This module uses the new wx namespace
17import wx.html
606d919c 18
96bfd053
RD
19import images
20
d14a1e28
RD
21# For debugging
22##wx.Trap();
23##print os.getpid(); raw_input("Press a key...")
6fa68946 24
1e4a197e 25
cf694132
RD
26#---------------------------------------------------------------------------
27
28
29_treeList = [
9c67cbec 30 # new stuff
1e4a197e 31 ('Recent Additions', [
3628e088 32 'wxVListBox',
2f0f3b0f 33 'wxListbook',
8b9a4190
RD
34 'wxMaskedNumCtrl',
35 'FloatCanvas',
6fa68946 36 'wxXmlResourceSubclass',
d14a1e28 37 'wxGridBagSizer',
9c67cbec
RD
38 ]),
39
1e4a197e 40 # managed windows == things with a (optional) caption you can close
9c67cbec
RD
41 ('Base Frames and Dialogs', [
42 'wxDialog',
43 'wxFrame',
44 'wxMDIWindows',
45 'wxMiniFrame',
af83019e 46 'wxWizard',
9c67cbec
RD
47 ]),
48
49 # the common dialogs
50 ('Common Dialogs', [
51 'wxColourDialog',
52 'wxDirDialog',
53 'wxFileDialog',
1fded56b 54 'wxFileDialog_Save',
9c67cbec
RD
55 'wxFindReplaceDialog',
56 'wxFontDialog',
57 'wxMessageDialog',
58 'wxPageSetupDialog',
59 'wxPrintDialog',
60 'wxProgressDialog',
61 'wxSingleChoiceDialog',
62 'wxTextEntryDialog',
63 ]),
64
af83019e 65 # dialogs from libraries
9c67cbec
RD
66 ('More Dialogs', [
67 'ErrorDialogs',
68 'ImageBrowser',
69 'wxMultipleChoiceDialog',
70 'wxScrolledMessageDialog',
71 ]),
72
73 # core controls
74 ('Core Windows/Controls', [
1fded56b 75 'PopupMenu',
9c67cbec
RD
76 'wxButton',
77 'wxCheckBox',
78 'wxCheckListBox',
79 'wxChoice',
80 'wxComboBox',
81 'wxGauge',
9c67cbec 82 'wxGrid',
1fded56b 83 'wxGrid_MegaExample',
2f0f3b0f 84 'wxListbook',
9c67cbec
RD
85 'wxListBox',
86 'wxListCtrl',
6f48b1b5 87 'wxListCtrl_virtual',
3115ef3e 88 'wxMenu',
9c67cbec
RD
89 'wxNotebook',
90 'wxPopupWindow',
91 'wxRadioBox',
1e4a197e 92 'wxRadioButton',
9c67cbec 93 'wxSashWindow',
9c67cbec 94 'wxScrolledWindow',
1e4a197e 95 'wxSlider',
9c67cbec
RD
96 'wxSpinButton',
97 'wxSpinCtrl',
1e4a197e 98 'wxSplitterWindow',
9c67cbec 99 'wxStaticBitmap',
1e4a197e 100 'wxStaticText',
9c67cbec
RD
101 'wxStatusBar',
102 'wxTextCtrl',
9c67cbec
RD
103 'wxToggleButton',
104 'wxToolBar',
105 'wxTreeCtrl',
106 'wxValidator',
107 ]),
108
d14a1e28
RD
109 ('Custom Controls', [
110 'AnalogClockWindow',
111 'ColourSelect',
112 'GenericButtons',
113 'wxEditor',
114 'wxGenericDirCtrl',
115 'wxLEDNumberCtrl',
116 'wxMultiSash',
117 'wxPopupControl',
118 'wxPyColourChooser',
119 'wxTreeListCtrl',
120 ]),
121
8b9a4190 122 # controls coming from other libraries
9c67cbec 123 ('More Windows/Controls', [
1e4a197e
RD
124 #'wxFloatBar', deprecated
125 #'wxMVCTree', deprecated
1fded56b 126 #'wxRightTextCtrl', deprecated as we have wxTE_RIGHT now.
9c67cbec
RD
127 'ContextHelp',
128 'FancyText',
8b9a4190 129 'FloatCanvas',
9c67cbec 130 'FileBrowseButton',
1fded56b
RD
131 'MaskedEditControls',
132 'PyShell',
9c67cbec 133 'PyCrust',
9c67cbec
RD
134 'SplitTree',
135 'TablePrint',
1e4a197e 136 'Throbber',
9c67cbec
RD
137 'wxCalendar',
138 'wxCalendarCtrl',
139 'wxDynamicSashWindow',
140 'wxEditableListBox',
9c67cbec 141 'wxHtmlWindow',
c731eb47 142 'wxIEHtmlWin',
1e4a197e 143 'wxIntCtrl',
9c67cbec 144 'wxMimeTypesManager',
8b9a4190 145 'wxMaskedNumCtrl',
fd3f2efe 146 'wxScrolledPanel',
9c67cbec
RD
147 'wxStyledTextCtrl_1',
148 'wxStyledTextCtrl_2',
1e4a197e 149 'wxTimeCtrl',
3628e088 150 'wxVListBox',
9c67cbec
RD
151 ]),
152
153 # How to lay out the controls in a frame/dialog
154 ('Window Layout', [
155 'LayoutAnchors',
156 'Layoutf',
157 'RowColSizer',
158 'Sizers',
d14a1e28 159 'wxGridBagSizer',
9c67cbec 160 'wxLayoutConstraints',
1e4a197e 161 'wxScrolledPanel',
628c7f79
RD
162 'wxXmlResource',
163 'wxXmlResourceHandler',
6fa68946 164 'wxXmlResourceSubclass',
9c67cbec
RD
165 ]),
166
167 # ditto
168 ('Process and Events', [
1e4a197e 169 'EventManager',
9c67cbec
RD
170 'infoframe',
171 'OOR',
172 'PythonEvents',
173 'Threads',
1e4a197e 174 'wxKeyEvents',
9c67cbec
RD
175 'wxProcess',
176 'wxTimer',
177 ]),
178
179 # Clipboard and DnD
180 ('Clipboard and DnD', [
181 'CustomDragAndDrop',
182 'DragAndDrop',
183 'URLDragAndDrop',
184 ]),
185
186 # Images
1e4a197e
RD
187 ('Using Images', [
188 'Throbber',
189 'wxArtProvider',
9c67cbec
RD
190 'wxDragImage',
191 'wxImage',
192 'wxImageFromStream',
193 'wxMask',
194 ]),
195
196 # Other stuff
197 ('Miscellaneous', [
198 'ColourDB',
199 'DialogUnits',
200 'DrawXXXList',
201 'FontEnumerator',
3628e088 202 'NewNamespace',
9c67cbec 203 'PrintFramework',
3628e088 204 'ShapedWindow',
1e4a197e 205 'Throbber',
9c67cbec
RD
206 'Unicode',
207 'wxFileHistory',
208 'wxJoystick',
209 'wxOGL',
210 'wxWave',
211 ]),
212
213 # need libs not coming with the demo
214 ('Objects using an external library', [
215 'ActiveXWrapper_Acrobat',
216 'ActiveXWrapper_IE',
217 'wxGLCanvas',
218 'wxPlotCanvas',
9c67cbec
RD
219 ]),
220
70a357c2 221
9c67cbec
RD
222 ('Check out the samples dir too', [
223 ]),
224
9c67cbec
RD
225]
226
227
cf694132
RD
228
229#---------------------------------------------------------------------------
8b9a4190 230# Show how to derive a custom wxLog class
cf694132 231
1fded56b 232class MyLog(wx.PyLog):
76bfdc78 233 def __init__(self, textCtrl, logTime=0):
1fded56b 234 wx.PyLog.__init__(self)
76bfdc78
RD
235 self.tc = textCtrl
236 self.logTime = logTime
237
238 def DoLogString(self, message, timeStamp):
239 if self.logTime:
240 message = time.strftime("%X", time.localtime(timeStamp)) + \
241 ": " + message
1e4a197e
RD
242 if self.tc:
243 self.tc.AppendText(message + '\n')
76bfdc78
RD
244
245
1fded56b 246class MyTP(wx.PyTipProvider):
861a0196
RD
247 def GetTip(self):
248 return "This is my tip"
249
1fded56b
RD
250#---------------------------------------------------------------------------
251# A class to be used to display source code in the demo. Try using the
252# wxSTC in the wxStyledTextCtrl_2 sample first, fall back to wxTextCtrl
253# if there is an error, such as the stc module not being present.
8b9a4190 254#
1fded56b
RD
255
256try:
257 ##raise ImportError
258 from wx import stc
259 from wxStyledTextCtrl_2 import PythonSTC
260 class DemoCodeViewer(PythonSTC):
261 def __init__(self, parent, ID):
262 PythonSTC.__init__(self, parent, ID)
263 self.SetEdgeMode(stc.STC_EDGE_NONE)
264 self.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
265 self.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
266
267 # Some methods to make it compatible with how the wxTextCtrl is used
268 def SetValue(self, value):
269 self.SetReadOnly(False)
270 self.SetText(value)
271 self.SetReadOnly(True)
272
273 def Clear(self):
274 self.ClearAll()
275
276 def SetInsertionPoint(self, pos):
277 self.SetCurrentPos(pos)
278
279 def ShowPosition(self, pos):
280 self.GotoPos(pos)
281
282 def GetLastPosition(self):
283 return self.GetLength()
284
285 def GetRange(self, start, end):
286 return self.GetTextRange(start, end)
287
288 def GetSelection(self):
289 return self.GetAnchor(), self.GetCurrentPos()
290
291 def SetSelection(self, start, end):
292 self.SetSelectionStart(start)
293 self.SetSelectionEnd(end)
294
295
296except ImportError:
297 class DemoCodeViewer(wx.TextCtrl):
298 def __init__(self, parent, ID):
299 wx.TextCtrl.__init__(self, parent, ID, style =
300 wx.TE_MULTILINE | wx.TE_READONLY |
301 wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL)
302
303
6c5ae2d2
RD
304#---------------------------------------------------------------------------
305
306def opj(path):
307 """Convert paths to the platform-specific separator"""
1e4a197e 308 return apply(os.path.join, tuple(path.split('/')))
6c5ae2d2
RD
309
310
76bfdc78
RD
311#---------------------------------------------------------------------------
312
1fded56b 313class wxPythonDemo(wx.Frame):
e9159fe8 314 overviewText = "wxPython Overview"
c368d904 315
cf694132 316 def __init__(self, parent, id, title):
1fded56b
RD
317 wx.Frame.__init__(self, parent, -1, title, size = (800, 600),
318 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
2f90df85 319
694759cf 320 self.cwd = os.getcwd()
3ca6a5f0 321 self.curOverview = ""
1e4a197e 322 self.window = None
694759cf 323
afb810d9 324 icon = images.getMondrianIcon()
96bfd053 325 self.SetIcon(icon)
c368d904 326
1fded56b 327 if wx.Platform == '__WXMSW__':
c368d904 328 # setup a taskbar icon, and catch some events from it
1fded56b 329 self.tbicon = wx.TaskBarIcon()
c368d904 330 self.tbicon.SetIcon(icon, "wxPython Demo")
1fded56b
RD
331 wx.EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
332 wx.EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
333 wx.EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
334 wx.EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
c368d904 335
1fded56b 336 wx.CallAfter(self.ShowTip)
cf694132
RD
337
338 self.otherWin = None
1fded56b
RD
339 wx.EVT_IDLE(self, self.OnIdle)
340 wx.EVT_CLOSE(self, self.OnCloseWindow)
341 wx.EVT_ICONIZE(self, self.OnIconfiy)
342 wx.EVT_MAXIMIZE(self, self.OnMaximize)
cf694132 343
1fded56b
RD
344 self.Centre(wx.BOTH)
345 self.CreateStatusBar(1, wx.ST_SIZEGRIP)
5a7823f5 346
8a12f92d
RD
347 splitter = wx.SplitterWindow(self, -1)
348 splitter2 = wx.SplitterWindow(splitter, -1)
5a7823f5 349
d56cebe7 350 def EmptyHandler(evt): pass
2f0f3b0f
RD
351 #wx.EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
352 #wx.EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
cf694132 353
1e4a197e
RD
354 # Prevent TreeCtrl from displaying all items after destruction when True
355 self.dying = False
cf694132
RD
356
357 # Make a File menu
1fded56b
RD
358 self.mainmenu = wx.MenuBar()
359 menu = wx.Menu()
360 exitID = wx.NewId()
f0261a72 361 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
1fded56b
RD
362 wx.EVT_MENU(self, exitID, self.OnFileExit)
363 wx.App_SetMacExitMenuItemId(exitID)
cf694132
RD
364 self.mainmenu.Append(menu, '&File')
365
ec3e670f 366 # Make a Demo menu
1fded56b 367 menu = wx.Menu()
ec3e670f 368 for item in _treeList:
1fded56b 369 submenu = wx.Menu()
ec3e670f 370 for childItem in item[1]:
1fded56b 371 mID = wx.NewId()
ec3e670f 372 submenu.Append(mID, childItem)
1fded56b
RD
373 wx.EVT_MENU(self, mID, self.OnDemoMenu)
374 menu.AppendMenu(wx.NewId(), item[0], submenu)
ec3e670f
RD
375 self.mainmenu.Append(menu, '&Demo')
376
377
cf694132 378 # Make a Help menu
1fded56b
RD
379 helpID = wx.NewId()
380 findID = wx.NewId()
381 findnextID = wx.NewId()
382 menu = wx.Menu()
1e4a197e
RD
383 menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code')
384 menu.Append(findnextID, 'Find &Next\tF3', 'Find Next')
385 menu.AppendSeparator()
2f90df85 386 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
1fded56b
RD
387 wx.App_SetMacAboutMenuItemId(helpID)
388 wx.EVT_MENU(self, helpID, self.OnHelpAbout)
389 wx.EVT_MENU(self, findID, self.OnHelpFind)
390 wx.EVT_MENU(self, findnextID, self.OnFindNext)
391 wx.EVT_COMMAND_FIND(self, -1, self.OnFind)
392 wx.EVT_COMMAND_FIND_NEXT(self, -1, self.OnFind)
393 wx.EVT_COMMAND_FIND_CLOSE(self, -1 , self.OnFindClose)
cf694132
RD
394 self.mainmenu.Append(menu, '&Help')
395 self.SetMenuBar(self.mainmenu)
396
1fded56b 397 self.finddata = wx.FindReplaceData()
1e4a197e
RD
398
399 if 0:
400 # This is another way to set Accelerators, in addition to
401 # using the '\t<key>' syntax in the menu items.
1fded56b
RD
402 aTable = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), exitID),
403 (wx.ACCEL_CTRL, ord('H'), helpID),
404 (wx.ACCEL_CTRL, ord('F'), findID),
405 (wx.ACCEL_NORMAL, WXK_F3, findnextID)
406 ])
1e4a197e 407 self.SetAcceleratorTable(aTable)
2f90df85 408
bb0054cd 409
cf694132 410 # Create a TreeCtrl
1fded56b 411 tID = wx.NewId()
f6bcfd97 412 self.treeMap = {}
3628e088
RD
413 self.tree = wx.TreeCtrl(splitter, tID, style =
414 wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
eb0f373c 415 )
afb810d9 416
e9159fe8 417 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
418 firstChild = None
419 for item in _treeList:
420 child = self.tree.AppendItem(root, item[0])
421 if not firstChild: firstChild = child
422 for childItem in item[1]:
423 theDemo = self.tree.AppendItem(child, childItem)
424 self.treeMap[childItem] = theDemo
425
426 self.tree.Expand(root)
427 self.tree.Expand(firstChild)
1fded56b
RD
428 wx.EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
429 wx.EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
430 wx.EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
431 wx.EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
cf694132 432
cf694132 433 # Create a Notebook
1fded56b 434 self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)
cf694132 435
1fded56b 436 # Set up a wx.html.HtmlWindow on the Overview Notebook page
0bdca46d
RD
437 # we put it in a panel first because there seems to be a
438 # refresh bug of some sort (wxGTK) when it is directly in
439 # the notebook...
440 if 0: # the old way
1fded56b 441 self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
0bdca46d
RD
442 self.nb.AddPage(self.ovr, self.overviewText)
443
1fded56b
RD
444 else: # hopefully I can remove this hacky code soon, see SF bug #216861
445 panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
446 self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
0bdca46d
RD
447 self.nb.AddPage(panel, self.overviewText)
448
449 def OnOvrSize(evt, ovr=self.ovr):
450 ovr.SetSize(evt.GetSize())
451
1fded56b
RD
452 wx.EVT_SIZE(panel, OnOvrSize)
453 wx.EVT_ERASE_BACKGROUND(panel, EmptyHandler)
0bdca46d 454
c368d904 455
e9159fe8 456 self.SetOverview(self.overviewText, overview)
cf694132
RD
457
458
1fded56b
RD
459 # Set up a notebook page for viewing the source code of each sample
460 self.txt = DemoCodeViewer(self.nb, -1)
cf694132 461 self.nb.AddPage(self.txt, "Demo Code")
1fded56b 462 self.GetDemoFile('Main.py')
cf694132
RD
463
464
cf694132 465 # Set up a log on the View Log Notebook page
1fded56b
RD
466 self.log = wx.TextCtrl(splitter2, -1,
467 style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
342639eb 468
f6bcfd97 469 # Set the wxWindows log target to be this textctrl
1fded56b 470 #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))
342639eb 471
1fded56b
RD
472 # But instead of the above we want to show how to use our own wx.Log class
473 wx.Log_SetActiveTarget(MyLog(self.log))
cf694132 474
f9b24f07 475 # for serious debugging
1fded56b
RD
476 #wx.Log_SetActiveTarget(wx.LogStderr())
477 #wx.Log_SetTraceMask(wx.TraceMessages)
5a7823f5 478
1e4a197e 479 self.Show(True)
5a7823f5 480
f9b24f07 481
f6bcfd97 482 # add the windows to the splitter and split it.
2f0f3b0f 483 splitter2.SplitHorizontally(self.nb, self.log, -120)
1e4a197e 484 splitter.SplitVertically(self.tree, splitter2, 180)
afb810d9 485
f6bcfd97 486 splitter.SetMinimumPaneSize(20)
afb810d9
RD
487 splitter2.SetMinimumPaneSize(20)
488
cf694132 489
2f0f3b0f
RD
490 # Make the splitter on the right expand the top wind when resized
491 def SplitterOnSize(evt):
492 splitter = evt.GetEventObject()
493 sz = splitter.GetSize()
494 splitter.SetSashPosition(sz.height - 120, False)
495 evt.Skip()
496 wx.EVT_SIZE(splitter2, SplitterOnSize)
497
cf694132 498
bb0054cd
RD
499 # select initial items
500 self.nb.SetSelection(0)
f6bcfd97 501 self.tree.SelectItem(root)
ec3e670f
RD
502
503 if len(sys.argv) == 2:
504 try:
505 selectedDemo = self.treeMap[sys.argv[1]]
506 except:
507 selectedDemo = None
f6bcfd97 508 if selectedDemo:
ec3e670f
RD
509 self.tree.SelectItem(selectedDemo)
510 self.tree.EnsureVisible(selectedDemo)
511
bb0054cd 512
1fded56b 513 wx.LogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
514
515
cf694132
RD
516 #---------------------------------------------
517 def WriteText(self, text):
f6bcfd97
BP
518 if text[-1:] == '\n':
519 text = text[:-1]
1fded56b 520 wx.LogMessage(text)
f6bcfd97 521
cf694132
RD
522
523 def write(self, txt):
524 self.WriteText(txt)
525
526 #---------------------------------------------
527 def OnItemExpanded(self, event):
528 item = event.GetItem()
1fded56b 529 wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 530 event.Skip()
cf694132
RD
531
532 #---------------------------------------------
533 def OnItemCollapsed(self, event):
534 item = event.GetItem()
1fded56b 535 wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 536 event.Skip()
f6bcfd97
BP
537
538 #---------------------------------------------
539 def OnTreeLeftDown(self, event):
540 pt = event.GetPosition();
541 item, flags = self.tree.HitTest(pt)
542 if item == self.tree.GetSelection():
d975da9b 543 self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
185d7c3e 544 event.Skip()
cf694132
RD
545
546 #---------------------------------------------
547 def OnSelChanged(self, event):
548 if self.dying:
549 return
550
5a7823f5
RD
551 item = event.GetItem()
552 itemText = self.tree.GetItemText(item)
553 self.RunDemo(itemText)
554
555
556 #---------------------------------------------
557 def RunDemo(self, itemText):
694759cf 558 os.chdir(self.cwd)
cf694132
RD
559 if self.nb.GetPageCount() == 3:
560 if self.nb.GetSelection() == 2:
561 self.nb.SetSelection(0)
1e4a197e
RD
562 # inform the window that it's time to quit if it cares
563 if self.window is not None:
564 if hasattr(self.window, "ShutdownDemo"):
565 self.window.ShutdownDemo()
1fded56b 566 wx.SafeYield() # in case the page has pending events
cf694132
RD
567 self.nb.DeletePage(2)
568
e9159fe8 569 if itemText == self.overviewText:
cf694132 570 self.GetDemoFile('Main.py')
e9159fe8 571 self.SetOverview(self.overviewText, overview)
cf694132 572 self.nb.Refresh();
e91a9dfc 573 self.window = None
cf694132
RD
574
575 else:
576 if os.path.exists(itemText + '.py'):
1fded56b
RD
577 wx.BeginBusyCursor()
578 wx.LogMessage("Running demo %s.py..." % itemText)
f6bcfd97
BP
579 try:
580 self.GetDemoFile(itemText + '.py')
581 module = __import__(itemText, globals())
e9159fe8 582 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97 583 finally:
1fded56b 584 wx.EndBusyCursor()
5a1eefc7 585 self.tree.Refresh()
cf694132
RD
586
587 # in case runTest is modal, make sure things look right...
588 self.nb.Refresh();
1fded56b 589 wx.SafeYield()
cf694132 590
f6bcfd97 591 self.window = module.runTest(self, self.nb, self) ###
1e4a197e 592 if self.window is not None:
e91a9dfc 593 self.nb.AddPage(self.window, 'Demo')
cf694132 594 self.nb.SetSelection(2)
eb28fd47 595 self.nb.Refresh() # without this wxMac has troubles showing the just added page
cf694132
RD
596
597 else:
f6bcfd97 598 self.ovr.SetPage("")
cf694132 599 self.txt.Clear()
e91a9dfc 600 self.window = None
cf694132 601
2f90df85 602
cf694132
RD
603
604 #---------------------------------------------
605 # Get the Demo files
606 def GetDemoFile(self, filename):
607 self.txt.Clear()
bb0054cd
RD
608 try:
609 self.txt.SetValue(open(filename).read())
8bf5d46e 610 except IOError:
1fded56b 611 self.txt.SetValue("Cannot open %s file." % filename)
cf694132
RD
612
613 self.txt.SetInsertionPoint(0)
614 self.txt.ShowPosition(0)
615
616 #---------------------------------------------
617 def SetOverview(self, name, text):
f6bcfd97
BP
618 self.curOverview = text
619 lead = text[:6]
620 if lead != '<html>' and lead != '<HTML>':
1e4a197e 621 text = '<br>'.join(text.split('\n'))
f6bcfd97 622 self.ovr.SetPage(text)
cf694132 623 self.nb.SetPageText(0, name)
cf694132
RD
624
625 #---------------------------------------------
626 # Menu methods
c368d904 627 def OnFileExit(self, *event):
cf694132
RD
628 self.Close()
629
cf694132 630 def OnHelpAbout(self, event):
e166644c 631 from About import MyAboutBox
ec3e670f 632 about = MyAboutBox(self)
cf694132
RD
633 about.ShowModal()
634 about.Destroy()
635
1e4a197e
RD
636 def OnHelpFind(self, event):
637 self.nb.SetSelection(1)
1fded56b
RD
638 self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
639 wx.FR_NOUPDOWN |
640 wx.FR_NOMATCHCASE |
641 wx.FR_NOWHOLEWORD)
1e4a197e
RD
642 self.finddlg.Show(True)
643
644 def OnFind(self, event):
645 self.nb.SetSelection(1)
646 end = self.txt.GetLastPosition()
647 textstring = self.txt.GetRange(0, end).lower()
648 start = self.txt.GetSelection()[1]
649 findstring = self.finddata.GetFindString().lower()
650 loc = textstring.find(findstring, start)
651 if loc == -1 and start != 0:
652 # string not found, start at beginning
653 start = 0
654 loc = textstring.find(findstring, start)
655 if loc == -1:
1fded56b 656 dlg = wx.MessageDialog(self, 'Find String Not Found',
1e4a197e 657 'Find String Not Found in Demo File',
1fded56b 658 wx.OK | wx.ICON_INFORMATION)
1e4a197e
RD
659 dlg.ShowModal()
660 dlg.Destroy()
661 if self.finddlg:
662 if loc == -1:
663 self.finddlg.SetFocus()
664 return
665 else:
666 self.finddlg.Destroy()
1e4a197e 667 self.txt.ShowPosition(loc)
1fded56b 668 self.txt.SetSelection(loc, loc + len(findstring))
1e4a197e
RD
669
670
671
672 def OnFindNext(self, event):
673 if self.finddata.GetFindString():
674 self.OnFind(event)
675 else:
676 self.OnHelpFind(event)
677
678 def OnFindClose(self, event):
679 event.GetDialog().Destroy()
680
cf694132
RD
681
682 #---------------------------------------------
683 def OnCloseWindow(self, event):
1e4a197e 684 self.dying = True
e91a9dfc 685 self.window = None
26197023 686 self.mainmenu = None
c368d904
RD
687 if hasattr(self, "tbicon"):
688 del self.tbicon
cf694132
RD
689 self.Destroy()
690
c368d904 691
cf694132
RD
692 #---------------------------------------------
693 def OnIdle(self, event):
694 if self.otherWin:
695 self.otherWin.Raise()
e91a9dfc 696 self.window = self.otherWin
cf694132
RD
697 self.otherWin = None
698
ccf691a4
RD
699
700 #---------------------------------------------
701 def ShowTip(self):
702 try:
703 showTipText = open(opj("data/showTips")).read()
704 showTip, index = eval(showTipText)
705 except IOError:
706 showTip, index = (1, 0)
707 if showTip:
1fded56b 708 tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
861a0196 709 ##tp = MyTP(0)
1fded56b 710 showTip = wx.ShowTip(self, tp)
ccf691a4
RD
711 index = tp.GetCurrentTip()
712 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
713
714
ec3e670f
RD
715 #---------------------------------------------
716 def OnDemoMenu(self, event):
f6bcfd97
BP
717 try:
718 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
719 except:
720 selectedDemo = None
721 if selectedDemo:
722 self.tree.SelectItem(selectedDemo)
723 self.tree.EnsureVisible(selectedDemo)
ec3e670f 724
c368d904
RD
725
726 #---------------------------------------------
727 def OnTaskBarActivate(self, evt):
728 if self.IsIconized():
1e4a197e 729 self.Iconize(False)
c368d904 730 if not self.IsShown():
1e4a197e 731 self.Show(True)
c368d904
RD
732 self.Raise()
733
734 #---------------------------------------------
735
736 TBMENU_RESTORE = 1000
737 TBMENU_CLOSE = 1001
738
739 def OnTaskBarMenu(self, evt):
1fded56b 740 menu = wx.Menu()
c368d904
RD
741 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
742 menu.Append(self.TBMENU_CLOSE, "Close")
743 self.tbicon.PopupMenu(menu)
744 menu.Destroy()
745
746 #---------------------------------------------
747 def OnTaskBarClose(self, evt):
748 self.Close()
749
1fded56b 750 # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
c368d904 751 # prod the main idle handler a bit to get the window to actually close
1fded56b 752 wx.GetApp().ProcessIdle()
c368d904
RD
753
754
f3d9dc1d
RD
755 #---------------------------------------------
756 def OnIconfiy(self, evt):
1fded56b 757 wx.LogMessage("OnIconfiy")
f3d9dc1d
RD
758 evt.Skip()
759
760 #---------------------------------------------
761 def OnMaximize(self, evt):
1fded56b 762 wx.LogMessage("OnMaximize")
f3d9dc1d
RD
763 evt.Skip()
764
765
766
767
cf694132
RD
768#---------------------------------------------------------------------------
769#---------------------------------------------------------------------------
770
1fded56b 771class MySplashScreen(wx.SplashScreen):
b5a5d647 772 def __init__(self):
1fded56b
RD
773 bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
774 wx.SplashScreen.__init__(self, bmp,
775 wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT,
40c4c5a3 776 4000, None, -1,
1fded56b
RD
777 style = wx.SIMPLE_BORDER|wx.FRAME_NO_TASKBAR|wx.STAY_ON_TOP)
778 wx.EVT_CLOSE(self, self.OnClose)
b5a5d647
RD
779
780 def OnClose(self, evt):
9fb56e0c 781 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
1e4a197e 782 frame.Show()
ccf691a4 783 evt.Skip() # Make sure the default handler runs too...
cf694132 784
b5a5d647 785
1fded56b 786class MyApp(wx.App):
b5a5d647
RD
787 def OnInit(self):
788 """
68320e40 789 Create and show the splash screen. It will then create and show
b5a5d647
RD
790 the main frame when it is time to do so.
791 """
1e4a197e
RD
792
793 #import locale
1fded56b 794 #self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
1e4a197e
RD
795 #locale.setlocale(locale.LC_ALL, 'fr')
796
1fded56b 797 wx.InitAllImageHandlers()
b5a5d647
RD
798 splash = MySplashScreen()
799 splash.Show()
1e4a197e 800 return True
b5a5d647
RD
801
802
803
cf694132
RD
804#---------------------------------------------------------------------------
805
806def main():
e02c03a4 807 try:
d56cebe7 808 demoPath = os.path.dirname(__file__)
e02c03a4
RD
809 os.chdir(demoPath)
810 except:
811 pass
d14a1e28 812 app = MyApp(0) #wx.Platform == "__WXMAC__")
cf694132
RD
813 app.MainLoop()
814
815
816#---------------------------------------------------------------------------
817
818
819
f6bcfd97 820overview = """<html><body>
1fded56b
RD
821<h2>wxPython</h2>
822
823<p> wxPython is a <b>GUI toolkit</b> for the <a
824href="http://www.python.org/">Python</a> programming language. It
825allows Python programmers to create programs with a robust, highly
826functional graphical user interface, simply and easily. It is
827implemented as a Python extension module (native code) that wraps the
828popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
829platform GUI library, which is written in C++.
830
831<p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
832means that it is free for anyone to use and the source code is
833available for anyone to look at and modify. Or anyone can contribute
8b9a4190 834fixes or enhancements to the project.
1fded56b
RD
835
836<p> wxPython is a <b>cross-platform</b> toolkit. This means that the
837same program will run on multiple platforms without modification.
838Currently supported platforms are 32-bit Microsoft Windows, most Unix
839or unix-like systems, and Macintosh OS X. Since the language is
840Python, wxPython programs are <b>simple, easy</b> to write and easy to
841understand.
842
843<p> <b>This demo</b> is not only a collection of test cases for
844wxPython, but is also designed to help you learn about and how to use
845wxPython. Each sample is listed in the tree control on the left.
846When a sample is selected in the tree then a module is loaded and run
847(usually in a tab of this notebook,) and the source code of the module
848is loaded in another tab for you to browse and learn from.
849
850"""
cf694132
RD
851
852
853#----------------------------------------------------------------------------
854#----------------------------------------------------------------------------
855
856if __name__ == '__main__':
857 main()
858
859#----------------------------------------------------------------------------
860
861
862
863
864
865
866