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',
30 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
32 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
33 'wxScrolledWindow', 'wxSplitterWindow',
34 'wxStatusBar', 'wxNotebook',
36 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
38 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
39 'wxSingleChoiceDialog', 'wxTextEntryDialog',
40 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
41 'wxMessageDialog', 'wxProgressDialog']),
43 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
44 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
45 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
46 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
47 'wxCalendarCtrl', 'wxToggleButton',
50 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
52 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
53 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
54 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
55 'PythonEvents', 'Threads',
56 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
57 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
61 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
62 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
63 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
64 'FileBrowseButton', 'GenericButtons', 'wxEditor',
65 'ColourSelect', 'ImageBrowser',
66 'infoframe', 'ColourDB', 'PyCrust',
69 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
73 #---------------------------------------------------------------------------
75 class wxPythonDemo(wxFrame
):
77 def __init__(self
, parent
, id, title
):
78 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
79 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
81 self
.cwd
= os
.getcwd()
85 icon
= wxIconFromXPMData(images
.getMondrianData())
87 # another way to do it
88 bmp
= images
.getMondrianBitmap()
90 icon
.CopyFromBitmap(bmp
)
94 if wxPlatform
== '__WXMSW__':
95 # setup a taskbar icon, and catch some events from it
96 self
.tbicon
= wxTaskBarIcon()
97 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
98 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
99 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
100 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
101 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
105 EVT_IDLE(self
, self
.OnIdle
)
106 EVT_CLOSE(self
, self
.OnCloseWindow
)
107 EVT_ICONIZE(self
, self
.OnIconfiy
)
108 EVT_MAXIMIZE(self
, self
.OnMaximize
)
111 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
113 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
114 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
116 def EmptyHandler(evt
): pass
117 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
118 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
120 # Prevent TreeCtrl from displaying all items after destruction
124 self
.mainmenu
= wxMenuBar()
127 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
128 EVT_MENU(self
, exitID
, self
.OnFileExit
)
129 self
.mainmenu
.Append(menu
, '&File')
133 for item
in _treeList
:
135 for childItem
in item
[1]:
137 submenu
.Append(mID
, childItem
)
138 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
139 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
140 self
.mainmenu
.Append(menu
, '&Demo')
146 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
147 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
148 self
.mainmenu
.Append(menu
, '&Help')
149 self
.SetMenuBar(self
.mainmenu
)
151 # set the menu accellerator table...
152 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
153 (wxACCEL_CTRL
, ord('H'), helpID
)])
154 self
.SetAcceleratorTable(aTable
)
160 self
.tree
= wxTreeCtrl(splitter
, tID
,
161 style
=wxTR_HAS_BUTTONS |
163 wxTR_HAS_VARIABLE_ROW_HEIGHT |
165 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
166 root
= self
.tree
.AddRoot("Overview")
168 for item
in _treeList
:
169 child
= self
.tree
.AppendItem(root
, item
[0])
170 if not firstChild
: firstChild
= child
171 for childItem
in item
[1]:
172 theDemo
= self
.tree
.AppendItem(child
, childItem
)
173 self
.treeMap
[childItem
] = theDemo
175 self
.tree
.Expand(root
)
176 self
.tree
.Expand(firstChild
)
177 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
178 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
179 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
180 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
183 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
185 # Set up a wxHtmlWindow on the Overview Notebook page
186 # we put it in a panel first because there seems to be a
187 # refresh bug of some sort (wxGTK) when it is directly in
190 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
191 self
.nb
.AddPage(self
.ovr
, "Overview")
193 else: # hopefully I can remove this hacky code soon, see bug #216861
194 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
195 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
196 self
.nb
.AddPage(panel
, "Overview")
198 def OnOvrSize(evt
, ovr
=self
.ovr
):
199 ovr
.SetSize(evt
.GetSize())
201 EVT_SIZE(panel
, OnOvrSize
)
202 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
205 self
.SetOverview("Overview", overview
)
208 # Set up a TextCtrl on the Demo Code Notebook page
209 self
.txt
= wxTextCtrl(self
.nb
, -1,
210 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
211 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
212 self
.nb
.AddPage(self
.txt
, "Demo Code")
215 # Set up a log on the View Log Notebook page
216 self
.log
= wxTextCtrl(splitter2
, -1,
217 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
218 # Set the wxWindows log target to be this textctrl
219 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
225 # add the windows to the splitter and split it.
226 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
227 splitter2
.SetSashPosition(450, true
)
228 splitter2
.SetMinimumPaneSize(20)
230 splitter
.SplitVertically(self
.tree
, splitter2
)
231 splitter
.SetSashPosition(180, true
)
232 splitter
.SetMinimumPaneSize(20)
235 # select initial items
236 self
.nb
.SetSelection(0)
237 self
.tree
.SelectItem(root
)
239 if len(sys
.argv
) == 2:
241 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
245 self
.tree
.SelectItem(selectedDemo
)
246 self
.tree
.EnsureVisible(selectedDemo
)
249 wxLogMessage('window handle: %s' % self
.GetHandle())
252 #---------------------------------------------
253 def WriteText(self
, text
):
254 if text
[-1:] == '\n':
259 def write(self
, txt
):
262 #---------------------------------------------
263 def OnItemExpanded(self
, event
):
264 item
= event
.GetItem()
265 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
268 #---------------------------------------------
269 def OnItemCollapsed(self
, event
):
270 item
= event
.GetItem()
271 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
274 #---------------------------------------------
275 def OnTreeLeftDown(self
, event
):
276 pt
= event
.GetPosition();
277 item
, flags
= self
.tree
.HitTest(pt
)
278 if item
== self
.tree
.GetSelection():
279 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
282 #---------------------------------------------
283 def OnSelChanged(self
, event
):
287 item
= event
.GetItem()
288 itemText
= self
.tree
.GetItemText(item
)
289 self
.RunDemo(itemText
)
292 #---------------------------------------------
293 def RunDemo(self
, itemText
):
295 if self
.nb
.GetPageCount() == 3:
296 if self
.nb
.GetSelection() == 2:
297 self
.nb
.SetSelection(0)
298 self
.nb
.DeletePage(2)
300 if itemText
== 'Overview':
301 self
.GetDemoFile('Main.py')
302 self
.SetOverview('Overview', overview
)
307 if os
.path
.exists(itemText
+ '.py'):
309 wxLogMessage("Running demo %s.py..." % itemText
)
311 self
.GetDemoFile(itemText
+ '.py')
312 module
= __import__(itemText
, globals())
313 self
.SetOverview(itemText
, module
.overview
)
317 # in case runTest is modal, make sure things look right...
321 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
323 self
.nb
.AddPage(self
.window
, 'Demo')
325 self
.nb
.SetSelection(2)
334 #---------------------------------------------
336 def GetDemoFile(self
, filename
):
339 self
.txt
.SetValue(open(filename
).read())
341 self
.txt
.WriteText("Cannot open %s file." % filename
)
343 self
.txt
.SetInsertionPoint(0)
344 self
.txt
.ShowPosition(0)
346 #---------------------------------------------
347 def SetOverview(self
, name
, text
):
348 self
.curOverview
= text
350 if lead
!= '<html>' and lead
!= '<HTML>':
351 text
= string
.join(string
.split(text
, '\n'), '<br>')
352 #text = '<font size="-1"><pre>' + text + '</pre></font>'
353 self
.ovr
.SetPage(text
)
354 self
.nb
.SetPageText(0, name
)
356 #---------------------------------------------
358 def OnFileExit(self
, *event
):
362 def OnHelpAbout(self
, event
):
363 from About
import MyAboutBox
364 about
= MyAboutBox(self
)
369 #---------------------------------------------
370 def OnCloseWindow(self
, event
):
374 if hasattr(self
, "tbicon"):
379 #---------------------------------------------
380 def OnIdle(self
, event
):
382 self
.otherWin
.Raise()
383 self
.window
= self
.otherWin
386 #---------------------------------------------
387 def OnDemoMenu(self
, event
):
389 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
393 self
.tree
.SelectItem(selectedDemo
)
394 self
.tree
.EnsureVisible(selectedDemo
)
397 #---------------------------------------------
398 def OnTaskBarActivate(self
, evt
):
399 if self
.IsIconized():
401 if not self
.IsShown():
405 #---------------------------------------------
407 TBMENU_RESTORE
= 1000
410 def OnTaskBarMenu(self
, evt
):
412 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
413 menu
.Append(self
.TBMENU_CLOSE
, "Close")
414 self
.tbicon
.PopupMenu(menu
)
417 #---------------------------------------------
418 def OnTaskBarClose(self
, evt
):
421 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
422 # prod the main idle handler a bit to get the window to actually close
423 wxGetApp().ProcessIdle()
426 #---------------------------------------------
427 def OnIconfiy(self
, evt
):
428 wxLogMessage("OnIconfiy")
431 #---------------------------------------------
432 def OnMaximize(self
, evt
):
433 wxLogMessage("OnMaximize")
439 #---------------------------------------------------------------------------
440 #---------------------------------------------------------------------------
444 wxInitAllImageHandlers()
446 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
447 duration
=4000, callback
=self
.AfterSplash
)
448 self
.splash
.Show(true
)
453 def AfterSplash(self
):
454 self
.splash
.Close(true
)
455 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
457 self
.SetTopWindow(frame
)
461 def ShowTip(self
, frame
):
463 showTipText
= open("data/showTips").read()
464 showTip
, index
= eval(showTipText
)
466 showTip
, index
= (1, 0)
467 #print showTip, index
469 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
470 showTip
= wxShowTip(frame
, tp
)
471 index
= tp
.GetCurrentTip()
472 open("data/showTips", "w").write(str( (showTip
, index
) ))
475 #---------------------------------------------------------------------------
479 demoPath
= os
.path
.dirname(__file__
)
487 #---------------------------------------------------------------------------
491 overview
= """<html><body>
494 Python is an interpreted, interactive, object-oriented programming
495 language often compared to Tcl, Perl, Scheme, or Java.
497 <p> Python combines remarkable power with very clear syntax. It has
498 modules, classes, exceptions, very high level dynamic data types, and
499 dynamic typing. There are interfaces to many system calls and
500 libraries, and new built-in modules are easily written in C or
501 C++. Python is also usable as an extension language for applications
502 that need a programmable interface. <p>
506 wxWindows is a free C++ framework designed to make cross-platform
507 programming child's play. Well, almost. wxWindows 2 supports Windows
508 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
509 underway. Other ports are under consideration. <p>
511 wxWindows is a set of libraries that allows C++ applications to
512 compile and run on several different types of computers, with minimal
513 source code changes. There is one library per supported GUI (such as
514 Motif, or Windows). As well as providing a common API (Application
515 Programming Interface) for GUI functionality, it provides
516 functionality for accessing some commonly-used operating system
517 facilities, such as copying or deleting files. wxWindows is a
518 'framework' in the sense that it provides a lot of built-in
519 functionality, which the application can use or replace as required,
520 thus saving a great deal of coding effort. Basic data structures such
521 as strings, linked lists and hash tables are also supported.
526 wxPython is a Python extension module that encapsulates the wxWindows
527 GUI classes. Currently it is only available for the Win32 and GTK
528 ports of wxWindows, but as soon as the other ports are brought up to
529 the same level as Win32 and GTK, it should be fairly trivial to
530 enable wxPython to be used with the new GUI.
534 The wxPython extension module attempts to mirror the class heiarchy
535 of wxWindows as closely as possible. This means that there is a
536 wxFrame class in wxPython that looks, smells, tastes and acts almost
537 the same as the wxFrame class in the C++ version. Unfortunately,
538 because of differences in the languages, wxPython doesn't match
539 wxWindows exactly, but the differences should be easy to absorb
540 because they are natural to Python. For example, some methods that
541 return multiple values via argument pointers in C++ will return a
542 tuple of values in Python.
546 There is still much to be done for wxPython, many classes still need
547 to be mirrored. Also, wxWindows is still somewhat of a moving target
548 so it is a bit of an effort just keeping wxPython up to date. On the
549 other hand, there are enough of the core classes completed that
550 useful applications can be written.
554 wxPython is close enough to the C++ version that the majority of
555 the wxPython documentation is actually just notes attached to the C++
556 documents that describe the places where wxPython is different. There
557 is also a series of sample programs included, and a series of
558 documentation pages that assist the programmer in getting started
564 #----------------------------------------------------------------------------
565 #----------------------------------------------------------------------------
567 if __name__
== '__main__':
570 #----------------------------------------------------------------------------