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
21 #---------------------------------------------------------------------------
25 ('New since last release', ['ColourSelect', 'ImageBrowser', 'infoframe',
26 'ColourDB', 'wxToggleButton',
29 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
31 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
32 'wxScrolledWindow', 'wxSplitterWindow',
33 'wxStatusBar', 'wxNotebook',
35 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
37 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
38 'wxSingleChoiceDialog', 'wxTextEntryDialog',
39 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
40 'wxMessageDialog', 'wxProgressDialog']),
42 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
43 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
44 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
45 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
46 'wxCalendarCtrl', 'wxToggleButton',
49 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', ]),
51 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
52 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
53 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
54 'PythonEvents', 'Threads',
55 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
56 'wxDragImage', "wxProcess", "FancyText",
59 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
60 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
61 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
62 'FileBrowseButton', 'GenericButtons', 'wxEditor',
63 'PyShellWindow', 'ColourSelect', 'ImageBrowser',
66 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
70 #---------------------------------------------------------------------------
72 class wxPythonDemo(wxFrame
):
74 def __init__(self
, parent
, id, title
):
75 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
76 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
78 self
.cwd
= os
.getcwd()
82 icon
= wxIconFromXPMData(images
.getMondrianData())
84 # another way to do it
85 bmp
= images
.getMondrianBitmap()
87 icon
.CopyFromBitmap(bmp
)
91 if wxPlatform
== '__WXMSW__':
92 # setup a taskbar icon, and catch some events from it
93 self
.tbicon
= wxTaskBarIcon()
94 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
95 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
96 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
97 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
98 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
102 EVT_IDLE(self
, self
.OnIdle
)
103 EVT_CLOSE(self
, self
.OnCloseWindow
)
104 EVT_ICONIZE(self
, self
.OnIconfiy
)
105 EVT_MAXIMIZE(self
, self
.OnMaximize
)
108 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
110 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
111 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
114 # Prevent TreeCtrl from displaying all items after destruction
118 self
.mainmenu
= wxMenuBar()
121 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
122 EVT_MENU(self
, exitID
, self
.OnFileExit
)
123 self
.mainmenu
.Append(menu
, '&File')
127 for item
in _treeList
:
129 for childItem
in item
[1]:
131 submenu
.Append(mID
, childItem
)
132 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
133 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
134 self
.mainmenu
.Append(menu
, '&Demo')
140 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
141 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
142 self
.mainmenu
.Append(menu
, '&Help')
143 self
.SetMenuBar(self
.mainmenu
)
145 # set the menu accellerator table...
146 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
147 (wxACCEL_CTRL
, ord('H'), helpID
)])
148 self
.SetAcceleratorTable(aTable
)
154 self
.tree
= wxTreeCtrl(splitter
, tID
,
155 style
=wxTR_HAS_BUTTONS |
157 wxTR_HAS_VARIABLE_ROW_HEIGHT |
159 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
160 root
= self
.tree
.AddRoot("Overview")
162 for item
in _treeList
:
163 child
= self
.tree
.AppendItem(root
, item
[0])
164 if not firstChild
: firstChild
= child
165 for childItem
in item
[1]:
166 theDemo
= self
.tree
.AppendItem(child
, childItem
)
167 self
.treeMap
[childItem
] = theDemo
169 self
.tree
.Expand(root
)
170 self
.tree
.Expand(firstChild
)
171 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
172 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
173 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
174 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
177 self
.nb
= wxNotebook(splitter2
, -1)
179 # Set up a wxHtmlWindow on the Overview Notebook page
180 # we put it in a panel first because there seems to be a
181 # refresh bug of some sort (wxGTK) when it is directly in
184 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
185 self
.nb
.AddPage(self
.ovr
, "Overview")
187 else: # hopefully I can remove this hacky code soon, see bug #216861
188 panel
= wxPanel(self
.nb
, -1)
189 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
190 self
.nb
.AddPage(panel
, "Overview")
192 def OnOvrSize(evt
, ovr
=self
.ovr
):
193 ovr
.SetSize(evt
.GetSize())
195 EVT_SIZE(panel
, OnOvrSize
)
197 self
.SetOverview("Overview", overview
)
200 # Set up a TextCtrl on the Demo Code Notebook page
201 self
.txt
= wxTextCtrl(self
.nb
, -1,
202 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
203 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
204 self
.nb
.AddPage(self
.txt
, "Demo Code")
207 # Set up a log on the View Log Notebook page
208 self
.log
= wxTextCtrl(splitter2
, -1,
209 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
210 # Set the wxWindows log target to be this textctrl
211 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
217 # add the windows to the splitter and split it.
218 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
219 splitter2
.SetSashPosition(450, true
)
220 splitter2
.SetMinimumPaneSize(20)
222 splitter
.SplitVertically(self
.tree
, splitter2
)
223 splitter
.SetSashPosition(180, true
)
224 splitter
.SetMinimumPaneSize(20)
227 # select initial items
228 self
.nb
.SetSelection(0)
229 self
.tree
.SelectItem(root
)
231 if len(sys
.argv
) == 2:
233 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
237 self
.tree
.SelectItem(selectedDemo
)
238 self
.tree
.EnsureVisible(selectedDemo
)
241 wxLogMessage('window handle: %s' % self
.GetHandle())
244 #---------------------------------------------
245 def WriteText(self
, text
):
246 if text
[-1:] == '\n':
251 def write(self
, txt
):
254 #---------------------------------------------
255 def OnItemExpanded(self
, event
):
256 item
= event
.GetItem()
257 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
260 #---------------------------------------------
261 def OnItemCollapsed(self
, event
):
262 item
= event
.GetItem()
263 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
266 #---------------------------------------------
267 def OnTreeLeftDown(self
, event
):
268 pt
= event
.GetPosition();
269 item
, flags
= self
.tree
.HitTest(pt
)
270 if item
== self
.tree
.GetSelection():
271 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
274 #---------------------------------------------
275 def OnSelChanged(self
, event
):
279 item
= event
.GetItem()
280 itemText
= self
.tree
.GetItemText(item
)
281 self
.RunDemo(itemText
)
284 #---------------------------------------------
285 def RunDemo(self
, itemText
):
287 if self
.nb
.GetPageCount() == 3:
288 if self
.nb
.GetSelection() == 2:
289 self
.nb
.SetSelection(0)
290 self
.nb
.DeletePage(2)
292 if itemText
== 'Overview':
293 self
.GetDemoFile('Main.py')
294 self
.SetOverview('Overview', overview
)
299 if os
.path
.exists(itemText
+ '.py'):
301 wxLogMessage("Running demo %s.py..." % itemText
)
303 self
.GetDemoFile(itemText
+ '.py')
304 module
= __import__(itemText
, globals())
305 self
.SetOverview(itemText
, module
.overview
)
309 # in case runTest is modal, make sure things look right...
313 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
315 self
.nb
.AddPage(self
.window
, 'Demo')
317 self
.nb
.SetSelection(2)
326 #---------------------------------------------
328 def GetDemoFile(self
, filename
):
331 self
.txt
.SetValue(open(filename
).read())
333 self
.txt
.WriteText("Cannot open %s file." % filename
)
335 self
.txt
.SetInsertionPoint(0)
336 self
.txt
.ShowPosition(0)
338 #---------------------------------------------
339 def SetOverview(self
, name
, text
):
340 self
.curOverview
= text
342 if lead
!= '<html>' and lead
!= '<HTML>':
343 text
= string
.join(string
.split(text
, '\n'), '<br>')
344 #text = '<font size="-1"><pre>' + text + '</pre></font>'
345 self
.ovr
.SetPage(text
)
346 self
.nb
.SetPageText(0, name
)
348 #---------------------------------------------
350 def OnFileExit(self
, *event
):
354 def OnHelpAbout(self
, event
):
355 from About
import MyAboutBox
356 about
= MyAboutBox(self
)
361 #---------------------------------------------
362 def OnCloseWindow(self
, event
):
366 if hasattr(self
, "tbicon"):
371 #---------------------------------------------
372 def OnIdle(self
, event
):
374 self
.otherWin
.Raise()
375 self
.window
= self
.otherWin
378 #---------------------------------------------
379 def OnDemoMenu(self
, event
):
381 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
385 self
.tree
.SelectItem(selectedDemo
)
386 self
.tree
.EnsureVisible(selectedDemo
)
389 #---------------------------------------------
390 def OnTaskBarActivate(self
, evt
):
391 if self
.IsIconized():
393 if not self
.IsShown():
397 #---------------------------------------------
399 TBMENU_RESTORE
= 1000
402 def OnTaskBarMenu(self
, evt
):
404 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
405 menu
.Append(self
.TBMENU_CLOSE
, "Close")
406 self
.tbicon
.PopupMenu(menu
)
409 #---------------------------------------------
410 def OnTaskBarClose(self
, evt
):
413 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
414 # prod the main idle handler a bit to get the window to actually close
415 wxGetApp().ProcessIdle()
418 #---------------------------------------------
419 def OnIconfiy(self
, evt
):
420 wxLogMessage("OnIconfiy")
423 #---------------------------------------------
424 def OnMaximize(self
, evt
):
425 wxLogMessage("OnMaximize")
431 #---------------------------------------------------------------------------
432 #---------------------------------------------------------------------------
436 wxInitAllImageHandlers()
438 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
439 duration
=4000, callback
=self
.AfterSplash
)
440 self
.splash
.Show(true
)
445 def AfterSplash(self
):
446 self
.splash
.Close(true
)
447 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
449 self
.SetTopWindow(frame
)
453 def ShowTip(self
, frame
):
455 showTipText
= open("data/showTips").read()
456 showTip
, index
= eval(showTipText
)
458 showTip
, index
= (1, 0)
459 #print showTip, index
461 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
462 showTip
= wxShowTip(frame
, tp
)
463 index
= tp
.GetCurrentTip()
464 open("data/showTips", "w").write(str( (showTip
, index
) ))
467 #---------------------------------------------------------------------------
471 demoPath
= os
.path
.split(__file__
)[0]
479 #---------------------------------------------------------------------------
483 overview
= """<html><body>
486 Python is an interpreted, interactive, object-oriented programming
487 language often compared to Tcl, Perl, Scheme, or Java.
489 <p> Python combines remarkable power with very clear syntax. It has
490 modules, classes, exceptions, very high level dynamic data types, and
491 dynamic typing. There are interfaces to many system calls and
492 libraries, and new built-in modules are easily written in C or
493 C++. Python is also usable as an extension language for applications
494 that need a programmable interface. <p>
498 wxWindows is a free C++ framework designed to make cross-platform
499 programming child's play. Well, almost. wxWindows 2 supports Windows
500 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
501 underway. Other ports are under consideration. <p>
503 wxWindows is a set of libraries that allows C++ applications to
504 compile and run on several different types of computers, with minimal
505 source code changes. There is one library per supported GUI (such as
506 Motif, or Windows). As well as providing a common API (Application
507 Programming Interface) for GUI functionality, it provides
508 functionality for accessing some commonly-used operating system
509 facilities, such as copying or deleting files. wxWindows is a
510 'framework' in the sense that it provides a lot of built-in
511 functionality, which the application can use or replace as required,
512 thus saving a great deal of coding effort. Basic data structures such
513 as strings, linked lists and hash tables are also supported.
518 wxPython is a Python extension module that encapsulates the wxWindows
519 GUI classes. Currently it is only available for the Win32 and GTK
520 ports of wxWindows, but as soon as the other ports are brought up to
521 the same level as Win32 and GTK, it should be fairly trivial to
522 enable wxPython to be used with the new GUI.
526 The wxPython extension module attempts to mirror the class heiarchy
527 of wxWindows as closely as possible. This means that there is a
528 wxFrame class in wxPython that looks, smells, tastes and acts almost
529 the same as the wxFrame class in the C++ version. Unfortunately,
530 because of differences in the languages, wxPython doesn't match
531 wxWindows exactly, but the differences should be easy to absorb
532 because they are natural to Python. For example, some methods that
533 return multiple values via argument pointers in C++ will return a
534 tuple of values in Python.
538 There is still much to be done for wxPython, many classes still need
539 to be mirrored. Also, wxWindows is still somewhat of a moving target
540 so it is a bit of an effort just keeping wxPython up to date. On the
541 other hand, there are enough of the core classes completed that
542 useful applications can be written.
546 wxPython is close enough to the C++ version that the majority of
547 the wxPython documentation is actually just notes attached to the C++
548 documents that describe the places where wxPython is different. There
549 is also a series of sample programs included, and a series of
550 documentation pages that assist the programmer in getting started
556 #----------------------------------------------------------------------------
557 #----------------------------------------------------------------------------
559 if __name__
== '__main__':
562 #----------------------------------------------------------------------------