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.gui.tools import youmagineGui
22 from Cura.util import profile
23 from Cura.util import version
24 from Cura.util import meshLoader
25 from Cura.util import resources
27 class mainWindow(wx.Frame):
29 super(mainWindow, self).__init__(None, title='Cura - ' + version.getVersion())
31 self.extruderCount = int(profile.getPreference('extruder_amount'))
33 wx.EVT_CLOSE(self, self.OnClose)
35 self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.loadSupportedExtensions()))
37 self.normalModeOnlyItems = []
39 mruFile = os.path.join(profile.getBasePath(), 'mru_filelist.ini')
40 self.config = wx.FileConfig(appName="Cura",
41 localFilename=mruFile,
42 style=wx.CONFIG_USE_LOCAL_FILE)
44 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)]
45 self.modelFileHistory = wx.FileHistory(10, self.ID_MRU_MODEL1)
46 self.config.SetPath("/ModelMRU")
47 self.modelFileHistory.Load(self.config)
49 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)]
50 self.profileFileHistory = wx.FileHistory(10, self.ID_MRU_PROFILE1)
51 self.config.SetPath("/ProfileMRU")
52 self.profileFileHistory.Load(self.config)
54 self.menubar = wx.MenuBar()
55 self.fileMenu = wx.Menu()
56 i = self.fileMenu.Append(-1, 'Load model file...\tCTRL+L')
57 self.Bind(wx.EVT_MENU, lambda e: self.scene.showLoadModel(), i)
58 i = self.fileMenu.Append(-1, 'Save model...\tCTRL+S')
59 self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveModel(), i)
60 i = self.fileMenu.Append(-1, 'Clear platform')
61 self.Bind(wx.EVT_MENU, lambda e: self.scene.OnDeleteAll(e), i)
63 self.fileMenu.AppendSeparator()
64 i = self.fileMenu.Append(-1, 'Print...\tCTRL+P')
65 self.Bind(wx.EVT_MENU, lambda e: self.scene.showPrintWindow(), i)
66 i = self.fileMenu.Append(-1, 'Save GCode...')
67 self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveGCode(), i)
68 i = self.fileMenu.Append(-1, 'Show slice engine log...')
69 self.Bind(wx.EVT_MENU, lambda e: self.scene._showSliceLog(), i)
71 self.fileMenu.AppendSeparator()
72 i = self.fileMenu.Append(-1, 'Open Profile...')
73 self.normalModeOnlyItems.append(i)
74 self.Bind(wx.EVT_MENU, self.OnLoadProfile, i)
75 i = self.fileMenu.Append(-1, 'Save Profile...')
76 self.normalModeOnlyItems.append(i)
77 self.Bind(wx.EVT_MENU, self.OnSaveProfile, i)
78 i = self.fileMenu.Append(-1, 'Load Profile from GCode...')
79 self.normalModeOnlyItems.append(i)
80 self.Bind(wx.EVT_MENU, self.OnLoadProfileFromGcode, i)
81 self.fileMenu.AppendSeparator()
82 i = self.fileMenu.Append(-1, 'Reset Profile to default')
83 self.normalModeOnlyItems.append(i)
84 self.Bind(wx.EVT_MENU, self.OnResetProfile, i)
86 self.fileMenu.AppendSeparator()
87 i = self.fileMenu.Append(-1, 'Preferences...\tCTRL+,')
88 self.Bind(wx.EVT_MENU, self.OnPreferences, i)
89 self.fileMenu.AppendSeparator()
92 modelHistoryMenu = wx.Menu()
93 self.fileMenu.AppendMenu(wx.NewId(), "&Recent Model Files", modelHistoryMenu)
94 self.modelFileHistory.UseMenu(modelHistoryMenu)
95 self.modelFileHistory.AddFilesToMenu()
96 self.Bind(wx.EVT_MENU_RANGE, self.OnModelMRU, id=self.ID_MRU_MODEL1, id2=self.ID_MRU_MODEL10)
99 profileHistoryMenu = wx.Menu()
100 self.fileMenu.AppendMenu(wx.NewId(), "&Recent Profile Files", profileHistoryMenu)
101 self.profileFileHistory.UseMenu(profileHistoryMenu)
102 self.profileFileHistory.AddFilesToMenu()
103 self.Bind(wx.EVT_MENU_RANGE, self.OnProfileMRU, id=self.ID_MRU_PROFILE1, id2=self.ID_MRU_PROFILE10)
105 self.fileMenu.AppendSeparator()
106 i = self.fileMenu.Append(wx.ID_EXIT, 'Quit')
107 self.Bind(wx.EVT_MENU, self.OnQuit, i)
108 self.menubar.Append(self.fileMenu, '&File')
110 toolsMenu = wx.Menu()
111 i = toolsMenu.Append(-1, 'Switch to quickprint...')
112 self.switchToQuickprintMenuItem = i
113 self.Bind(wx.EVT_MENU, self.OnSimpleSwitch, i)
114 i = toolsMenu.Append(-1, 'Switch to full settings...')
115 self.switchToNormalMenuItem = i
116 self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i)
117 toolsMenu.AppendSeparator()
118 #i = toolsMenu.Append(-1, 'Batch run...')
119 #self.Bind(wx.EVT_MENU, self.OnBatchRun, i)
120 #self.normalModeOnlyItems.append(i)
121 if minecraftImport.hasMinecraft():
122 i = toolsMenu.Append(-1, 'Minecraft import...')
123 self.Bind(wx.EVT_MENU, self.OnMinecraftImport, i)
124 if version.isDevVersion():
125 i = toolsMenu.Append(-1, 'PID Debugger...')
126 self.Bind(wx.EVT_MENU, self.OnPIDDebugger, i)
127 self.menubar.Append(toolsMenu, 'Tools')
129 expertMenu = wx.Menu()
130 i = expertMenu.Append(-1, 'Open expert settings...')
131 self.normalModeOnlyItems.append(i)
132 self.Bind(wx.EVT_MENU, self.OnExpertOpen, i)
133 expertMenu.AppendSeparator()
134 if firmwareInstall.getDefaultFirmware() is not None:
135 i = expertMenu.Append(-1, 'Install default Marlin firmware')
136 self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, i)
137 i = expertMenu.Append(-1, 'Install custom firmware')
138 self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i)
139 expertMenu.AppendSeparator()
140 i = expertMenu.Append(-1, 'Run first run wizard...')
141 self.Bind(wx.EVT_MENU, self.OnFirstRunWizard, i)
142 i = expertMenu.Append(-1, 'Run bed leveling wizard...')
143 self.Bind(wx.EVT_MENU, self.OnBedLevelWizard, i)
144 if self.extruderCount > 1:
145 i = expertMenu.Append(-1, 'Run head offset wizard...')
146 self.Bind(wx.EVT_MENU, self.OnHeadOffsetWizard, i)
147 self.menubar.Append(expertMenu, 'Expert')
150 i = helpMenu.Append(-1, 'Online documentation...')
151 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i)
152 i = helpMenu.Append(-1, 'Report a problem...')
153 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
154 i = helpMenu.Append(-1, 'Check for update...')
155 self.Bind(wx.EVT_MENU, self.OnCheckForUpdate, 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.youmagineButton = wx.BitmapButton(self.leftPane, -1, wx.Bitmap(resources.getPathForImage('youmagine-text.png')))
171 self.youmagineButton.SetToolTipString("Share your design to YouMagine.com")
172 self.youmagineButton.Bind(wx.EVT_BUTTON, self.OnYouMagine)
174 self.leftSizer = wx.BoxSizer(wx.VERTICAL)
175 self.leftSizer.Add(self.simpleSettingsPanel, 1)
176 self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND)
177 self.leftSizer.Add(self.youmagineButton, 0, wx.ALIGN_CENTER)
178 self.leftPane.SetSizer(self.leftSizer)
181 self.scene = sceneView.SceneView(self.rightPane)
183 #Main sizer, to position the preview window, buttons and tab control
184 sizer = wx.BoxSizer()
185 self.rightPane.SetSizer(sizer)
186 sizer.Add(self.scene, 1, flag=wx.EXPAND)
189 sizer = wx.BoxSizer(wx.VERTICAL)
191 sizer.Add(self.splitter, 1, wx.EXPAND)
195 self.updateProfileToControls()
197 self.SetBackgroundColour(self.normalSettingsPanel.GetBackgroundColour())
199 self.simpleSettingsPanel.Show(False)
200 self.normalSettingsPanel.Show(False)
202 # Set default window size & position
203 self.SetSize((wx.Display().GetClientArea().GetWidth()/2,wx.Display().GetClientArea().GetHeight()/2))
206 # Restore the window position, size & state from the preferences file
208 if profile.getPreference('window_maximized') == 'True':
211 posx = int(profile.getPreference('window_pos_x'))
212 posy = int(profile.getPreference('window_pos_y'))
213 width = int(profile.getPreference('window_width'))
214 height = int(profile.getPreference('window_height'))
215 if posx > 0 or posy > 0:
216 self.SetPosition((posx,posy))
217 if width > 0 and height > 0:
218 self.SetSize((width,height))
220 self.normalSashPos = int(profile.getPreference('window_normal_sash'))
222 self.normalSashPos = 0
224 if self.normalSashPos < self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5:
225 self.normalSashPos = self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5
227 self.splitter.SplitVertically(self.leftPane, self.rightPane, self.normalSashPos)
229 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
231 if wx.Display.GetFromPoint((self.GetPositionTuple()[0] + self.GetSizeTuple()[1], self.GetPositionTuple()[1] + self.GetSizeTuple()[1])) < 0:
233 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
234 self.SetSize((800,600))
237 self.updateSliceMode()
239 def updateSliceMode(self):
240 isSimple = profile.getPreference('startMode') == 'Simple'
242 self.normalSettingsPanel.Show(not isSimple)
243 self.simpleSettingsPanel.Show(isSimple)
244 self.leftPane.Layout()
246 for i in self.normalModeOnlyItems:
247 i.Enable(not isSimple)
248 self.switchToQuickprintMenuItem.Enable(not isSimple)
249 self.switchToNormalMenuItem.Enable(isSimple)
251 # Set splitter sash position & size
253 # Save normal mode sash
254 self.normalSashPos = self.splitter.GetSashPosition()
256 # Change location of sash to width of quick mode pane
257 (width, height) = self.simpleSettingsPanel.GetSizer().GetSize()
258 (width, height) = self.youmagineButton.GetSize()
259 self.splitter.SetSashPosition(width, True)
262 self.splitter.SetSashSize(0)
264 self.splitter.SetSashPosition(self.normalSashPos, True)
266 self.splitter.SetSashSize(4)
267 self.scene.updateProfileToControls()
269 def OnPreferences(self, e):
270 prefDialog = preferencesDialog.preferencesDialog(self)
274 def OnDropFiles(self, files):
276 profile.setPluginConfig([])
277 self.updateProfileToControls()
278 self.scene.loadScene(files)
280 def OnModelMRU(self, e):
281 fileNum = e.GetId() - self.ID_MRU_MODEL1
282 path = self.modelFileHistory.GetHistoryFile(fileNum)
284 self.modelFileHistory.AddFileToHistory(path) # move up the list
285 self.config.SetPath("/ModelMRU")
286 self.modelFileHistory.Save(self.config)
289 profile.putPreference('lastFile', path)
291 self.scene.loadScene(filelist)
293 def addToModelMRU(self, file):
294 self.modelFileHistory.AddFileToHistory(file)
295 self.config.SetPath("/ModelMRU")
296 self.modelFileHistory.Save(self.config)
299 def OnProfileMRU(self, e):
300 fileNum = e.GetId() - self.ID_MRU_PROFILE1
301 path = self.profileFileHistory.GetHistoryFile(fileNum)
303 self.profileFileHistory.AddFileToHistory(path) # move up the list
304 self.config.SetPath("/ProfileMRU")
305 self.profileFileHistory.Save(self.config)
308 profile.loadProfile(path)
309 self.updateProfileToControls()
311 def addToProfileMRU(self, file):
312 self.profileFileHistory.AddFileToHistory(file)
313 self.config.SetPath("/ProfileMRU")
314 self.profileFileHistory.Save(self.config)
317 def updateProfileToControls(self):
318 self.scene.updateProfileToControls()
319 self.normalSettingsPanel.updateProfileToControls()
320 self.simpleSettingsPanel.updateProfileToControls()
322 def OnLoadProfile(self, e):
323 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)
324 dlg.SetWildcard("ini files (*.ini)|*.ini")
325 if dlg.ShowModal() == wx.ID_OK:
326 profileFile = dlg.GetPath()
327 profile.loadProfile(profileFile)
328 self.updateProfileToControls()
330 # Update the Profile MRU
331 self.addToProfileMRU(profileFile)
334 def OnLoadProfileFromGcode(self, e):
335 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)
336 dlg.SetWildcard("gcode files (*.gcode)|*.gcode;*.g")
337 if dlg.ShowModal() == wx.ID_OK:
338 gcodeFile = dlg.GetPath()
339 f = open(gcodeFile, 'r')
342 if line.startswith(';CURA_PROFILE_STRING:'):
343 profile.loadProfileFromString(line[line.find(':')+1:].strip())
346 self.updateProfileToControls()
348 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)
351 def OnSaveProfile(self, e):
352 dlg=wx.FileDialog(self, "Select profile file to save", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
353 dlg.SetWildcard("ini files (*.ini)|*.ini")
354 if dlg.ShowModal() == wx.ID_OK:
355 profileFile = dlg.GetPath()
356 profile.saveProfile(profileFile)
359 def OnResetProfile(self, e):
360 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)
361 result = dlg.ShowModal() == wx.ID_YES
364 profile.resetProfile()
365 self.updateProfileToControls()
367 def OnSimpleSwitch(self, e):
368 profile.putPreference('startMode', 'Simple')
369 self.updateSliceMode()
371 def OnNormalSwitch(self, e):
372 profile.putPreference('startMode', 'Normal')
373 self.updateSliceMode()
375 def OnDefaultMarlinFirmware(self, e):
376 firmwareInstall.InstallFirmware()
378 def OnCustomFirmware(self, e):
379 if profile.getPreference('machine_type') == 'ultimaker':
380 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)
381 dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
382 dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
383 if dlg.ShowModal() == wx.ID_OK:
384 filename = dlg.GetPath()
385 if not(os.path.exists(filename)):
387 #For some reason my Ubuntu 10.10 crashes here.
388 firmwareInstall.InstallFirmware(filename)
390 def OnFirstRunWizard(self, e):
391 configWizard.configWizard()
392 self.updateProfileToControls()
394 def OnBedLevelWizard(self, e):
395 configWizard.bedLevelWizard()
397 def OnHeadOffsetWizard(self, e):
398 configWizard.headOffsetWizard()
400 def OnExpertOpen(self, e):
401 ecw = expertConfig.expertConfigWindow(lambda : self.scene.sceneUpdated())
405 def OnMinecraftImport(self, e):
406 mi = minecraftImport.minecraftImportWindow(self)
410 def OnPIDDebugger(self, e):
411 debugger = pidDebugger.debuggerWindow(self)
415 def OnYouMagine(self, e):
416 if len(self.scene._scene.objects()) < 1:
417 wx.MessageBox('You cannot upload to YouMagine without have a file loaded.', 'Cura', wx.OK | wx.ICON_ERROR)
419 youmagineGui.youmagineManager(self, self.scene._scene)
421 def OnCheckForUpdate(self, e):
422 newVersion = version.checkForNewerVersion()
423 if newVersion is not None:
424 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:
425 webbrowser.open(newVersion)
427 wx.MessageBox('You are running the latest version of Cura!', 'Awesome!', wx.ICON_INFORMATION)
429 def OnAbout(self, e):
430 info = wx.AboutDialogInfo()
432 info.SetDescription('End solution for Open Source Fused Filament Fabrication 3D printing.')
433 info.SetWebSite('http://software.ultimaker.com/')
434 info.SetCopyright('Copyright (C) David Braam')
436 This program is free software: you can redistribute it and/or modify
437 it under the terms of the GNU Affero General Public License as published by
438 the Free Software Foundation, either version 3 of the License, or
439 (at your option) any later version.
441 This program is distributed in the hope that it will be useful,
442 but WITHOUT ANY WARRANTY; without even the implied warranty of
443 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
444 GNU Affero General Public License for more details.
446 You should have received a copy of the GNU Affero General Public License
447 along with this program. If not, see <http://www.gnu.org/licenses/>.
451 def OnClose(self, e):
452 profile.saveProfile(profile.getDefaultProfilePath())
454 # Save the window position, size & state from the preferences file
455 profile.putPreference('window_maximized', self.IsMaximized())
456 if not self.IsMaximized() and not self.IsIconized():
457 (posx, posy) = self.GetPosition()
458 profile.putPreference('window_pos_x', posx)
459 profile.putPreference('window_pos_y', posy)
460 (width, height) = self.GetSize()
461 profile.putPreference('window_width', width)
462 profile.putPreference('window_height', height)
464 # Save normal sash position. If in normal mode (!simple mode), get last position of sash before saving it...
465 isSimple = profile.getPreference('startMode') == 'Simple'
467 self.normalSashPos = self.splitter.GetSashPosition()
468 profile.putPreference('window_normal_sash', self.normalSashPos)
470 #HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which keeps wxWidgets from quiting.
472 self.scene.OnPaint = lambda e : e
473 self.scene._slicer.cleanup()
479 class normalSettingsPanel(configBase.configPanelBase):
480 "Main user interface window"
481 def __init__(self, parent, callback = None):
482 super(normalSettingsPanel, self).__init__(parent, callback)
485 self.nb = wx.Notebook(self)
486 self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
487 self.GetSizer().Add(self.nb, 1, wx.EXPAND)
489 (left, right, self.printPanel) = self.CreateDynamicConfigTab(self.nb, 'Basic')
490 self._addSettingsToPanels('basic', left, right)
491 self.SizeLabelWidths(left, right)
493 (left, right, self.advancedPanel) = self.CreateDynamicConfigTab(self.nb, 'Advanced')
494 self._addSettingsToPanels('advanced', left, right)
495 self.SizeLabelWidths(left, right)
498 self.pluginPanel = pluginPanel.pluginPanel(self.nb, callback)
499 if len(self.pluginPanel.pluginList) > 0:
500 self.nb.AddPage(self.pluginPanel, "Plugins")
502 self.pluginPanel.Show(False)
505 self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback)
506 self.nb.AddPage(self.alterationPanel, "Start/End-GCode")
508 self.Bind(wx.EVT_SIZE, self.OnSize)
510 self.nb.SetSize(self.GetSize())
511 self.UpdateSize(self.printPanel)
512 self.UpdateSize(self.advancedPanel)
514 def _addSettingsToPanels(self, category, left, right):
515 count = len(profile.getSubCategoriesFor(category)) + len(profile.getSettingsForCategory(category))
519 for title in profile.getSubCategoriesFor(category):
520 n += 1 + len(profile.getSettingsForCategory(category, title))
523 configBase.TitleRow(p, title)
524 for s in profile.getSettingsForCategory(category, title):
525 if s.checkConditions():
526 configBase.SettingRow(p, s.getName())
528 def SizeLabelWidths(self, left, right):
529 leftWidth = self.getLabelColumnWidth(left)
530 rightWidth = self.getLabelColumnWidth(right)
531 maxWidth = max(leftWidth, rightWidth)
532 self.setLabelColumnWidth(left, maxWidth)
533 self.setLabelColumnWidth(right, maxWidth)
536 # Make the size of the Notebook control the same size as this control
537 self.nb.SetSize(self.GetSize())
539 # Propegate the OnSize() event (just in case)
542 # Perform out resize magic
543 self.UpdateSize(self.printPanel)
544 self.UpdateSize(self.advancedPanel)
546 def UpdateSize(self, configPanel):
547 sizer = configPanel.GetSizer()
551 # if width(col1) < best_width(col1) || width(col2) < best_width(col2):
554 # if width(col1) > (best_width(col1) + best_width(col1)):
555 # switch to horizontal
558 col1 = configPanel.leftPanel
559 colSize1 = col1.GetSize()
560 colBestSize1 = col1.GetBestSize()
561 col2 = configPanel.rightPanel
562 colSize2 = col2.GetSize()
563 colBestSize2 = col2.GetBestSize()
565 orientation = sizer.GetOrientation()
567 if orientation == wx.HORIZONTAL:
568 if (colSize1[0] <= colBestSize1[0]) or (colSize2[0] <= colBestSize2[0]):
570 sizer = wx.BoxSizer(wx.VERTICAL)
571 sizer.Add(configPanel.leftPanel, flag=wx.EXPAND)
572 sizer.Add(configPanel.rightPanel, flag=wx.EXPAND)
573 configPanel.SetSizer(sizer)
579 if max(colSize1[0], colSize2[0]) > (colBestSize1[0] + colBestSize2[0]):
581 sizer = wx.BoxSizer(wx.HORIZONTAL)
582 sizer.Add(configPanel.leftPanel, proportion=1, border=35, flag=wx.EXPAND)
583 sizer.Add(configPanel.rightPanel, proportion=1, flag=wx.EXPAND)
584 configPanel.SetSizer(sizer)
590 def updateProfileToControls(self):
591 super(normalSettingsPanel, self).updateProfileToControls()
592 self.alterationPanel.updateProfileToControls()
593 self.pluginPanel.updateProfileToControls()