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