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