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 #---------------------------------------------------------------------------
78 def __init__(self
, textCtrl
, logTime
=0):
79 wxPyLog
.__init
__(self
)
81 self
.logTime
= logTime
83 def DoLogString(self
, message
, timeStamp
):
85 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
87 self
.tc
.AppendText(message
+ '\n')
90 #---------------------------------------------------------------------------
92 class wxPythonDemo(wxFrame
):
94 def __init__(self
, parent
, id, title
):
95 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
96 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
98 self
.cwd
= os
.getcwd()
102 icon
= wxIconFromXPMData(images
.getMondrianData())
104 # another way to do it
105 bmp
= images
.getMondrianBitmap()
107 icon
.CopyFromBitmap(bmp
)
111 if wxPlatform
== '__WXMSW__':
112 # setup a taskbar icon, and catch some events from it
113 self
.tbicon
= wxTaskBarIcon()
114 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
115 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
116 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
117 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
118 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
122 EVT_IDLE(self
, self
.OnIdle
)
123 EVT_CLOSE(self
, self
.OnCloseWindow
)
124 EVT_ICONIZE(self
, self
.OnIconfiy
)
125 EVT_MAXIMIZE(self
, self
.OnMaximize
)
128 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
130 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
131 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
133 def EmptyHandler(evt
): pass
134 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
135 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
137 # Prevent TreeCtrl from displaying all items after destruction when true
141 self
.mainmenu
= wxMenuBar()
144 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
145 EVT_MENU(self
, exitID
, self
.OnFileExit
)
146 self
.mainmenu
.Append(menu
, '&File')
150 for item
in _treeList
:
152 for childItem
in item
[1]:
154 submenu
.Append(mID
, childItem
)
155 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
156 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
157 self
.mainmenu
.Append(menu
, '&Demo')
163 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
164 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
165 self
.mainmenu
.Append(menu
, '&Help')
166 self
.SetMenuBar(self
.mainmenu
)
168 # set the menu accellerator table...
169 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
170 (wxACCEL_CTRL
, ord('H'), helpID
)])
171 self
.SetAcceleratorTable(aTable
)
177 self
.tree
= wxTreeCtrl(splitter
, tID
,
178 style
=wxTR_HAS_BUTTONS |
180 wxTR_HAS_VARIABLE_ROW_HEIGHT |
182 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
183 root
= self
.tree
.AddRoot("Overview")
185 for item
in _treeList
:
186 child
= self
.tree
.AppendItem(root
, item
[0])
187 if not firstChild
: firstChild
= child
188 for childItem
in item
[1]:
189 theDemo
= self
.tree
.AppendItem(child
, childItem
)
190 self
.treeMap
[childItem
] = theDemo
192 self
.tree
.Expand(root
)
193 self
.tree
.Expand(firstChild
)
194 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
195 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
196 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
197 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
200 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
202 # Set up a wxHtmlWindow on the Overview Notebook page
203 # we put it in a panel first because there seems to be a
204 # refresh bug of some sort (wxGTK) when it is directly in
207 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
208 self
.nb
.AddPage(self
.ovr
, "Overview")
210 else: # hopefully I can remove this hacky code soon, see bug #216861
211 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
212 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
213 self
.nb
.AddPage(panel
, "Overview")
215 def OnOvrSize(evt
, ovr
=self
.ovr
):
216 ovr
.SetSize(evt
.GetSize())
218 EVT_SIZE(panel
, OnOvrSize
)
219 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
222 self
.SetOverview("Overview", overview
)
225 # Set up a TextCtrl on the Demo Code Notebook page
226 self
.txt
= wxTextCtrl(self
.nb
, -1,
227 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
228 self
.nb
.AddPage(self
.txt
, "Demo Code")
231 # Set up a log on the View Log Notebook page
232 self
.log
= wxTextCtrl(splitter2
, -1,
233 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
234 # Set the wxWindows log target to be this textctrl
235 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
236 wxLog_SetActiveTarget(MyLog(self
.log
))
242 # add the windows to the splitter and split it.
243 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
244 splitter2
.SetSashPosition(450, true
)
245 splitter2
.SetMinimumPaneSize(20)
247 splitter
.SplitVertically(self
.tree
, splitter2
)
248 splitter
.SetSashPosition(180, true
)
249 splitter
.SetMinimumPaneSize(20)
252 # select initial items
253 self
.nb
.SetSelection(0)
254 self
.tree
.SelectItem(root
)
256 if len(sys
.argv
) == 2:
258 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
262 self
.tree
.SelectItem(selectedDemo
)
263 self
.tree
.EnsureVisible(selectedDemo
)
266 wxLogMessage('window handle: %s' % self
.GetHandle())
269 #---------------------------------------------
270 def WriteText(self
, text
):
271 if text
[-1:] == '\n':
276 def write(self
, txt
):
279 #---------------------------------------------
280 def OnItemExpanded(self
, event
):
281 item
= event
.GetItem()
282 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
285 #---------------------------------------------
286 def OnItemCollapsed(self
, event
):
287 item
= event
.GetItem()
288 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
291 #---------------------------------------------
292 def OnTreeLeftDown(self
, event
):
293 pt
= event
.GetPosition();
294 item
, flags
= self
.tree
.HitTest(pt
)
295 if item
== self
.tree
.GetSelection():
296 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
299 #---------------------------------------------
300 def OnSelChanged(self
, event
):
304 item
= event
.GetItem()
305 itemText
= self
.tree
.GetItemText(item
)
306 self
.RunDemo(itemText
)
309 #---------------------------------------------
310 def RunDemo(self
, itemText
):
312 if self
.nb
.GetPageCount() == 3:
313 if self
.nb
.GetSelection() == 2:
314 self
.nb
.SetSelection(0)
315 self
.nb
.DeletePage(2)
317 if itemText
== 'Overview':
318 self
.GetDemoFile('Main.py')
319 self
.SetOverview('Overview', overview
)
324 if os
.path
.exists(itemText
+ '.py'):
326 wxLogMessage("Running demo %s.py..." % itemText
)
328 self
.GetDemoFile(itemText
+ '.py')
329 module
= __import__(itemText
, globals())
330 self
.SetOverview(itemText
, module
.overview
)
334 # in case runTest is modal, make sure things look right...
338 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
340 self
.nb
.AddPage(self
.window
, 'Demo')
342 self
.nb
.SetSelection(2)
351 #---------------------------------------------
353 def GetDemoFile(self
, filename
):
356 self
.txt
.SetValue(open(filename
).read())
358 self
.txt
.WriteText("Cannot open %s file." % filename
)
360 self
.txt
.SetInsertionPoint(0)
361 self
.txt
.ShowPosition(0)
363 #---------------------------------------------
364 def SetOverview(self
, name
, text
):
365 self
.curOverview
= text
367 if lead
!= '<html>' and lead
!= '<HTML>':
368 text
= string
.join(string
.split(text
, '\n'), '<br>')
369 #text = '<font size="-1"><pre>' + text + '</pre></font>'
370 self
.ovr
.SetPage(text
)
371 self
.nb
.SetPageText(0, name
)
373 #---------------------------------------------
375 def OnFileExit(self
, *event
):
379 def OnHelpAbout(self
, event
):
380 from About
import MyAboutBox
381 about
= MyAboutBox(self
)
386 #---------------------------------------------
387 def OnCloseWindow(self
, event
):
391 if hasattr(self
, "tbicon"):
396 #---------------------------------------------
397 def OnIdle(self
, event
):
399 self
.otherWin
.Raise()
400 self
.window
= self
.otherWin
403 #---------------------------------------------
404 def OnDemoMenu(self
, event
):
406 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
410 self
.tree
.SelectItem(selectedDemo
)
411 self
.tree
.EnsureVisible(selectedDemo
)
414 #---------------------------------------------
415 def OnTaskBarActivate(self
, evt
):
416 if self
.IsIconized():
418 if not self
.IsShown():
422 #---------------------------------------------
424 TBMENU_RESTORE
= 1000
427 def OnTaskBarMenu(self
, evt
):
429 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
430 menu
.Append(self
.TBMENU_CLOSE
, "Close")
431 self
.tbicon
.PopupMenu(menu
)
434 #---------------------------------------------
435 def OnTaskBarClose(self
, evt
):
438 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
439 # prod the main idle handler a bit to get the window to actually close
440 wxGetApp().ProcessIdle()
443 #---------------------------------------------
444 def OnIconfiy(self
, evt
):
445 wxLogMessage("OnIconfiy")
448 #---------------------------------------------
449 def OnMaximize(self
, evt
):
450 wxLogMessage("OnMaximize")
456 #---------------------------------------------------------------------------
457 #---------------------------------------------------------------------------
461 wxInitAllImageHandlers()
463 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
464 duration
=4000, callback
=self
.AfterSplash
)
465 self
.splash
.Show(true
)
470 def AfterSplash(self
):
471 self
.splash
.Close(true
)
472 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
474 self
.SetTopWindow(frame
)
478 def ShowTip(self
, frame
):
480 showTipText
= open("data/showTips").read()
481 showTip
, index
= eval(showTipText
)
483 showTip
, index
= (1, 0)
484 #print showTip, index
486 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
487 showTip
= wxShowTip(frame
, tp
)
488 index
= tp
.GetCurrentTip()
489 open("data/showTips", "w").write(str( (showTip
, index
) ))
492 #---------------------------------------------------------------------------
496 demoPath
= os
.path
.dirname(__file__
)
504 #---------------------------------------------------------------------------
508 overview
= """<html><body>
511 Python is an interpreted, interactive, object-oriented programming
512 language often compared to Tcl, Perl, Scheme, or Java.
514 <p> Python combines remarkable power with very clear syntax. It has
515 modules, classes, exceptions, very high level dynamic data types, and
516 dynamic typing. There are interfaces to many system calls and
517 libraries, and new built-in modules are easily written in C or
518 C++. Python is also usable as an extension language for applications
519 that need a programmable interface. <p>
523 wxWindows is a free C++ framework designed to make cross-platform
524 programming child's play. Well, almost. wxWindows 2 supports Windows
525 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
526 underway. Other ports are under consideration. <p>
528 wxWindows is a set of libraries that allows C++ applications to
529 compile and run on several different types of computers, with minimal
530 source code changes. There is one library per supported GUI (such as
531 Motif, or Windows). As well as providing a common API (Application
532 Programming Interface) for GUI functionality, it provides
533 functionality for accessing some commonly-used operating system
534 facilities, such as copying or deleting files. wxWindows is a
535 'framework' in the sense that it provides a lot of built-in
536 functionality, which the application can use or replace as required,
537 thus saving a great deal of coding effort. Basic data structures such
538 as strings, linked lists and hash tables are also supported.
543 wxPython is a Python extension module that encapsulates the wxWindows
544 GUI classes. Currently it is only available for the Win32 and GTK
545 ports of wxWindows, but as soon as the other ports are brought up to
546 the same level as Win32 and GTK, it should be fairly trivial to
547 enable wxPython to be used with the new GUI.
551 The wxPython extension module attempts to mirror the class heiarchy
552 of wxWindows as closely as possible. This means that there is a
553 wxFrame class in wxPython that looks, smells, tastes and acts almost
554 the same as the wxFrame class in the C++ version. Unfortunately,
555 because of differences in the languages, wxPython doesn't match
556 wxWindows exactly, but the differences should be easy to absorb
557 because they are natural to Python. For example, some methods that
558 return multiple values via argument pointers in C++ will return a
559 tuple of values in Python.
563 There is still much to be done for wxPython, many classes still need
564 to be mirrored. Also, wxWindows is still somewhat of a moving target
565 so it is a bit of an effort just keeping wxPython up to date. On the
566 other hand, there are enough of the core classes completed that
567 useful applications can be written.
571 wxPython is close enough to the C++ version that the majority of
572 the wxPython documentation is actually just notes attached to the C++
573 documents that describe the places where wxPython is different. There
574 is also a series of sample programs included, and a series of
575 documentation pages that assist the programmer in getting started
581 #----------------------------------------------------------------------------
582 #----------------------------------------------------------------------------
584 if __name__
== '__main__':
587 #----------------------------------------------------------------------------