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',
36 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
37 'wxGrid', 'wxSashWindow',
38 'wxScrolledWindow', 'wxSplitterWindow',
39 'wxStatusBar', 'wxNotebook',
41 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
45 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
46 'wxSingleChoiceDialog', 'wxTextEntryDialog',
47 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
48 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
51 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
52 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
53 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
54 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
55 'wxCalendarCtrl', 'wxToggleButton',
58 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
60 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
61 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
62 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
63 'PythonEvents', 'Threads',
64 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
65 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
69 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
70 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
71 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
72 'FileBrowseButton', 'GenericButtons', 'wxEditor',
73 'ColourSelect', 'ImageBrowser',
74 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
77 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
81 #---------------------------------------------------------------------------
84 def __init__(self
, textCtrl
, logTime
=0):
85 wxPyLog
.__init
__(self
)
87 self
.logTime
= logTime
89 def DoLogString(self
, message
, timeStamp
):
91 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
93 self
.tc
.AppendText(message
+ '\n')
96 #---------------------------------------------------------------------------
98 class wxPythonDemo(wxFrame
):
100 def __init__(self
, parent
, id, title
):
101 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
102 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
104 self
.cwd
= os
.getcwd()
105 self
.curOverview
= ""
108 icon
= wxIconFromXPMData(images
.getMondrianData())
110 # another way to do it
111 bmp
= images
.getMondrianBitmap()
113 icon
.CopyFromBitmap(bmp
)
117 if wxPlatform
== '__WXMSW__':
118 # setup a taskbar icon, and catch some events from it
119 self
.tbicon
= wxTaskBarIcon()
120 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
121 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
122 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
123 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
124 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
128 EVT_IDLE(self
, self
.OnIdle
)
129 EVT_CLOSE(self
, self
.OnCloseWindow
)
130 EVT_ICONIZE(self
, self
.OnIconfiy
)
131 EVT_MAXIMIZE(self
, self
.OnMaximize
)
134 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
136 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
137 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
139 def EmptyHandler(evt
): pass
140 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
141 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
143 # Prevent TreeCtrl from displaying all items after destruction when true
147 self
.mainmenu
= wxMenuBar()
150 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
151 EVT_MENU(self
, exitID
, self
.OnFileExit
)
152 self
.mainmenu
.Append(menu
, '&File')
156 for item
in _treeList
:
158 for childItem
in item
[1]:
160 submenu
.Append(mID
, childItem
)
161 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
162 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
163 self
.mainmenu
.Append(menu
, '&Demo')
169 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
170 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
171 self
.mainmenu
.Append(menu
, '&Help')
172 self
.SetMenuBar(self
.mainmenu
)
174 # set the menu accellerator table...
175 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
176 (wxACCEL_CTRL
, ord('H'), helpID
)])
177 self
.SetAcceleratorTable(aTable
)
183 self
.tree
= wxTreeCtrl(splitter
, tID
,
184 style
=wxTR_HAS_BUTTONS |
186 wxTR_HAS_VARIABLE_ROW_HEIGHT |
188 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
189 root
= self
.tree
.AddRoot("Overview")
191 for item
in _treeList
:
192 child
= self
.tree
.AppendItem(root
, item
[0])
193 if not firstChild
: firstChild
= child
194 for childItem
in item
[1]:
195 theDemo
= self
.tree
.AppendItem(child
, childItem
)
196 self
.treeMap
[childItem
] = theDemo
198 self
.tree
.Expand(root
)
199 self
.tree
.Expand(firstChild
)
200 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
201 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
202 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
203 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
206 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
208 # Set up a wxHtmlWindow on the Overview Notebook page
209 # we put it in a panel first because there seems to be a
210 # refresh bug of some sort (wxGTK) when it is directly in
213 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
214 self
.nb
.AddPage(self
.ovr
, "Overview")
216 else: # hopefully I can remove this hacky code soon, see bug #216861
217 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
218 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
219 self
.nb
.AddPage(panel
, "Overview")
221 def OnOvrSize(evt
, ovr
=self
.ovr
):
222 ovr
.SetSize(evt
.GetSize())
224 EVT_SIZE(panel
, OnOvrSize
)
225 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
228 self
.SetOverview("Overview", overview
)
231 # Set up a TextCtrl on the Demo Code Notebook page
232 self
.txt
= wxTextCtrl(self
.nb
, -1,
233 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
234 self
.nb
.AddPage(self
.txt
, "Demo Code")
237 # Set up a log on the View Log Notebook page
238 self
.log
= wxTextCtrl(splitter2
, -1,
239 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
240 # Set the wxWindows log target to be this textctrl
241 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
242 wxLog_SetActiveTarget(MyLog(self
.log
))
248 # add the windows to the splitter and split it.
249 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
250 splitter2
.SetSashPosition(450, true
)
251 splitter2
.SetMinimumPaneSize(20)
253 splitter
.SplitVertically(self
.tree
, splitter2
)
254 splitter
.SetSashPosition(180, true
)
255 splitter
.SetMinimumPaneSize(20)
258 # select initial items
259 self
.nb
.SetSelection(0)
260 self
.tree
.SelectItem(root
)
262 if len(sys
.argv
) == 2:
264 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
268 self
.tree
.SelectItem(selectedDemo
)
269 self
.tree
.EnsureVisible(selectedDemo
)
272 wxLogMessage('window handle: %s' % self
.GetHandle())
275 #---------------------------------------------
276 def WriteText(self
, text
):
277 if text
[-1:] == '\n':
282 def write(self
, txt
):
285 #---------------------------------------------
286 def OnItemExpanded(self
, event
):
287 item
= event
.GetItem()
288 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
291 #---------------------------------------------
292 def OnItemCollapsed(self
, event
):
293 item
= event
.GetItem()
294 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
297 #---------------------------------------------
298 def OnTreeLeftDown(self
, event
):
299 pt
= event
.GetPosition();
300 item
, flags
= self
.tree
.HitTest(pt
)
301 if item
== self
.tree
.GetSelection():
302 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
305 #---------------------------------------------
306 def OnSelChanged(self
, event
):
310 item
= event
.GetItem()
311 itemText
= self
.tree
.GetItemText(item
)
312 self
.RunDemo(itemText
)
315 #---------------------------------------------
316 def RunDemo(self
, itemText
):
318 if self
.nb
.GetPageCount() == 3:
319 if self
.nb
.GetSelection() == 2:
320 self
.nb
.SetSelection(0)
321 self
.nb
.DeletePage(2)
323 if itemText
== 'Overview':
324 self
.GetDemoFile('Main.py')
325 self
.SetOverview('Overview', overview
)
330 if os
.path
.exists(itemText
+ '.py'):
332 wxLogMessage("Running demo %s.py..." % itemText
)
334 self
.GetDemoFile(itemText
+ '.py')
335 module
= __import__(itemText
, globals())
336 self
.SetOverview(itemText
, module
.overview
)
340 # in case runTest is modal, make sure things look right...
344 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
346 self
.nb
.AddPage(self
.window
, 'Demo')
348 self
.nb
.SetSelection(2)
357 #---------------------------------------------
359 def GetDemoFile(self
, filename
):
362 self
.txt
.SetValue(open(filename
).read())
364 self
.txt
.WriteText("Cannot open %s file." % filename
)
366 self
.txt
.SetInsertionPoint(0)
367 self
.txt
.ShowPosition(0)
369 #---------------------------------------------
370 def SetOverview(self
, name
, text
):
371 self
.curOverview
= text
373 if lead
!= '<html>' and lead
!= '<HTML>':
374 text
= string
.join(string
.split(text
, '\n'), '<br>')
375 #text = '<font size="-1"><pre>' + text + '</pre></font>'
376 self
.ovr
.SetPage(text
)
377 self
.nb
.SetPageText(0, name
)
379 #---------------------------------------------
381 def OnFileExit(self
, *event
):
385 def OnHelpAbout(self
, event
):
386 from About
import MyAboutBox
387 about
= MyAboutBox(self
)
392 #---------------------------------------------
393 def OnCloseWindow(self
, event
):
397 if hasattr(self
, "tbicon"):
402 #---------------------------------------------
403 def OnIdle(self
, event
):
405 self
.otherWin
.Raise()
406 self
.window
= self
.otherWin
409 #---------------------------------------------
410 def OnDemoMenu(self
, event
):
412 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
416 self
.tree
.SelectItem(selectedDemo
)
417 self
.tree
.EnsureVisible(selectedDemo
)
420 #---------------------------------------------
421 def OnTaskBarActivate(self
, evt
):
422 if self
.IsIconized():
424 if not self
.IsShown():
428 #---------------------------------------------
430 TBMENU_RESTORE
= 1000
433 def OnTaskBarMenu(self
, evt
):
435 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
436 menu
.Append(self
.TBMENU_CLOSE
, "Close")
437 self
.tbicon
.PopupMenu(menu
)
440 #---------------------------------------------
441 def OnTaskBarClose(self
, evt
):
444 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
445 # prod the main idle handler a bit to get the window to actually close
446 wxGetApp().ProcessIdle()
449 #---------------------------------------------
450 def OnIconfiy(self
, evt
):
451 wxLogMessage("OnIconfiy")
454 #---------------------------------------------
455 def OnMaximize(self
, evt
):
456 wxLogMessage("OnMaximize")
462 #---------------------------------------------------------------------------
463 #---------------------------------------------------------------------------
467 wxInitAllImageHandlers()
469 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
470 duration
=4000, callback
=self
.AfterSplash
)
471 self
.splash
.Show(true
)
476 def AfterSplash(self
):
477 self
.splash
.Close(true
)
478 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
480 self
.SetTopWindow(frame
)
484 def ShowTip(self
, frame
):
486 showTipText
= open("data/showTips").read()
487 showTip
, index
= eval(showTipText
)
489 showTip
, index
= (1, 0)
490 #print showTip, index
492 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
493 showTip
= wxShowTip(frame
, tp
)
494 index
= tp
.GetCurrentTip()
495 open("data/showTips", "w").write(str( (showTip
, index
) ))
498 #---------------------------------------------------------------------------
502 demoPath
= os
.path
.dirname(__file__
)
510 #---------------------------------------------------------------------------
514 overview
= """<html><body>
517 Python is an interpreted, interactive, object-oriented programming
518 language often compared to Tcl, Perl, Scheme, or Java.
520 <p> Python combines remarkable power with very clear syntax. It has
521 modules, classes, exceptions, very high level dynamic data types, and
522 dynamic typing. There are interfaces to many system calls and
523 libraries, and new built-in modules are easily written in C or
524 C++. Python is also usable as an extension language for applications
525 that need a programmable interface. <p>
529 wxWindows is a free C++ framework designed to make cross-platform
530 programming child's play. Well, almost. wxWindows 2 supports Windows
531 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
532 underway. Other ports are under consideration. <p>
534 wxWindows is a set of libraries that allows C++ applications to
535 compile and run on several different types of computers, with minimal
536 source code changes. There is one library per supported GUI (such as
537 Motif, or Windows). As well as providing a common API (Application
538 Programming Interface) for GUI functionality, it provides
539 functionality for accessing some commonly-used operating system
540 facilities, such as copying or deleting files. wxWindows is a
541 'framework' in the sense that it provides a lot of built-in
542 functionality, which the application can use or replace as required,
543 thus saving a great deal of coding effort. Basic data structures such
544 as strings, linked lists and hash tables are also supported.
549 wxPython is a Python extension module that encapsulates the wxWindows
550 GUI classes. Currently it is only available for the Win32 and GTK
551 ports of wxWindows, but as soon as the other ports are brought up to
552 the same level as Win32 and GTK, it should be fairly trivial to
553 enable wxPython to be used with the new GUI.
557 The wxPython extension module attempts to mirror the class heiarchy
558 of wxWindows as closely as possible. This means that there is a
559 wxFrame class in wxPython that looks, smells, tastes and acts almost
560 the same as the wxFrame class in the C++ version. Unfortunately,
561 because of differences in the languages, wxPython doesn't match
562 wxWindows exactly, but the differences should be easy to absorb
563 because they are natural to Python. For example, some methods that
564 return multiple values via argument pointers in C++ will return a
565 tuple of values in Python.
569 There is still much to be done for wxPython, many classes still need
570 to be mirrored. Also, wxWindows is still somewhat of a moving target
571 so it is a bit of an effort just keeping wxPython up to date. On the
572 other hand, there are enough of the core classes completed that
573 useful applications can be written.
577 wxPython is close enough to the C++ version that the majority of
578 the wxPython documentation is actually just notes attached to the C++
579 documents that describe the places where wxPython is different. There
580 is also a series of sample programs included, and a series of
581 documentation pages that assist the programmer in getting started
587 #----------------------------------------------------------------------------
588 #----------------------------------------------------------------------------
590 if __name__
== '__main__':
593 #----------------------------------------------------------------------------