]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/Main.py
crash due to missing break before WM_HELP handler fixed
[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
15 from wxPython.wx import *
16 from wxPython.lib.splashscreen import SplashScreen
17 from wxPython.html import wxHtmlWindow
18
19 #---------------------------------------------------------------------------
20
21
22 _treeList = [
23 ('New since last release', ['PyShellWindow',
24 ]),
25
26 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
27
28 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
29 'wxScrolledWindow', 'wxSplitterWindow',
30 'wxStatusBar', 'wxNotebook',
31 'wxHtmlWindow',
32 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
33
34 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
35 'wxSingleChoiceDialog', 'wxTextEntryDialog',
36 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
37 'wxMessageDialog', 'wxProgressDialog']),
38
39 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
40 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
41 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
42 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
43 'wxCalendarCtrl',
44 ]),
45
46 ('Window Layout', ['wxLayoutConstraints', 'Sizers', 'OldSizers']),
47
48 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
49 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
50 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
51 'PythonEvents', 'Threads',
52 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
53 'wxDragImage', 'PyShellWindow',
54 ]),
55
56 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
57 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
58 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
59 'FileBrowseButton', 'GenericButtons', 'wxEditor']),
60
61 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
62
63 ]
64
65 #---------------------------------------------------------------------------
66
67 class wxPythonDemo(wxFrame):
68 def __init__(self, parent, id, title):
69 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
70 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
71
72 self.cwd = os.getcwd()
73 self.curOverview = ""
74
75 if wxPlatform == '__WXMSW__':
76 self.icon = wxIcon('bitmaps/mondrian.ico', wxBITMAP_TYPE_ICO)
77 self.SetIcon(self.icon)
78
79 self.otherWin = None
80 EVT_IDLE(self, self.OnIdle)
81 EVT_CLOSE(self, self.OnCloseWindow)
82
83 self.Centre(wxBOTH)
84 self.CreateStatusBar(1, wxST_SIZEGRIP)
85
86 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
87 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
88
89
90 # Prevent TreeCtrl from displaying all items after destruction
91 self.dying = false
92
93 # Make a File menu
94 self.mainmenu = wxMenuBar()
95 menu = wxMenu()
96 exitID = wxNewId()
97 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
98 EVT_MENU(self, exitID, self.OnFileExit)
99 self.mainmenu.Append(menu, '&File')
100
101 # Make a Demo menu
102 menu = wxMenu()
103 for item in _treeList:
104 submenu = wxMenu()
105 for childItem in item[1]:
106 mID = wxNewId()
107 submenu.Append(mID, childItem)
108 EVT_MENU(self, mID, self.OnDemoMenu)
109 menu.AppendMenu(wxNewId(), item[0], submenu)
110 self.mainmenu.Append(menu, '&Demo')
111
112
113 # Make a Help menu
114 helpID = wxNewId()
115 menu = wxMenu()
116 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
117 EVT_MENU(self, helpID, self.OnHelpAbout)
118 self.mainmenu.Append(menu, '&Help')
119 self.SetMenuBar(self.mainmenu)
120
121 # set the menu accellerator table...
122 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
123 (wxACCEL_CTRL, ord('H'), helpID)])
124 self.SetAcceleratorTable(aTable)
125
126
127 # Create a TreeCtrl
128 tID = wxNewId()
129 self.treeMap = {}
130 self.tree = wxTreeCtrl(splitter, tID,
131 style=wxTR_HAS_BUTTONS |
132 wxTR_EDIT_LABELS |
133 wxTR_HAS_VARIABLE_ROW_HEIGHT |
134 wxSUNKEN_BORDER)
135 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
136 root = self.tree.AddRoot("Overview")
137 firstChild = None
138 for item in _treeList:
139 child = self.tree.AppendItem(root, item[0])
140 if not firstChild: firstChild = child
141 for childItem in item[1]:
142 theDemo = self.tree.AppendItem(child, childItem)
143 self.treeMap[childItem] = theDemo
144
145 self.tree.Expand(root)
146 self.tree.Expand(firstChild)
147 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
148 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
149 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
150 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
151
152 # Create a Notebook
153 self.nb = wxNotebook(splitter2, -1)
154
155 # Set up a TextCtrl on the Overview Notebook page
156 self.ovr = wxHtmlWindow(self.nb, -1)
157 self.nb.AddPage(self.ovr, "Overview")
158
159
160 # Set up a TextCtrl on the Demo Code Notebook page
161 self.txt = wxTextCtrl(self.nb, -1,
162 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
163 self.txt.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false))
164 self.nb.AddPage(self.txt, "Demo Code")
165
166
167 # Set up a log on the View Log Notebook page
168 self.log = wxTextCtrl(splitter2, -1,
169 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
170 # Set the wxWindows log target to be this textctrl
171 wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
172
173
174
175 self.Show(true)
176
177 # add the windows to the splitter and split it.
178 splitter2.SplitHorizontally(self.nb, self.log)
179 splitter2.SetSashPosition(450, true)
180 splitter2.SetMinimumPaneSize(20)
181
182 splitter.SplitVertically(self.tree, splitter2)
183 splitter.SetSashPosition(180, true)
184 splitter.SetMinimumPaneSize(20)
185
186
187 # select initial items
188 self.nb.SetSelection(0)
189 self.tree.SelectItem(root)
190
191 if len(sys.argv) == 2:
192 try:
193 selectedDemo = self.treeMap[sys.argv[1]]
194 except:
195 selectedDemo = None
196 if selectedDemo:
197 self.tree.SelectItem(selectedDemo)
198 self.tree.EnsureVisible(selectedDemo)
199
200
201 wxLogMessage('window handle: %s' % self.GetHandle())
202
203
204 #---------------------------------------------
205 def WriteText(self, text):
206 if text[-1:] == '\n':
207 text = text[:-1]
208 wxLogMessage(text)
209
210
211 def write(self, txt):
212 self.WriteText(txt)
213
214 #---------------------------------------------
215 def OnItemExpanded(self, event):
216 item = event.GetItem()
217 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
218
219 #---------------------------------------------
220 def OnItemCollapsed(self, event):
221 item = event.GetItem()
222 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
223
224
225 #---------------------------------------------
226 def OnTreeLeftDown(self, event):
227 pt = event.GetPosition();
228 item, flags = self.tree.HitTest(pt)
229 if item == self.tree.GetSelection():
230 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
231 else:
232 event.Skip()
233
234 #---------------------------------------------
235 def OnSelChanged(self, event):
236 if self.dying:
237 return
238
239 item = event.GetItem()
240 itemText = self.tree.GetItemText(item)
241 self.RunDemo(itemText)
242
243
244 #---------------------------------------------
245 def RunDemo(self, itemText):
246 os.chdir(self.cwd)
247 if self.nb.GetPageCount() == 3:
248 if self.nb.GetSelection() == 2:
249 self.nb.SetSelection(0)
250 self.nb.DeletePage(2)
251
252 if itemText == 'Overview':
253 self.GetDemoFile('Main.py')
254 self.SetOverview('Overview', overview)
255 self.nb.Refresh();
256 self.window = None
257
258 else:
259 if os.path.exists(itemText + '.py'):
260 wxBeginBusyCursor()
261 wxLogMessage("Running demo %s.py..." % itemText)
262 try:
263 self.GetDemoFile(itemText + '.py')
264 module = __import__(itemText, globals())
265 self.SetOverview(itemText, module.overview)
266 finally:
267 wxEndBusyCursor()
268
269 # in case runTest is modal, make sure things look right...
270 self.nb.Refresh();
271 wxYield()
272
273 self.window = module.runTest(self, self.nb, self) ###
274 if self.window:
275 self.nb.AddPage(self.window, 'Demo')
276 wxYield()
277 self.nb.SetSelection(2)
278
279 else:
280 self.ovr.SetPage("")
281 self.txt.Clear()
282 self.window = None
283
284
285
286 #---------------------------------------------
287 # Get the Demo files
288 def GetDemoFile(self, filename):
289 self.txt.Clear()
290 try:
291 self.txt.SetValue(open(filename).read())
292 except IOError:
293 self.txt.WriteText("Cannot open %s file." % filename)
294
295 self.txt.SetInsertionPoint(0)
296 self.txt.ShowPosition(0)
297
298 #---------------------------------------------
299 def SetOverview(self, name, text):
300 self.curOverview = text
301 lead = text[:6]
302 if lead != '<html>' and lead != '<HTML>':
303 text = string.join(string.split(text, '\n'), '<br>')
304 #text = '<font size="-1"><pre>' + text + '</pre></font>'
305 self.ovr.SetPage(text)
306 self.nb.SetPageText(0, name)
307
308 #---------------------------------------------
309 # Menu methods
310 def OnFileExit(self, event):
311 self.Close()
312
313
314 def OnHelpAbout(self, event):
315 from About import MyAboutBox
316 about = MyAboutBox(self)
317 about.ShowModal()
318 about.Destroy()
319
320
321 #---------------------------------------------
322 def OnCloseWindow(self, event):
323 self.dying = true
324 self.window = None
325 self.mainmenu = None
326 self.Destroy()
327
328 #---------------------------------------------
329 def OnIdle(self, event):
330 if self.otherWin:
331 self.otherWin.Raise()
332 self.window = self.otherWin
333 self.otherWin = None
334
335 #---------------------------------------------
336 def OnDemoMenu(self, event):
337 try:
338 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
339 except:
340 selectedDemo = None
341 if selectedDemo:
342 self.tree.SelectItem(selectedDemo)
343 self.tree.EnsureVisible(selectedDemo)
344
345 #---------------------------------------------------------------------------
346 #---------------------------------------------------------------------------
347
348 class MyApp(wxApp):
349 def OnInit(self):
350 wxInitAllImageHandlers()
351
352 self.splash = SplashScreen(None, bitmapfile='bitmaps/splash.gif',
353 duration=4000, callback=self.AfterSplash)
354 self.splash.Show(true)
355 wxYield()
356 return true
357
358
359 def AfterSplash(self):
360 self.splash.Close(true)
361 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
362 frame.Show(true)
363 self.SetTopWindow(frame)
364 self.ShowTip(frame)
365
366
367 def ShowTip(self, frame):
368 try:
369 showTipText = open("data/showTips").read()
370 showTip, index = eval(showTipText)
371 except IOError:
372 showTip, index = (1, 0)
373 print showTip, index
374 if showTip:
375 tp = wxCreateFileTipProvider("data/tips.txt", index)
376 showTip = wxShowTip(frame, tp)
377 index = tp.GetCurrentTip()
378 open("data/showTips", "w").write(str( (showTip, index) ))
379
380
381 #---------------------------------------------------------------------------
382
383 def main():
384 try:
385 demoPath = os.path.split(__file__)[0]
386 os.chdir(demoPath)
387 except:
388 pass
389 app = MyApp(0)
390 app.MainLoop()
391
392
393 #---------------------------------------------------------------------------
394
395
396
397 overview = """<html><body>
398 <h2>Python</h2>
399
400 Python is an interpreted, interactive, object-oriented programming
401 language often compared to Tcl, Perl, Scheme, or Java.
402
403 <p> Python combines remarkable power with very clear syntax. It has
404 modules, classes, exceptions, very high level dynamic data types, and
405 dynamic typing. There are interfaces to many system calls and
406 libraries, and new built-in modules are easily written in C or
407 C++. Python is also usable as an extension language for applications
408 that need a programmable interface. <p>
409
410 <h2>wxWindows</h2>
411
412 wxWindows is a free C++ framework designed to make cross-platform
413 programming child's play. Well, almost. wxWindows 2 supports Windows
414 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
415 underway. Other ports are under consideration. <p>
416
417 wxWindows is a set of libraries that allows C++ applications to
418 compile and run on several different types of computers, with minimal
419 source code changes. There is one library per supported GUI (such as
420 Motif, or Windows). As well as providing a common API (Application
421 Programming Interface) for GUI functionality, it provides
422 functionality for accessing some commonly-used operating system
423 facilities, such as copying or deleting files. wxWindows is a
424 'framework' in the sense that it provides a lot of built-in
425 functionality, which the application can use or replace as required,
426 thus saving a great deal of coding effort. Basic data structures such
427 as strings, linked lists and hash tables are also supported.
428
429 <p>
430 <h2>wxPython</h2>
431
432 wxPython is a Python extension module that encapsulates the wxWindows
433 GUI classes. Currently it is only available for the Win32 and GTK
434 ports of wxWindows, but as soon as the other ports are brought up to
435 the same level as Win32 and GTK, it should be fairly trivial to
436 enable wxPython to be used with the new GUI.
437
438 <p>
439
440 The wxPython extension module attempts to mirror the class heiarchy
441 of wxWindows as closely as possible. This means that there is a
442 wxFrame class in wxPython that looks, smells, tastes and acts almost
443 the same as the wxFrame class in the C++ version. Unfortunately,
444 because of differences in the languages, wxPython doesn't match
445 wxWindows exactly, but the differences should be easy to absorb
446 because they are natural to Python. For example, some methods that
447 return multiple values via argument pointers in C++ will return a
448 tuple of values in Python.
449
450 <p>
451
452 There is still much to be done for wxPython, many classes still need
453 to be mirrored. Also, wxWindows is still somewhat of a moving target
454 so it is a bit of an effort just keeping wxPython up to date. On the
455 other hand, there are enough of the core classes completed that
456 useful applications can be written.
457
458 <p>
459
460 wxPython is close enough to the C++ version that the majority of
461 the wxPython documentation is actually just notes attached to the C++
462 documents that describe the places where wxPython is different. There
463 is also a series of sample programs included, and a series of
464 documentation pages that assist the programmer in getting started
465 with wxPython.
466
467 """
468
469
470 #----------------------------------------------------------------------------
471 #----------------------------------------------------------------------------
472
473 if __name__ == '__main__':
474 main()
475
476 #----------------------------------------------------------------------------
477
478
479
480
481
482
483