2 #----------------------------------------------------------------------------
4 # Purpose: Testing lots of stuff, controls, window types, etc.
8 # Created: A long time ago, in a galaxy far, far away...
10 # Copyright: (c) 1999 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------------
15 from wxPython
.wx
import *
16 from wxPython
.lib
.splashscreen
import SplashScreen
17 from wxPython
.html
import wxHtmlWindow
19 #---------------------------------------------------------------------------
23 ('New since last release', ['wxProcess',
26 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
28 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
29 'wxScrolledWindow', 'wxSplitterWindow',
30 'wxStatusBar', 'wxNotebook',
32 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
34 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
35 'wxSingleChoiceDialog', 'wxTextEntryDialog',
36 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
37 'wxMessageDialog', 'wxProgressDialog']),
39 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
40 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
41 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
42 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
46 ('Window Layout', ['wxLayoutConstraints', 'Sizers', ]),
48 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
49 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
50 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
51 'PythonEvents', 'Threads',
52 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
56 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
57 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
58 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
59 'FileBrowseButton', 'GenericButtons', 'wxEditor',
63 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
67 #---------------------------------------------------------------------------
69 class wxPythonDemo(wxFrame
):
71 def __init__(self
, parent
, id, title
):
72 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
73 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
75 self
.cwd
= os
.getcwd()
78 if wxPlatform
== '__WXMSW__':
79 icon
= wxIcon('bitmaps/mondrian.ico', wxBITMAP_TYPE_ICO
)
82 # setup a taskbar icon, and catch some events from it
83 self
.tbicon
= wxTaskBarIcon()
84 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
85 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
86 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
87 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
88 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
92 EVT_IDLE(self
, self
.OnIdle
)
93 EVT_CLOSE(self
, self
.OnCloseWindow
)
96 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
98 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
99 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
102 # Prevent TreeCtrl from displaying all items after destruction
106 self
.mainmenu
= wxMenuBar()
109 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
110 EVT_MENU(self
, exitID
, self
.OnFileExit
)
111 self
.mainmenu
.Append(menu
, '&File')
115 for item
in _treeList
:
117 for childItem
in item
[1]:
119 submenu
.Append(mID
, childItem
)
120 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
121 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
122 self
.mainmenu
.Append(menu
, '&Demo')
128 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
129 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
130 self
.mainmenu
.Append(menu
, '&Help')
131 self
.SetMenuBar(self
.mainmenu
)
133 # set the menu accellerator table...
134 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
135 (wxACCEL_CTRL
, ord('H'), helpID
)])
136 self
.SetAcceleratorTable(aTable
)
142 self
.tree
= wxTreeCtrl(splitter
, tID
,
143 style
=wxTR_HAS_BUTTONS |
145 wxTR_HAS_VARIABLE_ROW_HEIGHT |
147 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
148 root
= self
.tree
.AddRoot("Overview")
150 for item
in _treeList
:
151 child
= self
.tree
.AppendItem(root
, item
[0])
152 if not firstChild
: firstChild
= child
153 for childItem
in item
[1]:
154 theDemo
= self
.tree
.AppendItem(child
, childItem
)
155 self
.treeMap
[childItem
] = theDemo
157 self
.tree
.Expand(root
)
158 self
.tree
.Expand(firstChild
)
159 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
160 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
161 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
162 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
165 self
.nb
= wxNotebook(splitter2
, -1)
167 # Set up a wxHtmlWindow on the Overview Notebook page
168 # we put it in a panel first because there seems to be a
169 # refresh bug of some sort (wxGTK) when it is directly in
172 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
173 self
.nb
.AddPage(self
.ovr
, "Overview")
175 else: # hopefully I can remove this hacky code soon
176 panel
= wxPanel(self
.nb
, -1)
177 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
178 self
.nb
.AddPage(panel
, "Overview")
180 def OnOvrSize(evt
, ovr
=self
.ovr
):
181 ovr
.SetSize(evt
.GetSize())
183 EVT_SIZE(panel
, OnOvrSize
)
185 self
.SetOverview("Overview", overview
)
188 # Set up a TextCtrl on the Demo Code Notebook page
189 self
.txt
= wxTextCtrl(self
.nb
, -1,
190 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
191 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
192 self
.nb
.AddPage(self
.txt
, "Demo Code")
195 # Set up a log on the View Log Notebook page
196 self
.log
= wxTextCtrl(splitter2
, -1,
197 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
198 # Set the wxWindows log target to be this textctrl
199 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
205 # add the windows to the splitter and split it.
206 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
207 splitter2
.SetSashPosition(450, true
)
208 splitter2
.SetMinimumPaneSize(20)
210 splitter
.SplitVertically(self
.tree
, splitter2
)
211 splitter
.SetSashPosition(180, true
)
212 splitter
.SetMinimumPaneSize(20)
215 # select initial items
216 self
.nb
.SetSelection(0)
217 self
.tree
.SelectItem(root
)
219 if len(sys
.argv
) == 2:
221 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
225 self
.tree
.SelectItem(selectedDemo
)
226 self
.tree
.EnsureVisible(selectedDemo
)
229 wxLogMessage('window handle: %s' % self
.GetHandle())
232 #---------------------------------------------
233 def WriteText(self
, text
):
234 if text
[-1:] == '\n':
239 def write(self
, txt
):
242 #---------------------------------------------
243 def OnItemExpanded(self
, event
):
244 item
= event
.GetItem()
245 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
248 #---------------------------------------------
249 def OnItemCollapsed(self
, event
):
250 item
= event
.GetItem()
251 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
254 #---------------------------------------------
255 def OnTreeLeftDown(self
, event
):
256 pt
= event
.GetPosition();
257 item
, flags
= self
.tree
.HitTest(pt
)
258 if item
== self
.tree
.GetSelection():
259 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
262 #---------------------------------------------
263 def OnSelChanged(self
, event
):
267 item
= event
.GetItem()
268 itemText
= self
.tree
.GetItemText(item
)
269 self
.RunDemo(itemText
)
272 #---------------------------------------------
273 def RunDemo(self
, itemText
):
275 if self
.nb
.GetPageCount() == 3:
276 if self
.nb
.GetSelection() == 2:
277 self
.nb
.SetSelection(0)
278 self
.nb
.DeletePage(2)
280 if itemText
== 'Overview':
281 self
.GetDemoFile('Main.py')
282 self
.SetOverview('Overview', overview
)
287 if os
.path
.exists(itemText
+ '.py'):
289 wxLogMessage("Running demo %s.py..." % itemText
)
291 self
.GetDemoFile(itemText
+ '.py')
292 module
= __import__(itemText
, globals())
293 self
.SetOverview(itemText
, module
.overview
)
297 # in case runTest is modal, make sure things look right...
301 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
303 self
.nb
.AddPage(self
.window
, 'Demo')
305 self
.nb
.SetSelection(2)
314 #---------------------------------------------
316 def GetDemoFile(self
, filename
):
319 self
.txt
.SetValue(open(filename
).read())
321 self
.txt
.WriteText("Cannot open %s file." % filename
)
323 self
.txt
.SetInsertionPoint(0)
324 self
.txt
.ShowPosition(0)
326 #---------------------------------------------
327 def SetOverview(self
, name
, text
):
328 self
.curOverview
= text
330 if lead
!= '<html>' and lead
!= '<HTML>':
331 text
= string
.join(string
.split(text
, '\n'), '<br>')
332 #text = '<font size="-1"><pre>' + text + '</pre></font>'
333 self
.ovr
.SetPage(text
)
334 self
.nb
.SetPageText(0, name
)
336 #---------------------------------------------
338 def OnFileExit(self
, *event
):
342 def OnHelpAbout(self
, event
):
343 from About
import MyAboutBox
344 about
= MyAboutBox(self
)
349 #---------------------------------------------
350 def OnCloseWindow(self
, event
):
354 if hasattr(self
, "tbicon"):
359 #---------------------------------------------
360 def OnIdle(self
, event
):
362 self
.otherWin
.Raise()
363 self
.window
= self
.otherWin
366 #---------------------------------------------
367 def OnDemoMenu(self
, event
):
369 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
373 self
.tree
.SelectItem(selectedDemo
)
374 self
.tree
.EnsureVisible(selectedDemo
)
377 #---------------------------------------------
378 def OnTaskBarActivate(self
, evt
):
379 if self
.IsIconized():
381 if not self
.IsShown():
385 #---------------------------------------------
387 TBMENU_RESTORE
= 1000
390 def OnTaskBarMenu(self
, evt
):
392 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
393 menu
.Append(self
.TBMENU_CLOSE
, "Close")
394 self
.tbicon
.PopupMenu(menu
)
397 #---------------------------------------------
398 def OnTaskBarClose(self
, evt
):
401 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
402 # prod the main idle handler a bit to get the window to actually close
403 wxGetApp().ProcessIdle()
406 #---------------------------------------------------------------------------
407 #---------------------------------------------------------------------------
411 wxInitAllImageHandlers()
413 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
414 duration
=4000, callback
=self
.AfterSplash
)
415 self
.splash
.Show(true
)
420 def AfterSplash(self
):
421 self
.splash
.Close(true
)
422 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
424 self
.SetTopWindow(frame
)
428 def ShowTip(self
, frame
):
430 showTipText
= open("data/showTips").read()
431 showTip
, index
= eval(showTipText
)
433 showTip
, index
= (1, 0)
434 #print showTip, index
436 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
437 showTip
= wxShowTip(frame
, tp
)
438 index
= tp
.GetCurrentTip()
439 open("data/showTips", "w").write(str( (showTip
, index
) ))
442 #---------------------------------------------------------------------------
446 demoPath
= os
.path
.split(__file__
)[0]
454 #---------------------------------------------------------------------------
458 overview
= """<html><body>
461 Python is an interpreted, interactive, object-oriented programming
462 language often compared to Tcl, Perl, Scheme, or Java.
464 <p> Python combines remarkable power with very clear syntax. It has
465 modules, classes, exceptions, very high level dynamic data types, and
466 dynamic typing. There are interfaces to many system calls and
467 libraries, and new built-in modules are easily written in C or
468 C++. Python is also usable as an extension language for applications
469 that need a programmable interface. <p>
473 wxWindows is a free C++ framework designed to make cross-platform
474 programming child's play. Well, almost. wxWindows 2 supports Windows
475 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
476 underway. Other ports are under consideration. <p>
478 wxWindows is a set of libraries that allows C++ applications to
479 compile and run on several different types of computers, with minimal
480 source code changes. There is one library per supported GUI (such as
481 Motif, or Windows). As well as providing a common API (Application
482 Programming Interface) for GUI functionality, it provides
483 functionality for accessing some commonly-used operating system
484 facilities, such as copying or deleting files. wxWindows is a
485 'framework' in the sense that it provides a lot of built-in
486 functionality, which the application can use or replace as required,
487 thus saving a great deal of coding effort. Basic data structures such
488 as strings, linked lists and hash tables are also supported.
493 wxPython is a Python extension module that encapsulates the wxWindows
494 GUI classes. Currently it is only available for the Win32 and GTK
495 ports of wxWindows, but as soon as the other ports are brought up to
496 the same level as Win32 and GTK, it should be fairly trivial to
497 enable wxPython to be used with the new GUI.
501 The wxPython extension module attempts to mirror the class heiarchy
502 of wxWindows as closely as possible. This means that there is a
503 wxFrame class in wxPython that looks, smells, tastes and acts almost
504 the same as the wxFrame class in the C++ version. Unfortunately,
505 because of differences in the languages, wxPython doesn't match
506 wxWindows exactly, but the differences should be easy to absorb
507 because they are natural to Python. For example, some methods that
508 return multiple values via argument pointers in C++ will return a
509 tuple of values in Python.
513 There is still much to be done for wxPython, many classes still need
514 to be mirrored. Also, wxWindows is still somewhat of a moving target
515 so it is a bit of an effort just keeping wxPython up to date. On the
516 other hand, there are enough of the core classes completed that
517 useful applications can be written.
521 wxPython is close enough to the C++ version that the majority of
522 the wxPython documentation is actually just notes attached to the C++
523 documents that describe the places where wxPython is different. There
524 is also a series of sample programs included, and a series of
525 documentation pages that assist the programmer in getting started
531 #----------------------------------------------------------------------------
532 #----------------------------------------------------------------------------
534 if __name__
== '__main__':
537 #----------------------------------------------------------------------------