]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/XRCed/params.py
notes about sizer changes
[wxWidgets.git] / wxPython / wx / tools / XRCed / params.py
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 *
11 from wxPython.xrc import *
12
13 genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER',
14 'wxSUNKEN_BORDER', 'wxRAISED_BORDER',
15 'wxSTATIC_BORDER', 'wxNO_BORDER',
16 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
17 'wxNO_FULL_REPAINT_ON_RESIZE']
18
19 buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor
20
21 # Class that can properly disable children
22 class PPanel(wxPanel):
23 def __init__(self, parent, name):
24 wxPanel.__init__(self, parent, -1, name=name)
25 self.SetBackgroundColour(parent.GetBackgroundColour())
26 self.SetForegroundColour(parent.GetForegroundColour())
27 self.modified = self.freeze = False
28 def Enable(self, value):
29 # Something strange is going on with enable so we make sure...
30 for w in self.GetChildren():
31 w.Enable(value)
32 wxPanel.Enable(self, value)
33 def SetModified(self):
34 self.modified = True
35 g.panel.SetModified(True)
36 # Common method to set modified state
37 def OnChange(self, evt):
38 if self.freeze: return
39 self.SetModified()
40 evt.Skip()
41
42 class ParamBinaryOr(PPanel):
43 def __init__(self, parent, name):
44 PPanel.__init__(self, parent, name)
45 self.ID_TEXT_CTRL = wxNewId()
46 self.ID_BUTTON_CHOICES = wxNewId()
47 sizer = wxBoxSizer()
48 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
49 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
50 self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize)
51 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
52 self.SetAutoLayout(True)
53 self.SetSizer(sizer)
54 sizer.Fit(self)
55 EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
56 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
57 def GetValue(self):
58 return self.text.GetValue()
59 def SetValue(self, value):
60 self.freeze = True
61 self.text.SetValue(value)
62 self.freeze = False
63 def OnButtonChoices(self, evt):
64 dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES')
65 listBox = XRCCTRL(dlg, 'CHECK_LIST')
66 listBox.InsertItems(self.values, 0)
67 value = map(string.strip, self.text.GetValue().split('|'))
68 if value == ['']: value = []
69 ignored = []
70 for i in value:
71 try:
72 listBox.Check(self.values.index(i))
73 except ValueError:
74 # Try to find equal
75 if self.equal.has_key(i):
76 listBox.Check(self.values.index(self.equal[i]))
77 else:
78 print 'WARNING: unknown flag: %s: ignored.' % i
79 ignored.append(i)
80 if dlg.ShowModal() == wxID_OK:
81 value = []
82 for i in range(listBox.GetCount()):
83 if listBox.IsChecked(i):
84 value.append(self.values[i])
85 # Add ignored flags
86 value.extend(ignored)
87 if value:
88 self.SetValue(reduce(lambda a,b: a+'|'+b, value))
89 else:
90 self.SetValue('')
91 self.SetModified()
92 dlg.Destroy()
93
94 class ParamFlag(ParamBinaryOr):
95 values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
96 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
97 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
98 'wxALIGN_CENTRE_HORIZONTAL']
99 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
100 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
101 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'}
102 def __init__(self, parent, name):
103 ParamBinaryOr.__init__(self, parent, name)
104
105 class ParamStyle(ParamBinaryOr):
106 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
107 def __init__(self, parent, name):
108 self.values = g.currentXXX.winStyles + genericStyles
109 ParamBinaryOr.__init__(self, parent, name)
110
111 class ParamNonGenericStyle(ParamBinaryOr):
112 def __init__(self, parent, name):
113 self.values = g.currentXXX.winStyles
114 ParamBinaryOr.__init__(self, parent, name)
115
116 class ParamExStyle(ParamBinaryOr):
117 def __init__(self, parent, name):
118 if g.currentXXX:
119 self.values = g.currentXXX.exStyles # constant at the moment
120 else:
121 self.values = []
122 ParamBinaryOr.__init__(self, parent, name)
123
124 class ParamColour(PPanel):
125 def __init__(self, parent, name):
126 PPanel.__init__(self, parent, name)
127 self.ID_TEXT_CTRL = wxNewId()
128 self.ID_BUTTON = wxNewId()
129 sizer = wxBoxSizer()
130 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1))
131 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
132 self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(20, 1))
133 sizer.Add(self.button, 0, wxGROW | wxALIGN_CENTER_VERTICAL)
134 self.SetAutoLayout(True)
135 self.SetSizer(sizer)
136 sizer.Fit(self)
137 self.textModified = False
138 EVT_PAINT(self.button, self.OnPaintButton)
139 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
140 EVT_LEFT_DOWN(self.button, self.OnLeftDown)
141 def GetValue(self):
142 return self.text.GetValue()
143 def SetValue(self, value):
144 self.freeze = True
145 if not value: value = '#FFFFFF'
146 self.text.SetValue(str(value)) # update text ctrl
147 colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
148 self.button.SetBackgroundColour(colour)
149 self.button.Refresh()
150 self.freeze = False
151 def OnPaintButton(self, evt):
152 dc = wxPaintDC(self.button)
153 dc.SetBrush(wxTRANSPARENT_BRUSH)
154 if self.IsEnabled(): dc.SetPen(wxBLACK_PEN)
155 else: dc.SetPen(wxGREY_PEN)
156 size = self.button.GetSize()
157 dc.DrawRectangle(0, 0, size.width, size.height)
158 def OnLeftDown(self, evt):
159 data = wxColourData()
160 data.SetColour(self.GetValue())
161 dlg = wxColourDialog(self, data)
162 if dlg.ShowModal() == wxID_OK:
163 self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
164 self.SetModified()
165 dlg.Destroy()
166
167 ################################################################################
168
169 # Mapping from wx constants ro XML strings
170 fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
171 wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
172 wxMODERN: 'modern'}
173 fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
174 fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
175 def ReverseMap(m):
176 rm = {}
177 for k,v in m.items(): rm[v] = k
178 return rm
179 fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
180 fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
181 fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
182
183 class ParamFont(PPanel):
184 def __init__(self, parent, name):
185 PPanel.__init__(self, parent, name)
186 self.ID_TEXT_CTRL = wxNewId()
187 self.ID_BUTTON_SELECT = wxNewId()
188 sizer = wxBoxSizer()
189 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(200,-1))
190 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
191 self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
192 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
193 self.SetAutoLayout(True)
194 self.SetSizer(sizer)
195 sizer.Fit(self)
196 self.textModified = False
197 EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
198 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
199 def OnChange(self, evt):
200 PPanel.OnChange(self, evt)
201 self.textModified = True
202 def _defaultValue(self):
203 return ['12', 'default', 'normal', 'normal', '0', '', '']
204 def GetValue(self):
205 if self.textModified: # text has newer value
206 try:
207 return eval(self.text.GetValue())
208 except SyntaxError:
209 wxLogError('Syntax error in parameter value: ' + self.GetName())
210 return self._defaultValue()
211 return self.value
212 def SetValue(self, value):
213 self.freeze = True # disable other handlers
214 if not value: value = self._defaultValue()
215 self.value = value
216 self.text.SetValue(str(value)) # update text ctrl
217 self.freeze = False
218 def OnButtonSelect(self, evt):
219 if self.textModified: # text has newer value
220 try:
221 self.value = eval(self.text.GetValue())
222 except SyntaxError:
223 wxLogError('Syntax error in parameter value: ' + self.GetName())
224 self.value = self._defaultValue()
225 # Make initial font
226 # Default values
227 size = 12
228 family = wxDEFAULT
229 style = weight = wxNORMAL
230 underlined = 0
231 face = ''
232 enc = wxFONTENCODING_DEFAULT
233 # Fall back to default if exceptions
234 error = False
235 try:
236 try: size = int(self.value[0])
237 except ValueError: error = True
238 try: family = fontFamiliesXml2wx[self.value[1]]
239 except KeyError: error = True
240 try: style = fontStylesXml2wx[self.value[2]]
241 except KeyError: error = True
242 try: weight = fontWeightsXml2wx[self.value[3]]
243 except KeyError: error = True
244 try: underlined = int(self.value[4])
245 except ValueError: error = True
246 face = self.value[5]
247 mapper = wxFontMapper()
248 if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
249 except IndexError:
250 error = True
251 if error: wxLogError('Invalid font specification')
252 if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
253 font = wxFont(size, family, style, weight, underlined, face, enc)
254 data = wxFontData()
255 data.SetInitialFont(font)
256 dlg = wxFontDialog(self, data)
257 if dlg.ShowModal() == wxID_OK:
258 font = dlg.GetFontData().GetChosenFont()
259 value = [str(font.GetPointSize()),
260 fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
261 fontStylesWx2Xml.get(font.GetStyle(), "normal"),
262 fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
263 str(font.GetUnderlined()),
264 font.GetFaceName().encode(),
265 wxFontMapper_GetEncodingName(font.GetEncoding()).encode()
266 ]
267 # Add ignored flags
268 self.SetValue(value)
269 self.SetModified()
270 self.textModified = False
271 dlg.Destroy()
272
273 ################################################################################
274
275 class ParamInt(PPanel):
276 def __init__(self, parent, name):
277 PPanel.__init__(self, parent, name)
278 self.ID_SPIN_CTRL = wxNewId()
279 sizer = wxBoxSizer()
280 self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=(50,-1))
281 sizer.Add(self.spin)
282 self.SetAutoLayout(True)
283 self.SetSizer(sizer)
284 sizer.Fit(self)
285 EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
286 def GetValue(self):
287 return str(self.spin.GetValue())
288 def SetValue(self, value):
289 self.freeze = True
290 if not value: value = 0
291 self.spin.SetValue(int(value))
292 self.freeze = False
293
294 # Same as int but allows dialog units (XXXd)
295 class ParamUnit(PPanel):
296 def __init__(self, parent, name):
297 PPanel.__init__(self, parent, name)
298 self.ID_TEXT_CTRL = wxNewId()
299 self.ID_SPIN_BUTTON = wxNewId()
300 sizer = wxBoxSizer()
301 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(35,-1))
302 self.spin = wxSpinButton(self, self.ID_SPIN_BUTTON, style = wxSP_VERTICAL, size=(-1,1))
303 self.spin.SetRange(-10000, 10000)
304 sizer.Add(self.text, 0, wxEXPAND | wxRIGHT, 2)
305 sizer.Add(self.spin, 0, wxEXPAND)
306 self.SetAutoLayout(True)
307 self.SetSizer(sizer)
308 sizer.Fit(self)
309 EVT_SPIN_UP(self, self.ID_SPIN_BUTTON, self.OnSpinUp)
310 EVT_SPIN_DOWN(self, self.ID_SPIN_BUTTON, self.OnSpinDown)
311 def GetValue(self):
312 return self.text.GetValue()
313 def SetValue(self, value):
314 self.freeze = True
315 if not value: value = '0'
316 self.text.SetValue(value)
317 self.freeze = False
318 def Change(self, x):
319 # Check if we are working with dialog units
320 value = self.text.GetValue()
321 units = ''
322 if value[-1].upper() == 'D':
323 units = value[-1]
324 value = value[:-1]
325 try:
326 intValue = int(value) + x
327 self.spin.SetValue(intValue)
328 self.text.SetValue(str(intValue) + units)
329 self.SetModified()
330 except:
331 # !!! Strange, if I use wxLogWarning, event is re-generated
332 print 'incorrect unit format'
333 def OnSpinUp(self, evt):
334 self.Change(1)
335 def OnSpinDown(self, evt):
336 self.Change(-1)
337
338 class ParamMultilineText(PPanel):
339 def __init__(self, parent, name, textWidth=-1):
340 PPanel.__init__(self, parent, name)
341 self.ID_TEXT_CTRL = wxNewId()
342 self.ID_BUTTON_EDIT = wxNewId()
343 sizer = wxBoxSizer()
344 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
345 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
346 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
347 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
348 self.SetAutoLayout(True)
349 self.SetSizer(sizer)
350 sizer.Fit(self)
351 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
352 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
353 def GetValue(self):
354 return self.text.GetValue()
355 def SetValue(self, value):
356 self.freeze = True # disable other handlers
357 self.text.SetValue(value)
358 self.freeze = False # disable other handlers
359 def OnButtonEdit(self, evt):
360 dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT')
361 textCtrl = XRCCTRL(dlg, 'TEXT')
362 textCtrl.SetValue(self.text.GetValue())
363 if dlg.ShowModal() == wxID_OK:
364 self.text.SetValue(textCtrl.GetValue())
365 self.SetModified()
366 dlg.Destroy()
367
368 class ParamText(PPanel):
369 def __init__(self, parent, name, textWidth=-1):
370 PPanel.__init__(self, parent, name)
371 self.ID_TEXT_CTRL = wxNewId()
372 # We use sizer even here to have the same size of text control
373 sizer = wxBoxSizer()
374 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1))
375 if textWidth == -1: option = 1
376 else: option = 0
377 sizer.Add(self.text, option, wxALIGN_CENTER_VERTICAL)
378 self.SetAutoLayout(True)
379 self.SetSizer(sizer)
380 sizer.Fit(self)
381 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
382 def GetValue(self):
383 return self.text.GetValue()
384 def SetValue(self, value):
385 self.freeze = True # disable other handlers
386 self.text.SetValue(value)
387 self.freeze = False # disable other handlers
388
389 class ParamAccel(ParamText):
390 def __init__(self, parent, name):
391 ParamText.__init__(self, parent, name, 100)
392
393 class ParamPosSize(ParamText):
394 def __init__(self, parent, name):
395 ParamText.__init__(self, parent, name, 80)
396
397 class ParamLabel(ParamText):
398 def __init__(self, parent, name):
399 ParamText.__init__(self, parent, name, 200)
400
401 class ParamEncoding(ParamText):
402 def __init__(self, parent, name):
403 ParamText.__init__(self, parent, name, 100)
404
405 class ContentDialog(wxDialog):
406 def __init__(self, parent, value):
407 # Load from resource
408 pre = wxPreDialog()
409 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT')
410 self.this = pre.this
411 self._setOORInfo(self)
412 self.list = XRCCTRL(self, 'LIST')
413 # Set list items
414 for v in value:
415 self.list.Append(v)
416 self.SetAutoLayout(True)
417 self.GetSizer().Fit(self)
418 # Callbacks
419 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
420 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
421 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
422 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
423 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
424 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
425 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
426 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
427 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
428 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
429 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
430 def OnButtonUp(self, evt):
431 i = self.list.GetSelection()
432 str = self.list.GetString(i)
433 self.list.Delete(i)
434 self.list.InsertItems([str], i-1)
435 self.list.SetSelection(i-1)
436 def OnButtonDown(self, evt):
437 i = self.list.GetSelection()
438 str = self.list.GetString(i)
439 self.list.Delete(i)
440 self.list.InsertItems([str], i+1)
441 self.list.SetSelection(i+1)
442 def OnButtonAppend(self, evt):
443 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
444 self.list.Append(str)
445 def OnButtonRemove(self, evt):
446 self.list.Delete(self.list.GetSelection())
447 def OnUpdateUI(self, evt):
448 if evt.GetId() == self.ID_BUTTON_REMOVE:
449 evt.Enable(self.list.GetSelection() != -1)
450 elif evt.GetId() == self.ID_BUTTON_UP:
451 evt.Enable(self.list.GetSelection() > 0)
452 elif evt.GetId() == self.ID_BUTTON_DOWN:
453 evt.Enable(self.list.GetSelection() != -1 and \
454 self.list.GetSelection() < self.list.GetCount() - 1)
455
456 class ContentCheckListDialog(wxDialog):
457 def __init__(self, parent, value):
458 pre = wxPreDialog()
459 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECK_LIST')
460 self.this = pre.this
461 self._setOORInfo(self)
462 self.list = XRCCTRL(self, 'CHECK_LIST')
463 # Set list items
464 i = 0
465 for v,ch in value:
466 self.list.Append(v)
467 self.list.Check(i, ch)
468 i += 1
469 self.SetAutoLayout(True)
470 self.GetSizer().Fit(self)
471 # Callbacks
472 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
473 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
474 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
475 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
476 EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
477 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
478 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
479 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
480 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
481 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
482 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
483 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
484 def OnCheck(self, evt):
485 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
486 self.list.Deselect(evt.GetSelection())
487 def OnButtonUp(self, evt):
488 i = self.list.GetSelection()
489 str, ch = self.list.GetString(i), self.list.IsChecked(i)
490 self.list.Delete(i)
491 self.list.InsertItems([str], i-1)
492 self.list.Check(i-1, ch)
493 self.list.SetSelection(i-1)
494 def OnButtonDown(self, evt):
495 i = self.list.GetSelection()
496 str, ch = self.list.GetString(i), self.list.IsChecked(i)
497 self.list.Delete(i)
498 self.list.InsertItems([str], i+1)
499 self.list.Check(i+1, ch)
500 self.list.SetSelection(i+1)
501 def OnButtonAppend(self, evt):
502 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
503 self.list.Append(str)
504 def OnButtonRemove(self, evt):
505 self.list.Delete(self.list.GetSelection())
506 def OnUpdateUI(self, evt):
507 if evt.GetId() == self.ID_BUTTON_REMOVE:
508 evt.Enable(self.list.GetSelection() != -1)
509 elif evt.GetId() == self.ID_BUTTON_UP:
510 evt.Enable(self.list.GetSelection() > 0)
511 elif evt.GetId() == self.ID_BUTTON_DOWN:
512 evt.Enable(self.list.GetSelection() != -1 and \
513 self.list.GetSelection() < self.list.GetCount() - 1)
514
515 class ParamContent(PPanel):
516 def __init__(self, parent, name):
517 PPanel.__init__(self, parent, name)
518 self.ID_TEXT_CTRL = wxNewId()
519 self.ID_BUTTON_EDIT = wxNewId()
520 sizer = wxBoxSizer()
521 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
522 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
523 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
524 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
525 self.SetAutoLayout(True)
526 self.SetSizer(sizer)
527 sizer.Fit(self)
528 self.textModified = False
529 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
530 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
531 def OnChange(self, evt):
532 PPanel.OnChange(self, evt)
533 self.textModified = True
534 def GetValue(self):
535 if self.textModified: # text has newer value
536 try:
537 return eval(self.text.GetValue())
538 except SyntaxError:
539 wxLogError('Syntax error in parameter value: ' + self.GetName())
540 return []
541 return self.value
542 def SetValue(self, value):
543 self.freeze = True
544 if not value: value = []
545 self.value = value
546 self.text.SetValue(str(value)) # update text ctrl
547 self.freeze = False
548 def OnButtonEdit(self, evt):
549 if self.textModified: # text has newer value
550 try:
551 self.value = eval(self.text.GetValue())
552 except SyntaxError:
553 wxLogError('Syntax error in parameter value: ' + self.GetName())
554 self.value = []
555 dlg = ContentDialog(self, self.value)
556 if dlg.ShowModal() == wxID_OK:
557 value = []
558 for i in range(dlg.list.GetCount()):
559 value.append(dlg.list.GetString(i))
560 # Add ignored flags
561 self.SetValue(value)
562 self.SetModified()
563 self.textModified = False
564 dlg.Destroy()
565
566 # CheckList content
567 class ParamContentCheckList(ParamContent):
568 def __init__(self, parent, name):
569 ParamContent.__init__(self, parent, name)
570 def OnButtonEdit(self, evt):
571 if self.textModified: # text has newer value
572 try:
573 self.value = eval(self.text.GetValue())
574 except SyntaxError:
575 wxLogError('Syntax error in parameter value: ' + self.GetName())
576 self.value = []
577 dlg = ContentCheckListDialog(self, self.value)
578 if dlg.ShowModal() == wxID_OK:
579 value = []
580 for i in range(dlg.list.GetCount()):
581 value.append((dlg.list.GetString(i), dlg.list.IsChecked(i)))
582 # Add ignored flags
583 self.SetValue(value)
584 self.SetModified()
585 self.textModified = False
586 dlg.Destroy()
587
588 class IntListDialog(wxDialog):
589 def __init__(self, parent, value):
590 pre = wxPreDialog()
591 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST')
592 self.this = pre.this
593 self._setOORInfo(self)
594 self.list = XRCCTRL(self, 'LIST')
595 # Set list items
596 value.sort()
597 for v in value:
598 if type(v) != IntType:
599 wxLogError('Invalid item type')
600 else:
601 self.list.Append(str(v))
602 self.SetAutoLayout(True)
603 self.GetSizer().Fit(self)
604 # Callbacks
605 self.ID_BUTTON_ADD = XRCID('BUTTON_ADD')
606 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
607 EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend)
608 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
609 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
610 def OnButtonAppend(self, evt):
611 s = wxGetTextFromUser('Enter new number:', 'Add', '', self)
612 if not s: return
613 # Check that it's unique
614 try:
615 v = int(s)
616 s = str(v) # to be sure
617 i = self.list.FindString(s)
618 if i == -1: # ignore non-unique
619 # Find place to insert
620 found = False
621 for i in range(self.list.GetCount()):
622 if int(self.list.GetString(i)) > v:
623 found = True
624 break
625 if found: self.list.InsertItems([s], i)
626 else: self.list.Append(s)
627 except ValueError:
628 wxLogError('List item is not an int!')
629 def OnButtonRemove(self, evt):
630 self.list.Delete(self.list.GetSelection())
631 def OnUpdateUI(self, evt):
632 if evt.GetId() == self.ID_BUTTON_REMOVE:
633 evt.Enable(self.list.GetSelection() != -1)
634
635 # For growable list
636 class ParamIntList(ParamContent):
637 def __init__(self, parent, name):
638 ParamContent.__init__(self, parent, name)
639 def OnButtonEdit(self, evt):
640 if self.textModified: # text has newer value
641 try:
642 self.value = eval(self.text.GetValue())
643 except SyntaxError:
644 wxLogError('Syntax error in parameter value: ' + self.GetName())
645 self.value = []
646 dlg = IntListDialog(self, self.value)
647 if dlg.ShowModal() == wxID_OK:
648 value = []
649 for i in range(dlg.list.GetCount()):
650 value.append(int(dlg.list.GetString(i)))
651 # Add ignored flags
652 self.SetValue(value)
653 self.SetModified()
654 self.textModified = False
655 dlg.Destroy()
656
657 # Boxless radiobox
658 class RadioBox(PPanel):
659 def __init__(self, parent, id, choices,
660 pos=wxDefaultPosition, name='radiobox'):
661 PPanel.__init__(self, parent, name)
662 self.choices = choices
663 topSizer = wxBoxSizer()
664 for i in choices:
665 button = wxRadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i)
666 topSizer.Add(button, 0, wxRIGHT, 5)
667 EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
668 self.SetAutoLayout(True)
669 self.SetSizer(topSizer)
670 topSizer.Fit(self)
671 def SetStringSelection(self, value):
672 self.freeze = True
673 for i in self.choices:
674 self.FindWindowByName(i).SetValue(i == value)
675 self.value = value
676 self.freeze = False
677 def OnRadioChoice(self, evt):
678 if self.freeze: return
679 if evt.GetSelection():
680 self.value = evt.GetEventObject().GetName()
681 self.SetModified()
682 def GetStringSelection(self):
683 return self.value
684
685 class ParamBool(RadioBox):
686 values = {'yes': '1', 'no': '0'}
687 seulav = {'1': 'yes', '0': 'no'}
688 def __init__(self, parent, name):
689 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
690 def GetValue(self):
691 return self.values[self.GetStringSelection()]
692 def SetValue(self, value):
693 if not value: value = '1'
694 self.SetStringSelection(self.seulav[value])
695
696 class ParamOrient(RadioBox):
697 values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
698 seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
699 def __init__(self, parent, name):
700 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
701 def GetValue(self):
702 return self.values[self.GetStringSelection()]
703 def SetValue(self, value):
704 if not value: value = 'wxHORIZONTAL'
705 self.SetStringSelection(self.seulav[value])
706
707 class ParamFile(PPanel):
708 def __init__(self, parent, name):
709 PPanel.__init__(self, parent, name)
710 self.ID_TEXT_CTRL = wxNewId()
711 self.ID_BUTTON_BROWSE = wxNewId()
712 sizer = wxBoxSizer()
713 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
714 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
715 self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
716 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
717 self.SetAutoLayout(True)
718 self.SetSizer(sizer)
719 sizer.Fit(self)
720 self.textModified = False
721 EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
722 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
723 def OnChange(self, evt):
724 PPanel.OnChange(self, evt)
725 self.textModified = True
726 def GetValue(self):
727 if self.textModified: # text has newer value
728 return self.text.GetValue()
729 return self.value
730 def SetValue(self, value):
731 self.freeze = True
732 self.value = value
733 self.text.SetValue(value) # update text ctrl
734 self.freeze = False
735 def OnButtonBrowse(self, evt):
736 if self.textModified: # text has newer value
737 self.value = self.text.GetValue()
738 dlg = wxFileDialog(self,
739 defaultDir = os.path.abspath(os.path.dirname(self.value)),
740 defaultFile = os.path.basename(self.value))
741 if dlg.ShowModal() == wxID_OK:
742 # Get common part of selected path and current
743 if g.frame.dataFile:
744 curpath = os.path.abspath(g.frame.dataFile)
745 else:
746 curpath = os.path.join(os.getcwd(), '')
747 common = os.path.commonprefix([curpath, dlg.GetPath()])
748 self.SetValue(dlg.GetPath()[len(common):])
749 self.SetModified()
750 self.textModified = False
751 dlg.Destroy()
752
753 class ParamBitmap(PPanel):
754 def __init__(self, parent, name):
755 pre = wxPrePanel()
756 g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
757 self.this = pre.this
758 self._setOORInfo(self)
759 self.SetBackgroundColour(parent.GetBackgroundColour())
760 self.SetForegroundColour(parent.GetForegroundColour())
761 self.modified = self.freeze = False
762 self.radio_std = XRCCTRL(self, 'RADIO_STD')
763 self.radio_std.SetBackgroundColour(parent.GetBackgroundColour())
764 self.radio_std.SetForegroundColour(parent.GetForegroundColour())
765 self.radio_file = XRCCTRL(self, 'RADIO_FILE')
766 self.radio_file.SetBackgroundColour(parent.GetBackgroundColour())
767 self.radio_file.SetForegroundColour(parent.GetForegroundColour())
768 self.combo = XRCCTRL(self, 'COMBO_STD')
769 self.text = XRCCTRL(self, 'TEXT_FILE')
770 self.button = XRCCTRL(self, 'BUTTON_BROWSE')
771 self.textModified = False
772 self.SetAutoLayout(True)
773 self.GetSizer().SetMinSize((260, -1))
774 self.GetSizer().Fit(self)
775 EVT_RADIOBUTTON(self, XRCID('RADIO_STD'), self.OnRadioStd)
776 EVT_RADIOBUTTON(self, XRCID('RADIO_FILE'), self.OnRadioFile)
777 EVT_BUTTON(self, XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
778 EVT_COMBOBOX(self, XRCID('COMBO_STD'), self.OnCombo)
779 EVT_TEXT(self, XRCID('COMBO_STD'), self.OnChange)
780 EVT_TEXT(self, XRCID('TEXT_FILE'), self.OnChange)
781 def OnRadioStd(self, evt):
782 self.SetModified()
783 self.SetValue(['wxART_MISSING_IMAGE',''])
784 def OnRadioFile(self, evt):
785 self.SetModified()
786 self.SetValue(['',''])
787 def updateRadios(self):
788 if self.value[0]:
789 self.radio_std.SetValue(True)
790 self.radio_file.SetValue(False)
791 self.text.Enable(False)
792 self.button.Enable(False)
793 self.combo.Enable(True)
794 else:
795 self.radio_std.SetValue(False)
796 self.radio_file.SetValue(True)
797 self.text.Enable(True)
798 self.button.Enable(True)
799 self.combo.Enable(False)
800 def OnChange(self, evt):
801 PPanel.OnChange(self, evt)
802 self.textModified = True
803 def OnCombo(self, evt):
804 PPanel.OnChange(self, evt)
805 self.value[0] = self.combo.GetValue()
806 def GetValue(self):
807 if self.textModified: # text has newer value
808 return [self.combo.GetValue(), self.text.GetValue()]
809 return self.value
810 def SetValue(self, value):
811 self.freeze = True
812 if not value:
813 self.value = ['', '']
814 else:
815 self.value = value
816 self.combo.SetValue(self.value[0])
817 self.text.SetValue(self.value[1]) # update text ctrl
818 self.updateRadios()
819 self.freeze = False
820 def OnButtonBrowse(self, evt):
821 if self.textModified: # text has newer value
822 self.value[1] = self.text.GetValue()
823 dlg = wxFileDialog(self,
824 defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
825 defaultFile = os.path.basename(self.value[1]))
826 if dlg.ShowModal() == wxID_OK:
827 # Get common part of selected path and current
828 if g.frame.dataFile:
829 curpath = os.path.abspath(g.frame.dataFile)
830 else:
831 curpath = os.path.join(os.getcwd(), '')
832 common = os.path.commonprefix([curpath, dlg.GetPath()])
833 self.SetValue(['', dlg.GetPath()[len(common):]])
834 self.SetModified()
835 self.textModified = False
836 dlg.Destroy()
837
838 paramDict = {
839 'flag': ParamFlag,
840 'style': ParamStyle, 'exstyle': ParamExStyle,
841 'pos': ParamPosSize, 'size': ParamPosSize,
842 'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt,
843 'vgap': ParamUnit, 'hgap': ParamUnit,
844 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
845 'accel': ParamAccel,
846 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText,
847 'content': ParamContent, 'selection': ParamInt,
848 'min': ParamInt, 'max': ParamInt,
849 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
850 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
851 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
852 'encoding': ParamEncoding
853 }