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',
31 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
33 'wxGrid', 'wxSashWindow',
34 'wxScrolledWindow', 'wxSplitterWindow',
35 'wxStatusBar', 'wxNotebook',
37 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
39 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
40 'wxSingleChoiceDialog', 'wxTextEntryDialog',
41 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
42 'wxMessageDialog', 'wxProgressDialog']),
44 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
45 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
46 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
47 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
48 'wxCalendarCtrl', 'wxToggleButton',
51 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
53 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
54 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
55 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
56 'PythonEvents', 'Threads',
57 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
58 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
62 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
63 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
64 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
65 'FileBrowseButton', 'GenericButtons', 'wxEditor',
66 'ColourSelect', 'ImageBrowser',
67 'infoframe', 'ColourDB', 'PyCrust',
70 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
74 #---------------------------------------------------------------------------
76 class wxPythonDemo(wxFrame
):
78 def __init__(self
, parent
, id, title
):
79 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
80 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
82 self
.cwd
= os
.getcwd()
86 icon
= wxIconFromXPMData(images
.getMondrianData())
88 # another way to do it
89 bmp
= images
.getMondrianBitmap()
91 icon
.CopyFromBitmap(bmp
)
95 if wxPlatform
== '__WXMSW__':
96 # setup a taskbar icon, and catch some events from it
97 self
.tbicon
= wxTaskBarIcon()
98 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
99 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
100 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
101 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
102 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
106 EVT_IDLE(self
, self
.OnIdle
)
107 EVT_CLOSE(self
, self
.OnCloseWindow
)
108 EVT_ICONIZE(self
, self
.OnIconfiy
)
109 EVT_MAXIMIZE(self
, self
.OnMaximize
)
112 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
114 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
115 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
117 def EmptyHandler(evt
): pass
118 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
119 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
121 # Prevent TreeCtrl from displaying all items after destruction
125 self
.mainmenu
= wxMenuBar()
128 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
129 EVT_MENU(self
, exitID
, self
.OnFileExit
)
130 self
.mainmenu
.Append(menu
, '&File')
134 for item
in _treeList
:
136 for childItem
in item
[1]:
138 submenu
.Append(mID
, childItem
)
139 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
140 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
141 self
.mainmenu
.Append(menu
, '&Demo')
147 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
148 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
149 self
.mainmenu
.Append(menu
, '&Help')
150 self
.SetMenuBar(self
.mainmenu
)
152 # set the menu accellerator table...
153 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
154 (wxACCEL_CTRL
, ord('H'), helpID
)])
155 self
.SetAcceleratorTable(aTable
)
161 self
.tree
= wxTreeCtrl(splitter
, tID
,
162 style
=wxTR_HAS_BUTTONS |
164 wxTR_HAS_VARIABLE_ROW_HEIGHT |
166 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
167 root
= self
.tree
.AddRoot("Overview")
169 for item
in _treeList
:
170 child
= self
.tree
.AppendItem(root
, item
[0])
171 if not firstChild
: firstChild
= child
172 for childItem
in item
[1]:
173 theDemo
= self
.tree
.AppendItem(child
, childItem
)
174 self
.treeMap
[childItem
] = theDemo
176 self
.tree
.Expand(root
)
177 self
.tree
.Expand(firstChild
)
178 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
179 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
180 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
181 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
184 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
186 # Set up a wxHtmlWindow on the Overview Notebook page
187 # we put it in a panel first because there seems to be a
188 # refresh bug of some sort (wxGTK) when it is directly in
191 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
192 self
.nb
.AddPage(self
.ovr
, "Overview")
194 else: # hopefully I can remove this hacky code soon, see bug #216861
195 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
196 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
197 self
.nb
.AddPage(panel
, "Overview")
199 def OnOvrSize(evt
, ovr
=self
.ovr
):
200 ovr
.SetSize(evt
.GetSize())
202 EVT_SIZE(panel
, OnOvrSize
)
203 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
206 self
.SetOverview("Overview", overview
)
209 # Set up a TextCtrl on the Demo Code Notebook page
210 self
.txt
= wxTextCtrl(self
.nb
, -1,
211 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
212 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
213 self
.nb
.AddPage(self
.txt
, "Demo Code")
216 # Set up a log on the View Log Notebook page
217 self
.log
= wxTextCtrl(splitter2
, -1,
218 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
219 # Set the wxWindows log target to be this textctrl
220 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
226 # add the windows to the splitter and split it.
227 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
228 splitter2
.SetSashPosition(450, true
)
229 splitter2
.SetMinimumPaneSize(20)
231 splitter
.SplitVertically(self
.tree
, splitter2
)
232 splitter
.SetSashPosition(180, true
)
233 splitter
.SetMinimumPaneSize(20)
236 # select initial items
237 self
.nb
.SetSelection(0)
238 self
.tree
.SelectItem(root
)
240 if len(sys
.argv
) == 2:
242 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
246 self
.tree
.SelectItem(selectedDemo
)
247 self
.tree
.EnsureVisible(selectedDemo
)
250 wxLogMessage('window handle: %s' % self
.GetHandle())
253 #---------------------------------------------
254 def WriteText(self
, text
):
255 if text
[-1:] == '\n':
260 def write(self
, txt
):
263 #---------------------------------------------
264 def OnItemExpanded(self
, event
):
265 item
= event
.GetItem()
266 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
269 #---------------------------------------------
270 def OnItemCollapsed(self
, event
):
271 item
= event
.GetItem()
272 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
275 #---------------------------------------------
276 def OnTreeLeftDown(self
, event
):
277 pt
= event
.GetPosition();
278 item
, flags
= self
.tree
.HitTest(pt
)
279 if item
== self
.tree
.GetSelection():
280 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
283 #---------------------------------------------
284 def OnSelChanged(self
, event
):
288 item
= event
.GetItem()
289 itemText
= self
.tree
.GetItemText(item
)
290 self
.RunDemo(itemText
)
293 #---------------------------------------------
294 def RunDemo(self
, itemText
):
296 if self
.nb
.GetPageCount() == 3:
297 if self
.nb
.GetSelection() == 2:
298 self
.nb
.SetSelection(0)
299 self
.nb
.DeletePage(2)
301 if itemText
== 'Overview':
302 self
.GetDemoFile('Main.py')
303 self
.SetOverview('Overview', overview
)
308 if os
.path
.exists(itemText
+ '.py'):
310 wxLogMessage("Running demo %s.py..." % itemText
)
312 self
.GetDemoFile(itemText
+ '.py')
313 module
= __import__(itemText
, globals())
314 self
.SetOverview(itemText
, module
.overview
)
318 # in case runTest is modal, make sure things look right...
322 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
324 self
.nb
.AddPage(self
.window
, 'Demo')
326 self
.nb
.SetSelection(2)
335 #---------------------------------------------
337 def GetDemoFile(self
, filename
):
340 self
.txt
.SetValue(open(filename
).read())
342 self
.txt
.WriteText("Cannot open %s file." % filename
)
344 self
.txt
.SetInsertionPoint(0)
345 self
.txt
.ShowPosition(0)
347 #---------------------------------------------
348 def SetOverview(self
, name
, text
):
349 self
.curOverview
= text
351 if lead
!= '<html>' and lead
!= '<HTML>':
352 text
= string
.join(string
.split(text
, '\n'), '<br>')
353 #text = '<font size="-1"><pre>' + text + '</pre></font>'
354 self
.ovr
.SetPage(text
)
355 self
.nb
.SetPageText(0, name
)
357 #---------------------------------------------
359 def OnFileExit(self
, *event
):
363 def OnHelpAbout(self
, event
):
364 from About
import MyAboutBox
365 about
= MyAboutBox(self
)
370 #---------------------------------------------
371 def OnCloseWindow(self
, event
):
375 if hasattr(self
, "tbicon"):
380 #---------------------------------------------
381 def OnIdle(self
, event
):
383 self
.otherWin
.Raise()
384 self
.window
= self
.otherWin
387 #---------------------------------------------
388 def OnDemoMenu(self
, event
):
390 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
394 self
.tree
.SelectItem(selectedDemo
)
395 self
.tree
.EnsureVisible(selectedDemo
)
398 #---------------------------------------------
399 def OnTaskBarActivate(self
, evt
):
400 if self
.IsIconized():
402 if not self
.IsShown():
406 #---------------------------------------------
408 TBMENU_RESTORE
= 1000
411 def OnTaskBarMenu(self
, evt
):
413 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
414 menu
.Append(self
.TBMENU_CLOSE
, "Close")
415 self
.tbicon
.PopupMenu(menu
)
418 #---------------------------------------------
419 def OnTaskBarClose(self
, evt
):
422 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
423 # prod the main idle handler a bit to get the window to actually close
424 wxGetApp().ProcessIdle()
427 #---------------------------------------------
428 def OnIconfiy(self
, evt
):
429 wxLogMessage("OnIconfiy")
432 #---------------------------------------------
433 def OnMaximize(self
, evt
):
434 wxLogMessage("OnMaximize")
440 #---------------------------------------------------------------------------
441 #---------------------------------------------------------------------------
445 wxInitAllImageHandlers()
447 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
448 duration
=4000, callback
=self
.AfterSplash
)
449 self
.splash
.Show(true
)
454 def AfterSplash(self
):
455 self
.splash
.Close(true
)
456 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
458 self
.SetTopWindow(frame
)
462 def ShowTip(self
, frame
):
464 showTipText
= open("data/showTips").read()
465 showTip
, index
= eval(showTipText
)
467 showTip
, index
= (1, 0)
468 #print showTip, index
470 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
471 showTip
= wxShowTip(frame
, tp
)
472 index
= tp
.GetCurrentTip()
473 open("data/showTips", "w").write(str( (showTip
, index
) ))
476 #---------------------------------------------------------------------------
480 demoPath
= os
.path
.dirname(__file__
)
488 #---------------------------------------------------------------------------
492 overview
= """<html><body>
495 Python is an interpreted, interactive, object-oriented programming
496 language often compared to Tcl, Perl, Scheme, or Java.
498 <p> Python combines remarkable power with very clear syntax. It has
499 modules, classes, exceptions, very high level dynamic data types, and
500 dynamic typing. There are interfaces to many system calls and
501 libraries, and new built-in modules are easily written in C or
502 C++. Python is also usable as an extension language for applications
503 that need a programmable interface. <p>
507 wxWindows is a free C++ framework designed to make cross-platform
508 programming child's play. Well, almost. wxWindows 2 supports Windows
509 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
510 underway. Other ports are under consideration. <p>
512 wxWindows is a set of libraries that allows C++ applications to
513 compile and run on several different types of computers, with minimal
514 source code changes. There is one library per supported GUI (such as
515 Motif, or Windows). As well as providing a common API (Application
516 Programming Interface) for GUI functionality, it provides
517 functionality for accessing some commonly-used operating system
518 facilities, such as copying or deleting files. wxWindows is a
519 'framework' in the sense that it provides a lot of built-in
520 functionality, which the application can use or replace as required,
521 thus saving a great deal of coding effort. Basic data structures such
522 as strings, linked lists and hash tables are also supported.
527 wxPython is a Python extension module that encapsulates the wxWindows
528 GUI classes. Currently it is only available for the Win32 and GTK
529 ports of wxWindows, but as soon as the other ports are brought up to
530 the same level as Win32 and GTK, it should be fairly trivial to
531 enable wxPython to be used with the new GUI.
535 The wxPython extension module attempts to mirror the class heiarchy
536 of wxWindows as closely as possible. This means that there is a
537 wxFrame class in wxPython that looks, smells, tastes and acts almost
538 the same as the wxFrame class in the C++ version. Unfortunately,
539 because of differences in the languages, wxPython doesn't match
540 wxWindows exactly, but the differences should be easy to absorb
541 because they are natural to Python. For example, some methods that
542 return multiple values via argument pointers in C++ will return a
543 tuple of values in Python.
547 There is still much to be done for wxPython, many classes still need
548 to be mirrored. Also, wxWindows is still somewhat of a moving target
549 so it is a bit of an effort just keeping wxPython up to date. On the
550 other hand, there are enough of the core classes completed that
551 useful applications can be written.
555 wxPython is close enough to the C++ version that the majority of
556 the wxPython documentation is actually just notes attached to the C++
557 documents that describe the places where wxPython is different. There
558 is also a series of sample programs included, and a series of
559 documentation pages that assist the programmer in getting started
565 #----------------------------------------------------------------------------
566 #----------------------------------------------------------------------------
568 if __name__
== '__main__':
571 #----------------------------------------------------------------------------