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',
28 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
30 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
31 'wxScrolledWindow', 'wxSplitterWindow',
32 'wxStatusBar', 'wxNotebook',
34 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
36 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
37 'wxSingleChoiceDialog', 'wxTextEntryDialog',
38 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
39 'wxMessageDialog', 'wxProgressDialog']),
41 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
42 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
43 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
44 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
48 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', ]),
50 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
51 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
52 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
53 'PythonEvents', 'Threads',
54 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
55 'wxDragImage', "wxProcess", "FancyText",
58 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
59 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
60 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
61 'FileBrowseButton', 'GenericButtons', 'wxEditor',
62 'PyShellWindow', 'ColourSelect', 'ImageBrowser',
65 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
69 #---------------------------------------------------------------------------
71 class wxPythonDemo(wxFrame
):
73 def __init__(self
, parent
, id, title
):
74 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
75 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
77 self
.cwd
= os
.getcwd()
80 icon
= wxIconFromXPMData(images
.getMondrianData())
83 if wxPlatform
== '__WXMSW__':
84 # setup a taskbar icon, and catch some events from it
85 self
.tbicon
= wxTaskBarIcon()
86 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
87 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
88 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
89 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
90 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
94 EVT_IDLE(self
, self
.OnIdle
)
95 EVT_CLOSE(self
, self
.OnCloseWindow
)
96 EVT_ICONIZE(self
, self
.OnIconfiy
)
97 EVT_MAXIMIZE(self
, self
.OnMaximize
)
100 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
102 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
103 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
106 # Prevent TreeCtrl from displaying all items after destruction
110 self
.mainmenu
= wxMenuBar()
113 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
114 EVT_MENU(self
, exitID
, self
.OnFileExit
)
115 self
.mainmenu
.Append(menu
, '&File')
119 for item
in _treeList
:
121 for childItem
in item
[1]:
123 submenu
.Append(mID
, childItem
)
124 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
125 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
126 self
.mainmenu
.Append(menu
, '&Demo')
132 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
133 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
134 self
.mainmenu
.Append(menu
, '&Help')
135 self
.SetMenuBar(self
.mainmenu
)
137 # set the menu accellerator table...
138 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
139 (wxACCEL_CTRL
, ord('H'), helpID
)])
140 self
.SetAcceleratorTable(aTable
)
146 self
.tree
= wxTreeCtrl(splitter
, tID
,
147 style
=wxTR_HAS_BUTTONS |
149 wxTR_HAS_VARIABLE_ROW_HEIGHT |
151 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
152 root
= self
.tree
.AddRoot("Overview")
154 for item
in _treeList
:
155 child
= self
.tree
.AppendItem(root
, item
[0])
156 if not firstChild
: firstChild
= child
157 for childItem
in item
[1]:
158 theDemo
= self
.tree
.AppendItem(child
, childItem
)
159 self
.treeMap
[childItem
] = theDemo
161 self
.tree
.Expand(root
)
162 self
.tree
.Expand(firstChild
)
163 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
164 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
165 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
166 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
169 self
.nb
= wxNotebook(splitter2
, -1)
171 # Set up a wxHtmlWindow on the Overview Notebook page
172 # we put it in a panel first because there seems to be a
173 # refresh bug of some sort (wxGTK) when it is directly in
176 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
177 self
.nb
.AddPage(self
.ovr
, "Overview")
179 else: # hopefully I can remove this hacky code soon, see bug #216861
180 panel
= wxPanel(self
.nb
, -1)
181 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
182 self
.nb
.AddPage(panel
, "Overview")
184 def OnOvrSize(evt
, ovr
=self
.ovr
):
185 ovr
.SetSize(evt
.GetSize())
187 EVT_SIZE(panel
, OnOvrSize
)
189 self
.SetOverview("Overview", overview
)
192 # Set up a TextCtrl on the Demo Code Notebook page
193 self
.txt
= wxTextCtrl(self
.nb
, -1,
194 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
195 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
196 self
.nb
.AddPage(self
.txt
, "Demo Code")
199 # Set up a log on the View Log Notebook page
200 self
.log
= wxTextCtrl(splitter2
, -1,
201 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
202 # Set the wxWindows log target to be this textctrl
203 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
209 # add the windows to the splitter and split it.
210 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
211 splitter2
.SetSashPosition(450, true
)
212 splitter2
.SetMinimumPaneSize(20)
214 splitter
.SplitVertically(self
.tree
, splitter2
)
215 splitter
.SetSashPosition(180, true
)
216 splitter
.SetMinimumPaneSize(20)
219 # select initial items
220 self
.nb
.SetSelection(0)
221 self
.tree
.SelectItem(root
)
223 if len(sys
.argv
) == 2:
225 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
229 self
.tree
.SelectItem(selectedDemo
)
230 self
.tree
.EnsureVisible(selectedDemo
)
233 wxLogMessage('window handle: %s' % self
.GetHandle())
236 #---------------------------------------------
237 def WriteText(self
, text
):
238 if text
[-1:] == '\n':
243 def write(self
, txt
):
246 #---------------------------------------------
247 def OnItemExpanded(self
, event
):
248 item
= event
.GetItem()
249 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
252 #---------------------------------------------
253 def OnItemCollapsed(self
, event
):
254 item
= event
.GetItem()
255 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
258 #---------------------------------------------
259 def OnTreeLeftDown(self
, event
):
260 pt
= event
.GetPosition();
261 item
, flags
= self
.tree
.HitTest(pt
)
262 if item
== self
.tree
.GetSelection():
263 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
266 #---------------------------------------------
267 def OnSelChanged(self
, event
):
271 item
= event
.GetItem()
272 itemText
= self
.tree
.GetItemText(item
)
273 self
.RunDemo(itemText
)
276 #---------------------------------------------
277 def RunDemo(self
, itemText
):
279 if self
.nb
.GetPageCount() == 3:
280 if self
.nb
.GetSelection() == 2:
281 self
.nb
.SetSelection(0)
282 self
.nb
.DeletePage(2)
284 if itemText
== 'Overview':
285 self
.GetDemoFile('Main.py')
286 self
.SetOverview('Overview', overview
)
291 if os
.path
.exists(itemText
+ '.py'):
293 wxLogMessage("Running demo %s.py..." % itemText
)
295 self
.GetDemoFile(itemText
+ '.py')
296 module
= __import__(itemText
, globals())
297 self
.SetOverview(itemText
, module
.overview
)
301 # in case runTest is modal, make sure things look right...
305 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
307 self
.nb
.AddPage(self
.window
, 'Demo')
309 self
.nb
.SetSelection(2)
318 #---------------------------------------------
320 def GetDemoFile(self
, filename
):
323 self
.txt
.SetValue(open(filename
).read())
325 self
.txt
.WriteText("Cannot open %s file." % filename
)
327 self
.txt
.SetInsertionPoint(0)
328 self
.txt
.ShowPosition(0)
330 #---------------------------------------------
331 def SetOverview(self
, name
, text
):
332 self
.curOverview
= text
334 if lead
!= '<html>' and lead
!= '<HTML>':
335 text
= string
.join(string
.split(text
, '\n'), '<br>')
336 #text = '<font size="-1"><pre>' + text + '</pre></font>'
337 self
.ovr
.SetPage(text
)
338 self
.nb
.SetPageText(0, name
)
340 #---------------------------------------------
342 def OnFileExit(self
, *event
):
346 def OnHelpAbout(self
, event
):
347 from About
import MyAboutBox
348 about
= MyAboutBox(self
)
353 #---------------------------------------------
354 def OnCloseWindow(self
, event
):
358 if hasattr(self
, "tbicon"):
363 #---------------------------------------------
364 def OnIdle(self
, event
):
366 self
.otherWin
.Raise()
367 self
.window
= self
.otherWin
370 #---------------------------------------------
371 def OnDemoMenu(self
, event
):
373 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
377 self
.tree
.SelectItem(selectedDemo
)
378 self
.tree
.EnsureVisible(selectedDemo
)
381 #---------------------------------------------
382 def OnTaskBarActivate(self
, evt
):
383 if self
.IsIconized():
385 if not self
.IsShown():
389 #---------------------------------------------
391 TBMENU_RESTORE
= 1000
394 def OnTaskBarMenu(self
, evt
):
396 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
397 menu
.Append(self
.TBMENU_CLOSE
, "Close")
398 self
.tbicon
.PopupMenu(menu
)
401 #---------------------------------------------
402 def OnTaskBarClose(self
, evt
):
405 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
406 # prod the main idle handler a bit to get the window to actually close
407 wxGetApp().ProcessIdle()
410 #---------------------------------------------
411 def OnIconfiy(self
, evt
):
412 wxLogMessage("OnIconfiy")
415 #---------------------------------------------
416 def OnMaximize(self
, evt
):
417 wxLogMessage("OnMaximize")
423 #---------------------------------------------------------------------------
424 #---------------------------------------------------------------------------
428 wxInitAllImageHandlers()
430 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
431 duration
=4000, callback
=self
.AfterSplash
)
432 self
.splash
.Show(true
)
437 def AfterSplash(self
):
438 self
.splash
.Close(true
)
439 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
441 self
.SetTopWindow(frame
)
445 def ShowTip(self
, frame
):
447 showTipText
= open("data/showTips").read()
448 showTip
, index
= eval(showTipText
)
450 showTip
, index
= (1, 0)
451 #print showTip, index
453 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
454 showTip
= wxShowTip(frame
, tp
)
455 index
= tp
.GetCurrentTip()
456 open("data/showTips", "w").write(str( (showTip
, index
) ))
459 #---------------------------------------------------------------------------
463 demoPath
= os
.path
.split(__file__
)[0]
471 #---------------------------------------------------------------------------
475 overview
= """<html><body>
478 Python is an interpreted, interactive, object-oriented programming
479 language often compared to Tcl, Perl, Scheme, or Java.
481 <p> Python combines remarkable power with very clear syntax. It has
482 modules, classes, exceptions, very high level dynamic data types, and
483 dynamic typing. There are interfaces to many system calls and
484 libraries, and new built-in modules are easily written in C or
485 C++. Python is also usable as an extension language for applications
486 that need a programmable interface. <p>
490 wxWindows is a free C++ framework designed to make cross-platform
491 programming child's play. Well, almost. wxWindows 2 supports Windows
492 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
493 underway. Other ports are under consideration. <p>
495 wxWindows is a set of libraries that allows C++ applications to
496 compile and run on several different types of computers, with minimal
497 source code changes. There is one library per supported GUI (such as
498 Motif, or Windows). As well as providing a common API (Application
499 Programming Interface) for GUI functionality, it provides
500 functionality for accessing some commonly-used operating system
501 facilities, such as copying or deleting files. wxWindows is a
502 'framework' in the sense that it provides a lot of built-in
503 functionality, which the application can use or replace as required,
504 thus saving a great deal of coding effort. Basic data structures such
505 as strings, linked lists and hash tables are also supported.
510 wxPython is a Python extension module that encapsulates the wxWindows
511 GUI classes. Currently it is only available for the Win32 and GTK
512 ports of wxWindows, but as soon as the other ports are brought up to
513 the same level as Win32 and GTK, it should be fairly trivial to
514 enable wxPython to be used with the new GUI.
518 The wxPython extension module attempts to mirror the class heiarchy
519 of wxWindows as closely as possible. This means that there is a
520 wxFrame class in wxPython that looks, smells, tastes and acts almost
521 the same as the wxFrame class in the C++ version. Unfortunately,
522 because of differences in the languages, wxPython doesn't match
523 wxWindows exactly, but the differences should be easy to absorb
524 because they are natural to Python. For example, some methods that
525 return multiple values via argument pointers in C++ will return a
526 tuple of values in Python.
530 There is still much to be done for wxPython, many classes still need
531 to be mirrored. Also, wxWindows is still somewhat of a moving target
532 so it is a bit of an effort just keeping wxPython up to date. On the
533 other hand, there are enough of the core classes completed that
534 useful applications can be written.
538 wxPython is close enough to the C++ version that the majority of
539 the wxPython documentation is actually just notes attached to the C++
540 documents that describe the places where wxPython is different. There
541 is also a series of sample programs included, and a series of
542 documentation pages that assist the programmer in getting started
548 #----------------------------------------------------------------------------
549 #----------------------------------------------------------------------------
551 if __name__
== '__main__':
554 #----------------------------------------------------------------------------