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',
46 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
47 'wxGrid', 'wxSashWindow',
48 'wxScrolledWindow', 'wxSplitterWindow',
49 'wxStatusBar', 'wxNotebook',
51 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
53 'wxDynamicSashWindow',
56 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
57 'wxSingleChoiceDialog', 'wxTextEntryDialog',
58 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
59 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
62 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
63 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
64 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
65 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
66 'wxCalendarCtrl', 'wxToggleButton',
67 'wxEditableListBox', 'wxLEDNumberCtrl',
70 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
72 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
74 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
75 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
76 'PythonEvents', 'Threads',
77 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
78 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
79 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
83 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
84 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
85 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
86 'FileBrowseButton', 'GenericButtons', 'wxEditor',
87 'ColourSelect', 'ImageBrowser',
88 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
92 ('Cool Contribs', ['pyTree', 'hangman',
99 #---------------------------------------------------------------------------
101 class MyLog(wxPyLog
):
102 def __init__(self
, textCtrl
, logTime
=0):
103 wxPyLog
.__init
__(self
)
105 self
.logTime
= logTime
107 def DoLogString(self
, message
, timeStamp
):
109 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
111 self
.tc
.AppendText(message
+ '\n')
114 #---------------------------------------------------------------------------
116 class wxPythonDemo(wxFrame
):
118 def __init__(self
, parent
, id, title
):
119 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
120 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
122 self
.cwd
= os
.getcwd()
123 self
.curOverview
= ""
126 icon
= wxIconFromXPMData(images
.getMondrianData())
128 # another way to do it
129 bmp
= images
.getMondrianBitmap()
131 icon
.CopyFromBitmap(bmp
)
135 if wxPlatform
== '__WXMSW__':
136 # setup a taskbar icon, and catch some events from it
137 self
.tbicon
= wxTaskBarIcon()
138 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
139 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
140 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
141 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
142 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
146 EVT_IDLE(self
, self
.OnIdle
)
147 EVT_CLOSE(self
, self
.OnCloseWindow
)
148 EVT_ICONIZE(self
, self
.OnIconfiy
)
149 EVT_MAXIMIZE(self
, self
.OnMaximize
)
152 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
154 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
155 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
157 def EmptyHandler(evt
): pass
158 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
159 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
161 # Prevent TreeCtrl from displaying all items after destruction when true
165 self
.mainmenu
= wxMenuBar()
168 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
169 EVT_MENU(self
, exitID
, self
.OnFileExit
)
170 self
.mainmenu
.Append(menu
, '&File')
174 for item
in _treeList
:
176 for childItem
in item
[1]:
178 submenu
.Append(mID
, childItem
)
179 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
180 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
181 self
.mainmenu
.Append(menu
, '&Demo')
187 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
188 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
189 self
.mainmenu
.Append(menu
, '&Help')
190 self
.SetMenuBar(self
.mainmenu
)
192 # set the menu accellerator table...
193 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
194 (wxACCEL_CTRL
, ord('H'), helpID
)])
195 self
.SetAcceleratorTable(aTable
)
201 self
.tree
= wxTreeCtrl(splitter
, tID
,
202 style
=wxTR_HAS_BUTTONS |
204 wxTR_HAS_VARIABLE_ROW_HEIGHT |
206 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
207 root
= self
.tree
.AddRoot("Overview")
209 for item
in _treeList
:
210 child
= self
.tree
.AppendItem(root
, item
[0])
211 if not firstChild
: firstChild
= child
212 for childItem
in item
[1]:
213 theDemo
= self
.tree
.AppendItem(child
, childItem
)
214 self
.treeMap
[childItem
] = theDemo
216 self
.tree
.Expand(root
)
217 self
.tree
.Expand(firstChild
)
218 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
219 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
220 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
221 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
224 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
226 # Set up a wxHtmlWindow on the Overview Notebook page
227 # we put it in a panel first because there seems to be a
228 # refresh bug of some sort (wxGTK) when it is directly in
231 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
232 self
.nb
.AddPage(self
.ovr
, "Overview")
234 else: # hopefully I can remove this hacky code soon, see bug #216861
235 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
236 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
237 self
.nb
.AddPage(panel
, "Overview")
239 def OnOvrSize(evt
, ovr
=self
.ovr
):
240 ovr
.SetSize(evt
.GetSize())
242 EVT_SIZE(panel
, OnOvrSize
)
243 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
246 self
.SetOverview("Overview", overview
)
249 # Set up a TextCtrl on the Demo Code Notebook page
250 self
.txt
= wxTextCtrl(self
.nb
, -1,
251 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
252 self
.nb
.AddPage(self
.txt
, "Demo Code")
255 # Set up a log on the View Log Notebook page
256 self
.log
= wxTextCtrl(splitter2
, -1,
257 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
258 # Set the wxWindows log target to be this textctrl
259 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
260 wxLog_SetActiveTarget(MyLog(self
.log
))
266 # add the windows to the splitter and split it.
267 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
268 splitter2
.SetSashPosition(450, true
)
269 splitter2
.SetMinimumPaneSize(20)
271 splitter
.SplitVertically(self
.tree
, splitter2
)
272 splitter
.SetSashPosition(180, true
)
273 splitter
.SetMinimumPaneSize(20)
276 # select initial items
277 self
.nb
.SetSelection(0)
278 self
.tree
.SelectItem(root
)
280 if len(sys
.argv
) == 2:
282 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
286 self
.tree
.SelectItem(selectedDemo
)
287 self
.tree
.EnsureVisible(selectedDemo
)
290 wxLogMessage('window handle: %s' % self
.GetHandle())
293 #---------------------------------------------
294 def WriteText(self
, text
):
295 if text
[-1:] == '\n':
300 def write(self
, txt
):
303 #---------------------------------------------
304 def OnItemExpanded(self
, event
):
305 item
= event
.GetItem()
306 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
309 #---------------------------------------------
310 def OnItemCollapsed(self
, event
):
311 item
= event
.GetItem()
312 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
315 #---------------------------------------------
316 def OnTreeLeftDown(self
, event
):
317 pt
= event
.GetPosition();
318 item
, flags
= self
.tree
.HitTest(pt
)
319 if item
== self
.tree
.GetSelection():
320 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
323 #---------------------------------------------
324 def OnSelChanged(self
, event
):
328 item
= event
.GetItem()
329 itemText
= self
.tree
.GetItemText(item
)
330 self
.RunDemo(itemText
)
333 #---------------------------------------------
334 def RunDemo(self
, itemText
):
336 if self
.nb
.GetPageCount() == 3:
337 if self
.nb
.GetSelection() == 2:
338 self
.nb
.SetSelection(0)
339 self
.nb
.DeletePage(2)
341 if itemText
== 'Overview':
342 self
.GetDemoFile('Main.py')
343 self
.SetOverview('Overview', overview
)
348 if os
.path
.exists(itemText
+ '.py'):
350 wxLogMessage("Running demo %s.py..." % itemText
)
352 self
.GetDemoFile(itemText
+ '.py')
353 module
= __import__(itemText
, globals())
354 self
.SetOverview(itemText
, module
.overview
)
358 # in case runTest is modal, make sure things look right...
362 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
364 self
.nb
.AddPage(self
.window
, 'Demo')
366 self
.nb
.SetSelection(2)
375 #---------------------------------------------
377 def GetDemoFile(self
, filename
):
380 self
.txt
.SetValue(open(filename
).read())
382 self
.txt
.WriteText("Cannot open %s file." % filename
)
384 self
.txt
.SetInsertionPoint(0)
385 self
.txt
.ShowPosition(0)
387 #---------------------------------------------
388 def SetOverview(self
, name
, text
):
389 self
.curOverview
= text
391 if lead
!= '<html>' and lead
!= '<HTML>':
392 text
= string
.join(string
.split(text
, '\n'), '<br>')
393 #text = '<font size="-1"><pre>' + text + '</pre></font>'
394 self
.ovr
.SetPage(text
)
395 self
.nb
.SetPageText(0, name
)
397 #---------------------------------------------
399 def OnFileExit(self
, *event
):
403 def OnHelpAbout(self
, event
):
404 from About
import MyAboutBox
405 about
= MyAboutBox(self
)
410 #---------------------------------------------
411 def OnCloseWindow(self
, event
):
415 if hasattr(self
, "tbicon"):
420 #---------------------------------------------
421 def OnIdle(self
, event
):
423 self
.otherWin
.Raise()
424 self
.window
= self
.otherWin
427 #---------------------------------------------
428 def OnDemoMenu(self
, event
):
430 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
434 self
.tree
.SelectItem(selectedDemo
)
435 self
.tree
.EnsureVisible(selectedDemo
)
438 #---------------------------------------------
439 def OnTaskBarActivate(self
, evt
):
440 if self
.IsIconized():
442 if not self
.IsShown():
446 #---------------------------------------------
448 TBMENU_RESTORE
= 1000
451 def OnTaskBarMenu(self
, evt
):
453 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
454 menu
.Append(self
.TBMENU_CLOSE
, "Close")
455 self
.tbicon
.PopupMenu(menu
)
458 #---------------------------------------------
459 def OnTaskBarClose(self
, evt
):
462 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
463 # prod the main idle handler a bit to get the window to actually close
464 wxGetApp().ProcessIdle()
467 #---------------------------------------------
468 def OnIconfiy(self
, evt
):
469 wxLogMessage("OnIconfiy")
472 #---------------------------------------------
473 def OnMaximize(self
, evt
):
474 wxLogMessage("OnMaximize")
480 #---------------------------------------------------------------------------
481 #---------------------------------------------------------------------------
485 wxInitAllImageHandlers()
487 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
488 duration
=4000, callback
=self
.AfterSplash
)
489 self
.splash
.Show(true
)
494 def AfterSplash(self
):
495 self
.splash
.Close(true
)
496 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
498 self
.SetTopWindow(frame
)
502 def ShowTip(self
, frame
):
504 showTipText
= open("data/showTips").read()
505 showTip
, index
= eval(showTipText
)
507 showTip
, index
= (1, 0)
508 #print showTip, index
510 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
511 showTip
= wxShowTip(frame
, tp
)
512 index
= tp
.GetCurrentTip()
513 open("data/showTips", "w").write(str( (showTip
, index
) ))
516 #---------------------------------------------------------------------------
520 demoPath
= os
.path
.dirname(__file__
)
528 #---------------------------------------------------------------------------
532 overview
= """<html><body>
535 Python is an interpreted, interactive, object-oriented programming
536 language often compared to Tcl, Perl, Scheme, or Java.
538 <p> Python combines remarkable power with very clear syntax. It has
539 modules, classes, exceptions, very high level dynamic data types, and
540 dynamic typing. There are interfaces to many system calls and
541 libraries, and new built-in modules are easily written in C or
542 C++. Python is also usable as an extension language for applications
543 that need a programmable interface. <p>
547 wxWindows is a free C++ framework designed to make cross-platform
548 programming child's play. Well, almost. wxWindows 2 supports Windows
549 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
550 underway. Other ports are under consideration. <p>
552 wxWindows is a set of libraries that allows C++ applications to
553 compile and run on several different types of computers, with minimal
554 source code changes. There is one library per supported GUI (such as
555 Motif, or Windows). As well as providing a common API (Application
556 Programming Interface) for GUI functionality, it provides
557 functionality for accessing some commonly-used operating system
558 facilities, such as copying or deleting files. wxWindows is a
559 'framework' in the sense that it provides a lot of built-in
560 functionality, which the application can use or replace as required,
561 thus saving a great deal of coding effort. Basic data structures such
562 as strings, linked lists and hash tables are also supported.
567 wxPython is a Python extension module that encapsulates the wxWindows
568 GUI classes. Currently it is only available for the Win32 and GTK
569 ports of wxWindows, but as soon as the other ports are brought up to
570 the same level as Win32 and GTK, it should be fairly trivial to
571 enable wxPython to be used with the new GUI.
575 The wxPython extension module attempts to mirror the class heiarchy
576 of wxWindows as closely as possible. This means that there is a
577 wxFrame class in wxPython that looks, smells, tastes and acts almost
578 the same as the wxFrame class in the C++ version. Unfortunately,
579 because of differences in the languages, wxPython doesn't match
580 wxWindows exactly, but the differences should be easy to absorb
581 because they are natural to Python. For example, some methods that
582 return multiple values via argument pointers in C++ will return a
583 tuple of values in Python.
587 There is still much to be done for wxPython, many classes still need
588 to be mirrored. Also, wxWindows is still somewhat of a moving target
589 so it is a bit of an effort just keeping wxPython up to date. On the
590 other hand, there are enough of the core classes completed that
591 useful applications can be written.
595 wxPython is close enough to the C++ version that the majority of
596 the wxPython documentation is actually just notes attached to the C++
597 documents that describe the places where wxPython is different. There
598 is also a series of sample programs included, and a series of
599 documentation pages that assist the programmer in getting started
605 #----------------------------------------------------------------------------
606 #----------------------------------------------------------------------------
608 if __name__
== '__main__':
611 #----------------------------------------------------------------------------