chiark / gitweb /
No longer allow to resize the preferences and expert config windows. Fixed #250....
[cura.git] / Cura / gui / configBase.py
1 from __future__ import absolute_import
2 import __init__
3
4 import wx, wx.lib.stattext, os, sys, platform, types
5
6 from util import validators
7 from util import profile
8
9 def main():
10         app = wx.App(False)
11         mainWindow()
12         app.MainLoop()
13
14 class configWindowBase(wx.Frame):
15         "A base class for configuration dialogs. Handles creation of settings, and popups"
16         def __init__(self, title, style=wx.DEFAULT_FRAME_STYLE):
17                 super(configWindowBase, self).__init__(None, title=title, style=style)
18                 
19                 self.settingControlList = []
20                 
21                 #Create the popup window
22                 self.popup = wx.PopupWindow(self, flags=wx.BORDER_SIMPLE)
23                 self.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
24                 self.popup.setting = None
25                 self.popup.text = wx.StaticText(self.popup, -1, '');
26                 self.popup.sizer = wx.BoxSizer()
27                 self.popup.sizer.Add(self.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
28                 self.popup.SetSizer(self.popup.sizer)
29         
30         def CreateConfigTab(self, nb, name):
31                 leftConfigPanel, rightConfigPanel, configPanel = self.CreateConfigPanel(nb)
32                 nb.AddPage(configPanel, name)
33                 return leftConfigPanel, rightConfigPanel
34         
35         def CreateConfigPanel(self, parent):
36                 configPanel = wx.Panel(parent);
37                 leftConfigPanel = wx.Panel(configPanel)
38                 rightConfigPanel = wx.Panel(configPanel)
39                 sizer = wx.GridBagSizer(2, 2)
40                 leftConfigPanel.SetSizer(sizer)
41                 sizer = wx.GridBagSizer(2, 2)
42                 rightConfigPanel.SetSizer(sizer)
43                 sizer = wx.BoxSizer(wx.HORIZONTAL)
44                 configPanel.SetSizer(sizer)
45                 sizer.Add(leftConfigPanel, border=35, flag=wx.RIGHT)
46                 sizer.Add(rightConfigPanel)
47                 leftConfigPanel.main = self
48                 rightConfigPanel.main = self
49                 return leftConfigPanel, rightConfigPanel, configPanel
50
51         def OnPopupDisplay(self, setting):
52                 self.popup.setting = setting
53                 self.UpdatePopup(setting)
54                 self.popup.Show(True)
55                 
56         def OnPopupHide(self, e):
57                 self.popup.Show(False)
58         
59         def UpdatePopup(self, setting):
60                 if self.popup.setting == setting:
61                         if setting.validationMsg != '':
62                                 self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.helpText)
63                         else:
64                                 self.popup.text.SetLabel(setting.helpText)
65                         self.popup.text.Wrap(350)
66                         self.popup.Fit()
67                         x, y = setting.ctrl.ClientToScreenXY(0, 0)
68                         sx, sy = setting.ctrl.GetSizeTuple()
69                         #if platform.system() == "Windows":
70                         #       for some reason, under windows, the popup is relative to the main window... in some cases. (Wierd ass bug)
71                         #       wx, wy = self.ClientToScreenXY(0, 0)
72                         #       x -= wx
73                         #       y -= wy
74                         self.popup.SetPosition((x, y+sy))
75         
76         def updateProfileToControls(self):
77                 "Update the configuration wx controls to show the new configuration settings"
78                 for setting in self.settingControlList:
79                         if setting.type == 'profile':
80                                 setting.SetValue(profile.getProfileSetting(setting.configName))
81                         else:
82                                 setting.SetValue(profile.getPreference(setting.configName))
83                 self.Update()
84
85 class TitleRow():
86         def __init__(self, panel, name):
87                 "Add a title row to the configuration panel"
88                 sizer = panel.GetSizer()
89                 x = sizer.GetRows()
90                 self.title = wx.StaticText(panel, -1, name)
91                 self.title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
92                 sizer.Add(self.title, (x,0), (1,3), flag=wx.EXPAND|wx.TOP|wx.LEFT, border=10)
93                 sizer.Add(wx.StaticLine(panel), (x+1,0), (1,3), flag=wx.EXPAND|wx.LEFT,border=10)
94                 sizer.SetRows(x + 2)
95
96 class SettingRow():
97         def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO', type = 'profile'):
98                 "Add a setting to the configuration panel"
99                 sizer = panel.GetSizer()
100                 x = sizer.GetRows()
101                 y = 0
102                 flag = 0
103                 
104                 self.validators = []
105                 self.validationMsg = ''
106                 self.helpText = helpText
107                 self.configName = configName
108                 self.panel = panel
109                 self.type = type
110
111                 self.label = wx.lib.stattext.GenStaticText(panel, -1, label)
112                 self.label.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
113                 self.label.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
114
115                 getSettingFunc = profile.getPreference
116                 if self.type == 'profile':
117                         getSettingFunc = profile.getProfileSetting
118                 if isinstance(defaultValue, types.StringTypes):
119                         self.ctrl = wx.TextCtrl(panel, -1, getSettingFunc(configName))
120                         self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)
121                         flag = wx.EXPAND
122                 elif isinstance(defaultValue, types.BooleanType):
123                         self.ctrl = wx.CheckBox(panel, -1, style=wx.ALIGN_RIGHT)
124                         self.SetValue(getSettingFunc(configName))
125                         self.ctrl.Bind(wx.EVT_CHECKBOX, self.OnSettingChange)
126                 elif isinstance(defaultValue, wx.Colour):
127                         self.ctrl = wx.ColourPickerCtrl(panel, -1)
128                         self.SetValue(getSettingFunc(configName))
129                         self.ctrl.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnSettingChange)
130                 else:
131                         self.ctrl = wx.ComboBox(panel, -1, getSettingFunc(configName), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
132                         self.ctrl.Bind(wx.EVT_COMBOBOX, self.OnSettingChange)
133                         self.ctrl.Bind(wx.EVT_LEFT_DOWN, self.OnMouseExit)
134                         flag = wx.EXPAND
135
136                 sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT,border=10)
137                 sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|flag)
138                 sizer.SetRows(x+1)
139
140                 self.ctrl.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
141                 self.ctrl.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
142                 
143                 self.defaultBGColour = self.ctrl.GetBackgroundColour()
144                 
145                 panel.main.settingControlList.append(self)
146
147         def OnMouseEnter(self, e):
148                 self.panel.main.OnPopupDisplay(self)
149
150         def OnMouseExit(self, e):
151                 self.panel.main.OnPopupHide(self)
152                 e.Skip()
153
154         def OnSettingChange(self, e):
155                 if self.type == 'profile':
156                         profile.putProfileSetting(self.configName, self.GetValue())
157                 else:
158                         profile.putPreference(self.configName, self.GetValue())
159                 result = validators.SUCCESS
160                 msgs = []
161                 for validator in self.validators:
162                         res, err = validator.validate()
163                         if res == validators.ERROR:
164                                 result = res
165                         elif res == validators.WARNING and result != validators.ERROR:
166                                 result = res
167                         if res != validators.SUCCESS:
168                                 msgs.append(err)
169                 if result == validators.ERROR:
170                         self.ctrl.SetBackgroundColour('Red')
171                 elif result == validators.WARNING:
172                         self.ctrl.SetBackgroundColour('Yellow')
173                 else:
174                         self.ctrl.SetBackgroundColour(self.defaultBGColour)
175                 self.ctrl.Refresh()
176
177                 self.validationMsg = '\n'.join(msgs)
178                 self.panel.main.UpdatePopup(self)
179
180         def GetValue(self):
181                 if isinstance(self.ctrl, wx.ColourPickerCtrl):
182                         return str(self.ctrl.GetColour().GetAsString(wx.C2S_HTML_SYNTAX))
183                 else:
184                         return str(self.ctrl.GetValue())
185
186         def SetValue(self, value):
187                 if isinstance(self.ctrl, wx.CheckBox):
188                         self.ctrl.SetValue(str(value) == "True")
189                 elif isinstance(self.ctrl, wx.ColourPickerCtrl):
190                         self.ctrl.SetColour(value)
191                 else:
192                         self.ctrl.SetValue(value)
193
194 #Settings notify works as a validator, but instead of validating anything, it calls another function, which can use the value.
195 # A bit hacky, bit it works.
196 class settingNotify():
197         def __init__(self, setting, func):
198                 self.setting = setting
199                 self.setting.validators.append(self)
200                 self.func = func
201         
202         def validate(self):
203                 self.func()
204                 return validators.SUCCESS, ''
205