1#!/usr/bin/env python
2
3# ------------------------------------------------------------------
4# Display a splash screen as quickly as possible (before importing
5# modules and initialising Pmw).
6
7import Tkinter
8root = Tkinter.Tk(className = 'Demo')
9root.withdraw()
10
11splash = Tkinter.Toplevel()
12splash.withdraw()
13splash.title('Welcome to the Pmw demos')
14text = Tkinter.Label(splash,
15    font=('Helvetica', 16, 'bold'),
16    relief = 'raised',
17    borderwidth = 2,
18    padx=50, pady=50,
19    text =
20    'Welcome to the Pmw megawidgets demo.\n'
21    '\n'
22    'In a moment the main window will appear.\n'
23    'Please enjoy yourself while you wait.\n'
24    'You may be interested to know that splash screens\n'
25    '(as this window is called) were first devised to draw\n'
26    'attention away from the fact the certain applications\n'
27    'are slow to start. They are normally flashier and more\n'
28    'entertaining than this one. This is a budget model.'
29)
30text.pack(fill = 'both', expand = 1)
31splash.update_idletasks()
32
33width = splash.winfo_reqwidth()
34height = splash.winfo_reqheight()
35x = (root.winfo_screenwidth() - width) / 2 - root.winfo_vrootx()
36y = (root.winfo_screenheight() - height) / 3 - root.winfo_vrooty()
37if x < 0:
38    x = 0
39if y < 0:
40    y = 0
41geometry = '%dx%d+%d+%d' % (width, height, x, y)
42
43splash.geometry(geometry)
44splash.update_idletasks()
45splash.deiconify()
46root.update()
47
48# ------------------------------------------------------------------
49
50# Now crank up the application windows.
51
52import imp
53import os
54import re
55import string
56import sys
57import types
58import Tkinter
59import DemoVersion
60import Args
61
62# Find where the other scripts are, so they can be listed.
63if __name__ == '__main__':
64    script_name = sys.argv[0]
65else:
66    script_name = imp.find_module('DemoVersion')[1]
67
68script_name = os.path.normpath(script_name)
69script_name = DemoVersion.expandLinks(script_name)
70script_dir = os.path.dirname(script_name)
71script_dir = DemoVersion.expandLinks(script_dir)
72
73# Add the '../../..' directory to the path.
74package_dir = os.path.dirname(script_dir)
75package_dir = DemoVersion.expandLinks(package_dir)
76package_dir = os.path.dirname(package_dir)
77package_dir = DemoVersion.expandLinks(package_dir)
78package_dir = os.path.dirname(package_dir)
79package_dir = DemoVersion.expandLinks(package_dir)
80sys.path[:0] = [package_dir]
81
82# Import Pmw after modifying sys.path (it may not be in the default path).
83import Pmw
84DemoVersion.setPmwVersion()
85
86class Demo(Pmw.MegaWidget):
87
88    def __init__(self, parent=None, **kw):
89
90	# Define the megawidget options.
91	optiondefs = ()
92	self.defineoptions(kw, optiondefs)
93
94	# Initialise the base class (after defining the options).
95        Pmw.MegaWidget.__init__(self, parent)
96
97	# Create the contents.
98	top = self.interior()
99
100	panes = Pmw.PanedWidget(top, orient = 'horizontal')
101	panes.pack(fill = 'both', expand = 1)
102
103	panes.add('widgetlist')
104	self._widgetlist = Pmw.ScrolledListBox(panes.pane('widgetlist'),
105		selectioncommand = Pmw.busycallback(self.startDemo),
106		label_text = 'Select a widget:',
107		labelpos = 'nw',
108		vscrollmode = 'dynamic',
109		hscrollmode = 'none',
110		listbox_exportselection = 0)
111	self._widgetlist.pack(fill = 'both', expand = 1, padx = 8)
112
113	panes.add('info')
114	self._status = Tkinter.Label(panes.pane('info'))
115	self._status.pack(padx = 8, anchor = 'w')
116
117	self._example = Tkinter.Frame(panes.pane('info'),
118		borderwidth = 2,
119		relief = 'sunken',
120	        background = 'white')
121	self._example.pack(fill = 'both', expand = 1, padx = 8)
122
123	self.buttonBox = Pmw.ButtonBox(top)
124	self.buttonBox.pack(fill = 'x')
125
126	# Add the buttons and make them all the same width.
127	self._traceText = 'Trace tk calls'
128	self._stopTraceText = 'Stop trace'
129	self.buttonBox.add('Trace', text = self._traceText,
130	        command = self.trace)
131	self.buttonBox.add('Code', text = 'Show code', command = self.showCode)
132	self.buttonBox.add('Exit', text = 'Exit', command = root.destroy)
133	self.buttonBox.alignbuttons()
134
135	# Create the window to display the python code.
136	self.codeWindow = Pmw.TextDialog(parent,
137	    title = 'Python source',
138	    buttons = ('Dismiss',),
139	    scrolledtext_labelpos = 'n',
140	    label_text = 'Source')
141	self.codeWindow.withdraw()
142	self.codeWindow.insert('end', '')
143
144	self.demoName = None
145	self._loadDemos()
146
147	# Check keywords and initialise options.
148	self.initialiseoptions()
149
150    def startDemo(self):
151	# Import the selected module and create and instance of the module's
152	# Demo class.
153
154	sels = self._widgetlist.getcurselection()
155	if len(sels) == 0:
156	    print 'No demonstrations to display'
157	    return
158	demoName = sels[0]
159
160	# Ignore if this if it is a sub title.
161	if demoName[0] != ' ':
162	    self._widgetlist.bell()
163	    return
164
165	# Strip the leading two spaces.
166	demoName = demoName[2:]
167
168	# Ignore if this demo is already being shown.
169	if self.demoName == demoName:
170	    return
171
172	self.demoName = demoName
173
174	self.showStatus('Loading ' + demoName)
175	# Busy cursor
176	self.update_idletasks()
177
178	for window in self._example.winfo_children():
179	    window.destroy()
180
181	frame = Tkinter.Frame(self._example)
182	frame.pack(expand = 1)
183	exec 'import ' + demoName
184        # Need to keep a reference to the widget, so that variables, etc
185        # are not deleted.
186	self.widget = eval(demoName + '.Demo(frame)')
187	title = eval(demoName + '.title')
188	self.showStatus(title)
189
190	if self.codeWindow.state() == 'normal':
191	    self.insertCode()
192
193    def showStatus(self, text):
194	self._status.configure(text = text)
195
196    def showCode(self):
197	if self.codeWindow.state() != 'normal':
198	    if self.demoName is None:
199		print 'No demonstration selected'
200		return
201	    self.insertCode()
202
203	self.codeWindow.show()
204
205    def insertCode(self):
206	self.codeWindow.clear()
207	fileName = os.path.join(script_dir, self.demoName + '.py')
208	self.codeWindow.importfile(fileName)
209	self.codeWindow.configure(label_text = self.demoName + ' source')
210
211    def trace(self):
212	text = self.buttonBox.component('Trace').cget('text')
213	if text == self._traceText:
214	    self.buttonBox.configure(Trace_text = self._stopTraceText)
215	    Pmw.tracetk(root, 1)
216	    self.showStatus('Trace will appear on standard output')
217	else:
218	    self.buttonBox.configure(Trace_text = self._traceText)
219	    Pmw.tracetk(root, 0)
220	    self.showStatus('Tk call tracing stopped')
221
222    def _loadDemos(self):
223	files = os.listdir(script_dir)
224	files.sort()
225	megawidgets = []
226	others = []
227	for file in files:
228	    if re.search('.py$', file) is not None and \
229		    file not in ['All.py', 'DemoVersion.py', 'Args.py']:
230		demoName = file[:-3]
231		index = string.find(demoName, '_')
232		if index < 0:
233		    testattr = demoName
234		else:
235		    testattr = demoName[:index]
236		if hasattr(Pmw, testattr):
237		    megawidgets.append(demoName)
238		else:
239		    others.append(demoName)
240
241	self._widgetlist.insert('end', 'Megawidget demos:')
242	for name in megawidgets:
243	    self._widgetlist.insert('end', '  ' + name)
244	self._widgetlist.insert('end', 'Other demos:')
245	for name in others:
246	    self._widgetlist.insert('end', '  ' + name)
247	self._widgetlist.select_set(1)
248
249class StdOut:
250    def __init__(self, displayCommand):
251        self.displayCommand = displayCommand
252	self.text = '\n'
253
254    def write(self, text):
255	if self.text[-1] == '\n':
256	    self.text = text
257	else:
258	    self.text = self.text + text
259	if self.text[-1] == '\n':
260	    text = self.text[:-1]
261	else:
262	    text = self.text
263	self.displayCommand(text)
264
265if os.name == 'nt':
266    defaultFontSize = 16
267else:
268    defaultFontSize = 12
269
270commandLineArgSpecs = (
271    ('fontscheme', 0, 'scheme',  'fonts to use [eg pmw2] (Tk defaults)'),
272    ('fontsize',   0, 'num',     'size of fonts to use with fontscheme', defaultFontSize),
273    ('stdout',     0, Args.Bool, 'print messages rather than display in label'),
274)
275
276program = 'All.py'
277msg = Args.parseArgs(program, sys.argv, commandLineArgSpecs, 0)
278if msg is not None:
279    print msg
280    sys.exit()
281
282size = Args.get('fontsize')
283fontScheme = Args.get('fontscheme')
284Pmw.initialise(root, size = size, fontScheme = fontScheme, useTkOptionDb = 1)
285
286root.title('Pmw ' + Pmw.version() + ' megawidget demonstration')
287if size < 18:
288    geometry = '800x550'
289else:
290    geometry = '1000x700'
291root.geometry(geometry)
292
293demo = Demo(root)
294demo.pack(fill = 'both', expand = 1)
295demo.focus()
296
297# Redirect standard output from demos to status line (unless -stdout
298# option given on command line).
299if not Args.get('stdout'):
300    sys.stdout = StdOut(demo.showStatus)
301
302# Start the first demo.
303demo.startDemo()
304
305# Get rid of the splash screen
306root.deiconify()
307root.update()
308splash.destroy()
309
310root.mainloop()
311