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