1 from __future__ import absolute_import
\r
4 import wx, os, platform, types, webbrowser, threading, time, re
\r
7 from gui import firmwareInstall
\r
8 from util import machineCom
\r
9 from util import profile
\r
11 class InfoPage(wx.wizard.WizardPageSimple):
\r
12 def __init__(self, parent, title):
\r
13 wx.wizard.WizardPageSimple.__init__(self, parent)
\r
15 sizer = wx.GridBagSizer(5, 5)
\r
17 self.SetSizer(sizer)
\r
18 sizer.AddGrowableCol(1)
\r
20 title = wx.StaticText(self, -1, title)
\r
21 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
\r
22 sizer.Add(title, pos=(0, 0), span=(1,2), flag=wx.ALIGN_CENTRE|wx.ALL)
\r
23 sizer.Add(wx.StaticLine(self, -1), pos=(1,0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
27 def AddText(self,info):
\r
28 text = wx.StaticText(self, -1, info)
\r
29 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT|wx.RIGHT)
\r
33 def AddSeperator(self):
\r
34 self.GetSizer().Add(wx.StaticLine(self, -1), pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
37 def AddHiddenSeperator(self):
\r
40 def AddRadioButton(self, label, style = 0):
\r
41 radio = wx.RadioButton(self, -1, label, style=style)
\r
42 self.GetSizer().Add(radio, pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
46 def AddCheckbox(self, label, checked = False):
\r
47 check = wx.CheckBox(self, -1)
\r
48 text = wx.StaticText(self, -1, label)
\r
49 check.SetValue(checked)
\r
50 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT|wx.RIGHT)
\r
51 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1,2), flag=wx.ALL)
\r
55 def AddButton(self, label):
\r
56 button = wx.Button(self, -1, label)
\r
57 self.GetSizer().Add(button, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
61 def AddDualButton(self, label1, label2):
\r
62 button1 = wx.Button(self, -1, label1)
\r
63 self.GetSizer().Add(button1, pos=(self.rowNr, 0), flag=wx.RIGHT)
\r
64 button2 = wx.Button(self, -1, label2)
\r
65 self.GetSizer().Add(button2, pos=(self.rowNr, 1))
\r
67 return button1, button2
\r
69 def AddTextCtrl(self, value):
\r
70 ret = wx.TextCtrl(self, -1, value)
\r
71 self.GetSizer().Add(ret, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
75 def AddLabelTextCtrl(self, info, value):
\r
76 text = wx.StaticText(self, -1, info)
\r
77 ret = wx.TextCtrl(self, -1, value)
\r
78 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
79 self.GetSizer().Add(ret, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
83 def AddTextCtrlButton(self, value, buttonText):
\r
84 text = wx.TextCtrl(self, -1, value)
\r
85 button = wx.Button(self, -1, buttonText)
\r
86 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
87 self.GetSizer().Add(button, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
91 def AllowNext(self):
\r
94 def StoreData(self):
\r
97 class FirstInfoPage(InfoPage):
\r
98 def __init__(self, parent):
\r
99 super(FirstInfoPage, self).__init__(parent, "First time run wizard")
\r
100 self.AddText('Welcome, and thanks for trying Cura!')
\r
101 self.AddSeperator()
\r
102 self.AddText('This wizard will help you with the following steps:')
\r
103 self.AddText('* Configure Cura for your machine')
\r
104 self.AddText('* Upgrade your firmware')
\r
105 self.AddText('* Calibrate your machine')
\r
106 #self.AddText('* Do your first print')
\r
108 class RepRapInfoPage(InfoPage):
\r
109 def __init__(self, parent):
\r
110 super(RepRapInfoPage, self).__init__(parent, "RepRap information")
\r
111 self.AddText('RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.')
\r
112 self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.')
\r
113 self.AddSeperator()
\r
114 self.AddText('You will have to manually install Marlin or Sprinter firmware.')
\r
115 self.AddSeperator()
\r
116 self.machineWidth = self.AddLabelTextCtrl('Machine width (mm)', '80')
\r
117 self.machineDepth = self.AddLabelTextCtrl('Machine depth (mm)', '80')
\r
118 self.machineHeight = self.AddLabelTextCtrl('Machine height (mm)', '60')
\r
119 self.nozzleSize = self.AddLabelTextCtrl('Nozzle size (mm)', '0.5')
\r
120 self.heatedBed = self.AddCheckbox('Heated bed')
\r
122 def StoreData(self):
\r
123 profile.putPreference('machine_width', self.machineWidth.GetValue())
\r
124 profile.putPreference('machine_depth', self.machineDepth.GetValue())
\r
125 profile.putPreference('machine_height', self.machineHeight.GetValue())
\r
126 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
\r
127 profile.putProfileSetting('machine_center_x', profile.getPreferenceFloat('machine_width') / 2)
\r
128 profile.putProfileSetting('machine_center_y', profile.getPreferenceFloat('machine_depth') / 2)
\r
129 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
\r
130 profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
\r
132 class MachineSelectPage(InfoPage):
\r
133 def __init__(self, parent):
\r
134 super(MachineSelectPage, self).__init__(parent, "Select your machine")
\r
135 self.AddText('What kind of machine do you have:')
\r
137 self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)
\r
138 self.UltimakerRadio.SetValue(True)
\r
139 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
\r
140 self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")
\r
141 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
\r
143 def OnUltimakerSelect(self, e):
\r
144 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
\r
146 def OnOtherSelect(self, e):
\r
147 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().repRapInfoPage)
\r
149 def StoreData(self):
\r
150 if self.UltimakerRadio.GetValue():
\r
151 profile.putPreference('machine_width', '205')
\r
152 profile.putPreference('machine_depth', '205')
\r
153 profile.putPreference('machine_height', '200')
\r
154 profile.putPreference('machine_type', 'ultimaker')
\r
155 profile.putProfileSetting('nozzle_size', '0.4')
\r
156 profile.putProfileSetting('machine_center_x', '100')
\r
157 profile.putProfileSetting('machine_center_y', '100')
\r
159 profile.putPreference('machine_width', '80')
\r
160 profile.putPreference('machine_depth', '80')
\r
161 profile.putPreference('machine_height', '60')
\r
162 profile.putPreference('machine_type', 'reprap')
\r
163 profile.putProfileSetting('nozzle_size', '0.5')
\r
164 profile.putProfileSetting('machine_center_x', '40')
\r
165 profile.putProfileSetting('machine_center_y', '40')
\r
166 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
\r
168 class FirmwareUpgradePage(InfoPage):
\r
169 def __init__(self, parent):
\r
170 super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
\r
171 self.AddText('Firmware is the piece of software running directly on your 3D printer.\nThis firmware controls the step motors, regulates the temperature\nand ultimately makes your printer work.')
\r
172 self.AddHiddenSeperator()
\r
173 self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')
\r
174 self.AddHiddenSeperator()
\r
175 self.AddText('Cura requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.')
\r
176 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
\r
177 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
\r
178 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
179 self.AddHiddenSeperator()
\r
180 self.AddText('Do not upgrade to this firmware if:')
\r
181 self.AddText('* You have an older machine based on ATMega1280')
\r
182 self.AddText('* Have other changes in the firmware')
\r
183 button = self.AddButton('Goto this page for a custom firmware')
\r
184 button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
\r
186 def AllowNext(self):
\r
189 def OnUpgradeClick(self, e):
\r
190 if firmwareInstall.InstallFirmware():
\r
191 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
193 def OnSkipClick(self, e):
\r
194 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
196 def OnUrlClick(self, e):
\r
197 webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
\r
199 class UltimakerCheckupPage(InfoPage):
\r
200 def __init__(self, parent):
\r
201 super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
\r
202 self.AddText('It is a good idea to do a few sanity checks now on your Ultimaker.\nYou can skip these if you know your machine is functional.')
\r
203 b1, b2 = self.AddDualButton('Run checks', 'Skip checks')
\r
204 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
\r
205 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
206 self.AddSeperator()
\r
207 self.checkPanel = None
\r
209 def AllowNext(self):
\r
212 def OnSkipClick(self, e):
\r
213 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
215 def OnCheckClick(self, e):
\r
216 if self.checkPanel != None:
\r
217 self.checkPanel.Destroy()
\r
218 self.checkPanel = wx.Panel(self)
\r
219 self.checkPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
\r
220 self.GetSizer().Add(self.checkPanel, 0, wx.LEFT|wx.RIGHT, 5)
\r
221 threading.Thread(target=self.OnRun).start()
\r
223 def AddProgressText(self, info):
\r
224 text = wx.StaticText(self.checkPanel, -1, info)
\r
225 self.checkPanel.GetSizer().Add(text, 0)
\r
226 self.checkPanel.Layout()
\r
230 wx.CallAfter(self.AddProgressText, "Connecting to machine...")
\r
231 self.comm = machineCom.MachineCom()
\r
233 if not self.comm.isOpen():
\r
234 wx.CallAfter(self.AddProgressText, "Error: Failed to open serial port to machine")
\r
235 wx.CallAfter(self.AddProgressText, "If this keeps happening, try disconnecting and reconnecting the USB cable")
\r
238 wx.CallAfter(self.AddProgressText, "Checking start message...")
\r
239 if self.DoCommCommandWithTimeout(None, 'start') == False:
\r
240 wx.CallAfter(self.AddProgressText, "Error: Missing start message.")
\r
244 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
\r
247 wx.CallAfter(self.AddProgressText, "Disabling step motors...")
\r
248 if self.DoCommCommandWithTimeout('M84') == False:
\r
249 wx.CallAfter(self.AddProgressText, "Error: Missing reply to Deactivate steppers (M84).")
\r
253 if self.DoCommCommandWithTimeout("M104 S0") == False:
\r
254 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
258 wx.MessageBox('Please move the printer head to the center of the machine\nalso move the platform so it is not at the highest or lowest position,\nand make sure the machine is powered on.', 'Machine check', wx.OK | wx.ICON_INFORMATION)
\r
260 idleTemp = self.readTemp()
\r
262 wx.CallAfter(self.AddProgressText, "Waiting for head to cool down before temperature test...")
\r
263 while idleTemp > 40:
\r
264 idleTemp = self.readTemp()
\r
267 wx.CallAfter(self.AddProgressText, "Checking heater and temperature sensor...")
\r
268 wx.CallAfter(self.AddProgressText, "(This takes about 30 seconds)")
\r
269 if self.DoCommCommandWithTimeout("M104 S100") == False:
\r
270 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
275 tempInc = self.readTemp() - idleTemp
\r
277 if self.DoCommCommandWithTimeout("M104 S0") == False:
\r
278 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
283 wx.CallAfter(self.AddProgressText, "Your temperature sensor or heater is not working!")
\r
286 wx.CallAfter(self.AddProgressText, "Heater and temperature sensor working\nWarning: head might still be hot!")
\r
288 wx.CallAfter(self.AddProgressText, "Checking endstops")
\r
289 if self.DoCommCommandWithTimeout('M119', 'x_min') != "x_min:L x_max:L y_min:L y_max:L z_min:L z_max:L":
\r
290 wx.CallAfter(self.AddProgressText, "Error: There is a problem in your endstops!\nOne of them seems to be pressed while it shouldn't\ncheck the cable connections and the switches themselfs.")
\r
293 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front left corner.")
\r
294 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:H x_max:L y_min:L y_max:L z_min:L z_max:L"):
\r
295 wx.CallAfter(self.AddProgressText, "Failed to check the x_min endstop!")
\r
298 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front right corner.")
\r
299 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:H y_min:L y_max:L z_min:L z_max:L"):
\r
300 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
303 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the front left corner.")
\r
304 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:H y_max:L z_min:L z_max:L"):
\r
305 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
308 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the back left corner.")
\r
309 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:H z_min:L z_max:L"):
\r
310 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
313 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the top.")
\r
314 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:L z_min:H z_max:L"):
\r
315 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
318 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the bottom.")
\r
319 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:L z_min:L z_max:H"):
\r
320 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
323 wx.CallAfter(self.AddProgressText, "End stops are working.")
\r
325 wx.CallAfter(self.AddProgressText, "Done!")
\r
326 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
\r
329 def readTemp(self):
\r
330 line = self.DoCommCommandWithTimeout("M105", "ok T:")
\r
333 return int(re.search('T:([0-9]*)', line).group(1))
\r
335 def DoCommCommandAndWaitForReply(self, cmd, replyStart, reply):
\r
337 ret = self.DoCommCommandWithTimeout(cmd, replyStart)
\r
344 def DoCommCommandWithTimeout(self, cmd = None, replyStart = 'ok'):
\r
346 self.comm.sendCommand(cmd)
\r
347 t = threading.Timer(5, self.OnSerialTimeout)
\r
350 line = self.comm.readline()
\r
351 if line == '' or line == None:
\r
354 print line.rstrip()
\r
355 if replyStart in line:
\r
358 return line.rstrip()
\r
360 def OnSerialTimeout(self):
\r
363 class UltimakerCalibrationPage(InfoPage):
\r
364 def __init__(self, parent):
\r
365 super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
\r
367 self.AddText("Your Ultimaker requires some calibration.")
\r
368 self.AddText("This calibration is needed for a proper extrusion amount.")
\r
369 self.AddSeperator()
\r
370 self.AddText("The following values are needed:")
\r
371 self.AddText("* Diameter of filament")
\r
372 self.AddText("* Number of steps per mm of filament extrusion")
\r
373 self.AddSeperator()
\r
374 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
\r
375 self.AddSeperator()
\r
376 self.AddText("First we need the diameter of your filament:")
\r
377 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
\r
378 self.AddText("If you do not own digital Calipers that can measure\nat least 2 digits then use 2.89mm.\nWhich is the average diameter of most filament.")
\r
379 self.AddText("Note: This value can be changed later at any time.")
\r
381 def StoreData(self):
\r
382 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
\r
384 class UltimakerCalibrateStepsPerEPage(InfoPage):
\r
385 def __init__(self, parent):
\r
386 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
\r
388 if profile.getPreference('steps_per_e') == '0':
\r
389 profile.putPreference('steps_per_e', '865.888')
\r
391 self.AddText("Calibrating the Steps Per E requires some manual actions.")
\r
392 self.AddText("First remove any filament from your machine.")
\r
393 self.AddText("Next put in your filament so the tip is aligned with the\ntop of the extruder drive.")
\r
394 self.AddText("We'll push the filament 100mm")
\r
395 self.extrudeButton = self.AddButton("Extrude 100mm filament")
\r
396 self.AddText("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)")
\r
397 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton('100', 'Save')
\r
398 self.AddText("This results in the following steps per E:")
\r
399 self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
\r
400 self.AddText("You can repeat these steps to get better calibration.")
\r
401 self.AddSeperator()
\r
402 self.AddText("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")
\r
403 self.heatButton = self.AddButton("Heatup for filament removal")
\r
405 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
\r
406 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
\r
407 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
\r
409 def OnSaveLengthClick(self, e):
\r
410 currentEValue = float(self.stepsPerEInput.GetValue())
\r
411 realExtrudeLength = float(self.lengthInput.GetValue())
\r
412 newEValue = currentEValue * 100 / realExtrudeLength
\r
413 self.stepsPerEInput.SetValue(str(newEValue))
\r
414 self.lengthInput.SetValue("100")
\r
416 def OnExtrudeClick(self, e):
\r
417 threading.Thread(target=self.OnExtrudeRun).start()
\r
419 def OnExtrudeRun(self):
\r
420 self.heatButton.Enable(False)
\r
421 self.extrudeButton.Enable(False)
\r
422 currentEValue = float(self.stepsPerEInput.GetValue())
\r
423 self.comm = machineCom.MachineCom()
\r
424 if not self.comm.isOpen():
\r
425 wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)
\r
426 self.heatButton.Enable(True)
\r
427 self.extrudeButton.Enable(True)
\r
430 line = self.comm.readline()
\r
433 if 'start' in line:
\r
435 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
\r
438 self.sendGCommand('M302') #Disable cold extrusion protection
\r
439 self.sendGCommand("M92 E%f" % (currentEValue))
\r
440 self.sendGCommand("G92 E0")
\r
441 self.sendGCommand("G1 E100 F600")
\r
444 self.extrudeButton.Enable()
\r
445 self.heatButton.Enable()
\r
447 def OnHeatClick(self, e):
\r
448 threading.Thread(target=self.OnHeatRun).start()
\r
450 def OnHeatRun(self):
\r
451 self.heatButton.Enable(False)
\r
452 self.extrudeButton.Enable(False)
\r
453 self.comm = machineCom.MachineCom()
\r
454 if not self.comm.isOpen():
\r
455 wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)
\r
456 self.heatButton.Enable(True)
\r
457 self.extrudeButton.Enable(True)
\r
460 line = self.comm.readline()
\r
462 self.heatButton.Enable(True)
\r
463 self.extrudeButton.Enable(True)
\r
465 if 'start' in line:
\r
467 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
\r
470 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
\r
471 wx.MessageBox('Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)', 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
\r
472 self.sendGCommand('M104 S0')
\r
475 self.heatButton.Enable(True)
\r
476 self.extrudeButton.Enable(True)
\r
478 def sendGCommand(self, cmd):
\r
479 self.comm.sendCommand(cmd) #Disable cold extrusion protection
\r
481 line = self.comm.readline()
\r
484 if line.startswith('ok'):
\r
487 def StoreData(self):
\r
488 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
\r
490 class configWizard(wx.wizard.Wizard):
\r
491 def __init__(self):
\r
492 super(configWizard, self).__init__(None, -1, "Configuration Wizard")
\r
494 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
\r
495 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
\r
497 self.firstInfoPage = FirstInfoPage(self)
\r
498 self.machineSelectPage = MachineSelectPage(self)
\r
499 self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)
\r
500 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
\r
501 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
\r
502 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
\r
503 self.repRapInfoPage = RepRapInfoPage(self)
\r
505 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
\r
506 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)
\r
507 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
\r
508 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)
\r
509 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
\r
511 self.FitToPage(self.firstInfoPage)
\r
512 self.GetPageAreaSizer().Add(self.firstInfoPage)
\r
514 self.RunWizard(self.firstInfoPage)
\r
517 def OnPageChanging(self, e):
\r
518 e.GetPage().StoreData()
\r
520 def OnPageChanged(self, e):
\r
521 if e.GetPage().AllowNext():
\r
522 self.FindWindowById(wx.ID_FORWARD).Enable()
\r
524 self.FindWindowById(wx.ID_FORWARD).Disable()
\r
525 self.FindWindowById(wx.ID_BACKWARD).Disable()
\r