1#!/usr/bin/env python
2
3import wx
4import wx.adv
5from wx.adv import Wizard as wiz
6from wx.adv import WizardPage, WizardPageSimple
7import images
8
9#----------------------------------------------------------------------
10
11def makePageTitle(wizPg, title):
12    sizer = wx.BoxSizer(wx.VERTICAL)
13    wizPg.SetSizer(sizer)
14    title = wx.StaticText(wizPg, -1, title)
15    title.SetFont(wx.Font(18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
16    sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
17    sizer.Add(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 5)
18    return sizer
19
20#----------------------------------------------------------------------
21
22class TitledPage(wx.adv.WizardPageSimple):
23    def __init__(self, parent, title):
24        WizardPageSimple.__init__(self, parent)
25        self.sizer = makePageTitle(self, title)
26
27
28#----------------------------------------------------------------------
29
30class SkipNextPage(wx.adv.WizardPage):
31    def __init__(self, parent, title):
32        WizardPage.__init__(self, parent)
33        self.next = self.prev = None
34        self.sizer = makePageTitle(self, title)
35
36        self.cb = wx.CheckBox(self, -1, "Skip next page")
37        self.sizer.Add(self.cb, 0, wx.ALL, 5)
38
39    def SetNext(self, next):
40        self.next = next
41
42    def SetPrev(self, prev):
43        self.prev = prev
44
45
46    # Classes derived from wxPyWizardPanel must override
47    # GetNext and GetPrev, and may also override GetBitmap
48    # as well as all those methods overridable by
49    # wx.PyWindow.
50
51    def GetNext(self):
52        """If the checkbox is set then return the next page's next page"""
53        if self.cb.GetValue():
54            self.next.GetNext().SetPrev(self)
55            return self.next.GetNext()
56        else:
57            self.next.GetNext().SetPrev(self.next)
58            return self.next
59
60    def GetPrev(self):
61        return self.prev
62
63#----------------------------------------------------------------------
64
65class UseAltBitmapPage(WizardPage):
66    def __init__(self, parent, title):
67        WizardPage.__init__(self, parent)
68        self.next = self.prev = None
69        self.sizer = makePageTitle(self, title)
70
71        self.sizer.Add(wx.StaticText(self, -1, "This page uses a different bitmap"),
72                       0, wx.ALL, 5)
73
74    def SetNext(self, next):
75        self.next = next
76
77    def SetPrev(self, prev):
78        self.prev = prev
79
80    def GetNext(self):
81        return self.next
82
83    def GetPrev(self):
84        return self.prev
85
86    def GetBitmap(self):
87        # You usually wouldn't need to override this method
88        # since you can set a non-default bitmap in the
89        # wxWizardPageSimple constructor, but if you need to
90        # dynamically change the bitmap based on the
91        # contents of the wizard, or need to also change the
92        # next/prev order then it can be done by overriding
93        # GetBitmap.
94        return images.WizTest2.GetBitmap()
95
96#----------------------------------------------------------------------
97
98class TestPanel(wx.Panel):
99    def __init__(self, parent, log):
100        self.log = log
101        wx.Panel.__init__(self, parent, -1)
102
103        b = wx.Button(self, -1, "Run Simple Wizard", pos=(50, 50))
104        self.Bind(wx.EVT_BUTTON, self.OnRunSimpleWizard, b)
105
106        b = wx.Button(self, -1, "Run Dynamic Wizard", pos=(50, 100))
107        self.Bind(wx.EVT_BUTTON, self.OnRunDynamicWizard, b)
108
109        self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGED, self.OnWizPageChanged)
110        self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging)
111        self.Bind(wx.adv.EVT_WIZARD_CANCEL, self.OnWizCancel)
112
113
114    def OnWizPageChanged(self, evt):
115        if evt.GetDirection():
116            dir = "forward"
117        else:
118            dir = "backward"
119
120        page = evt.GetPage()
121        self.log.write("OnWizPageChanged: %s, %s\n" % (dir, page.__class__))
122
123
124    def OnWizPageChanging(self, evt):
125        if evt.GetDirection():
126            dir = "forward"
127        else:
128            dir = "backward"
129
130        page = evt.GetPage()
131        self.log.write("OnWizPageChanging: %s, %s\n" % (dir, page.__class__))
132
133
134    def OnWizCancel(self, evt):
135        page = evt.GetPage()
136        self.log.write("OnWizCancel: %s\n" % page.__class__)
137
138        # Show how to prevent cancelling of the wizard.  The
139        # other events can be Veto'd too.
140        if page is self.page1:
141            wx.MessageBox("Cancelling on the first page has been prevented.", "Sorry")
142            evt.Veto()
143
144
145    def OnWizFinished(self, evt):
146        self.log.write("OnWizFinished\n")
147
148
149    def OnRunSimpleWizard(self, evt):
150        # Create the wizard and the pages
151        wizard = wiz(self, -1, "Simple Wizard", images.WizTest1.GetBitmap())
152        page1 = TitledPage(wizard, "Page 1")
153        page2 = TitledPage(wizard, "Page 2")
154        page3 = TitledPage(wizard, "Page 3")
155        page4 = TitledPage(wizard, "Page 4")
156        self.page1 = page1
157
158        page1.sizer.Add(wx.StaticText(page1, -1, """
159This wizard is totally useless, but is meant to show how to
160chain simple wizard pages together in a non-dynamic manner.
161IOW, the order of the pages never changes, and so the
162wxWizardPageSimple class can easily be used for the pages."""))
163        wizard.FitToPage(page1)
164        page4.sizer.Add(wx.StaticText(page4, -1, "\nThis is the last page."))
165
166        # Use the convenience Chain function to connect the pages
167        WizardPageSimple.Chain(page1, page2)
168        WizardPageSimple.Chain(page2, page3)
169        WizardPageSimple.Chain(page3, page4)
170
171        wizard.GetPageAreaSizer().Add(page1)
172        if wizard.RunWizard(page1):
173            wx.MessageBox("Wizard completed successfully", "That's all folks!")
174        else:
175            wx.MessageBox("Wizard was cancelled", "That's all folks!")
176
177
178    def OnRunDynamicWizard(self, evt):
179        # Create the wizard and the pages
180        #wizard = wx.PreWizard()
181        #wizard.SetExtraStyle(wx.WIZARD_EX_HELPBUTTON)
182        #wizard.Create(self, self.ID_wiz, "Simple Wizard",
183        #              images.WizTest1.GetBitmap())
184        wizard = wiz(self, -1, "Dynamic Wizard", images.WizTest1.GetBitmap())
185
186        page1 = TitledPage(wizard, "Page 1")
187        page2 = SkipNextPage(wizard, "Page 2")
188        page3 = TitledPage(wizard, "Page 3")
189        page4 = UseAltBitmapPage(wizard, "Page 4")
190        page5 = TitledPage(wizard, "Page 5")
191        self.page1 = page1
192
193        page1.sizer.Add(wx.StaticText(page1, -1, """
194This wizard shows the ability to choose at runtime the order
195of the pages and also which bitmap is shown.
196"""))
197        wizard.FitToPage(page1)
198        page5.sizer.Add(wx.StaticText(page5, -1, "\nThis is the last page."))
199
200        # Set the initial order of the pages
201        page1.SetNext(page2)
202        page2.SetPrev(page1)
203        page2.SetNext(page3)
204        page3.SetPrev(page2)
205        page3.SetNext(page4)
206        page4.SetPrev(page3)
207        page4.SetNext(page5)
208        page5.SetPrev(page4)
209
210
211        wizard.GetPageAreaSizer().Add(page1)
212        if wizard.RunWizard(page1):
213            wx.MessageBox("Wizard completed successfully", "That's all folks!")
214        else:
215            wx.MessageBox("Wizard was cancelled", "That's all folks!")
216
217#----------------------------------------------------------------------
218
219def runTest(frame, nb, log):
220    win = TestPanel(nb, log)
221    return win
222
223#----------------------------------------------------------------------
224
225
226
227overview = """<html><body>
228<h2><center>wxWizard</center></h2>
229
230wxWizard is the central class for implementing 'wizard-like'
231dialogs. These dialogs are mostly familiar to Windows users and are
232nothing else but a sequence of 'pages' each of them displayed inside a
233dialog which has the buttons to pass to the next (and previous) pages.
234<p>
235The wizards are typically used to decompose a complex dialog into
236several simple steps and are mainly useful to the novice users, hence
237it is important to keep them as simple as possible.
238
239</body></html>
240"""
241
242
243
244if __name__ == '__main__':
245    import sys,os
246    import run
247    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
248
249