]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Doc mods
[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
14import sys, os
15from wxPython.wx import *
9fb56e0c 16from wxPython.lib.splashscreen import SplashScreen
f6bcfd97 17from wxPython.html import wxHtmlWindow
cf694132
RD
18
19#---------------------------------------------------------------------------
20
21
22_treeList = [
f6bcfd97
BP
23 ('New since last release', ['PyShellWindow',
24 ]),
e395c057 25
cf694132
RD
26 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
27
b1462dfa 28 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
f6bcfd97
BP
29 'wxScrolledWindow', 'wxSplitterWindow',
30 'wxStatusBar', 'wxNotebook',
31 'wxHtmlWindow',
32 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
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',
f6bcfd97
BP
41 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
42 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
43 'wxCalendarCtrl',
6999b0d8 44 ]),
cf694132 45
2f90df85 46 ('Window Layout', ['wxLayoutConstraints', 'Sizers', 'OldSizers']),
cf694132 47
b1462dfa
RD
48 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
49 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 50 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
51 'PythonEvents', 'Threads',
52 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
53 'wxDragImage', 'PyShellWindow',
54 ]),
cf694132 55
e0473f5f 56 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 57 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
694759cf 58 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
1b55cabf 59 'FileBrowseButton', 'GenericButtons', 'wxEditor']),
cf694132 60
8bf5d46e 61 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
cf694132
RD
62
63 ]
64
65#---------------------------------------------------------------------------
66
67class wxPythonDemo(wxFrame):
68 def __init__(self, parent, id, title):
f6bcfd97
BP
69 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
70 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
2f90df85 71
694759cf 72 self.cwd = os.getcwd()
3ca6a5f0 73 self.curOverview = ""
694759cf 74
cf694132
RD
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)
f6bcfd97 81 EVT_CLOSE(self, self.OnCloseWindow)
cf694132
RD
82
83 self.Centre(wxBOTH)
84 self.CreateStatusBar(1, wxST_SIZEGRIP)
5a7823f5 85
f6bcfd97
BP
86 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
87 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
5a7823f5 88
cf694132
RD
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()
2f90df85 96 exitID = wxNewId()
f0261a72 97 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
2f90df85 98 EVT_MENU(self, exitID, self.OnFileExit)
cf694132
RD
99 self.mainmenu.Append(menu, '&File')
100
ec3e670f
RD
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
cf694132 113 # Make a Help menu
2f90df85 114 helpID = wxNewId()
cf694132 115 menu = wxMenu()
2f90df85
RD
116 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
117 EVT_MENU(self, helpID, self.OnHelpAbout)
cf694132
RD
118 self.mainmenu.Append(menu, '&Help')
119 self.SetMenuBar(self.mainmenu)
120
2f90df85 121 # set the menu accellerator table...
f0261a72 122 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
2f90df85
RD
123 (wxACCEL_CTRL, ord('H'), helpID)])
124 self.SetAcceleratorTable(aTable)
125
bb0054cd 126
cf694132 127 # Create a TreeCtrl
f6bcfd97
BP
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)
cf694132 151
cf694132 152 # Create a Notebook
f6bcfd97 153 self.nb = wxNotebook(splitter2, -1)
cf694132
RD
154
155 # Set up a TextCtrl on the Overview Notebook page
f6bcfd97 156 self.ovr = wxHtmlWindow(self.nb, -1)
cf694132
RD
157 self.nb.AddPage(self.ovr, "Overview")
158
159
160 # Set up a TextCtrl on the Demo Code Notebook page
efc5f224
RD
161 self.txt = wxTextCtrl(self.nb, -1,
162 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
bb0054cd 163 self.txt.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false))
cf694132
RD
164 self.nb.AddPage(self.txt, "Demo Code")
165
166
cf694132 167 # Set up a log on the View Log Notebook page
f6bcfd97 168 self.log = wxTextCtrl(splitter2, -1,
efc5f224 169 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
f6bcfd97
BP
170 # Set the wxWindows log target to be this textctrl
171 wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
cf694132
RD
172
173
5a7823f5 174
f6bcfd97 175 self.Show(true)
5a7823f5 176
f6bcfd97
BP
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)
cf694132 181
f6bcfd97
BP
182 splitter.SplitVertically(self.tree, splitter2)
183 splitter.SetSashPosition(180, true)
184 splitter.SetMinimumPaneSize(20)
cf694132 185
cf694132 186
bb0054cd
RD
187 # select initial items
188 self.nb.SetSelection(0)
f6bcfd97 189 self.tree.SelectItem(root)
ec3e670f
RD
190
191 if len(sys.argv) == 2:
192 try:
193 selectedDemo = self.treeMap[sys.argv[1]]
194 except:
195 selectedDemo = None
f6bcfd97 196 if selectedDemo:
ec3e670f
RD
197 self.tree.SelectItem(selectedDemo)
198 self.tree.EnsureVisible(selectedDemo)
199
bb0054cd 200
f6bcfd97 201 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
202
203
cf694132
RD
204 #---------------------------------------------
205 def WriteText(self, text):
f6bcfd97
BP
206 if text[-1:] == '\n':
207 text = text[:-1]
208 wxLogMessage(text)
209
cf694132
RD
210
211 def write(self, txt):
212 self.WriteText(txt)
213
214 #---------------------------------------------
215 def OnItemExpanded(self, event):
216 item = event.GetItem()
f6bcfd97 217 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
cf694132
RD
218
219 #---------------------------------------------
220 def OnItemCollapsed(self, event):
221 item = event.GetItem()
f6bcfd97
BP
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()
cf694132
RD
233
234 #---------------------------------------------
235 def OnSelChanged(self, event):
236 if self.dying:
237 return
238
5a7823f5
RD
239 item = event.GetItem()
240 itemText = self.tree.GetItemText(item)
241 self.RunDemo(itemText)
242
243
244 #---------------------------------------------
245 def RunDemo(self, itemText):
694759cf 246 os.chdir(self.cwd)
cf694132
RD
247 if self.nb.GetPageCount() == 3:
248 if self.nb.GetSelection() == 2:
249 self.nb.SetSelection(0)
250 self.nb.DeletePage(2)
251
cf694132
RD
252 if itemText == 'Overview':
253 self.GetDemoFile('Main.py')
254 self.SetOverview('Overview', overview)
cf694132 255 self.nb.Refresh();
e91a9dfc 256 self.window = None
cf694132
RD
257
258 else:
259 if os.path.exists(itemText + '.py'):
9d8bd15f 260 wxBeginBusyCursor()
f6bcfd97
BP
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()
cf694132
RD
268
269 # in case runTest is modal, make sure things look right...
270 self.nb.Refresh();
271 wxYield()
272
f6bcfd97 273 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
274 if self.window:
275 self.nb.AddPage(self.window, 'Demo')
dcd38683 276 wxYield()
cf694132 277 self.nb.SetSelection(2)
cf694132
RD
278
279 else:
f6bcfd97 280 self.ovr.SetPage("")
cf694132 281 self.txt.Clear()
e91a9dfc 282 self.window = None
cf694132 283
2f90df85 284
cf694132
RD
285
286 #---------------------------------------------
287 # Get the Demo files
288 def GetDemoFile(self, filename):
289 self.txt.Clear()
bb0054cd
RD
290 try:
291 self.txt.SetValue(open(filename).read())
8bf5d46e 292 except IOError:
cf694132
RD
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):
f6bcfd97
BP
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)
cf694132 306 self.nb.SetPageText(0, name)
cf694132
RD
307
308 #---------------------------------------------
309 # Menu methods
310 def OnFileExit(self, event):
311 self.Close()
312
313
314 def OnHelpAbout(self, event):
e166644c 315 from About import MyAboutBox
ec3e670f 316 about = MyAboutBox(self)
cf694132
RD
317 about.ShowModal()
318 about.Destroy()
319
320
321 #---------------------------------------------
322 def OnCloseWindow(self, event):
323 self.dying = true
e91a9dfc 324 self.window = None
26197023 325 self.mainmenu = None
cf694132
RD
326 self.Destroy()
327
328 #---------------------------------------------
329 def OnIdle(self, event):
330 if self.otherWin:
331 self.otherWin.Raise()
e91a9dfc 332 self.window = self.otherWin
cf694132
RD
333 self.otherWin = None
334
ec3e670f
RD
335 #---------------------------------------------
336 def OnDemoMenu(self, event):
f6bcfd97
BP
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)
ec3e670f 344
cf694132
RD
345#---------------------------------------------------------------------------
346#---------------------------------------------------------------------------
347
348class MyApp(wxApp):
349 def OnInit(self):
f6bcfd97 350 wxInitAllImageHandlers()
9fb56e0c
RD
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
f6bcfd97 358
9fb56e0c
RD
359 def AfterSplash(self):
360 self.splash.Close(true)
361 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132
RD
362 frame.Show(true)
363 self.SetTopWindow(frame)
f6bcfd97
BP
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
cf694132
RD
380
381#---------------------------------------------------------------------------
382
383def main():
e02c03a4
RD
384 try:
385 demoPath = os.path.split(__file__)[0]
386 os.chdir(demoPath)
387 except:
388 pass
cf694132
RD
389 app = MyApp(0)
390 app.MainLoop()
391
392
393#---------------------------------------------------------------------------
394
395
396
f6bcfd97
BP
397overview = """<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 """
cf694132
RD
468
469
470#----------------------------------------------------------------------------
471#----------------------------------------------------------------------------
472
473if __name__ == '__main__':
474 main()
475
476#----------------------------------------------------------------------------
477
478
479
480
481
482
483