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