1 from __future__ import absolute_import
2 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
8 from Cura.gui import configBase
9 from Cura.gui import expertConfig
10 from Cura.gui import alterationPanel
11 from Cura.gui import pluginPanel
12 from Cura.gui import preferencesDialog
13 from Cura.gui import configWizard
14 from Cura.gui import firmwareInstall
15 from Cura.gui import simpleMode
16 from Cura.gui import sceneView
17 from Cura.gui.util import dropTarget
18 #from Cura.gui.tools import batchRun
19 from Cura.gui.tools import pidDebugger
20 from Cura.gui.tools import minecraftImport
21 from Cura.util import profile
22 from Cura.util import version
23 from Cura.util import meshLoader
25 class mainWindow(wx.Frame):
27 super(mainWindow, self).__init__(None, title='Cura - ' + version.getVersion())
29 self.extruderCount = int(profile.getMachineSetting('extruder_amount'))
31 wx.EVT_CLOSE(self, self.OnClose)
33 self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.loadSupportedExtensions() + ['.g', '.gcode']))
35 self.normalModeOnlyItems = []
37 mruFile = os.path.join(profile.getBasePath(), 'mru_filelist.ini')
38 self.config = wx.FileConfig(appName="Cura",
39 localFilename=mruFile,
40 style=wx.CONFIG_USE_LOCAL_FILE)
42 self.ID_MRU_MODEL1, self.ID_MRU_MODEL2, self.ID_MRU_MODEL3, self.ID_MRU_MODEL4, self.ID_MRU_MODEL5, self.ID_MRU_MODEL6, self.ID_MRU_MODEL7, self.ID_MRU_MODEL8, self.ID_MRU_MODEL9, self.ID_MRU_MODEL10 = [wx.NewId() for line in xrange(10)]
43 self.modelFileHistory = wx.FileHistory(10, self.ID_MRU_MODEL1)
44 self.config.SetPath("/ModelMRU")
45 self.modelFileHistory.Load(self.config)
47 self.ID_MRU_PROFILE1, self.ID_MRU_PROFILE2, self.ID_MRU_PROFILE3, self.ID_MRU_PROFILE4, self.ID_MRU_PROFILE5, self.ID_MRU_PROFILE6, self.ID_MRU_PROFILE7, self.ID_MRU_PROFILE8, self.ID_MRU_PROFILE9, self.ID_MRU_PROFILE10 = [wx.NewId() for line in xrange(10)]
48 self.profileFileHistory = wx.FileHistory(10, self.ID_MRU_PROFILE1)
49 self.config.SetPath("/ProfileMRU")
50 self.profileFileHistory.Load(self.config)
52 self.menubar = wx.MenuBar()
53 self.fileMenu = wx.Menu()
54 i = self.fileMenu.Append(-1, _("Load model file...\tCTRL+L"))
55 self.Bind(wx.EVT_MENU, lambda e: self.scene.showLoadModel(), i)
56 i = self.fileMenu.Append(-1, _("Save model...\tCTRL+S"))
57 self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveModel(), i)
58 i = self.fileMenu.Append(-1, _("Clear platform"))
59 self.Bind(wx.EVT_MENU, lambda e: self.scene.OnDeleteAll(e), i)
61 self.fileMenu.AppendSeparator()
62 i = self.fileMenu.Append(-1, _("Print...\tCTRL+P"))
63 self.Bind(wx.EVT_MENU, lambda e: self.scene.showPrintWindow(), i)
64 i = self.fileMenu.Append(-1, _("Save GCode..."))
65 self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveGCode(), i)
66 i = self.fileMenu.Append(-1, _("Show slice engine log..."))
67 self.Bind(wx.EVT_MENU, lambda e: self.scene._showSliceLog(), i)
69 self.fileMenu.AppendSeparator()
70 i = self.fileMenu.Append(-1, _("Open Profile..."))
71 self.normalModeOnlyItems.append(i)
72 self.Bind(wx.EVT_MENU, self.OnLoadProfile, i)
73 i = self.fileMenu.Append(-1, _("Save Profile..."))
74 self.normalModeOnlyItems.append(i)
75 self.Bind(wx.EVT_MENU, self.OnSaveProfile, i)
76 i = self.fileMenu.Append(-1, _("Load Profile from GCode..."))
77 self.normalModeOnlyItems.append(i)
78 self.Bind(wx.EVT_MENU, self.OnLoadProfileFromGcode, i)
79 self.fileMenu.AppendSeparator()
80 i = self.fileMenu.Append(-1, _("Reset Profile to default"))
81 self.normalModeOnlyItems.append(i)
82 self.Bind(wx.EVT_MENU, self.OnResetProfile, i)
84 self.fileMenu.AppendSeparator()
85 i = self.fileMenu.Append(-1, _("Preferences...\tCTRL+,"))
86 self.Bind(wx.EVT_MENU, self.OnPreferences, i)
87 self.fileMenu.AppendSeparator()
90 modelHistoryMenu = wx.Menu()
91 self.fileMenu.AppendMenu(wx.NewId(), _("&Recent Model Files"), modelHistoryMenu)
92 self.modelFileHistory.UseMenu(modelHistoryMenu)
93 self.modelFileHistory.AddFilesToMenu()
94 self.Bind(wx.EVT_MENU_RANGE, self.OnModelMRU, id=self.ID_MRU_MODEL1, id2=self.ID_MRU_MODEL10)
97 profileHistoryMenu = wx.Menu()
98 self.fileMenu.AppendMenu(wx.NewId(), _("&Recent Profile Files"), profileHistoryMenu)
99 self.profileFileHistory.UseMenu(profileHistoryMenu)
100 self.profileFileHistory.AddFilesToMenu()
101 self.Bind(wx.EVT_MENU_RANGE, self.OnProfileMRU, id=self.ID_MRU_PROFILE1, id2=self.ID_MRU_PROFILE10)
103 self.fileMenu.AppendSeparator()
104 i = self.fileMenu.Append(wx.ID_EXIT, _("Quit"))
105 self.Bind(wx.EVT_MENU, self.OnQuit, i)
106 self.menubar.Append(self.fileMenu, _("&File"))
108 toolsMenu = wx.Menu()
109 i = toolsMenu.Append(-1, _("Switch to quickprint..."))
110 self.switchToQuickprintMenuItem = i
111 self.Bind(wx.EVT_MENU, self.OnSimpleSwitch, i)
112 i = toolsMenu.Append(-1, _("Switch to full settings..."))
113 self.switchToNormalMenuItem = i
114 self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i)
115 #toolsMenu.AppendSeparator()
116 #i = toolsMenu.Append(-1, 'Batch run...')
117 #self.Bind(wx.EVT_MENU, self.OnBatchRun, i)
118 #self.normalModeOnlyItems.append(i)
119 if minecraftImport.hasMinecraft():
120 i = toolsMenu.Append(-1, _("Minecraft import..."))
121 self.Bind(wx.EVT_MENU, self.OnMinecraftImport, i)
122 if version.isDevVersion():
123 i = toolsMenu.Append(-1, _("PID Debugger..."))
124 self.Bind(wx.EVT_MENU, self.OnPIDDebugger, i)
125 self.menubar.Append(toolsMenu, _("Tools"))
127 expertMenu = wx.Menu()
128 i = expertMenu.Append(-1, _("Open expert settings..."))
129 self.normalModeOnlyItems.append(i)
130 self.Bind(wx.EVT_MENU, self.OnExpertOpen, i)
131 expertMenu.AppendSeparator()
132 if firmwareInstall.getDefaultFirmware() is not None:
133 i = expertMenu.Append(-1, _("Install default Marlin firmware"))
134 self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, i)
135 i = expertMenu.Append(-1, _("Install custom firmware"))
136 self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i)
137 expertMenu.AppendSeparator()
138 i = expertMenu.Append(-1, _("Run first run wizard..."))
139 self.Bind(wx.EVT_MENU, self.OnFirstRunWizard, i)
140 i = expertMenu.Append(-1, _("Run bed leveling wizard..."))
141 self.Bind(wx.EVT_MENU, self.OnBedLevelWizard, i)
142 if self.extruderCount > 1:
143 i = expertMenu.Append(-1, _("Run head offset wizard..."))
144 self.Bind(wx.EVT_MENU, self.OnHeadOffsetWizard, i)
145 self.menubar.Append(expertMenu, _("Expert"))
148 i = helpMenu.Append(-1, _("Online documentation..."))
149 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i)
150 i = helpMenu.Append(-1, _("Report a problem..."))
151 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
152 i = helpMenu.Append(-1, _("Check for update..."))
153 self.Bind(wx.EVT_MENU, self.OnCheckForUpdate, i)
154 i = helpMenu.Append(-1, _("Open YouMagine website..."))
155 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://www.youmagine.com/'), i)
156 i = helpMenu.Append(-1, _("About Cura..."))
157 self.Bind(wx.EVT_MENU, self.OnAbout, i)
158 self.menubar.Append(helpMenu, _("Help"))
159 self.SetMenuBar(self.menubar)
161 self.splitter = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_LIVE_UPDATE)
162 self.leftPane = wx.Panel(self.splitter, style=wx.BORDER_NONE)
163 self.rightPane = wx.Panel(self.splitter, style=wx.BORDER_NONE)
164 self.splitter.Bind(wx.EVT_SPLITTER_DCLICK, lambda evt: evt.Veto())
167 self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, lambda : self.scene.sceneUpdated())
168 self.normalSettingsPanel = normalSettingsPanel(self.leftPane, lambda : self.scene.sceneUpdated())
170 self.leftSizer = wx.BoxSizer(wx.VERTICAL)
171 self.leftSizer.Add(self.simpleSettingsPanel, 1)
172 self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND)
173 self.leftPane.SetSizer(self.leftSizer)
176 self.scene = sceneView.SceneView(self.rightPane)
178 #Main sizer, to position the preview window, buttons and tab control
179 sizer = wx.BoxSizer()
180 self.rightPane.SetSizer(sizer)
181 sizer.Add(self.scene, 1, flag=wx.EXPAND)
184 sizer = wx.BoxSizer(wx.VERTICAL)
186 sizer.Add(self.splitter, 1, wx.EXPAND)
190 self.updateProfileToControls()
192 self.SetBackgroundColour(self.normalSettingsPanel.GetBackgroundColour())
194 self.simpleSettingsPanel.Show(False)
195 self.normalSettingsPanel.Show(False)
197 # Set default window size & position
198 self.SetSize((wx.Display().GetClientArea().GetWidth()/2,wx.Display().GetClientArea().GetHeight()/2))
201 # Restore the window position, size & state from the preferences file
203 if profile.getPreference('window_maximized') == 'True':
206 posx = int(profile.getPreference('window_pos_x'))
207 posy = int(profile.getPreference('window_pos_y'))
208 width = int(profile.getPreference('window_width'))
209 height = int(profile.getPreference('window_height'))
210 if posx > 0 or posy > 0:
211 self.SetPosition((posx,posy))
212 if width > 0 and height > 0:
213 self.SetSize((width,height))
215 self.normalSashPos = int(profile.getPreference('window_normal_sash'))
217 self.normalSashPos = 0
219 if self.normalSashPos < self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5:
220 self.normalSashPos = self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5
222 self.splitter.SplitVertically(self.leftPane, self.rightPane, self.normalSashPos)
224 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
226 if wx.Display.GetFromPoint((self.GetPositionTuple()[0] + self.GetSizeTuple()[1], self.GetPositionTuple()[1] + self.GetSizeTuple()[1])) < 0:
228 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
229 self.SetSize((800,600))
232 self.updateSliceMode()
234 def updateSliceMode(self):
235 isSimple = profile.getPreference('startMode') == 'Simple'
237 self.normalSettingsPanel.Show(not isSimple)
238 self.simpleSettingsPanel.Show(isSimple)
239 self.leftPane.Layout()
241 for i in self.normalModeOnlyItems:
242 i.Enable(not isSimple)
243 self.switchToQuickprintMenuItem.Enable(not isSimple)
244 self.switchToNormalMenuItem.Enable(isSimple)
246 # Set splitter sash position & size
248 # Save normal mode sash
249 self.normalSashPos = self.splitter.GetSashPosition()
251 # Change location of sash to width of quick mode pane
252 (width, height) = self.simpleSettingsPanel.GetSizer().GetSize()
253 self.splitter.SetSashPosition(width, True)
256 self.splitter.SetSashSize(0)
258 self.splitter.SetSashPosition(self.normalSashPos, True)
260 self.splitter.SetSashSize(4)
261 self.scene.updateProfileToControls()
263 def OnPreferences(self, e):
264 prefDialog = preferencesDialog.preferencesDialog(self)
268 def OnDropFiles(self, files):
269 print "dropped ", files
271 profile.setPluginConfig([])
272 self.updateProfileToControls()
273 self.scene.loadFiles(files)
275 def OnModelMRU(self, e):
276 fileNum = e.GetId() - self.ID_MRU_MODEL1
277 path = self.modelFileHistory.GetHistoryFile(fileNum)
279 self.modelFileHistory.AddFileToHistory(path) # move up the list
280 self.config.SetPath("/ModelMRU")
281 self.modelFileHistory.Save(self.config)
284 profile.putPreference('lastFile', path)
286 self.scene.loadFiles(filelist)
288 def addToModelMRU(self, file):
289 self.modelFileHistory.AddFileToHistory(file)
290 self.config.SetPath("/ModelMRU")
291 self.modelFileHistory.Save(self.config)
294 def OnProfileMRU(self, e):
295 fileNum = e.GetId() - self.ID_MRU_PROFILE1
296 path = self.profileFileHistory.GetHistoryFile(fileNum)
298 self.profileFileHistory.AddFileToHistory(path) # move up the list
299 self.config.SetPath("/ProfileMRU")
300 self.profileFileHistory.Save(self.config)
303 profile.loadProfile(path)
304 self.updateProfileToControls()
306 def addToProfileMRU(self, file):
307 self.profileFileHistory.AddFileToHistory(file)
308 self.config.SetPath("/ProfileMRU")
309 self.profileFileHistory.Save(self.config)
312 def updateProfileToControls(self):
313 self.scene.updateProfileToControls()
314 self.normalSettingsPanel.updateProfileToControls()
315 self.simpleSettingsPanel.updateProfileToControls()
317 def OnLoadProfile(self, e):
318 dlg=wx.FileDialog(self, _("Select profile file to load"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
319 dlg.SetWildcard("ini files (*.ini)|*.ini")
320 if dlg.ShowModal() == wx.ID_OK:
321 profileFile = dlg.GetPath()
322 profile.loadProfile(profileFile)
323 self.updateProfileToControls()
325 # Update the Profile MRU
326 self.addToProfileMRU(profileFile)
329 def OnLoadProfileFromGcode(self, e):
330 dlg=wx.FileDialog(self, _("Select gcode file to load profile from"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
331 dlg.SetWildcard("gcode files (*.gcode)|*.gcode;*.g")
332 if dlg.ShowModal() == wx.ID_OK:
333 gcodeFile = dlg.GetPath()
334 f = open(gcodeFile, 'r')
337 if line.startswith(';CURA_PROFILE_STRING:'):
338 profile.loadProfileFromString(line[line.find(':')+1:].strip())
341 self.updateProfileToControls()
343 wx.MessageBox(_("No profile found in GCode file.\nThis feature only works with GCode files made by Cura 12.07 or newer."), _("Profile load error"), wx.OK | wx.ICON_INFORMATION)
346 def OnSaveProfile(self, e):
347 dlg=wx.FileDialog(self, _("Select profile file to save"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
348 dlg.SetWildcard("ini files (*.ini)|*.ini")
349 if dlg.ShowModal() == wx.ID_OK:
350 profileFile = dlg.GetPath()
351 profile.saveProfile(profileFile)
354 def OnResetProfile(self, e):
355 dlg = wx.MessageDialog(self, _("This will reset all profile settings to defaults.\nUnless you have saved your current profile, all settings will be lost!\nDo you really want to reset?"), _("Profile reset"), wx.YES_NO | wx.ICON_QUESTION)
356 result = dlg.ShowModal() == wx.ID_YES
359 profile.resetProfile()
360 self.updateProfileToControls()
362 def OnSimpleSwitch(self, e):
363 profile.putPreference('startMode', 'Simple')
364 self.updateSliceMode()
366 def OnNormalSwitch(self, e):
367 profile.putPreference('startMode', 'Normal')
368 self.updateSliceMode()
370 def OnDefaultMarlinFirmware(self, e):
371 firmwareInstall.InstallFirmware()
373 def OnCustomFirmware(self, e):
374 if profile.getPreference('machine_type').startswith('ultimaker'):
375 wx.MessageBox(_("Warning: Installing a custom firmware does not guarantee that you machine will function correctly, and could damage your machine."), _("Firmware update"), wx.OK | wx.ICON_EXCLAMATION)
376 dlg=wx.FileDialog(self, _("Open firmware to upload"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
377 dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
378 if dlg.ShowModal() == wx.ID_OK:
379 filename = dlg.GetPath()
380 if not(os.path.exists(filename)):
382 #For some reason my Ubuntu 10.10 crashes here.
383 firmwareInstall.InstallFirmware(filename)
385 def OnFirstRunWizard(self, e):
386 configWizard.configWizard()
387 self.updateProfileToControls()
389 def OnBedLevelWizard(self, e):
390 configWizard.bedLevelWizard()
392 def OnHeadOffsetWizard(self, e):
393 configWizard.headOffsetWizard()
395 def OnExpertOpen(self, e):
396 ecw = expertConfig.expertConfigWindow(lambda : self.scene.sceneUpdated())
400 def OnMinecraftImport(self, e):
401 mi = minecraftImport.minecraftImportWindow(self)
405 def OnPIDDebugger(self, e):
406 debugger = pidDebugger.debuggerWindow(self)
410 def OnCheckForUpdate(self, e):
411 newVersion = version.checkForNewerVersion()
412 if newVersion is not None:
413 if wx.MessageBox(_("A new version of Cura is available, would you like to download?"), _("New version available"), wx.YES_NO | wx.ICON_INFORMATION) == wx.YES:
414 webbrowser.open(newVersion)
416 wx.MessageBox(_("You are running the latest version of Cura!"), _("Awesome!"), wx.ICON_INFORMATION)
418 def OnAbout(self, e):
419 info = wx.AboutDialogInfo()
421 info.SetDescription(_("End solution for Open Source Fused Filament Fabrication 3D printing."))
422 info.SetWebSite('http://software.ultimaker.com/')
423 info.SetCopyright(_("Copyright (C) David Braam"))
425 This program is free software: you can redistribute it and/or modify
426 it under the terms of the GNU Affero General Public License as published by
427 the Free Software Foundation, either version 3 of the License, or
428 (at your option) any later version.
430 This program is distributed in the hope that it will be useful,
431 but WITHOUT ANY WARRANTY; without even the implied warranty of
432 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
433 GNU Affero General Public License for more details.
435 You should have received a copy of the GNU Affero General Public License
436 along with this program. If not, see <http://www.gnu.org/licenses/>.
440 def OnClose(self, e):
441 profile.saveProfile(profile.getDefaultProfilePath())
443 # Save the window position, size & state from the preferences file
444 profile.putPreference('window_maximized', self.IsMaximized())
445 if not self.IsMaximized() and not self.IsIconized():
446 (posx, posy) = self.GetPosition()
447 profile.putPreference('window_pos_x', posx)
448 profile.putPreference('window_pos_y', posy)
449 (width, height) = self.GetSize()
450 profile.putPreference('window_width', width)
451 profile.putPreference('window_height', height)
453 # Save normal sash position. If in normal mode (!simple mode), get last position of sash before saving it...
454 isSimple = profile.getPreference('startMode') == 'Simple'
456 self.normalSashPos = self.splitter.GetSashPosition()
457 profile.putPreference('window_normal_sash', self.normalSashPos)
459 #HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which keeps wxWidgets from quiting.
461 self.scene.OnPaint = lambda e : e
462 self.scene._slicer.cleanup()
468 class normalSettingsPanel(configBase.configPanelBase):
469 "Main user interface window"
470 def __init__(self, parent, callback = None):
471 super(normalSettingsPanel, self).__init__(parent, callback)
474 self.nb = wx.Notebook(self)
475 self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
476 self.GetSizer().Add(self.nb, 1, wx.EXPAND)
478 (left, right, self.printPanel) = self.CreateDynamicConfigTab(self.nb, 'Basic')
479 self._addSettingsToPanels('basic', left, right)
480 self.SizeLabelWidths(left, right)
482 (left, right, self.advancedPanel) = self.CreateDynamicConfigTab(self.nb, 'Advanced')
483 self._addSettingsToPanels('advanced', left, right)
484 self.SizeLabelWidths(left, right)
487 self.pluginPanel = pluginPanel.pluginPanel(self.nb, callback)
488 if len(self.pluginPanel.pluginList) > 0:
489 self.nb.AddPage(self.pluginPanel, "Plugins")
491 self.pluginPanel.Show(False)
494 if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
495 self.alterationPanel = None
497 self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback)
498 self.nb.AddPage(self.alterationPanel, "Start/End-GCode")
500 self.Bind(wx.EVT_SIZE, self.OnSize)
502 self.nb.SetSize(self.GetSize())
503 self.UpdateSize(self.printPanel)
504 self.UpdateSize(self.advancedPanel)
506 def _addSettingsToPanels(self, category, left, right):
507 count = len(profile.getSubCategoriesFor(category)) + len(profile.getSettingsForCategory(category))
511 for title in profile.getSubCategoriesFor(category):
512 n += 1 + len(profile.getSettingsForCategory(category, title))
515 configBase.TitleRow(p, title)
516 for s in profile.getSettingsForCategory(category, title):
517 if s.checkConditions():
518 configBase.SettingRow(p, s.getName())
520 def SizeLabelWidths(self, left, right):
521 leftWidth = self.getLabelColumnWidth(left)
522 rightWidth = self.getLabelColumnWidth(right)
523 maxWidth = max(leftWidth, rightWidth)
524 self.setLabelColumnWidth(left, maxWidth)
525 self.setLabelColumnWidth(right, maxWidth)
528 # Make the size of the Notebook control the same size as this control
529 self.nb.SetSize(self.GetSize())
531 # Propegate the OnSize() event (just in case)
534 # Perform out resize magic
535 self.UpdateSize(self.printPanel)
536 self.UpdateSize(self.advancedPanel)
538 def UpdateSize(self, configPanel):
539 sizer = configPanel.GetSizer()
543 # if width(col1) < best_width(col1) || width(col2) < best_width(col2):
546 # if width(col1) > (best_width(col1) + best_width(col1)):
547 # switch to horizontal
550 col1 = configPanel.leftPanel
551 colSize1 = col1.GetSize()
552 colBestSize1 = col1.GetBestSize()
553 col2 = configPanel.rightPanel
554 colSize2 = col2.GetSize()
555 colBestSize2 = col2.GetBestSize()
557 orientation = sizer.GetOrientation()
559 if orientation == wx.HORIZONTAL:
560 if (colSize1[0] <= colBestSize1[0]) or (colSize2[0] <= colBestSize2[0]):
562 sizer = wx.BoxSizer(wx.VERTICAL)
563 sizer.Add(configPanel.leftPanel, flag=wx.EXPAND)
564 sizer.Add(configPanel.rightPanel, flag=wx.EXPAND)
565 configPanel.SetSizer(sizer)
571 if max(colSize1[0], colSize2[0]) > (colBestSize1[0] + colBestSize2[0]):
573 sizer = wx.BoxSizer(wx.HORIZONTAL)
574 sizer.Add(configPanel.leftPanel, proportion=1, border=35, flag=wx.EXPAND)
575 sizer.Add(configPanel.rightPanel, proportion=1, flag=wx.EXPAND)
576 configPanel.SetSizer(sizer)
582 def updateProfileToControls(self):
583 super(normalSettingsPanel, self).updateProfileToControls()
584 if self.alterationPanel is not None:
585 self.alterationPanel.updateProfileToControls()
586 self.pluginPanel.updateProfileToControls()