1 from __future__ import absolute_import
3 import wx, wx.lib.stattext, types
5 from Cura.util import validators
6 from Cura.util import profile
8 class configPanelBase(wx.Panel):
9 "A base class for configuration dialogs. Handles creation of settings, and popups"
10 def __init__(self, parent):
11 super(configPanelBase, self).__init__(parent)
13 self.settingControlList = []
15 #Create the popup window
16 self.popup = wx.PopupWindow(self, flags=wx.BORDER_SIMPLE)
17 self.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
18 self.popup.setting = None
19 self.popup.text = wx.StaticText(self.popup, -1, '');
20 self.popup.sizer = wx.BoxSizer()
21 self.popup.sizer.Add(self.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
22 self.popup.SetSizer(self.popup.sizer)
24 def CreateConfigTab(self, nb, name):
25 leftConfigPanel, rightConfigPanel, configPanel = self.CreateConfigPanel(nb)
26 nb.AddPage(configPanel, name)
27 return leftConfigPanel, rightConfigPanel
29 def CreateConfigPanel(self, parent):
30 configPanel = wx.Panel(parent);
31 leftConfigPanel = wx.Panel(configPanel)
32 rightConfigPanel = wx.Panel(configPanel)
33 sizer = wx.GridBagSizer(2, 2)
34 leftConfigPanel.SetSizer(sizer)
35 sizer = wx.GridBagSizer(2, 2)
36 rightConfigPanel.SetSizer(sizer)
37 sizer = wx.BoxSizer(wx.HORIZONTAL)
38 configPanel.SetSizer(sizer)
39 sizer.Add(leftConfigPanel, border=35, flag=wx.RIGHT)
40 sizer.Add(rightConfigPanel)
41 leftConfigPanel.main = self
42 rightConfigPanel.main = self
43 return leftConfigPanel, rightConfigPanel, configPanel
45 def CreateSimpleConfigTab(self, nb, name):
46 leftConfigPanel, configPanel = self.CreateSimpleConfigPanel(nb)
47 nb.AddPage(configPanel, name)
48 return leftConfigPanel
50 def CreateSimpleConfigPanel(self, parent):
51 configPanel = wx.lib.scrolledpanel.ScrolledPanel(parent)
52 leftConfigPanel = wx.Panel(configPanel)
54 sizer = wx.GridBagSizer(2, 2)
55 leftConfigPanel.SetSizer(sizer)
56 sizer.AddGrowableCol(1)
58 sizer = wx.BoxSizer(wx.HORIZONTAL)
59 configPanel.SetSizer(sizer)
60 sizer.Add(leftConfigPanel, 1, wx.EXPAND)
62 configPanel.SetAutoLayout(1)
63 configPanel.SetupScrolling()
65 leftConfigPanel.main = self
66 return leftConfigPanel, configPanel
68 def OnPopupDisplay(self, setting):
69 self.popup.setting = setting
70 self.UpdatePopup(setting)
73 def OnPopupHide(self, e):
74 self.popup.Show(False)
76 def UpdatePopup(self, setting):
77 if self.popup.setting == setting:
78 if setting.validationMsg != '':
79 self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.helpText)
81 self.popup.text.SetLabel(setting.helpText)
82 self.popup.text.Wrap(350)
84 x, y = setting.ctrl.ClientToScreenXY(0, 0)
85 sx, sy = setting.ctrl.GetSizeTuple()
86 #if platform.system() == "Windows":
87 # for some reason, under windows, the popup is relative to the main window... in some cases. (Wierd ass bug)
88 # wx, wy = self.ClientToScreenXY(0, 0)
91 self.popup.SetPosition((x, y+sy))
93 def updateProfileToControls(self):
94 "Update the configuration wx controls to show the new configuration settings"
95 for setting in self.settingControlList:
96 if setting.type == 'profile':
97 setting.SetValue(profile.getProfileSetting(setting.configName))
99 setting.SetValue(profile.getPreference(setting.configName))
103 def __init__(self, panel, name):
104 "Add a title row to the configuration panel"
105 sizer = panel.GetSizer()
107 self.title = wx.StaticText(panel, -1, name)
108 self.title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
109 sizer.Add(self.title, (x,0), (1,3), flag=wx.EXPAND|wx.TOP|wx.LEFT, border=10)
110 sizer.Add(wx.StaticLine(panel), (x+1,0), (1,3), flag=wx.EXPAND|wx.LEFT,border=10)
114 def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO', type = 'profile'):
115 "Add a setting to the configuration panel"
116 sizer = panel.GetSizer()
122 self.validationMsg = ''
123 self.helpText = helpText
124 self.configName = configName
128 self.label = wx.lib.stattext.GenStaticText(panel, -1, label)
129 self.label.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
130 self.label.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
132 getSettingFunc = profile.getPreference
133 if self.type == 'profile':
134 getSettingFunc = profile.getProfileSetting
135 if isinstance(defaultValue, types.StringTypes):
136 self.ctrl = wx.TextCtrl(panel, -1, getSettingFunc(configName))
137 self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)
139 elif isinstance(defaultValue, types.BooleanType):
140 self.ctrl = wx.CheckBox(panel, -1, style=wx.ALIGN_RIGHT)
141 self.SetValue(getSettingFunc(configName))
142 self.ctrl.Bind(wx.EVT_CHECKBOX, self.OnSettingChange)
143 elif isinstance(defaultValue, wx.Colour):
144 self.ctrl = wx.ColourPickerCtrl(panel, -1)
145 self.SetValue(getSettingFunc(configName))
146 self.ctrl.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnSettingChange)
148 self.ctrl = wx.ComboBox(panel, -1, getSettingFunc(configName), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
149 self.ctrl.Bind(wx.EVT_COMBOBOX, self.OnSettingChange)
150 self.ctrl.Bind(wx.EVT_LEFT_DOWN, self.OnMouseExit)
153 sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT,border=10)
154 sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|flag)
157 self.ctrl.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
158 self.ctrl.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
160 self.defaultBGColour = self.ctrl.GetBackgroundColour()
162 panel.main.settingControlList.append(self)
164 def OnMouseEnter(self, e):
165 self.panel.main.OnPopupDisplay(self)
167 def OnMouseExit(self, e):
168 self.panel.main.OnPopupHide(self)
171 def OnSettingChange(self, e):
172 if self.type == 'profile':
173 profile.putProfileSetting(self.configName, self.GetValue())
175 profile.putPreference(self.configName, self.GetValue())
176 result = validators.SUCCESS
178 for validator in self.validators:
179 res, err = validator.validate()
180 if res == validators.ERROR:
182 elif res == validators.WARNING and result != validators.ERROR:
184 if res != validators.SUCCESS:
186 if result == validators.ERROR:
187 self.ctrl.SetBackgroundColour('Red')
188 elif result == validators.WARNING:
189 self.ctrl.SetBackgroundColour('Yellow')
191 self.ctrl.SetBackgroundColour(self.defaultBGColour)
194 self.validationMsg = '\n'.join(msgs)
195 self.panel.main.UpdatePopup(self)
198 if isinstance(self.ctrl, wx.ColourPickerCtrl):
199 return str(self.ctrl.GetColour().GetAsString(wx.C2S_HTML_SYNTAX))
201 return str(self.ctrl.GetValue())
203 def SetValue(self, value):
204 if isinstance(self.ctrl, wx.CheckBox):
205 self.ctrl.SetValue(str(value) == "True")
206 elif isinstance(self.ctrl, wx.ColourPickerCtrl):
207 self.ctrl.SetColour(value)
209 self.ctrl.SetValue(value)
211 #Settings notify works as a validator, but instead of validating anything, it calls another function, which can use the value.
212 # A bit hacky, bit it works.
213 class settingNotify():
214 def __init__(self, setting, func):
215 self.setting = setting
216 self.setting.validators.append(self)
221 return validators.SUCCESS, ''