]>
Commit | Line | Data |
---|---|---|
d14a1e28 RD |
1 | # Name: params.py |
2 | # Purpose: Classes for parameter introduction | |
3 | # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> | |
4 | # Created: 22.08.2001 | |
5 | # RCS-ID: $Id$ | |
6 | ||
7 | import string | |
8 | import os.path | |
9 | from globals import * | |
10 | from types import * | |
d14a1e28 | 11 | |
b2371711 | 12 | genericStyles = [ |
306b6fe9 | 13 | 'wxSIMPLE_BORDER', 'wxSUNKEN_BORDER', 'wxDOUBLE_BORDER', |
64bce500 | 14 | 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER', |
306b6fe9 RR |
15 | 'wxCLIP_CHILDREN', 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', |
16 | 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE' | |
64bce500 RR |
17 | ] |
18 | ||
19 | genericExStyles = [ | |
20 | 'wxWS_EX_VALIDATE_RECURSIVELY', | |
b2371711 | 21 | 'wxWS_EX_BLOCK_EVENTS', |
64bce500 RR |
22 | 'wxWS_EX_TRANSIENT', |
23 | 'wxFRAME_EX_CONTEXTHELP', | |
24 | 'wxWS_EX_PROCESS_IDLE', | |
25 | 'wxWS_EX_PROCESS_UI_UPDATES' | |
26 | ] | |
d14a1e28 | 27 | |
b372319f RR |
28 | # Global var initialized in Panel.__init__ for button size in screen pixels |
29 | buttonSize = None | |
30 | # Button size in dialog units | |
31 | buttonSizeD = (35,-1) | |
d14a1e28 RD |
32 | |
33 | # Class that can properly disable children | |
29a41103 | 34 | class PPanel(wx.Panel): |
d14a1e28 | 35 | def __init__(self, parent, name): |
29a41103 | 36 | wx.Panel.__init__(self, parent, -1, name=name) |
d14a1e28 RD |
37 | self.modified = self.freeze = False |
38 | def Enable(self, value): | |
f2ccaa22 | 39 | self.enabled = value |
d14a1e28 RD |
40 | # Something strange is going on with enable so we make sure... |
41 | for w in self.GetChildren(): | |
42 | w.Enable(value) | |
29a41103 | 43 | #wx.Panel.Enable(self, value) |
7df24e78 RR |
44 | def SetModified(self, state=True): |
45 | self.modified = state | |
46 | if state: g.panel.SetModified(True) | |
d14a1e28 RD |
47 | # Common method to set modified state |
48 | def OnChange(self, evt): | |
49 | if self.freeze: return | |
50 | self.SetModified() | |
51 | evt.Skip() | |
52 | ||
53 | class ParamBinaryOr(PPanel): | |
54 | def __init__(self, parent, name): | |
55 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
56 | self.ID_TEXT_CTRL = wx.NewId() |
57 | self.ID_BUTTON_CHOICES = wx.NewId() | |
58 | sizer = wx.BoxSizer() | |
59 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1)) | |
60 | sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) | |
61 | self.button = wx.Button(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize) | |
62 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) | |
b372319f | 63 | self.SetSizer(sizer) |
29a41103 RD |
64 | wx.EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices) |
65 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
d14a1e28 RD |
66 | def GetValue(self): |
67 | return self.text.GetValue() | |
68 | def SetValue(self, value): | |
69 | self.freeze = True | |
70 | self.text.SetValue(value) | |
71 | self.freeze = False | |
72 | def OnButtonChoices(self, evt): | |
a4c013b2 | 73 | dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES') |
c032d94e RR |
74 | if self.GetName() == 'flag': dlg.SetTitle('Sizer item flags') |
75 | elif self.GetName() == 'style': dlg.SetTitle('Window styles') | |
76 | elif self.GetName() == 'exstyle': dlg.SetTitle('Extended window styles') | |
29a41103 | 77 | listBox = xrc.XRCCTRL(dlg, 'CHECKLIST') |
a4c013b2 | 78 | listBox.InsertItems(self.values, 0) |
d14a1e28 RD |
79 | value = map(string.strip, self.text.GetValue().split('|')) |
80 | if value == ['']: value = [] | |
81 | ignored = [] | |
82 | for i in value: | |
83 | try: | |
84 | listBox.Check(self.values.index(i)) | |
85 | except ValueError: | |
86 | # Try to find equal | |
87 | if self.equal.has_key(i): | |
88 | listBox.Check(self.values.index(self.equal[i])) | |
89 | else: | |
90 | print 'WARNING: unknown flag: %s: ignored.' % i | |
91 | ignored.append(i) | |
29a41103 | 92 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 | 93 | value = [] |
31f04352 | 94 | for i in range(listBox.GetCount()): |
d14a1e28 RD |
95 | if listBox.IsChecked(i): |
96 | value.append(self.values[i]) | |
97 | # Add ignored flags | |
98 | value.extend(ignored) | |
c37cba89 | 99 | self.SetValue('|'.join(value)) |
d14a1e28 RD |
100 | self.SetModified() |
101 | dlg.Destroy() | |
102 | ||
103 | class ParamFlag(ParamBinaryOr): | |
104 | values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', | |
306b6fe9 RR |
105 | 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxSTRETCH_NOT', |
106 | 'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT', | |
107 | 'wxALIGN_TOP', 'wxALIGN_BOTTOM', | |
108 | 'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL', | |
109 | 'wxADJUST_MINSIZE', 'wxFIXED_MINSIZE' | |
9abdd2cb | 110 | ] |
d14a1e28 RD |
111 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', |
112 | 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', | |
306b6fe9 RR |
113 | 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL', |
114 | 'wxUP': 'wxTOP', 'wxDOWN': 'wxBOTTOM', 'wxNORTH': 'wxTOP', | |
115 | 'wxSOUTH': 'wxBOTTOM', 'wxWEST': 'wxLEFT', 'wxEAST': 'wxRIGHT'} | |
d14a1e28 RD |
116 | def __init__(self, parent, name): |
117 | ParamBinaryOr.__init__(self, parent, name) | |
118 | ||
c032d94e | 119 | class ParamNonGenericStyle(ParamBinaryOr): |
d14a1e28 | 120 | def __init__(self, parent, name): |
c032d94e | 121 | self.values = g.currentXXX.winStyles |
d14a1e28 RD |
122 | ParamBinaryOr.__init__(self, parent, name) |
123 | ||
c032d94e RR |
124 | class ParamStyle(ParamBinaryOr): |
125 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} | |
d14a1e28 | 126 | def __init__(self, parent, name): |
d14a1e28 | 127 | ParamBinaryOr.__init__(self, parent, name) |
c032d94e RR |
128 | self.valuesSpecific = g.currentXXX.winStyles |
129 | if self.valuesSpecific: # override if using specific styles | |
130 | # Remove duplicates | |
131 | self.valuesGeneric = [s for s in genericStyles | |
132 | if s not in self.valuesSpecific] | |
29a41103 | 133 | wx.EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoicesBoth) |
c032d94e RR |
134 | else: |
135 | self.values = genericStyles | |
136 | def OnButtonChoicesBoth(self, evt): | |
137 | dlg = g.frame.res.LoadDialog(self, 'DIALOG_STYLES') | |
29a41103 | 138 | listBoxSpecific = xrc.XRCCTRL(dlg, 'CHECKLIST_SPECIFIC') |
c032d94e | 139 | listBoxSpecific.InsertItems(self.valuesSpecific, 0) |
29a41103 | 140 | listBoxGeneric = xrc.XRCCTRL(dlg, 'CHECKLIST_GENERIC') |
c032d94e RR |
141 | listBoxGeneric.InsertItems(self.valuesGeneric, 0) |
142 | value = map(string.strip, self.text.GetValue().split('|')) | |
143 | if value == ['']: value = [] | |
144 | # Set specific styles | |
145 | value2 = [] # collect generic and ignored here | |
146 | for i in value: | |
147 | try: | |
148 | listBoxSpecific.Check(self.valuesSpecific.index(i)) | |
149 | except ValueError: | |
150 | # Try to find equal | |
151 | if self.equal.has_key(i): | |
152 | listBoxSpecific.Check(self.valuesSpecific.index(self.equal[i])) | |
153 | else: | |
154 | value2.append(i) | |
155 | ignored = [] | |
156 | # Set generic styles, collect non-standart values | |
157 | for i in value2: | |
158 | try: | |
159 | listBoxGeneric.Check(self.valuesGeneric.index(i)) | |
160 | except ValueError: | |
161 | # Try to find equal | |
162 | if self.equal.has_key(i): | |
163 | listBoxGeneric.Check(self.valuesGeneric.index(self.equal[i])) | |
164 | else: | |
165 | print 'WARNING: unknown flag: %s: ignored.' % i | |
166 | ignored.append(i) | |
29a41103 | 167 | if dlg.ShowModal() == wx.ID_OK: |
c032d94e RR |
168 | value = [self.valuesSpecific[i] |
169 | for i in range(listBoxSpecific.GetCount()) | |
170 | if listBoxSpecific.IsChecked(i)] + \ | |
171 | [self.valuesGeneric[i] | |
172 | for i in range(listBoxGeneric.GetCount()) | |
173 | if listBoxGeneric.IsChecked(i)] + ignored | |
c37cba89 | 174 | self.SetValue('|'.join(value)) |
c032d94e RR |
175 | self.SetModified() |
176 | dlg.Destroy() | |
d14a1e28 RD |
177 | |
178 | class ParamExStyle(ParamBinaryOr): | |
179 | def __init__(self, parent, name): | |
180 | if g.currentXXX: | |
64bce500 | 181 | self.values = g.currentXXX.exStyles + genericExStyles |
d14a1e28 RD |
182 | else: |
183 | self.values = [] | |
184 | ParamBinaryOr.__init__(self, parent, name) | |
185 | ||
186 | class ParamColour(PPanel): | |
187 | def __init__(self, parent, name): | |
188 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
189 | self.ID_TEXT_CTRL = wx.NewId() |
190 | self.ID_BUTTON = wx.NewId() | |
191 | sizer = wx.BoxSizer() | |
192 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(80,-1)) | |
193 | sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2) | |
194 | self.button = wx.Panel(self, self.ID_BUTTON, wx.DefaultPosition, wx.Size(20, 20)) | |
195 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5) | |
b372319f | 196 | self.SetSizer(sizer) |
d14a1e28 | 197 | self.textModified = False |
29a41103 RD |
198 | wx.EVT_PAINT(self.button, self.OnPaintButton) |
199 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
200 | wx.EVT_LEFT_DOWN(self.button, self.OnLeftDown) | |
d14a1e28 RD |
201 | def GetValue(self): |
202 | return self.text.GetValue() | |
203 | def SetValue(self, value): | |
204 | self.freeze = True | |
205 | if not value: value = '#FFFFFF' | |
206 | self.text.SetValue(str(value)) # update text ctrl | |
99328372 | 207 | try: |
29a41103 | 208 | colour = wx.Colour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16)) |
99328372 RR |
209 | self.button.SetBackgroundColour(colour) |
210 | except: # ignore errors | |
211 | pass | |
d14a1e28 RD |
212 | self.button.Refresh() |
213 | self.freeze = False | |
214 | def OnPaintButton(self, evt): | |
29a41103 RD |
215 | dc = wx.PaintDC(self.button) |
216 | dc.SetBrush(wx.TRANSPARENT_BRUSH) | |
217 | if self.IsEnabled(): dc.SetPen(wx.BLACK_PEN) | |
218 | else: dc.SetPen(wx.GREY_PEN) | |
d14a1e28 | 219 | size = self.button.GetSize() |
b09afc93 | 220 | dc.DrawRectangle(0, 0, size.width, size.height) |
d14a1e28 | 221 | def OnLeftDown(self, evt): |
29a41103 | 222 | data = wx.ColourData() |
d14a1e28 | 223 | data.SetColour(self.GetValue()) |
29a41103 RD |
224 | dlg = wx.ColourDialog(self, data) |
225 | if dlg.ShowModal() == wx.ID_OK: | |
d14a1e28 RD |
226 | self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get()) |
227 | self.SetModified() | |
228 | dlg.Destroy() | |
229 | ||
230 | ################################################################################ | |
231 | ||
f65bb0f8 | 232 | # Mapping from wx constants to XML strings |
29a41103 RD |
233 | fontFamiliesWx2Xml = {wx.DEFAULT: 'default', wx.DECORATIVE: 'decorative', |
234 | wx.ROMAN: 'roman', wx.SCRIPT: 'script', wx.SWISS: 'swiss', | |
235 | wx.MODERN: 'modern'} | |
236 | fontStylesWx2Xml = {wx.NORMAL: 'normal', wx.SLANT: 'slant', wx.ITALIC: 'italic'} | |
237 | fontWeightsWx2Xml = {wx.NORMAL: 'normal', wx.LIGHT: 'light', wx.BOLD: 'bold'} | |
d14a1e28 RD |
238 | def ReverseMap(m): |
239 | rm = {} | |
240 | for k,v in m.items(): rm[v] = k | |
241 | return rm | |
242 | fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml) | |
243 | fontStylesXml2wx = ReverseMap(fontStylesWx2Xml) | |
244 | fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml) | |
245 | ||
246 | class ParamFont(PPanel): | |
247 | def __init__(self, parent, name): | |
248 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
249 | self.ID_TEXT_CTRL = wx.NewId() |
250 | self.ID_BUTTON_SELECT = wx.NewId() | |
251 | sizer = wx.BoxSizer() | |
252 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(200,-1)) | |
253 | sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) | |
254 | self.button = wx.Button(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize) | |
255 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) | |
b372319f | 256 | self.SetSizer(sizer) |
d14a1e28 | 257 | self.textModified = False |
29a41103 RD |
258 | wx.EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect) |
259 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
d14a1e28 RD |
260 | def OnChange(self, evt): |
261 | PPanel.OnChange(self, evt) | |
262 | self.textModified = True | |
263 | def _defaultValue(self): | |
306b6fe9 | 264 | return [`g._sysFont.GetPointSize()`, 'default', 'normal', 'normal', '0', '', ''] |
d14a1e28 RD |
265 | def GetValue(self): |
266 | if self.textModified: # text has newer value | |
267 | try: | |
268 | return eval(self.text.GetValue()) | |
269 | except SyntaxError: | |
29a41103 | 270 | wx.LogError('Syntax error in parameter value: ' + self.GetName()) |
d14a1e28 RD |
271 | return self._defaultValue() |
272 | return self.value | |
273 | def SetValue(self, value): | |
274 | self.freeze = True # disable other handlers | |
275 | if not value: value = self._defaultValue() | |
276 | self.value = value | |
277 | self.text.SetValue(str(value)) # update text ctrl | |
278 | self.freeze = False | |
279 | def OnButtonSelect(self, evt): | |
280 | if self.textModified: # text has newer value | |
281 | try: | |
282 | self.value = eval(self.text.GetValue()) | |
283 | except SyntaxError: | |
29a41103 | 284 | wx.LogError('Syntax error in parameter value: ' + self.GetName()) |
d14a1e28 RD |
285 | self.value = self._defaultValue() |
286 | # Make initial font | |
287 | # Default values | |
306b6fe9 | 288 | size = g._sysFont.GetPointSize() |
29a41103 RD |
289 | family = wx.DEFAULT |
290 | style = weight = wx.NORMAL | |
d14a1e28 RD |
291 | underlined = 0 |
292 | face = '' | |
29a41103 | 293 | enc = wx.FONTENCODING_DEFAULT |
d14a1e28 RD |
294 | # Fall back to default if exceptions |
295 | error = False | |
296 | try: | |
297 | try: size = int(self.value[0]) | |
29a41103 | 298 | except ValueError: error = True; wx.LogError('Invalid size specification') |
d14a1e28 | 299 | try: family = fontFamiliesXml2wx[self.value[1]] |
29a41103 | 300 | except KeyError: error = True; wx.LogError('Invalid family specification') |
d14a1e28 | 301 | try: style = fontStylesXml2wx[self.value[2]] |
29a41103 | 302 | except KeyError: error = True; wx.LogError('Invalid style specification') |
d14a1e28 | 303 | try: weight = fontWeightsXml2wx[self.value[3]] |
29a41103 | 304 | except KeyError: error = True; wx.LogError('Invalid weight specification') |
016f67ba | 305 | try: underlined = bool(self.value[4]) |
29a41103 | 306 | except ValueError: error = True; wx.LogError('Invalid underlined flag specification') |
d14a1e28 | 307 | face = self.value[5] |
d14a1e28 RD |
308 | except IndexError: |
309 | error = True | |
29a41103 | 310 | mapper = wx.FontMapper() |
016f67ba RR |
311 | if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6]) |
312 | ||
29a41103 RD |
313 | if error: wx.LogError('Invalid font specification') |
314 | if enc == wx.FONTENCODING_DEFAULT: enc = wx.FONTENCODING_SYSTEM | |
315 | font = wx.Font(size, family, style, weight, underlined, face, enc) | |
316 | data = wx.FontData() | |
d14a1e28 | 317 | data.SetInitialFont(font) |
29a41103 RD |
318 | dlg = wx.FontDialog(self, data) |
319 | if dlg.ShowModal() == wx.ID_OK: | |
d14a1e28 | 320 | font = dlg.GetFontData().GetChosenFont() |
29a41103 | 321 | if font.GetEncoding() == wx.FONTENCODING_SYSTEM: |
016f67ba RR |
322 | encName = '' |
323 | else: | |
29a41103 | 324 | encName = wx.FontMapper.GetEncodingName(font.GetEncoding()).encode() |
d14a1e28 RD |
325 | value = [str(font.GetPointSize()), |
326 | fontFamiliesWx2Xml.get(font.GetFamily(), "default"), | |
327 | fontStylesWx2Xml.get(font.GetStyle(), "normal"), | |
328 | fontWeightsWx2Xml.get(font.GetWeight(), "normal"), | |
0d9b8891 | 329 | str(int(font.GetUnderlined())), |
d14a1e28 | 330 | font.GetFaceName().encode(), |
016f67ba | 331 | encName |
d14a1e28 | 332 | ] |
d14a1e28 RD |
333 | self.SetValue(value) |
334 | self.SetModified() | |
335 | self.textModified = False | |
336 | dlg.Destroy() | |
337 | ||
338 | ################################################################################ | |
339 | ||
340 | class ParamInt(PPanel): | |
341 | def __init__(self, parent, name): | |
342 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
343 | self.ID_SPIN_CTRL = wx.NewId() |
344 | sizer = wx.BoxSizer() | |
345 | self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1)) | |
c032d94e RR |
346 | self.spin.SetRange(-2147483648, 2147483647) # min/max integers |
347 | sizer.Add(self.spin) | |
b372319f | 348 | self.SetSizer(sizer) |
29a41103 | 349 | wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) |
c032d94e RR |
350 | def GetValue(self): |
351 | return str(self.spin.GetValue()) | |
352 | def SetValue(self, value): | |
353 | self.freeze = True | |
354 | if not value: value = 0 | |
355 | self.spin.SetValue(int(value)) | |
356 | self.freeze = False | |
357 | ||
358 | # Non-negative number | |
359 | class ParamIntNN(PPanel): | |
360 | def __init__(self, parent, name): | |
361 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
362 | self.ID_SPIN_CTRL = wx.NewId() |
363 | sizer = wx.BoxSizer() | |
364 | self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1)) | |
c032d94e | 365 | self.spin.SetRange(0, 10000) # min/max integers |
d14a1e28 | 366 | sizer.Add(self.spin) |
b372319f | 367 | self.SetSizer(sizer) |
29a41103 | 368 | wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) |
d14a1e28 RD |
369 | def GetValue(self): |
370 | return str(self.spin.GetValue()) | |
371 | def SetValue(self, value): | |
372 | self.freeze = True | |
373 | if not value: value = 0 | |
374 | self.spin.SetValue(int(value)) | |
375 | self.freeze = False | |
376 | ||
377 | # Same as int but allows dialog units (XXXd) | |
378 | class ParamUnit(PPanel): | |
379 | def __init__(self, parent, name): | |
380 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
381 | self.ID_TEXT_CTRL = wx.NewId() |
382 | self.ID_SPIN_BUTTON = wx.NewId() | |
383 | sizer = wx.BoxSizer(wx.HORIZONTAL) | |
e2dc45d8 | 384 | self.spin = wx.SpinButton(self, self.ID_SPIN_BUTTON, style = wx.SP_VERTICAL, size=(-1,0)) |
c032d94e | 385 | textW = 60 - self.spin.GetSize()[0] |
29a41103 | 386 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(textW,-1)) |
d14a1e28 | 387 | self.spin.SetRange(-10000, 10000) |
29a41103 RD |
388 | sizer.Add(self.text, 0, wx.EXPAND) |
389 | sizer.Add(self.spin, 0, wx.EXPAND) | |
b372319f | 390 | self.SetSizer(sizer) |
538a0c0d RR |
391 | self.spin.Bind(wx.EVT_SPIN_UP, self.OnSpinUp) |
392 | self.spin.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown) | |
d14a1e28 RD |
393 | def GetValue(self): |
394 | return self.text.GetValue() | |
395 | def SetValue(self, value): | |
538a0c0d | 396 | if not value: value = '0' |
d14a1e28 | 397 | self.text.SetValue(value) |
538a0c0d | 398 | self.Change(0) |
d14a1e28 | 399 | def Change(self, x): |
538a0c0d | 400 | self.freeze = True |
d14a1e28 RD |
401 | # Check if we are working with dialog units |
402 | value = self.text.GetValue() | |
403 | units = '' | |
404 | if value[-1].upper() == 'D': | |
405 | units = value[-1] | |
406 | value = value[:-1] | |
407 | try: | |
408 | intValue = int(value) + x | |
409 | self.spin.SetValue(intValue) | |
538a0c0d RR |
410 | if x: # 0 can be passed to update spin value only |
411 | self.text.SetValue(str(intValue) + units) | |
412 | self.SetModified() | |
d14a1e28 | 413 | except: |
29a41103 | 414 | # !!! Strange, if I use wx.LogWarning, event is re-generated |
7df24e78 | 415 | print 'ERROR: incorrect unit format' |
538a0c0d | 416 | self.freeze = False |
d14a1e28 | 417 | def OnSpinUp(self, evt): |
538a0c0d | 418 | self.freeze = True |
d14a1e28 RD |
419 | self.Change(1) |
420 | def OnSpinDown(self, evt): | |
538a0c0d RR |
421 | if self.freeze: return |
422 | self.freeze = True | |
d14a1e28 RD |
423 | self.Change(-1) |
424 | ||
d14a1e28 RD |
425 | class ParamMultilineText(PPanel): |
426 | def __init__(self, parent, name, textWidth=-1): | |
427 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
428 | self.ID_TEXT_CTRL = wx.NewId() |
429 | self.ID_BUTTON_EDIT = wx.NewId() | |
430 | sizer = wx.BoxSizer() | |
431 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1)) | |
432 | sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) | |
433 | self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) | |
434 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) | |
538a0c0d | 435 | self.SetSizerAndFit(sizer) |
29a41103 RD |
436 | wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) |
437 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
d14a1e28 RD |
438 | def GetValue(self): |
439 | return self.text.GetValue() | |
440 | def SetValue(self, value): | |
441 | self.freeze = True # disable other handlers | |
442 | self.text.SetValue(value) | |
443 | self.freeze = False # disable other handlers | |
444 | def OnButtonEdit(self, evt): | |
a4c013b2 | 445 | dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT') |
29a41103 | 446 | textCtrl = xrc.XRCCTRL(dlg, 'TEXT') |
a4c013b2 | 447 | textCtrl.SetValue(self.text.GetValue()) |
29a41103 | 448 | if dlg.ShowModal() == wx.ID_OK: |
a4c013b2 | 449 | self.text.SetValue(textCtrl.GetValue()) |
d14a1e28 RD |
450 | self.SetModified() |
451 | dlg.Destroy() | |
452 | ||
453 | class ParamText(PPanel): | |
fe295b0d | 454 | def __init__(self, parent, name, textWidth=-1, style=0): |
d14a1e28 | 455 | PPanel.__init__(self, parent, name) |
29a41103 | 456 | self.ID_TEXT_CTRL = wx.NewId() |
d14a1e28 | 457 | # We use sizer even here to have the same size of text control |
29a41103 | 458 | sizer = wx.BoxSizer() |
fe295b0d | 459 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(textWidth,-1), style=style) |
d14a1e28 RD |
460 | if textWidth == -1: option = 1 |
461 | else: option = 0 | |
29a41103 | 462 | sizer.Add(self.text, option, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2) |
b372319f | 463 | self.SetSizer(sizer) |
29a41103 | 464 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) |
d14a1e28 RD |
465 | def GetValue(self): |
466 | return self.text.GetValue() | |
467 | def SetValue(self, value): | |
468 | self.freeze = True # disable other handlers | |
469 | self.text.SetValue(value) | |
470 | self.freeze = False # disable other handlers | |
471 | ||
472 | class ParamAccel(ParamText): | |
473 | def __init__(self, parent, name): | |
474 | ParamText.__init__(self, parent, name, 100) | |
475 | ||
476 | class ParamPosSize(ParamText): | |
477 | def __init__(self, parent, name): | |
478 | ParamText.__init__(self, parent, name, 80) | |
479 | ||
480 | class ParamLabel(ParamText): | |
481 | def __init__(self, parent, name): | |
482 | ParamText.__init__(self, parent, name, 200) | |
483 | ||
484 | class ParamEncoding(ParamText): | |
485 | def __init__(self, parent, name): | |
486 | ParamText.__init__(self, parent, name, 100) | |
487 | ||
b372319f RR |
488 | class ParamComment(ParamText): |
489 | def __init__(self, parent, name): | |
fe295b0d RR |
490 | ParamText.__init__(self, parent, name, 330 + buttonSize[0], |
491 | style=wx.TE_PROCESS_ENTER) | |
b372319f | 492 | |
29a41103 | 493 | class ContentDialog(wx.Dialog): |
d14a1e28 RD |
494 | def __init__(self, parent, value): |
495 | # Load from resource | |
29a41103 | 496 | pre = wx.PreDialog() |
d14a1e28 | 497 | g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT') |
29a41103 RD |
498 | self.PostCreate(pre) |
499 | self.list = xrc.XRCCTRL(self, 'LIST') | |
d14a1e28 RD |
500 | # Set list items |
501 | for v in value: | |
502 | self.list.Append(v) | |
503 | self.SetAutoLayout(True) | |
504 | self.GetSizer().Fit(self) | |
505 | # Callbacks | |
29a41103 RD |
506 | self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND') |
507 | self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE') | |
508 | self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP') | |
509 | self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN') | |
510 | wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) | |
511 | wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) | |
512 | wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) | |
513 | wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
514 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) | |
515 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) | |
516 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
d14a1e28 RD |
517 | def OnButtonUp(self, evt): |
518 | i = self.list.GetSelection() | |
519 | str = self.list.GetString(i) | |
520 | self.list.Delete(i) | |
521 | self.list.InsertItems([str], i-1) | |
522 | self.list.SetSelection(i-1) | |
523 | def OnButtonDown(self, evt): | |
524 | i = self.list.GetSelection() | |
525 | str = self.list.GetString(i) | |
526 | self.list.Delete(i) | |
527 | self.list.InsertItems([str], i+1) | |
528 | self.list.SetSelection(i+1) | |
529 | def OnButtonAppend(self, evt): | |
29a41103 | 530 | str = wx.GetTextFromUser('Enter new item:', 'Append', '', self) |
d14a1e28 RD |
531 | self.list.Append(str) |
532 | def OnButtonRemove(self, evt): | |
533 | self.list.Delete(self.list.GetSelection()) | |
534 | def OnUpdateUI(self, evt): | |
535 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
536 | evt.Enable(self.list.GetSelection() != -1) | |
537 | elif evt.GetId() == self.ID_BUTTON_UP: | |
538 | evt.Enable(self.list.GetSelection() > 0) | |
539 | elif evt.GetId() == self.ID_BUTTON_DOWN: | |
540 | evt.Enable(self.list.GetSelection() != -1 and \ | |
31f04352 | 541 | self.list.GetSelection() < self.list.GetCount() - 1) |
d14a1e28 | 542 | |
29a41103 | 543 | class ContentCheckListDialog(wx.Dialog): |
d14a1e28 | 544 | def __init__(self, parent, value): |
29a41103 | 545 | pre = wx.PreDialog() |
c032d94e | 546 | g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECKLIST') |
29a41103 | 547 | self.PostCreate(pre) |
75aa1946 | 548 | self.list = xrc.XRCCTRL(self, 'CHECK_LIST') |
d14a1e28 RD |
549 | # Set list items |
550 | i = 0 | |
551 | for v,ch in value: | |
552 | self.list.Append(v) | |
553 | self.list.Check(i, ch) | |
554 | i += 1 | |
555 | self.SetAutoLayout(True) | |
556 | self.GetSizer().Fit(self) | |
557 | # Callbacks | |
29a41103 RD |
558 | self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND') |
559 | self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE') | |
560 | self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP') | |
561 | self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN') | |
562 | wx.EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck) | |
563 | wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) | |
564 | wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) | |
565 | wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) | |
566 | wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
567 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) | |
568 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) | |
569 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
d14a1e28 RD |
570 | def OnCheck(self, evt): |
571 | # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking | |
572 | self.list.Deselect(evt.GetSelection()) | |
573 | def OnButtonUp(self, evt): | |
574 | i = self.list.GetSelection() | |
575 | str, ch = self.list.GetString(i), self.list.IsChecked(i) | |
576 | self.list.Delete(i) | |
577 | self.list.InsertItems([str], i-1) | |
578 | self.list.Check(i-1, ch) | |
579 | self.list.SetSelection(i-1) | |
580 | def OnButtonDown(self, evt): | |
581 | i = self.list.GetSelection() | |
582 | str, ch = self.list.GetString(i), self.list.IsChecked(i) | |
583 | self.list.Delete(i) | |
584 | self.list.InsertItems([str], i+1) | |
585 | self.list.Check(i+1, ch) | |
586 | self.list.SetSelection(i+1) | |
587 | def OnButtonAppend(self, evt): | |
29a41103 | 588 | str = wx.GetTextFromUser('Enter new item:', 'Append', '', self) |
d14a1e28 RD |
589 | self.list.Append(str) |
590 | def OnButtonRemove(self, evt): | |
591 | self.list.Delete(self.list.GetSelection()) | |
592 | def OnUpdateUI(self, evt): | |
593 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
594 | evt.Enable(self.list.GetSelection() != -1) | |
595 | elif evt.GetId() == self.ID_BUTTON_UP: | |
596 | evt.Enable(self.list.GetSelection() > 0) | |
597 | elif evt.GetId() == self.ID_BUTTON_DOWN: | |
598 | evt.Enable(self.list.GetSelection() != -1 and \ | |
31f04352 | 599 | self.list.GetSelection() < self.list.GetCount() - 1) |
d14a1e28 RD |
600 | |
601 | class ParamContent(PPanel): | |
602 | def __init__(self, parent, name): | |
603 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
604 | self.ID_TEXT_CTRL = wx.NewId() |
605 | self.ID_BUTTON_EDIT = wx.NewId() | |
606 | sizer = wx.BoxSizer() | |
607 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1)) | |
608 | sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) | |
609 | self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) | |
610 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) | |
b372319f | 611 | self.SetSizer(sizer) |
d14a1e28 | 612 | self.textModified = False |
29a41103 RD |
613 | wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) |
614 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
d14a1e28 RD |
615 | def OnChange(self, evt): |
616 | PPanel.OnChange(self, evt) | |
617 | self.textModified = True | |
618 | def GetValue(self): | |
619 | if self.textModified: # text has newer value | |
620 | try: | |
e484fddf | 621 | return self.text.GetValue().split('|') |
7df24e78 | 622 | except ValueError: |
d14a1e28 RD |
623 | return [] |
624 | return self.value | |
625 | def SetValue(self, value): | |
626 | self.freeze = True | |
627 | if not value: value = [] | |
628 | self.value = value | |
c37cba89 | 629 | repr_ = '|'.join(map(str, value)) |
e484fddf | 630 | self.text.SetValue(repr_) # update text ctrl |
d14a1e28 RD |
631 | self.freeze = False |
632 | def OnButtonEdit(self, evt): | |
633 | if self.textModified: # text has newer value | |
e484fddf | 634 | self.value = self.GetValue() |
d14a1e28 | 635 | dlg = ContentDialog(self, self.value) |
29a41103 | 636 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 | 637 | value = [] |
31f04352 | 638 | for i in range(dlg.list.GetCount()): |
d14a1e28 | 639 | value.append(dlg.list.GetString(i)) |
d14a1e28 RD |
640 | self.SetValue(value) |
641 | self.SetModified() | |
642 | self.textModified = False | |
643 | dlg.Destroy() | |
7df24e78 RR |
644 | def SetModified(self, state=True): |
645 | PPanel.SetModified(self, state) | |
646 | self.textModified = False | |
d14a1e28 RD |
647 | |
648 | # CheckList content | |
649 | class ParamContentCheckList(ParamContent): | |
650 | def __init__(self, parent, name): | |
651 | ParamContent.__init__(self, parent, name) | |
652 | def OnButtonEdit(self, evt): | |
653 | if self.textModified: # text has newer value | |
e484fddf | 654 | self.value = self.GetValue() |
d14a1e28 | 655 | dlg = ContentCheckListDialog(self, self.value) |
29a41103 | 656 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 | 657 | value = [] |
31f04352 | 658 | for i in range(dlg.list.GetCount()): |
efa5f709 | 659 | value.append((dlg.list.GetString(i), int(dlg.list.IsChecked(i)))) |
d14a1e28 RD |
660 | self.SetValue(value) |
661 | self.SetModified() | |
662 | self.textModified = False | |
663 | dlg.Destroy() | |
75aa1946 RR |
664 | def SetValue(self, value): |
665 | self.freeze = True | |
666 | if not value: value = [] | |
667 | self.value = value | |
c37cba89 | 668 | repr_ = '|'.join(map(str,value)) |
75aa1946 RR |
669 | self.text.SetValue(repr_) # update text ctrl |
670 | self.freeze = False | |
d14a1e28 | 671 | |
29a41103 | 672 | class IntListDialog(wx.Dialog): |
d14a1e28 | 673 | def __init__(self, parent, value): |
29a41103 | 674 | pre = wx.PreDialog() |
d14a1e28 | 675 | g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST') |
29a41103 RD |
676 | self.PostCreate(pre) |
677 | self.list = xrc.XRCCTRL(self, 'LIST') | |
d14a1e28 RD |
678 | # Set list items |
679 | value.sort() | |
680 | for v in value: | |
681 | if type(v) != IntType: | |
29a41103 | 682 | wx.LogError('Invalid item type') |
d14a1e28 RD |
683 | else: |
684 | self.list.Append(str(v)) | |
685 | self.SetAutoLayout(True) | |
686 | self.GetSizer().Fit(self) | |
687 | # Callbacks | |
29a41103 RD |
688 | self.spinCtrl = xrc.XRCCTRL(self, 'SPIN') |
689 | wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_ADD'), self.OnButtonAdd) | |
690 | self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE') | |
691 | wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
692 | wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_CLEAR'), self.OnButtonClear) | |
693 | wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
c032d94e | 694 | def OnButtonAdd(self, evt): |
d14a1e28 RD |
695 | # Check that it's unique |
696 | try: | |
c032d94e | 697 | v = self.spinCtrl.GetValue() |
d14a1e28 RD |
698 | s = str(v) # to be sure |
699 | i = self.list.FindString(s) | |
700 | if i == -1: # ignore non-unique | |
701 | # Find place to insert | |
702 | found = False | |
31f04352 | 703 | for i in range(self.list.GetCount()): |
d14a1e28 RD |
704 | if int(self.list.GetString(i)) > v: |
705 | found = True | |
706 | break | |
707 | if found: self.list.InsertItems([s], i) | |
708 | else: self.list.Append(s) | |
709 | except ValueError: | |
29a41103 | 710 | wx.LogError('List item is not an int!') |
d14a1e28 RD |
711 | def OnButtonRemove(self, evt): |
712 | self.list.Delete(self.list.GetSelection()) | |
c032d94e RR |
713 | def OnButtonClear(self, evt): |
714 | self.list.Clear() | |
d14a1e28 RD |
715 | def OnUpdateUI(self, evt): |
716 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
717 | evt.Enable(self.list.GetSelection() != -1) | |
718 | ||
719 | # For growable list | |
720 | class ParamIntList(ParamContent): | |
721 | def __init__(self, parent, name): | |
722 | ParamContent.__init__(self, parent, name) | |
723 | def OnButtonEdit(self, evt): | |
724 | if self.textModified: # text has newer value | |
725 | try: | |
c37cba89 | 726 | self.value = map(int, self.text.GetValue().split('|')) |
7df24e78 | 727 | except ValueError: |
d14a1e28 RD |
728 | self.value = [] |
729 | dlg = IntListDialog(self, self.value) | |
29a41103 | 730 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 | 731 | value = [] |
31f04352 | 732 | for i in range(dlg.list.GetCount()): |
d14a1e28 | 733 | value.append(int(dlg.list.GetString(i))) |
d14a1e28 RD |
734 | self.SetValue(value) |
735 | self.SetModified() | |
736 | self.textModified = False | |
737 | dlg.Destroy() | |
738 | ||
739 | # Boxless radiobox | |
740 | class RadioBox(PPanel): | |
741 | def __init__(self, parent, id, choices, | |
29a41103 | 742 | pos=wx.DefaultPosition, name='radiobox'): |
d14a1e28 | 743 | PPanel.__init__(self, parent, name) |
d14a1e28 | 744 | self.choices = choices |
29a41103 | 745 | topSizer = wx.BoxSizer() |
d14a1e28 | 746 | for i in choices: |
29a41103 RD |
747 | button = wx.RadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i) |
748 | topSizer.Add(button, 0, wx.RIGHT, 5) | |
749 | wx.EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice) | |
b372319f | 750 | self.SetSizer(topSizer) |
d14a1e28 RD |
751 | def SetStringSelection(self, value): |
752 | self.freeze = True | |
753 | for i in self.choices: | |
754 | self.FindWindowByName(i).SetValue(i == value) | |
755 | self.value = value | |
756 | self.freeze = False | |
757 | def OnRadioChoice(self, evt): | |
758 | if self.freeze: return | |
759 | if evt.GetSelection(): | |
760 | self.value = evt.GetEventObject().GetName() | |
761 | self.SetModified() | |
762 | def GetStringSelection(self): | |
763 | return self.value | |
764 | ||
765 | class ParamBool(RadioBox): | |
766 | values = {'yes': '1', 'no': '0'} | |
767 | seulav = {'1': 'yes', '0': 'no'} | |
768 | def __init__(self, parent, name): | |
a4c013b2 | 769 | RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name) |
d14a1e28 RD |
770 | def GetValue(self): |
771 | return self.values[self.GetStringSelection()] | |
772 | def SetValue(self, value): | |
773 | if not value: value = '1' | |
774 | self.SetStringSelection(self.seulav[value]) | |
775 | ||
776 | class ParamOrient(RadioBox): | |
777 | values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'} | |
778 | seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'} | |
779 | def __init__(self, parent, name): | |
a4c013b2 | 780 | RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name) |
d14a1e28 RD |
781 | def GetValue(self): |
782 | return self.values[self.GetStringSelection()] | |
783 | def SetValue(self, value): | |
784 | if not value: value = 'wxHORIZONTAL' | |
785 | self.SetStringSelection(self.seulav[value]) | |
786 | ||
68ae5821 RD |
787 | class ParamOrientation(RadioBox): |
788 | values = {'horizontal': 'horizontal', 'vertical': 'vertical'} | |
789 | seulav = {'horizontal': 'horizontal', 'vertical': 'vertical'} | |
790 | def __init__(self, parent, name): | |
791 | RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name) | |
792 | def GetValue(self): | |
793 | return self.values[self.GetStringSelection()] | |
794 | def SetValue(self, value): | |
795 | if not value: value = 'vertical' | |
796 | self.SetStringSelection(self.seulav[value]) | |
797 | ||
d14a1e28 RD |
798 | class ParamFile(PPanel): |
799 | def __init__(self, parent, name): | |
800 | PPanel.__init__(self, parent, name) | |
29a41103 RD |
801 | self.ID_TEXT_CTRL = wx.NewId() |
802 | self.ID_BUTTON_BROWSE = wx.NewId() | |
803 | sizer = wx.BoxSizer() | |
804 | self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1)) | |
805 | sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) | |
806 | self.button = wx.Button(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize) | |
807 | sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) | |
b372319f | 808 | self.SetSizer(sizer) |
d14a1e28 | 809 | self.textModified = False |
29a41103 RD |
810 | wx.EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse) |
811 | wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
d14a1e28 RD |
812 | def OnChange(self, evt): |
813 | PPanel.OnChange(self, evt) | |
814 | self.textModified = True | |
815 | def GetValue(self): | |
816 | if self.textModified: # text has newer value | |
817 | return self.text.GetValue() | |
818 | return self.value | |
819 | def SetValue(self, value): | |
820 | self.freeze = True | |
821 | self.value = value | |
822 | self.text.SetValue(value) # update text ctrl | |
823 | self.freeze = False | |
824 | def OnButtonBrowse(self, evt): | |
825 | if self.textModified: # text has newer value | |
826 | self.value = self.text.GetValue() | |
29a41103 | 827 | dlg = wx.FileDialog(self, |
d14a1e28 RD |
828 | defaultDir = os.path.abspath(os.path.dirname(self.value)), |
829 | defaultFile = os.path.basename(self.value)) | |
29a41103 | 830 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 RD |
831 | # Get common part of selected path and current |
832 | if g.frame.dataFile: | |
833 | curpath = os.path.abspath(g.frame.dataFile) | |
834 | else: | |
835 | curpath = os.path.join(os.getcwd(), '') | |
836 | common = os.path.commonprefix([curpath, dlg.GetPath()]) | |
837 | self.SetValue(dlg.GetPath()[len(common):]) | |
838 | self.SetModified() | |
839 | self.textModified = False | |
840 | dlg.Destroy() | |
841 | ||
842 | class ParamBitmap(PPanel): | |
843 | def __init__(self, parent, name): | |
29a41103 | 844 | pre = wx.PrePanel() |
d14a1e28 | 845 | g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP') |
29a41103 | 846 | self.PostCreate(pre) |
d14a1e28 | 847 | self.modified = self.freeze = False |
29a41103 RD |
848 | self.radio_std = xrc.XRCCTRL(self, 'RADIO_STD') |
849 | self.radio_file = xrc.XRCCTRL(self, 'RADIO_FILE') | |
850 | self.combo = xrc.XRCCTRL(self, 'COMBO_STD') | |
851 | self.text = xrc.XRCCTRL(self, 'TEXT_FILE') | |
852 | self.button = xrc.XRCCTRL(self, 'BUTTON_BROWSE') | |
d14a1e28 RD |
853 | self.textModified = False |
854 | self.SetAutoLayout(True) | |
855 | self.GetSizer().SetMinSize((260, -1)) | |
856 | self.GetSizer().Fit(self) | |
29a41103 RD |
857 | wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_STD'), self.OnRadioStd) |
858 | wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_FILE'), self.OnRadioFile) | |
859 | wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_BROWSE'), self.OnButtonBrowse) | |
860 | wx.EVT_COMBOBOX(self, xrc.XRCID('COMBO_STD'), self.OnCombo) | |
861 | wx.EVT_TEXT(self, xrc.XRCID('COMBO_STD'), self.OnChange) | |
862 | wx.EVT_TEXT(self, xrc.XRCID('TEXT_FILE'), self.OnChange) | |
d14a1e28 RD |
863 | def OnRadioStd(self, evt): |
864 | self.SetModified() | |
865 | self.SetValue(['wxART_MISSING_IMAGE','']) | |
866 | def OnRadioFile(self, evt): | |
867 | self.SetModified() | |
868 | self.SetValue(['','']) | |
869 | def updateRadios(self): | |
870 | if self.value[0]: | |
871 | self.radio_std.SetValue(True) | |
872 | self.radio_file.SetValue(False) | |
873 | self.text.Enable(False) | |
874 | self.button.Enable(False) | |
875 | self.combo.Enable(True) | |
876 | else: | |
877 | self.radio_std.SetValue(False) | |
878 | self.radio_file.SetValue(True) | |
879 | self.text.Enable(True) | |
880 | self.button.Enable(True) | |
881 | self.combo.Enable(False) | |
882 | def OnChange(self, evt): | |
883 | PPanel.OnChange(self, evt) | |
884 | self.textModified = True | |
885 | def OnCombo(self, evt): | |
886 | PPanel.OnChange(self, evt) | |
887 | self.value[0] = self.combo.GetValue() | |
888 | def GetValue(self): | |
889 | if self.textModified: # text has newer value | |
890 | return [self.combo.GetValue(), self.text.GetValue()] | |
891 | return self.value | |
892 | def SetValue(self, value): | |
893 | self.freeze = True | |
894 | if not value: | |
895 | self.value = ['', ''] | |
896 | else: | |
897 | self.value = value | |
898 | self.combo.SetValue(self.value[0]) | |
899 | self.text.SetValue(self.value[1]) # update text ctrl | |
900 | self.updateRadios() | |
901 | self.freeze = False | |
902 | def OnButtonBrowse(self, evt): | |
903 | if self.textModified: # text has newer value | |
904 | self.value[1] = self.text.GetValue() | |
29a41103 | 905 | dlg = wx.FileDialog(self, |
d14a1e28 RD |
906 | defaultDir = os.path.abspath(os.path.dirname(self.value[1])), |
907 | defaultFile = os.path.basename(self.value[1])) | |
29a41103 | 908 | if dlg.ShowModal() == wx.ID_OK: |
d14a1e28 RD |
909 | # Get common part of selected path and current |
910 | if g.frame.dataFile: | |
911 | curpath = os.path.abspath(g.frame.dataFile) | |
912 | else: | |
913 | curpath = os.path.join(os.getcwd(), '') | |
914 | common = os.path.commonprefix([curpath, dlg.GetPath()]) | |
915 | self.SetValue(['', dlg.GetPath()[len(common):]]) | |
916 | self.SetModified() | |
917 | self.textModified = False | |
918 | dlg.Destroy() | |
919 | ||
920 | paramDict = { | |
921 | 'flag': ParamFlag, | |
922 | 'style': ParamStyle, 'exstyle': ParamExStyle, | |
923 | 'pos': ParamPosSize, 'size': ParamPosSize, | |
80389ff7 | 924 | 'cellpos': ParamPosSize, 'cellspan': ParamPosSize, |
c032d94e | 925 | 'border': ParamUnit, 'cols': ParamIntNN, 'rows': ParamIntNN, |
d14a1e28 RD |
926 | 'vgap': ParamUnit, 'hgap': ParamUnit, |
927 | 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool, | |
928 | 'accel': ParamAccel, | |
929 | 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText, | |
c032d94e | 930 | 'content': ParamContent, 'selection': ParamIntNN, |
d14a1e28 RD |
931 | 'min': ParamInt, 'max': ParamInt, |
932 | 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont, | |
933 | 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool, | |
934 | 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap, | |
b372319f RR |
935 | 'encoding': ParamEncoding, 'borders': ParamUnit, |
936 | 'comment': ParamComment | |
d14a1e28 | 937 | } |