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