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