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',
45 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
46 'wxGrid', 'wxSashWindow',
47 'wxScrolledWindow', 'wxSplitterWindow',
48 'wxStatusBar', 'wxNotebook',
50 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
52 'wxDynamicSashWindow',
55 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
56 'wxSingleChoiceDialog', 'wxTextEntryDialog',
57 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
58 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
61 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
62 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
63 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
64 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
65 'wxCalendarCtrl', 'wxToggleButton',
66 'wxEditableListBox', 'wxLEDNumberCtrl',
69 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
71 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
73 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
74 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
75 'PythonEvents', 'Threads',
76 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
77 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
78 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
82 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
83 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
84 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
85 'FileBrowseButton', 'GenericButtons', 'wxEditor',
86 'ColourSelect', 'ImageBrowser',
87 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
91 ('Cool Contribs', ['pyTree', 'hangman',
98 #---------------------------------------------------------------------------
100 class MyLog(wxPyLog
):
101 def __init__(self
, textCtrl
, logTime
=0):
102 wxPyLog
.__init
__(self
)
104 self
.logTime
= logTime
106 def DoLogString(self
, message
, timeStamp
):
108 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
110 self
.tc
.AppendText(message
+ '\n')
113 #---------------------------------------------------------------------------
115 class wxPythonDemo(wxFrame
):
117 def __init__(self
, parent
, id, title
):
118 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
119 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
121 self
.cwd
= os
.getcwd()
122 self
.curOverview
= ""
125 icon
= wxIconFromXPMData(images
.getMondrianData())
127 # another way to do it
128 bmp
= images
.getMondrianBitmap()
130 icon
.CopyFromBitmap(bmp
)
134 if wxPlatform
== '__WXMSW__':
135 # setup a taskbar icon, and catch some events from it
136 self
.tbicon
= wxTaskBarIcon()
137 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
138 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
139 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
140 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
141 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
145 EVT_IDLE(self
, self
.OnIdle
)
146 EVT_CLOSE(self
, self
.OnCloseWindow
)
147 EVT_ICONIZE(self
, self
.OnIconfiy
)
148 EVT_MAXIMIZE(self
, self
.OnMaximize
)
151 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
153 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
154 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
156 def EmptyHandler(evt
): pass
157 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
158 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
160 # Prevent TreeCtrl from displaying all items after destruction when true
164 self
.mainmenu
= wxMenuBar()
167 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
168 EVT_MENU(self
, exitID
, self
.OnFileExit
)
169 self
.mainmenu
.Append(menu
, '&File')
173 for item
in _treeList
:
175 for childItem
in item
[1]:
177 submenu
.Append(mID
, childItem
)
178 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
179 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
180 self
.mainmenu
.Append(menu
, '&Demo')
186 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
187 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
188 self
.mainmenu
.Append(menu
, '&Help')
189 self
.SetMenuBar(self
.mainmenu
)
191 # set the menu accellerator table...
192 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
193 (wxACCEL_CTRL
, ord('H'), helpID
)])
194 self
.SetAcceleratorTable(aTable
)
200 self
.tree
= wxTreeCtrl(splitter
, tID
,
201 style
=wxTR_HAS_BUTTONS |
203 wxTR_HAS_VARIABLE_ROW_HEIGHT |
205 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
206 root
= self
.tree
.AddRoot("Overview")
208 for item
in _treeList
:
209 child
= self
.tree
.AppendItem(root
, item
[0])
210 if not firstChild
: firstChild
= child
211 for childItem
in item
[1]:
212 theDemo
= self
.tree
.AppendItem(child
, childItem
)
213 self
.treeMap
[childItem
] = theDemo
215 self
.tree
.Expand(root
)
216 self
.tree
.Expand(firstChild
)
217 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
218 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
219 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
220 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
223 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
225 # Set up a wxHtmlWindow on the Overview Notebook page
226 # we put it in a panel first because there seems to be a
227 # refresh bug of some sort (wxGTK) when it is directly in
230 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
231 self
.nb
.AddPage(self
.ovr
, "Overview")
233 else: # hopefully I can remove this hacky code soon, see bug #216861
234 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
235 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
236 self
.nb
.AddPage(panel
, "Overview")
238 def OnOvrSize(evt
, ovr
=self
.ovr
):
239 ovr
.SetSize(evt
.GetSize())
241 EVT_SIZE(panel
, OnOvrSize
)
242 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
245 self
.SetOverview("Overview", overview
)
248 # Set up a TextCtrl on the Demo Code Notebook page
249 self
.txt
= wxTextCtrl(self
.nb
, -1,
250 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
251 self
.nb
.AddPage(self
.txt
, "Demo Code")
254 # Set up a log on the View Log Notebook page
255 self
.log
= wxTextCtrl(splitter2
, -1,
256 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
257 # Set the wxWindows log target to be this textctrl
258 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
259 wxLog_SetActiveTarget(MyLog(self
.log
))
265 # add the windows to the splitter and split it.
266 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
267 splitter2
.SetSashPosition(450, true
)
268 splitter2
.SetMinimumPaneSize(20)
270 splitter
.SplitVertically(self
.tree
, splitter2
)
271 splitter
.SetSashPosition(180, true
)
272 splitter
.SetMinimumPaneSize(20)
275 # select initial items
276 self
.nb
.SetSelection(0)
277 self
.tree
.SelectItem(root
)
279 if len(sys
.argv
) == 2:
281 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
285 self
.tree
.SelectItem(selectedDemo
)
286 self
.tree
.EnsureVisible(selectedDemo
)
289 wxLogMessage('window handle: %s' % self
.GetHandle())
292 #---------------------------------------------
293 def WriteText(self
, text
):
294 if text
[-1:] == '\n':
299 def write(self
, txt
):
302 #---------------------------------------------
303 def OnItemExpanded(self
, event
):
304 item
= event
.GetItem()
305 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
308 #---------------------------------------------
309 def OnItemCollapsed(self
, event
):
310 item
= event
.GetItem()
311 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
314 #---------------------------------------------
315 def OnTreeLeftDown(self
, event
):
316 pt
= event
.GetPosition();
317 item
, flags
= self
.tree
.HitTest(pt
)
318 if item
== self
.tree
.GetSelection():
319 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
322 #---------------------------------------------
323 def OnSelChanged(self
, event
):
327 item
= event
.GetItem()
328 itemText
= self
.tree
.GetItemText(item
)
329 self
.RunDemo(itemText
)
332 #---------------------------------------------
333 def RunDemo(self
, itemText
):
335 if self
.nb
.GetPageCount() == 3:
336 if self
.nb
.GetSelection() == 2:
337 self
.nb
.SetSelection(0)
338 self
.nb
.DeletePage(2)
340 if itemText
== 'Overview':
341 self
.GetDemoFile('Main.py')
342 self
.SetOverview('Overview', overview
)
347 if os
.path
.exists(itemText
+ '.py'):
349 wxLogMessage("Running demo %s.py..." % itemText
)
351 self
.GetDemoFile(itemText
+ '.py')
352 module
= __import__(itemText
, globals())
353 self
.SetOverview(itemText
, module
.overview
)
357 # in case runTest is modal, make sure things look right...
361 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
363 self
.nb
.AddPage(self
.window
, 'Demo')
365 self
.nb
.SetSelection(2)
374 #---------------------------------------------
376 def GetDemoFile(self
, filename
):
379 self
.txt
.SetValue(open(filename
).read())
381 self
.txt
.WriteText("Cannot open %s file." % filename
)
383 self
.txt
.SetInsertionPoint(0)
384 self
.txt
.ShowPosition(0)
386 #---------------------------------------------
387 def SetOverview(self
, name
, text
):
388 self
.curOverview
= text
390 if lead
!= '<html>' and lead
!= '<HTML>':
391 text
= string
.join(string
.split(text
, '\n'), '<br>')
392 #text = '<font size="-1"><pre>' + text + '</pre></font>'
393 self
.ovr
.SetPage(text
)
394 self
.nb
.SetPageText(0, name
)
396 #---------------------------------------------
398 def OnFileExit(self
, *event
):
402 def OnHelpAbout(self
, event
):
403 from About
import MyAboutBox
404 about
= MyAboutBox(self
)
409 #---------------------------------------------
410 def OnCloseWindow(self
, event
):
414 if hasattr(self
, "tbicon"):
419 #---------------------------------------------
420 def OnIdle(self
, event
):
422 self
.otherWin
.Raise()
423 self
.window
= self
.otherWin
426 #---------------------------------------------
427 def OnDemoMenu(self
, event
):
429 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
433 self
.tree
.SelectItem(selectedDemo
)
434 self
.tree
.EnsureVisible(selectedDemo
)
437 #---------------------------------------------
438 def OnTaskBarActivate(self
, evt
):
439 if self
.IsIconized():
441 if not self
.IsShown():
445 #---------------------------------------------
447 TBMENU_RESTORE
= 1000
450 def OnTaskBarMenu(self
, evt
):
452 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
453 menu
.Append(self
.TBMENU_CLOSE
, "Close")
454 self
.tbicon
.PopupMenu(menu
)
457 #---------------------------------------------
458 def OnTaskBarClose(self
, evt
):
461 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
462 # prod the main idle handler a bit to get the window to actually close
463 wxGetApp().ProcessIdle()
466 #---------------------------------------------
467 def OnIconfiy(self
, evt
):
468 wxLogMessage("OnIconfiy")
471 #---------------------------------------------
472 def OnMaximize(self
, evt
):
473 wxLogMessage("OnMaximize")
479 #---------------------------------------------------------------------------
480 #---------------------------------------------------------------------------
484 wxInitAllImageHandlers()
486 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
487 duration
=4000, callback
=self
.AfterSplash
)
488 self
.splash
.Show(true
)
493 def AfterSplash(self
):
494 self
.splash
.Close(true
)
495 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
497 self
.SetTopWindow(frame
)
501 def ShowTip(self
, frame
):
503 showTipText
= open("data/showTips").read()
504 showTip
, index
= eval(showTipText
)
506 showTip
, index
= (1, 0)
507 #print showTip, index
509 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
510 showTip
= wxShowTip(frame
, tp
)
511 index
= tp
.GetCurrentTip()
512 open("data/showTips", "w").write(str( (showTip
, index
) ))
515 #---------------------------------------------------------------------------
519 demoPath
= os
.path
.dirname(__file__
)
527 #---------------------------------------------------------------------------
531 overview
= """<html><body>
534 Python is an interpreted, interactive, object-oriented programming
535 language often compared to Tcl, Perl, Scheme, or Java.
537 <p> Python combines remarkable power with very clear syntax. It has
538 modules, classes, exceptions, very high level dynamic data types, and
539 dynamic typing. There are interfaces to many system calls and
540 libraries, and new built-in modules are easily written in C or
541 C++. Python is also usable as an extension language for applications
542 that need a programmable interface. <p>
546 wxWindows is a free C++ framework designed to make cross-platform
547 programming child's play. Well, almost. wxWindows 2 supports Windows
548 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
549 underway. Other ports are under consideration. <p>
551 wxWindows is a set of libraries that allows C++ applications to
552 compile and run on several different types of computers, with minimal
553 source code changes. There is one library per supported GUI (such as
554 Motif, or Windows). As well as providing a common API (Application
555 Programming Interface) for GUI functionality, it provides
556 functionality for accessing some commonly-used operating system
557 facilities, such as copying or deleting files. wxWindows is a
558 'framework' in the sense that it provides a lot of built-in
559 functionality, which the application can use or replace as required,
560 thus saving a great deal of coding effort. Basic data structures such
561 as strings, linked lists and hash tables are also supported.
566 wxPython is a Python extension module that encapsulates the wxWindows
567 GUI classes. Currently it is only available for the Win32 and GTK
568 ports of wxWindows, but as soon as the other ports are brought up to
569 the same level as Win32 and GTK, it should be fairly trivial to
570 enable wxPython to be used with the new GUI.
574 The wxPython extension module attempts to mirror the class heiarchy
575 of wxWindows as closely as possible. This means that there is a
576 wxFrame class in wxPython that looks, smells, tastes and acts almost
577 the same as the wxFrame class in the C++ version. Unfortunately,
578 because of differences in the languages, wxPython doesn't match
579 wxWindows exactly, but the differences should be easy to absorb
580 because they are natural to Python. For example, some methods that
581 return multiple values via argument pointers in C++ will return a
582 tuple of values in Python.
586 There is still much to be done for wxPython, many classes still need
587 to be mirrored. Also, wxWindows is still somewhat of a moving target
588 so it is a bit of an effort just keeping wxPython up to date. On the
589 other hand, there are enough of the core classes completed that
590 useful applications can be written.
594 wxPython is close enough to the C++ version that the majority of
595 the wxPython documentation is actually just notes attached to the C++
596 documents that describe the places where wxPython is different. There
597 is also a series of sample programs included, and a series of
598 documentation pages that assist the programmer in getting started
604 #----------------------------------------------------------------------------
605 #----------------------------------------------------------------------------
607 if __name__
== '__main__':
610 #----------------------------------------------------------------------------