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.getPreference('extruder_amount'))
31 wx.EVT_CLOSE(self, self.OnClose)
33 self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.loadSupportedExtensions()))
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, 'About Cura...')
155 self.Bind(wx.EVT_MENU, self.OnAbout, i)
156 self.menubar.Append(helpMenu, 'Help')
157 self.SetMenuBar(self.menubar)
159 self.splitter = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_LIVE_UPDATE)
160 self.leftPane = wx.Panel(self.splitter, style=wx.BORDER_NONE)
161 self.rightPane = wx.Panel(self.splitter, style=wx.BORDER_NONE)
162 self.splitter.Bind(wx.EVT_SPLITTER_DCLICK, lambda evt: evt.Veto())
165 self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, lambda : self.scene.sceneUpdated())
166 self.normalSettingsPanel = normalSettingsPanel(self.leftPane, lambda : self.scene.sceneUpdated())
168 self.leftSizer = wx.BoxSizer(wx.VERTICAL)
169 self.leftSizer.Add(self.simpleSettingsPanel)
170 self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND)
171 self.leftPane.SetSizer(self.leftSizer)
174 self.scene = sceneView.SceneView(self.rightPane)
176 #Main sizer, to position the preview window, buttons and tab control
177 sizer = wx.BoxSizer()
178 self.rightPane.SetSizer(sizer)
179 sizer.Add(self.scene, 1, flag=wx.EXPAND)
182 sizer = wx.BoxSizer(wx.VERTICAL)
184 sizer.Add(self.splitter, 1, wx.EXPAND)
188 self.updateProfileToControls()
190 self.SetBackgroundColour(self.normalSettingsPanel.GetBackgroundColour())
192 self.simpleSettingsPanel.Show(False)
193 self.normalSettingsPanel.Show(False)
195 # Set default window size & position
196 self.SetSize((wx.Display().GetClientArea().GetWidth()/2,wx.Display().GetClientArea().GetHeight()/2))
199 # Restore the window position, size & state from the preferences file
201 if profile.getPreference('window_maximized') == 'True':
204 posx = int(profile.getPreference('window_pos_x'))
205 posy = int(profile.getPreference('window_pos_y'))
206 width = int(profile.getPreference('window_width'))
207 height = int(profile.getPreference('window_height'))
208 if posx > 0 or posy > 0:
209 self.SetPosition((posx,posy))
210 if width > 0 and height > 0:
211 self.SetSize((width,height))
213 self.normalSashPos = int(profile.getPreference('window_normal_sash'))
215 self.normalSashPos = 0
217 if self.normalSashPos < self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5:
218 self.normalSashPos = self.normalSettingsPanel.printPanel.GetBestSize()[0] + 5
220 self.splitter.SplitVertically(self.leftPane, self.rightPane, self.normalSashPos)
222 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
224 if wx.Display.GetFromPoint((self.GetPositionTuple()[0] + self.GetSizeTuple()[1], self.GetPositionTuple()[1] + self.GetSizeTuple()[1])) < 0:
226 if wx.Display.GetFromPoint(self.GetPosition()) < 0:
227 self.SetSize((800,600))
230 self.updateSliceMode()
232 def updateSliceMode(self):
233 isSimple = profile.getPreference('startMode') == 'Simple'
235 self.normalSettingsPanel.Show(not isSimple)
236 self.simpleSettingsPanel.Show(isSimple)
237 self.leftPane.Layout()
239 for i in self.normalModeOnlyItems:
240 i.Enable(not isSimple)
241 self.switchToQuickprintMenuItem.Enable(not isSimple)
242 self.switchToNormalMenuItem.Enable(isSimple)
244 # Set splitter sash position & size
246 # Save normal mode sash
247 self.normalSashPos = self.splitter.GetSashPosition()
249 # Change location of sash to width of quick mode pane
250 (width, height) = self.simpleSettingsPanel.GetSizer().GetSize()
251 self.splitter.SetSashPosition(width, True)
254 self.splitter.SetSashSize(0)
256 self.splitter.SetSashPosition(self.normalSashPos, True)
258 self.splitter.SetSashSize(4)
259 self.scene.updateProfileToControls()
261 def OnPreferences(self, e):
262 prefDialog = preferencesDialog.preferencesDialog(self)
266 def OnDropFiles(self, files):
268 profile.setPluginConfig([])
269 self.updateProfileToControls()
270 self.scene.loadScene(files)
272 def OnModelMRU(self, e):
273 fileNum = e.GetId() - self.ID_MRU_MODEL1
274 path = self.modelFileHistory.GetHistoryFile(fileNum)
276 self.modelFileHistory.AddFileToHistory(path) # move up the list
277 self.config.SetPath("/ModelMRU")
278 self.modelFileHistory.Save(self.config)
281 profile.putPreference('lastFile', path)
283 self.scene.loadScene(filelist)
285 def addToModelMRU(self, file):
286 self.modelFileHistory.AddFileToHistory(file)
287 self.config.SetPath("/ModelMRU")
288 self.modelFileHistory.Save(self.config)
291 def OnProfileMRU(self, e):
292 fileNum = e.GetId() - self.ID_MRU_PROFILE1
293 path = self.profileFileHistory.GetHistoryFile(fileNum)
295 self.profileFileHistory.AddFileToHistory(path) # move up the list
296 self.config.SetPath("/ProfileMRU")
297 self.profileFileHistory.Save(self.config)
300 profile.loadProfile(path)
301 self.updateProfileToControls()
303 def addToProfileMRU(self, file):
304 self.profileFileHistory.AddFileToHistory(file)
305 self.config.SetPath("/ProfileMRU")
306 self.profileFileHistory.Save(self.config)
309 def updateProfileToControls(self):
310 self.scene.updateProfileToControls()
311 self.normalSettingsPanel.updateProfileToControls()
312 self.simpleSettingsPanel.updateProfileToControls()
314 def OnLoadProfile(self, e):
315 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)
316 dlg.SetWildcard("ini files (*.ini)|*.ini")
317 if dlg.ShowModal() == wx.ID_OK:
318 profileFile = dlg.GetPath()
319 profile.loadProfile(profileFile)
320 self.updateProfileToControls()
322 # Update the Profile MRU
323 self.addToProfileMRU(profileFile)
326 def OnLoadProfileFromGcode(self, e):
327 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)
328 dlg.SetWildcard("gcode files (*.gcode)|*.gcode;*.g")
329 if dlg.ShowModal() == wx.ID_OK:
330 gcodeFile = dlg.GetPath()
331 f = open(gcodeFile, 'r')
334 if line.startswith(';CURA_PROFILE_STRING:'):
335 profile.loadProfileFromString(line[line.find(':')+1:].strip())
338 self.updateProfileToControls()
340 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)
343 def OnSaveProfile(self, e):
344 dlg=wx.FileDialog(self, "Select profile file to save", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
345 dlg.SetWildcard("ini files (*.ini)|*.ini")
346 if dlg.ShowModal() == wx.ID_OK:
347 profileFile = dlg.GetPath()
348 profile.saveProfile(profileFile)
351 def OnResetProfile(self, e):
352 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)
353 result = dlg.ShowModal() == wx.ID_YES
356 profile.resetProfile()
357 self.updateProfileToControls()
359 def OnBatchRun(self, e):
360 br = batchRun.batchRunWindow(self)
364 def OnSimpleSwitch(self, e):
365 profile.putPreference('startMode', 'Simple')
366 self.updateSliceMode()
368 def OnNormalSwitch(self, e):
369 profile.putPreference('startMode', 'Normal')
370 self.updateSliceMode()
372 def OnDefaultMarlinFirmware(self, e):
373 firmwareInstall.InstallFirmware()
375 def OnCustomFirmware(self, e):
376 if profile.getPreference('machine_type') == 'ultimaker':
377 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)
378 dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
379 dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
380 if dlg.ShowModal() == wx.ID_OK:
381 filename = dlg.GetPath()
382 if not(os.path.exists(filename)):
384 #For some reason my Ubuntu 10.10 crashes here.
385 firmwareInstall.InstallFirmware(filename)
387 def OnFirstRunWizard(self, e):
388 configWizard.configWizard()
389 self.updateProfileToControls()
391 def OnBedLevelWizard(self, e):
392 configWizard.bedLevelWizard()
394 def OnHeadOffsetWizard(self, e):
395 configWizard.headOffsetWizard()
397 def OnExpertOpen(self, e):
398 ecw = expertConfig.expertConfigWindow(lambda : self.scene.sceneUpdated())
402 def OnMinecraftImport(self, e):
403 mi = minecraftImport.minecraftImportWindow(self)
407 def OnPIDDebugger(self, e):
408 debugger = pidDebugger.debuggerWindow(self)
412 def OnCheckForUpdate(self, e):
413 newVersion = version.checkForNewerVersion()
414 if newVersion is not None:
415 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:
416 webbrowser.open(newVersion)
418 wx.MessageBox('You are running the latest version of Cura!', 'Awesome!', wx.ICON_INFORMATION)
420 def OnAbout(self, e):
421 info = wx.AboutDialogInfo()
423 info.SetDescription('End solution for Open Source Fused Filament Fabrication 3D printing.')
424 info.SetWebSite('http://software.ultimaker.com/')
425 info.SetCopyright('Copyright (C) David Braam')
427 This program is free software: you can redistribute it and/or modify
428 it under the terms of the GNU Affero General Public License as published by
429 the Free Software Foundation, either version 3 of the License, or
430 (at your option) any later version.
432 This program is distributed in the hope that it will be useful,
433 but WITHOUT ANY WARRANTY; without even the implied warranty of
434 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
435 GNU Affero General Public License for more details.
437 You should have received a copy of the GNU Affero General Public License
438 along with this program. If not, see <http://www.gnu.org/licenses/>.
442 def OnClose(self, e):
443 profile.saveProfile(profile.getDefaultProfilePath())
445 # Save the window position, size & state from the preferences file
446 profile.putPreference('window_maximized', self.IsMaximized())
447 if not self.IsMaximized() and not self.IsIconized():
448 (posx, posy) = self.GetPosition()
449 profile.putPreference('window_pos_x', posx)
450 profile.putPreference('window_pos_y', posy)
451 (width, height) = self.GetSize()
452 profile.putPreference('window_width', width)
453 profile.putPreference('window_height', height)
455 # Save normal sash position. If in normal mode (!simple mode), get last position of sash before saving it...
456 isSimple = profile.getPreference('startMode') == 'Simple'
458 self.normalSashPos = self.splitter.GetSashPosition()
459 profile.putPreference('window_normal_sash', self.normalSashPos)
461 #HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which keeps wxWidgets from quiting.
463 self.scene.OnPaint = lambda e : e
464 self.scene._slicer.cleanup()
470 class normalSettingsPanel(configBase.configPanelBase):
471 "Main user interface window"
472 def __init__(self, parent, callback = None):
473 super(normalSettingsPanel, self).__init__(parent, callback)
476 self.nb = wx.Notebook(self)
477 self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
478 self.GetSizer().Add(self.nb, 1, wx.EXPAND)
480 (left, right, self.printPanel) = self.CreateDynamicConfigTab(self.nb, 'Basic')
481 self._addSettingsToPanels('basic', left, right)
482 self.SizeLabelWidths(left, right)
484 (left, right, self.advancedPanel) = self.CreateDynamicConfigTab(self.nb, 'Advanced')
485 self._addSettingsToPanels('advanced', left, right)
486 self.SizeLabelWidths(left, right)
489 self.pluginPanel = pluginPanel.pluginPanel(self.nb, callback)
490 if len(self.pluginPanel.pluginList) > 0:
491 self.nb.AddPage(self.pluginPanel, "Plugins")
493 self.pluginPanel.Show(False)
496 self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback)
497 self.nb.AddPage(self.alterationPanel, "Start/End-GCode")
499 self.Bind(wx.EVT_SIZE, self.OnSize)
501 self.nb.SetSize(self.GetSize())
502 self.UpdateSize(self.printPanel)
503 self.UpdateSize(self.advancedPanel)
505 def _addSettingsToPanels(self, category, left, right):
506 count = len(profile.getSubCategoriesFor(category)) + len(profile.getSettingsForCategory(category))
510 for title in profile.getSubCategoriesFor(category):
511 n += 1 + len(profile.getSettingsForCategory(category, title))
514 configBase.TitleRow(p, title)
515 for s in profile.getSettingsForCategory(category, title):
516 if s.checkConditions():
517 configBase.SettingRow(p, s.getName())
519 def SizeLabelWidths(self, left, right):
520 leftWidth = self.getLabelColumnWidth(left)
521 rightWidth = self.getLabelColumnWidth(right)
522 maxWidth = max(leftWidth, rightWidth)
523 self.setLabelColumnWidth(left, maxWidth)
524 self.setLabelColumnWidth(right, maxWidth)
527 # Make the size of the Notebook control the same size as this control
528 self.nb.SetSize(self.GetSize())
530 # Propegate the OnSize() event (just in case)
533 # Perform out resize magic
534 self.UpdateSize(self.printPanel)
535 self.UpdateSize(self.advancedPanel)
537 def UpdateSize(self, configPanel):
538 sizer = configPanel.GetSizer()
542 # if width(col1) < best_width(col1) || width(col2) < best_width(col2):
545 # if width(col1) > (best_width(col1) + best_width(col1)):
546 # switch to horizontal
549 col1 = configPanel.leftPanel
550 colSize1 = col1.GetSize()
551 colBestSize1 = col1.GetBestSize()
552 col2 = configPanel.rightPanel
553 colSize2 = col2.GetSize()
554 colBestSize2 = col2.GetBestSize()
556 orientation = sizer.GetOrientation()
558 if orientation == wx.HORIZONTAL:
559 if (colSize1[0] <= colBestSize1[0]) or (colSize2[0] <= colBestSize2[0]):
561 sizer = wx.BoxSizer(wx.VERTICAL)
562 sizer.Add(configPanel.leftPanel, flag=wx.EXPAND)
563 sizer.Add(configPanel.rightPanel, flag=wx.EXPAND)
564 configPanel.SetSizer(sizer)
570 if max(colSize1[0], colSize2[0]) > (colBestSize1[0] + colBestSize2[0]):
572 sizer = wx.BoxSizer(wx.HORIZONTAL)
573 sizer.Add(configPanel.leftPanel, proportion=1, border=35, flag=wx.EXPAND)
574 sizer.Add(configPanel.rightPanel, proportion=1, flag=wx.EXPAND)
575 configPanel.SetSizer(sizer)
581 def updateProfileToControls(self):
582 super(normalSettingsPanel, self).updateProfileToControls()
583 self.alterationPanel.updateProfileToControls()
584 self.pluginPanel.updateProfileToControls()