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', ['ContextHelp',
33 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
34 'wxGrid', 'wxSashWindow',
35 'wxScrolledWindow', 'wxSplitterWindow',
36 'wxStatusBar', 'wxNotebook',
38 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
40 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
41 'wxSingleChoiceDialog', 'wxTextEntryDialog',
42 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
43 'wxMessageDialog', 'wxProgressDialog']),
45 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
46 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
47 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
48 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
49 'wxCalendarCtrl', 'wxToggleButton',
52 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
54 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
55 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
56 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
57 'PythonEvents', 'Threads',
58 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
59 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
63 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
64 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
65 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
66 'FileBrowseButton', 'GenericButtons', 'wxEditor',
67 'ColourSelect', 'ImageBrowser',
68 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
71 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
75 #---------------------------------------------------------------------------
77 class wxPythonDemo(wxFrame
):
79 def __init__(self
, parent
, id, title
):
80 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
81 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
83 self
.cwd
= os
.getcwd()
87 icon
= wxIconFromXPMData(images
.getMondrianData())
89 # another way to do it
90 bmp
= images
.getMondrianBitmap()
92 icon
.CopyFromBitmap(bmp
)
96 if wxPlatform
== '__WXMSW__':
97 # setup a taskbar icon, and catch some events from it
98 self
.tbicon
= wxTaskBarIcon()
99 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
100 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
101 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
102 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
103 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
107 EVT_IDLE(self
, self
.OnIdle
)
108 EVT_CLOSE(self
, self
.OnCloseWindow
)
109 EVT_ICONIZE(self
, self
.OnIconfiy
)
110 EVT_MAXIMIZE(self
, self
.OnMaximize
)
113 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
115 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
116 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
118 def EmptyHandler(evt
): pass
119 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
120 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
122 # Prevent TreeCtrl from displaying all items after destruction when true
126 self
.mainmenu
= wxMenuBar()
129 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
130 EVT_MENU(self
, exitID
, self
.OnFileExit
)
131 self
.mainmenu
.Append(menu
, '&File')
135 for item
in _treeList
:
137 for childItem
in item
[1]:
139 submenu
.Append(mID
, childItem
)
140 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
141 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
142 self
.mainmenu
.Append(menu
, '&Demo')
148 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
149 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
150 self
.mainmenu
.Append(menu
, '&Help')
151 self
.SetMenuBar(self
.mainmenu
)
153 # set the menu accellerator table...
154 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
155 (wxACCEL_CTRL
, ord('H'), helpID
)])
156 self
.SetAcceleratorTable(aTable
)
162 self
.tree
= wxTreeCtrl(splitter
, tID
,
163 style
=wxTR_HAS_BUTTONS |
165 wxTR_HAS_VARIABLE_ROW_HEIGHT |
167 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
168 root
= self
.tree
.AddRoot("Overview")
170 for item
in _treeList
:
171 child
= self
.tree
.AppendItem(root
, item
[0])
172 if not firstChild
: firstChild
= child
173 for childItem
in item
[1]:
174 theDemo
= self
.tree
.AppendItem(child
, childItem
)
175 self
.treeMap
[childItem
] = theDemo
177 self
.tree
.Expand(root
)
178 self
.tree
.Expand(firstChild
)
179 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
180 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
181 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
182 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
185 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
187 # Set up a wxHtmlWindow on the Overview Notebook page
188 # we put it in a panel first because there seems to be a
189 # refresh bug of some sort (wxGTK) when it is directly in
192 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
193 self
.nb
.AddPage(self
.ovr
, "Overview")
195 else: # hopefully I can remove this hacky code soon, see bug #216861
196 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
197 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
198 self
.ovr
.SetFonts("", "", [7, 8, 10, 12, 16, 22, 30])
199 self
.nb
.AddPage(panel
, "Overview")
201 def OnOvrSize(evt
, ovr
=self
.ovr
):
202 ovr
.SetSize(evt
.GetSize())
204 EVT_SIZE(panel
, OnOvrSize
)
205 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
208 self
.SetOverview("Overview", overview
)
211 # Set up a TextCtrl on the Demo Code Notebook page
212 self
.txt
= wxTextCtrl(self
.nb
, -1,
213 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
214 self
.nb
.AddPage(self
.txt
, "Demo Code")
217 # Set up a log on the View Log Notebook page
218 self
.log
= wxTextCtrl(splitter2
, -1,
219 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
220 # Set the wxWindows log target to be this textctrl
221 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
227 # add the windows to the splitter and split it.
228 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
229 splitter2
.SetSashPosition(450, true
)
230 splitter2
.SetMinimumPaneSize(20)
232 splitter
.SplitVertically(self
.tree
, splitter2
)
233 splitter
.SetSashPosition(180, true
)
234 splitter
.SetMinimumPaneSize(20)
237 # select initial items
238 self
.nb
.SetSelection(0)
239 self
.tree
.SelectItem(root
)
241 if len(sys
.argv
) == 2:
243 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
247 self
.tree
.SelectItem(selectedDemo
)
248 self
.tree
.EnsureVisible(selectedDemo
)
251 wxLogMessage('window handle: %s' % self
.GetHandle())
254 #---------------------------------------------
255 def WriteText(self
, text
):
256 if text
[-1:] == '\n':
261 def write(self
, txt
):
264 #---------------------------------------------
265 def OnItemExpanded(self
, event
):
266 item
= event
.GetItem()
267 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
270 #---------------------------------------------
271 def OnItemCollapsed(self
, event
):
272 item
= event
.GetItem()
273 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
276 #---------------------------------------------
277 def OnTreeLeftDown(self
, event
):
278 pt
= event
.GetPosition();
279 item
, flags
= self
.tree
.HitTest(pt
)
280 if item
== self
.tree
.GetSelection():
281 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
284 #---------------------------------------------
285 def OnSelChanged(self
, event
):
289 item
= event
.GetItem()
290 itemText
= self
.tree
.GetItemText(item
)
291 self
.RunDemo(itemText
)
294 #---------------------------------------------
295 def RunDemo(self
, itemText
):
297 if self
.nb
.GetPageCount() == 3:
298 if self
.nb
.GetSelection() == 2:
299 self
.nb
.SetSelection(0)
300 self
.nb
.DeletePage(2)
302 if itemText
== 'Overview':
303 self
.GetDemoFile('Main.py')
304 self
.SetOverview('Overview', overview
)
309 if os
.path
.exists(itemText
+ '.py'):
311 wxLogMessage("Running demo %s.py..." % itemText
)
313 self
.GetDemoFile(itemText
+ '.py')
314 module
= __import__(itemText
, globals())
315 self
.SetOverview(itemText
, module
.overview
)
319 # in case runTest is modal, make sure things look right...
323 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
325 self
.nb
.AddPage(self
.window
, 'Demo')
327 self
.nb
.SetSelection(2)
336 #---------------------------------------------
338 def GetDemoFile(self
, filename
):
341 self
.txt
.SetValue(open(filename
).read())
343 self
.txt
.WriteText("Cannot open %s file." % filename
)
345 self
.txt
.SetInsertionPoint(0)
346 self
.txt
.ShowPosition(0)
348 #---------------------------------------------
349 def SetOverview(self
, name
, text
):
350 self
.curOverview
= text
352 if lead
!= '<html>' and lead
!= '<HTML>':
353 text
= string
.join(string
.split(text
, '\n'), '<br>')
354 #text = '<font size="-1"><pre>' + text + '</pre></font>'
355 self
.ovr
.SetPage(text
)
356 self
.nb
.SetPageText(0, name
)
358 #---------------------------------------------
360 def OnFileExit(self
, *event
):
364 def OnHelpAbout(self
, event
):
365 from About
import MyAboutBox
366 about
= MyAboutBox(self
)
371 #---------------------------------------------
372 def OnCloseWindow(self
, event
):
376 if hasattr(self
, "tbicon"):
381 #---------------------------------------------
382 def OnIdle(self
, event
):
384 self
.otherWin
.Raise()
385 self
.window
= self
.otherWin
388 #---------------------------------------------
389 def OnDemoMenu(self
, event
):
391 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
395 self
.tree
.SelectItem(selectedDemo
)
396 self
.tree
.EnsureVisible(selectedDemo
)
399 #---------------------------------------------
400 def OnTaskBarActivate(self
, evt
):
401 if self
.IsIconized():
403 if not self
.IsShown():
407 #---------------------------------------------
409 TBMENU_RESTORE
= 1000
412 def OnTaskBarMenu(self
, evt
):
414 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
415 menu
.Append(self
.TBMENU_CLOSE
, "Close")
416 self
.tbicon
.PopupMenu(menu
)
419 #---------------------------------------------
420 def OnTaskBarClose(self
, evt
):
423 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
424 # prod the main idle handler a bit to get the window to actually close
425 wxGetApp().ProcessIdle()
428 #---------------------------------------------
429 def OnIconfiy(self
, evt
):
430 wxLogMessage("OnIconfiy")
433 #---------------------------------------------
434 def OnMaximize(self
, evt
):
435 wxLogMessage("OnMaximize")
441 #---------------------------------------------------------------------------
442 #---------------------------------------------------------------------------
446 wxInitAllImageHandlers()
448 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
449 duration
=4000, callback
=self
.AfterSplash
)
450 self
.splash
.Show(true
)
455 def AfterSplash(self
):
456 self
.splash
.Close(true
)
457 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
459 self
.SetTopWindow(frame
)
463 def ShowTip(self
, frame
):
465 showTipText
= open("data/showTips").read()
466 showTip
, index
= eval(showTipText
)
468 showTip
, index
= (1, 0)
469 #print showTip, index
471 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
472 showTip
= wxShowTip(frame
, tp
)
473 index
= tp
.GetCurrentTip()
474 open("data/showTips", "w").write(str( (showTip
, index
) ))
477 #---------------------------------------------------------------------------
481 demoPath
= os
.path
.dirname(__file__
)
489 #---------------------------------------------------------------------------
493 overview
= """<html><body>
496 Python is an interpreted, interactive, object-oriented programming
497 language often compared to Tcl, Perl, Scheme, or Java.
499 <p> Python combines remarkable power with very clear syntax. It has
500 modules, classes, exceptions, very high level dynamic data types, and
501 dynamic typing. There are interfaces to many system calls and
502 libraries, and new built-in modules are easily written in C or
503 C++. Python is also usable as an extension language for applications
504 that need a programmable interface. <p>
508 wxWindows is a free C++ framework designed to make cross-platform
509 programming child's play. Well, almost. wxWindows 2 supports Windows
510 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
511 underway. Other ports are under consideration. <p>
513 wxWindows is a set of libraries that allows C++ applications to
514 compile and run on several different types of computers, with minimal
515 source code changes. There is one library per supported GUI (such as
516 Motif, or Windows). As well as providing a common API (Application
517 Programming Interface) for GUI functionality, it provides
518 functionality for accessing some commonly-used operating system
519 facilities, such as copying or deleting files. wxWindows is a
520 'framework' in the sense that it provides a lot of built-in
521 functionality, which the application can use or replace as required,
522 thus saving a great deal of coding effort. Basic data structures such
523 as strings, linked lists and hash tables are also supported.
528 wxPython is a Python extension module that encapsulates the wxWindows
529 GUI classes. Currently it is only available for the Win32 and GTK
530 ports of wxWindows, but as soon as the other ports are brought up to
531 the same level as Win32 and GTK, it should be fairly trivial to
532 enable wxPython to be used with the new GUI.
536 The wxPython extension module attempts to mirror the class heiarchy
537 of wxWindows as closely as possible. This means that there is a
538 wxFrame class in wxPython that looks, smells, tastes and acts almost
539 the same as the wxFrame class in the C++ version. Unfortunately,
540 because of differences in the languages, wxPython doesn't match
541 wxWindows exactly, but the differences should be easy to absorb
542 because they are natural to Python. For example, some methods that
543 return multiple values via argument pointers in C++ will return a
544 tuple of values in Python.
548 There is still much to be done for wxPython, many classes still need
549 to be mirrored. Also, wxWindows is still somewhat of a moving target
550 so it is a bit of an effort just keeping wxPython up to date. On the
551 other hand, there are enough of the core classes completed that
552 useful applications can be written.
556 wxPython is close enough to the C++ version that the majority of
557 the wxPython documentation is actually just notes attached to the C++
558 documents that describe the places where wxPython is different. There
559 is also a series of sample programs included, and a series of
560 documentation pages that assist the programmer in getting started
566 #----------------------------------------------------------------------------
567 #----------------------------------------------------------------------------
569 if __name__
== '__main__':
572 #----------------------------------------------------------------------------