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',
32 'wxFindReplaceDialog',
39 'wxDynamicSashWindow',
42 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
43 'wxGrid', 'wxSashWindow',
44 'wxScrolledWindow', 'wxSplitterWindow',
45 'wxStatusBar', 'wxNotebook',
47 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
49 'wxDynamicSashWindow',
52 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
53 'wxSingleChoiceDialog', 'wxTextEntryDialog',
54 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
55 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
58 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
59 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
60 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
61 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
62 'wxCalendarCtrl', 'wxToggleButton',
65 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
67 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
69 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
70 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
71 'PythonEvents', 'Threads',
72 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
73 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
74 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
77 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
78 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
79 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
80 'FileBrowseButton', 'GenericButtons', 'wxEditor',
81 'ColourSelect', 'ImageBrowser',
82 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
86 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
90 #---------------------------------------------------------------------------
93 def __init__(self
, textCtrl
, logTime
=0):
94 wxPyLog
.__init
__(self
)
96 self
.logTime
= logTime
98 def DoLogString(self
, message
, timeStamp
):
100 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
102 self
.tc
.AppendText(message
+ '\n')
105 #---------------------------------------------------------------------------
107 class wxPythonDemo(wxFrame
):
109 def __init__(self
, parent
, id, title
):
110 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
111 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
113 self
.cwd
= os
.getcwd()
114 self
.curOverview
= ""
117 icon
= wxIconFromXPMData(images
.getMondrianData())
119 # another way to do it
120 bmp
= images
.getMondrianBitmap()
122 icon
.CopyFromBitmap(bmp
)
126 if wxPlatform
== '__WXMSW__':
127 # setup a taskbar icon, and catch some events from it
128 self
.tbicon
= wxTaskBarIcon()
129 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
130 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
131 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
132 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
133 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
137 EVT_IDLE(self
, self
.OnIdle
)
138 EVT_CLOSE(self
, self
.OnCloseWindow
)
139 EVT_ICONIZE(self
, self
.OnIconfiy
)
140 EVT_MAXIMIZE(self
, self
.OnMaximize
)
143 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
145 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
146 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
148 def EmptyHandler(evt
): pass
149 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
150 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
152 # Prevent TreeCtrl from displaying all items after destruction when true
156 self
.mainmenu
= wxMenuBar()
159 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
160 EVT_MENU(self
, exitID
, self
.OnFileExit
)
161 self
.mainmenu
.Append(menu
, '&File')
165 for item
in _treeList
:
167 for childItem
in item
[1]:
169 submenu
.Append(mID
, childItem
)
170 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
171 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
172 self
.mainmenu
.Append(menu
, '&Demo')
178 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
179 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
180 self
.mainmenu
.Append(menu
, '&Help')
181 self
.SetMenuBar(self
.mainmenu
)
183 # set the menu accellerator table...
184 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
185 (wxACCEL_CTRL
, ord('H'), helpID
)])
186 self
.SetAcceleratorTable(aTable
)
192 self
.tree
= wxTreeCtrl(splitter
, tID
,
193 style
=wxTR_HAS_BUTTONS |
195 wxTR_HAS_VARIABLE_ROW_HEIGHT |
197 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
198 root
= self
.tree
.AddRoot("Overview")
200 for item
in _treeList
:
201 child
= self
.tree
.AppendItem(root
, item
[0])
202 if not firstChild
: firstChild
= child
203 for childItem
in item
[1]:
204 theDemo
= self
.tree
.AppendItem(child
, childItem
)
205 self
.treeMap
[childItem
] = theDemo
207 self
.tree
.Expand(root
)
208 self
.tree
.Expand(firstChild
)
209 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
210 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
211 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
212 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
215 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
217 # Set up a wxHtmlWindow on the Overview Notebook page
218 # we put it in a panel first because there seems to be a
219 # refresh bug of some sort (wxGTK) when it is directly in
222 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
223 self
.nb
.AddPage(self
.ovr
, "Overview")
225 else: # hopefully I can remove this hacky code soon, see bug #216861
226 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
227 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
228 self
.nb
.AddPage(panel
, "Overview")
230 def OnOvrSize(evt
, ovr
=self
.ovr
):
231 ovr
.SetSize(evt
.GetSize())
233 EVT_SIZE(panel
, OnOvrSize
)
234 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
237 self
.SetOverview("Overview", overview
)
240 # Set up a TextCtrl on the Demo Code Notebook page
241 self
.txt
= wxTextCtrl(self
.nb
, -1,
242 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
243 self
.nb
.AddPage(self
.txt
, "Demo Code")
246 # Set up a log on the View Log Notebook page
247 self
.log
= wxTextCtrl(splitter2
, -1,
248 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
249 # Set the wxWindows log target to be this textctrl
250 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
251 wxLog_SetActiveTarget(MyLog(self
.log
))
257 # add the windows to the splitter and split it.
258 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
259 splitter2
.SetSashPosition(450, true
)
260 splitter2
.SetMinimumPaneSize(20)
262 splitter
.SplitVertically(self
.tree
, splitter2
)
263 splitter
.SetSashPosition(180, true
)
264 splitter
.SetMinimumPaneSize(20)
267 # select initial items
268 self
.nb
.SetSelection(0)
269 self
.tree
.SelectItem(root
)
271 if len(sys
.argv
) == 2:
273 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
277 self
.tree
.SelectItem(selectedDemo
)
278 self
.tree
.EnsureVisible(selectedDemo
)
281 wxLogMessage('window handle: %s' % self
.GetHandle())
284 #---------------------------------------------
285 def WriteText(self
, text
):
286 if text
[-1:] == '\n':
291 def write(self
, txt
):
294 #---------------------------------------------
295 def OnItemExpanded(self
, event
):
296 item
= event
.GetItem()
297 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
300 #---------------------------------------------
301 def OnItemCollapsed(self
, event
):
302 item
= event
.GetItem()
303 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
306 #---------------------------------------------
307 def OnTreeLeftDown(self
, event
):
308 pt
= event
.GetPosition();
309 item
, flags
= self
.tree
.HitTest(pt
)
310 if item
== self
.tree
.GetSelection():
311 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
314 #---------------------------------------------
315 def OnSelChanged(self
, event
):
319 item
= event
.GetItem()
320 itemText
= self
.tree
.GetItemText(item
)
321 self
.RunDemo(itemText
)
324 #---------------------------------------------
325 def RunDemo(self
, itemText
):
327 if self
.nb
.GetPageCount() == 3:
328 if self
.nb
.GetSelection() == 2:
329 self
.nb
.SetSelection(0)
330 self
.nb
.DeletePage(2)
332 if itemText
== 'Overview':
333 self
.GetDemoFile('Main.py')
334 self
.SetOverview('Overview', overview
)
339 if os
.path
.exists(itemText
+ '.py'):
341 wxLogMessage("Running demo %s.py..." % itemText
)
343 self
.GetDemoFile(itemText
+ '.py')
344 module
= __import__(itemText
, globals())
345 self
.SetOverview(itemText
, module
.overview
)
349 # in case runTest is modal, make sure things look right...
353 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
355 self
.nb
.AddPage(self
.window
, 'Demo')
357 self
.nb
.SetSelection(2)
366 #---------------------------------------------
368 def GetDemoFile(self
, filename
):
371 self
.txt
.SetValue(open(filename
).read())
373 self
.txt
.WriteText("Cannot open %s file." % filename
)
375 self
.txt
.SetInsertionPoint(0)
376 self
.txt
.ShowPosition(0)
378 #---------------------------------------------
379 def SetOverview(self
, name
, text
):
380 self
.curOverview
= text
382 if lead
!= '<html>' and lead
!= '<HTML>':
383 text
= string
.join(string
.split(text
, '\n'), '<br>')
384 #text = '<font size="-1"><pre>' + text + '</pre></font>'
385 self
.ovr
.SetPage(text
)
386 self
.nb
.SetPageText(0, name
)
388 #---------------------------------------------
390 def OnFileExit(self
, *event
):
394 def OnHelpAbout(self
, event
):
395 from About
import MyAboutBox
396 about
= MyAboutBox(self
)
401 #---------------------------------------------
402 def OnCloseWindow(self
, event
):
406 if hasattr(self
, "tbicon"):
411 #---------------------------------------------
412 def OnIdle(self
, event
):
414 self
.otherWin
.Raise()
415 self
.window
= self
.otherWin
418 #---------------------------------------------
419 def OnDemoMenu(self
, event
):
421 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
425 self
.tree
.SelectItem(selectedDemo
)
426 self
.tree
.EnsureVisible(selectedDemo
)
429 #---------------------------------------------
430 def OnTaskBarActivate(self
, evt
):
431 if self
.IsIconized():
433 if not self
.IsShown():
437 #---------------------------------------------
439 TBMENU_RESTORE
= 1000
442 def OnTaskBarMenu(self
, evt
):
444 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
445 menu
.Append(self
.TBMENU_CLOSE
, "Close")
446 self
.tbicon
.PopupMenu(menu
)
449 #---------------------------------------------
450 def OnTaskBarClose(self
, evt
):
453 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
454 # prod the main idle handler a bit to get the window to actually close
455 wxGetApp().ProcessIdle()
458 #---------------------------------------------
459 def OnIconfiy(self
, evt
):
460 wxLogMessage("OnIconfiy")
463 #---------------------------------------------
464 def OnMaximize(self
, evt
):
465 wxLogMessage("OnMaximize")
471 #---------------------------------------------------------------------------
472 #---------------------------------------------------------------------------
476 wxInitAllImageHandlers()
478 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
479 duration
=4000, callback
=self
.AfterSplash
)
480 self
.splash
.Show(true
)
485 def AfterSplash(self
):
486 self
.splash
.Close(true
)
487 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
489 self
.SetTopWindow(frame
)
493 def ShowTip(self
, frame
):
495 showTipText
= open("data/showTips").read()
496 showTip
, index
= eval(showTipText
)
498 showTip
, index
= (1, 0)
499 #print showTip, index
501 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
502 showTip
= wxShowTip(frame
, tp
)
503 index
= tp
.GetCurrentTip()
504 open("data/showTips", "w").write(str( (showTip
, index
) ))
507 #---------------------------------------------------------------------------
511 demoPath
= os
.path
.dirname(__file__
)
519 #---------------------------------------------------------------------------
523 overview
= """<html><body>
526 Python is an interpreted, interactive, object-oriented programming
527 language often compared to Tcl, Perl, Scheme, or Java.
529 <p> Python combines remarkable power with very clear syntax. It has
530 modules, classes, exceptions, very high level dynamic data types, and
531 dynamic typing. There are interfaces to many system calls and
532 libraries, and new built-in modules are easily written in C or
533 C++. Python is also usable as an extension language for applications
534 that need a programmable interface. <p>
538 wxWindows is a free C++ framework designed to make cross-platform
539 programming child's play. Well, almost. wxWindows 2 supports Windows
540 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
541 underway. Other ports are under consideration. <p>
543 wxWindows is a set of libraries that allows C++ applications to
544 compile and run on several different types of computers, with minimal
545 source code changes. There is one library per supported GUI (such as
546 Motif, or Windows). As well as providing a common API (Application
547 Programming Interface) for GUI functionality, it provides
548 functionality for accessing some commonly-used operating system
549 facilities, such as copying or deleting files. wxWindows is a
550 'framework' in the sense that it provides a lot of built-in
551 functionality, which the application can use or replace as required,
552 thus saving a great deal of coding effort. Basic data structures such
553 as strings, linked lists and hash tables are also supported.
558 wxPython is a Python extension module that encapsulates the wxWindows
559 GUI classes. Currently it is only available for the Win32 and GTK
560 ports of wxWindows, but as soon as the other ports are brought up to
561 the same level as Win32 and GTK, it should be fairly trivial to
562 enable wxPython to be used with the new GUI.
566 The wxPython extension module attempts to mirror the class heiarchy
567 of wxWindows as closely as possible. This means that there is a
568 wxFrame class in wxPython that looks, smells, tastes and acts almost
569 the same as the wxFrame class in the C++ version. Unfortunately,
570 because of differences in the languages, wxPython doesn't match
571 wxWindows exactly, but the differences should be easy to absorb
572 because they are natural to Python. For example, some methods that
573 return multiple values via argument pointers in C++ will return a
574 tuple of values in Python.
578 There is still much to be done for wxPython, many classes still need
579 to be mirrored. Also, wxWindows is still somewhat of a moving target
580 so it is a bit of an effort just keeping wxPython up to date. On the
581 other hand, there are enough of the core classes completed that
582 useful applications can be written.
586 wxPython is close enough to the C++ version that the majority of
587 the wxPython documentation is actually just notes attached to the C++
588 documents that describe the places where wxPython is different. There
589 is also a series of sample programs included, and a series of
590 documentation pages that assist the programmer in getting started
596 #----------------------------------------------------------------------------
597 #----------------------------------------------------------------------------
599 if __name__
== '__main__':
602 #----------------------------------------------------------------------------