]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/tools/XRCed/params.py
Tweaks to work around wxMac bugs
[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
13genericStyles = ['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
19buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor
20
21# Class that can properly disable children
22class PPanel(wxPanel):
23 def __init__(self, parent, name):
24 wxPanel.__init__(self, parent, -1, name=name)
b09afc93
RD
25 self.SetBackgroundColour(parent.GetBackgroundColour())
26 self.SetForegroundColour(parent.GetForegroundColour())
d14a1e28
RD
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
42class 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()
d14a1e28
RD
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):
a4c013b2
RR
64 dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES')
65 listBox = XRCCTRL(dlg, 'CHECK_LIST')
66 listBox.InsertItems(self.values, 0)
d14a1e28
RD
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)
d14a1e28
RD
80 if dlg.ShowModal() == wxID_OK:
81 value = []
31f04352 82 for i in range(listBox.GetCount()):
d14a1e28
RD
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
94class ParamFlag(ParamBinaryOr):
95 values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
96 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
9abdd2cb 97 'wxFIXED_MINSIZE',
d14a1e28 98 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
9abdd2cb
RD
99 'wxALIGN_CENTRE_HORIZONTAL',
100 ]
d14a1e28
RD
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
107class 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
113class ParamNonGenericStyle(ParamBinaryOr):
114 def __init__(self, parent, name):
115 self.values = g.currentXXX.winStyles
116 ParamBinaryOr.__init__(self, parent, name)
117
118class 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
126class 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()
d14a1e28
RD
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()
b09afc93 159 dc.DrawRectangle(0, 0, size.width, size.height)
d14a1e28
RD
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
172fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
173 wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
174 wxMODERN: 'modern'}
175fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
176fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
177def ReverseMap(m):
178 rm = {}
179 for k,v in m.items(): rm[v] = k
180 return rm
181fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
182fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
183fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
184
185class 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()
d14a1e28
RD
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
277class 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))
d14a1e28
RD
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)
297class 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)
d14a1e28
RD
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
d14a1e28
RD
340class 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()
d14a1e28 345 sizer = wxBoxSizer()
d14a1e28
RD
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):
a4c013b2
RR
362 dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT')
363 textCtrl = XRCCTRL(dlg, 'TEXT')
364 textCtrl.SetValue(self.text.GetValue())
d14a1e28 365 if dlg.ShowModal() == wxID_OK:
a4c013b2 366 self.text.SetValue(textCtrl.GetValue())
d14a1e28
RD
367 self.SetModified()
368 dlg.Destroy()
369
370class 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()
d14a1e28
RD
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
391class ParamAccel(ParamText):
392 def __init__(self, parent, name):
393 ParamText.__init__(self, parent, name, 100)
394
395class ParamPosSize(ParamText):
396 def __init__(self, parent, name):
397 ParamText.__init__(self, parent, name, 80)
398
399class ParamLabel(ParamText):
400 def __init__(self, parent, name):
401 ParamText.__init__(self, parent, name, 200)
402
403class ParamEncoding(ParamText):
404 def __init__(self, parent, name):
405 ParamText.__init__(self, parent, name, 100)
406
407class 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)
a4c013b2 414 self.list = XRCCTRL(self, 'LIST')
d14a1e28
RD
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
31f04352
RR
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')
d14a1e28
RD
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 \
31f04352 456 self.list.GetSelection() < self.list.GetCount() - 1)
d14a1e28
RD
457
458class 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)
a4c013b2 464 self.list = XRCCTRL(self, 'CHECK_LIST')
d14a1e28
RD
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
31f04352
RR
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')
d14a1e28
RD
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 \
31f04352 515 self.list.GetSelection() < self.list.GetCount() - 1)
d14a1e28
RD
516
517class 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()
d14a1e28
RD
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 = []
31f04352 560 for i in range(dlg.list.GetCount()):
d14a1e28
RD
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
569class 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 = []
31f04352 582 for i in range(dlg.list.GetCount()):
d14a1e28
RD
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
590class 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)
a4c013b2 596 self.list = XRCCTRL(self, 'LIST')
d14a1e28
RD
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
31f04352
RR
607 self.ID_BUTTON_ADD = XRCID('BUTTON_ADD')
608 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
d14a1e28
RD
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
31f04352 623 for i in range(self.list.GetCount()):
d14a1e28
RD
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
638class 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 = []
31f04352 651 for i in range(dlg.list.GetCount()):
d14a1e28
RD
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
660class RadioBox(PPanel):
661 def __init__(self, parent, id, choices,
662 pos=wxDefaultPosition, name='radiobox'):
663 PPanel.__init__(self, parent, name)
d14a1e28
RD
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
687class ParamBool(RadioBox):
688 values = {'yes': '1', 'no': '0'}
689 seulav = {'1': 'yes', '0': 'no'}
690 def __init__(self, parent, name):
a4c013b2 691 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
d14a1e28
RD
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
698class ParamOrient(RadioBox):
699 values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
700 seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
701 def __init__(self, parent, name):
a4c013b2 702 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
d14a1e28
RD
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
68ae5821
RD
709class ParamOrientation(RadioBox):
710 values = {'horizontal': 'horizontal', 'vertical': 'vertical'}
711 seulav = {'horizontal': 'horizontal', 'vertical': 'vertical'}
712 def __init__(self, parent, name):
713 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
714 def GetValue(self):
715 return self.values[self.GetStringSelection()]
716 def SetValue(self, value):
717 if not value: value = 'vertical'
718 self.SetStringSelection(self.seulav[value])
719
d14a1e28
RD
720class ParamFile(PPanel):
721 def __init__(self, parent, name):
722 PPanel.__init__(self, parent, name)
723 self.ID_TEXT_CTRL = wxNewId()
724 self.ID_BUTTON_BROWSE = wxNewId()
d14a1e28
RD
725 sizer = wxBoxSizer()
726 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
727 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
728 self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
729 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
730 self.SetAutoLayout(True)
731 self.SetSizer(sizer)
732 sizer.Fit(self)
733 self.textModified = False
734 EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
735 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
736 def OnChange(self, evt):
737 PPanel.OnChange(self, evt)
738 self.textModified = True
739 def GetValue(self):
740 if self.textModified: # text has newer value
741 return self.text.GetValue()
742 return self.value
743 def SetValue(self, value):
744 self.freeze = True
745 self.value = value
746 self.text.SetValue(value) # update text ctrl
747 self.freeze = False
748 def OnButtonBrowse(self, evt):
749 if self.textModified: # text has newer value
750 self.value = self.text.GetValue()
751 dlg = wxFileDialog(self,
752 defaultDir = os.path.abspath(os.path.dirname(self.value)),
753 defaultFile = os.path.basename(self.value))
754 if dlg.ShowModal() == wxID_OK:
755 # Get common part of selected path and current
756 if g.frame.dataFile:
757 curpath = os.path.abspath(g.frame.dataFile)
758 else:
759 curpath = os.path.join(os.getcwd(), '')
760 common = os.path.commonprefix([curpath, dlg.GetPath()])
761 self.SetValue(dlg.GetPath()[len(common):])
762 self.SetModified()
763 self.textModified = False
764 dlg.Destroy()
765
766class ParamBitmap(PPanel):
767 def __init__(self, parent, name):
768 pre = wxPrePanel()
769 g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
770 self.this = pre.this
771 self._setOORInfo(self)
b09afc93
RD
772 self.SetBackgroundColour(parent.GetBackgroundColour())
773 self.SetForegroundColour(parent.GetForegroundColour())
d14a1e28 774 self.modified = self.freeze = False
a4c013b2 775 self.radio_std = XRCCTRL(self, 'RADIO_STD')
b09afc93
RD
776 self.radio_std.SetBackgroundColour(parent.GetBackgroundColour())
777 self.radio_std.SetForegroundColour(parent.GetForegroundColour())
a4c013b2 778 self.radio_file = XRCCTRL(self, 'RADIO_FILE')
b09afc93
RD
779 self.radio_file.SetBackgroundColour(parent.GetBackgroundColour())
780 self.radio_file.SetForegroundColour(parent.GetForegroundColour())
a4c013b2
RR
781 self.combo = XRCCTRL(self, 'COMBO_STD')
782 self.text = XRCCTRL(self, 'TEXT_FILE')
783 self.button = XRCCTRL(self, 'BUTTON_BROWSE')
d14a1e28
RD
784 self.textModified = False
785 self.SetAutoLayout(True)
786 self.GetSizer().SetMinSize((260, -1))
787 self.GetSizer().Fit(self)
31f04352
RR
788 EVT_RADIOBUTTON(self, XRCID('RADIO_STD'), self.OnRadioStd)
789 EVT_RADIOBUTTON(self, XRCID('RADIO_FILE'), self.OnRadioFile)
790 EVT_BUTTON(self, XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
791 EVT_COMBOBOX(self, XRCID('COMBO_STD'), self.OnCombo)
792 EVT_TEXT(self, XRCID('COMBO_STD'), self.OnChange)
793 EVT_TEXT(self, XRCID('TEXT_FILE'), self.OnChange)
d14a1e28
RD
794 def OnRadioStd(self, evt):
795 self.SetModified()
796 self.SetValue(['wxART_MISSING_IMAGE',''])
797 def OnRadioFile(self, evt):
798 self.SetModified()
799 self.SetValue(['',''])
800 def updateRadios(self):
801 if self.value[0]:
802 self.radio_std.SetValue(True)
803 self.radio_file.SetValue(False)
804 self.text.Enable(False)
805 self.button.Enable(False)
806 self.combo.Enable(True)
807 else:
808 self.radio_std.SetValue(False)
809 self.radio_file.SetValue(True)
810 self.text.Enable(True)
811 self.button.Enable(True)
812 self.combo.Enable(False)
813 def OnChange(self, evt):
814 PPanel.OnChange(self, evt)
815 self.textModified = True
816 def OnCombo(self, evt):
817 PPanel.OnChange(self, evt)
818 self.value[0] = self.combo.GetValue()
819 def GetValue(self):
820 if self.textModified: # text has newer value
821 return [self.combo.GetValue(), self.text.GetValue()]
822 return self.value
823 def SetValue(self, value):
824 self.freeze = True
825 if not value:
826 self.value = ['', '']
827 else:
828 self.value = value
829 self.combo.SetValue(self.value[0])
830 self.text.SetValue(self.value[1]) # update text ctrl
831 self.updateRadios()
832 self.freeze = False
833 def OnButtonBrowse(self, evt):
834 if self.textModified: # text has newer value
835 self.value[1] = self.text.GetValue()
836 dlg = wxFileDialog(self,
837 defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
838 defaultFile = os.path.basename(self.value[1]))
839 if dlg.ShowModal() == wxID_OK:
840 # Get common part of selected path and current
841 if g.frame.dataFile:
842 curpath = os.path.abspath(g.frame.dataFile)
843 else:
844 curpath = os.path.join(os.getcwd(), '')
845 common = os.path.commonprefix([curpath, dlg.GetPath()])
846 self.SetValue(['', dlg.GetPath()[len(common):]])
847 self.SetModified()
848 self.textModified = False
849 dlg.Destroy()
850
851paramDict = {
852 'flag': ParamFlag,
853 'style': ParamStyle, 'exstyle': ParamExStyle,
854 'pos': ParamPosSize, 'size': ParamPosSize,
855 'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt,
856 'vgap': ParamUnit, 'hgap': ParamUnit,
857 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
858 'accel': ParamAccel,
859 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText,
860 'content': ParamContent, 'selection': ParamInt,
861 'min': ParamInt, 'max': ParamInt,
862 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
863 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
864 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
865 'encoding': ParamEncoding
866 }