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 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
40 'wxGrid', 'wxSashWindow',
41 'wxScrolledWindow', 'wxSplitterWindow',
42 'wxStatusBar', 'wxNotebook',
44 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
48 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
49 'wxSingleChoiceDialog', 'wxTextEntryDialog',
50 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
51 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
54 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
55 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
56 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
57 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
58 'wxCalendarCtrl', 'wxToggleButton',
61 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
63 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
64 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
65 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
66 'PythonEvents', 'Threads',
67 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
68 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
69 'wxJoystick', 'DrawXXXList', 'ErrorDialogs',
72 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
73 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
74 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
75 'FileBrowseButton', 'GenericButtons', 'wxEditor',
76 'ColourSelect', 'ImageBrowser',
77 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
81 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
85 #---------------------------------------------------------------------------
88 def __init__(self
, textCtrl
, logTime
=0):
89 wxPyLog
.__init
__(self
)
91 self
.logTime
= logTime
93 def DoLogString(self
, message
, timeStamp
):
95 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
97 self
.tc
.AppendText(message
+ '\n')
100 #---------------------------------------------------------------------------
102 class wxPythonDemo(wxFrame
):
104 def __init__(self
, parent
, id, title
):
105 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
106 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
108 self
.cwd
= os
.getcwd()
109 self
.curOverview
= ""
112 icon
= wxIconFromXPMData(images
.getMondrianData())
114 # another way to do it
115 bmp
= images
.getMondrianBitmap()
117 icon
.CopyFromBitmap(bmp
)
121 if wxPlatform
== '__WXMSW__':
122 # setup a taskbar icon, and catch some events from it
123 self
.tbicon
= wxTaskBarIcon()
124 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
125 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
126 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
127 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
128 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
132 EVT_IDLE(self
, self
.OnIdle
)
133 EVT_CLOSE(self
, self
.OnCloseWindow
)
134 EVT_ICONIZE(self
, self
.OnIconfiy
)
135 EVT_MAXIMIZE(self
, self
.OnMaximize
)
138 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
140 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
141 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
143 def EmptyHandler(evt
): pass
144 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
145 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
147 # Prevent TreeCtrl from displaying all items after destruction when true
151 self
.mainmenu
= wxMenuBar()
154 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
155 EVT_MENU(self
, exitID
, self
.OnFileExit
)
156 self
.mainmenu
.Append(menu
, '&File')
160 for item
in _treeList
:
162 for childItem
in item
[1]:
164 submenu
.Append(mID
, childItem
)
165 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
166 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
167 self
.mainmenu
.Append(menu
, '&Demo')
173 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
174 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
175 self
.mainmenu
.Append(menu
, '&Help')
176 self
.SetMenuBar(self
.mainmenu
)
178 # set the menu accellerator table...
179 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
180 (wxACCEL_CTRL
, ord('H'), helpID
)])
181 self
.SetAcceleratorTable(aTable
)
187 self
.tree
= wxTreeCtrl(splitter
, tID
,
188 style
=wxTR_HAS_BUTTONS |
190 wxTR_HAS_VARIABLE_ROW_HEIGHT |
192 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
193 root
= self
.tree
.AddRoot("Overview")
195 for item
in _treeList
:
196 child
= self
.tree
.AppendItem(root
, item
[0])
197 if not firstChild
: firstChild
= child
198 for childItem
in item
[1]:
199 theDemo
= self
.tree
.AppendItem(child
, childItem
)
200 self
.treeMap
[childItem
] = theDemo
202 self
.tree
.Expand(root
)
203 self
.tree
.Expand(firstChild
)
204 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
205 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
206 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
207 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
210 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
212 # Set up a wxHtmlWindow on the Overview Notebook page
213 # we put it in a panel first because there seems to be a
214 # refresh bug of some sort (wxGTK) when it is directly in
217 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
218 self
.nb
.AddPage(self
.ovr
, "Overview")
220 else: # hopefully I can remove this hacky code soon, see bug #216861
221 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
222 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
223 self
.nb
.AddPage(panel
, "Overview")
225 def OnOvrSize(evt
, ovr
=self
.ovr
):
226 ovr
.SetSize(evt
.GetSize())
228 EVT_SIZE(panel
, OnOvrSize
)
229 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
232 self
.SetOverview("Overview", overview
)
235 # Set up a TextCtrl on the Demo Code Notebook page
236 self
.txt
= wxTextCtrl(self
.nb
, -1,
237 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
238 self
.nb
.AddPage(self
.txt
, "Demo Code")
241 # Set up a log on the View Log Notebook page
242 self
.log
= wxTextCtrl(splitter2
, -1,
243 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
244 # Set the wxWindows log target to be this textctrl
245 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
246 wxLog_SetActiveTarget(MyLog(self
.log
))
252 # add the windows to the splitter and split it.
253 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
254 splitter2
.SetSashPosition(450, true
)
255 splitter2
.SetMinimumPaneSize(20)
257 splitter
.SplitVertically(self
.tree
, splitter2
)
258 splitter
.SetSashPosition(180, true
)
259 splitter
.SetMinimumPaneSize(20)
262 # select initial items
263 self
.nb
.SetSelection(0)
264 self
.tree
.SelectItem(root
)
266 if len(sys
.argv
) == 2:
268 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
272 self
.tree
.SelectItem(selectedDemo
)
273 self
.tree
.EnsureVisible(selectedDemo
)
276 wxLogMessage('window handle: %s' % self
.GetHandle())
279 #---------------------------------------------
280 def WriteText(self
, text
):
281 if text
[-1:] == '\n':
286 def write(self
, txt
):
289 #---------------------------------------------
290 def OnItemExpanded(self
, event
):
291 item
= event
.GetItem()
292 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
295 #---------------------------------------------
296 def OnItemCollapsed(self
, event
):
297 item
= event
.GetItem()
298 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
301 #---------------------------------------------
302 def OnTreeLeftDown(self
, event
):
303 pt
= event
.GetPosition();
304 item
, flags
= self
.tree
.HitTest(pt
)
305 if item
== self
.tree
.GetSelection():
306 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
309 #---------------------------------------------
310 def OnSelChanged(self
, event
):
314 item
= event
.GetItem()
315 itemText
= self
.tree
.GetItemText(item
)
316 self
.RunDemo(itemText
)
319 #---------------------------------------------
320 def RunDemo(self
, itemText
):
322 if self
.nb
.GetPageCount() == 3:
323 if self
.nb
.GetSelection() == 2:
324 self
.nb
.SetSelection(0)
325 self
.nb
.DeletePage(2)
327 if itemText
== 'Overview':
328 self
.GetDemoFile('Main.py')
329 self
.SetOverview('Overview', overview
)
334 if os
.path
.exists(itemText
+ '.py'):
336 wxLogMessage("Running demo %s.py..." % itemText
)
338 self
.GetDemoFile(itemText
+ '.py')
339 module
= __import__(itemText
, globals())
340 self
.SetOverview(itemText
, module
.overview
)
344 # in case runTest is modal, make sure things look right...
348 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
350 self
.nb
.AddPage(self
.window
, 'Demo')
352 self
.nb
.SetSelection(2)
361 #---------------------------------------------
363 def GetDemoFile(self
, filename
):
366 self
.txt
.SetValue(open(filename
).read())
368 self
.txt
.WriteText("Cannot open %s file." % filename
)
370 self
.txt
.SetInsertionPoint(0)
371 self
.txt
.ShowPosition(0)
373 #---------------------------------------------
374 def SetOverview(self
, name
, text
):
375 self
.curOverview
= text
377 if lead
!= '<html>' and lead
!= '<HTML>':
378 text
= string
.join(string
.split(text
, '\n'), '<br>')
379 #text = '<font size="-1"><pre>' + text + '</pre></font>'
380 self
.ovr
.SetPage(text
)
381 self
.nb
.SetPageText(0, name
)
383 #---------------------------------------------
385 def OnFileExit(self
, *event
):
389 def OnHelpAbout(self
, event
):
390 from About
import MyAboutBox
391 about
= MyAboutBox(self
)
396 #---------------------------------------------
397 def OnCloseWindow(self
, event
):
401 if hasattr(self
, "tbicon"):
406 #---------------------------------------------
407 def OnIdle(self
, event
):
409 self
.otherWin
.Raise()
410 self
.window
= self
.otherWin
413 #---------------------------------------------
414 def OnDemoMenu(self
, event
):
416 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
420 self
.tree
.SelectItem(selectedDemo
)
421 self
.tree
.EnsureVisible(selectedDemo
)
424 #---------------------------------------------
425 def OnTaskBarActivate(self
, evt
):
426 if self
.IsIconized():
428 if not self
.IsShown():
432 #---------------------------------------------
434 TBMENU_RESTORE
= 1000
437 def OnTaskBarMenu(self
, evt
):
439 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
440 menu
.Append(self
.TBMENU_CLOSE
, "Close")
441 self
.tbicon
.PopupMenu(menu
)
444 #---------------------------------------------
445 def OnTaskBarClose(self
, evt
):
448 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
449 # prod the main idle handler a bit to get the window to actually close
450 wxGetApp().ProcessIdle()
453 #---------------------------------------------
454 def OnIconfiy(self
, evt
):
455 wxLogMessage("OnIconfiy")
458 #---------------------------------------------
459 def OnMaximize(self
, evt
):
460 wxLogMessage("OnMaximize")
466 #---------------------------------------------------------------------------
467 #---------------------------------------------------------------------------
471 wxInitAllImageHandlers()
473 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
474 duration
=4000, callback
=self
.AfterSplash
)
475 self
.splash
.Show(true
)
480 def AfterSplash(self
):
481 self
.splash
.Close(true
)
482 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
484 self
.SetTopWindow(frame
)
488 def ShowTip(self
, frame
):
490 showTipText
= open("data/showTips").read()
491 showTip
, index
= eval(showTipText
)
493 showTip
, index
= (1, 0)
494 #print showTip, index
496 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
497 showTip
= wxShowTip(frame
, tp
)
498 index
= tp
.GetCurrentTip()
499 open("data/showTips", "w").write(str( (showTip
, index
) ))
502 #---------------------------------------------------------------------------
506 demoPath
= os
.path
.dirname(__file__
)
514 #---------------------------------------------------------------------------
518 overview
= """<html><body>
521 Python is an interpreted, interactive, object-oriented programming
522 language often compared to Tcl, Perl, Scheme, or Java.
524 <p> Python combines remarkable power with very clear syntax. It has
525 modules, classes, exceptions, very high level dynamic data types, and
526 dynamic typing. There are interfaces to many system calls and
527 libraries, and new built-in modules are easily written in C or
528 C++. Python is also usable as an extension language for applications
529 that need a programmable interface. <p>
533 wxWindows is a free C++ framework designed to make cross-platform
534 programming child's play. Well, almost. wxWindows 2 supports Windows
535 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
536 underway. Other ports are under consideration. <p>
538 wxWindows is a set of libraries that allows C++ applications to
539 compile and run on several different types of computers, with minimal
540 source code changes. There is one library per supported GUI (such as
541 Motif, or Windows). As well as providing a common API (Application
542 Programming Interface) for GUI functionality, it provides
543 functionality for accessing some commonly-used operating system
544 facilities, such as copying or deleting files. wxWindows is a
545 'framework' in the sense that it provides a lot of built-in
546 functionality, which the application can use or replace as required,
547 thus saving a great deal of coding effort. Basic data structures such
548 as strings, linked lists and hash tables are also supported.
553 wxPython is a Python extension module that encapsulates the wxWindows
554 GUI classes. Currently it is only available for the Win32 and GTK
555 ports of wxWindows, but as soon as the other ports are brought up to
556 the same level as Win32 and GTK, it should be fairly trivial to
557 enable wxPython to be used with the new GUI.
561 The wxPython extension module attempts to mirror the class heiarchy
562 of wxWindows as closely as possible. This means that there is a
563 wxFrame class in wxPython that looks, smells, tastes and acts almost
564 the same as the wxFrame class in the C++ version. Unfortunately,
565 because of differences in the languages, wxPython doesn't match
566 wxWindows exactly, but the differences should be easy to absorb
567 because they are natural to Python. For example, some methods that
568 return multiple values via argument pointers in C++ will return a
569 tuple of values in Python.
573 There is still much to be done for wxPython, many classes still need
574 to be mirrored. Also, wxWindows is still somewhat of a moving target
575 so it is a bit of an effort just keeping wxPython up to date. On the
576 other hand, there are enough of the core classes completed that
577 useful applications can be written.
581 wxPython is close enough to the C++ version that the majority of
582 the wxPython documentation is actually just notes attached to the C++
583 documents that describe the places where wxPython is different. There
584 is also a series of sample programs included, and a series of
585 documentation pages that assist the programmer in getting started
591 #----------------------------------------------------------------------------
592 #----------------------------------------------------------------------------
594 if __name__
== '__main__':
597 #----------------------------------------------------------------------------