]> git.saurik.com Git - wxWidgets.git/blob - wxPython/tools/XRCed/params.py
fixed wxString::resize() which was completely broken
[wxWidgets.git] / wxPython / 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 from wxPython.wx import *
8 from wxPython.xrc import *
9 import string
10
11 # Object which is currently processed
12 currentXXX = None
13 def SetCurrentXXX(xxx):
14 global currentXXX
15 currentXXX = xxx
16
17 genericStyles = ['wxSIMPLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER',
18 'wxTAB_TRAVERSAL', 'wxWANTS_CHARS', 'wxVSCROLL', 'wxHSCROLL']
19
20 # Class that can properly disable children
21 class PPanel(wxPanel):
22 def __init__(self, parent, id, name):
23 wxPanel.__init__(self, parent, id, name=name)
24 def Enable(self, value):
25 for w in self.GetChildren():
26 w.Enable(value)
27
28 class ParamBinaryOr(PPanel):
29 def __init__(self, parent, id, value, size, name):
30 PPanel.__init__(self, parent, id, name)
31 self.ID_TEXT_CTRL = wxNewId()
32 self.ID_BUTTON_CHOICES = wxNewId()
33 self.SetBackgroundColour(panel.GetBackgroundColour())
34 sizer = wxBoxSizer()
35 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, value, size=wxSize(200,-1))
36 sizer.Add(self.text, 0, wxRIGHT, 10)
37 self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...')
38 sizer.Add(self.button)
39 self.SetAutoLayout(true)
40 self.SetSizer(sizer)
41 sizer.Fit(self)
42 EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
43 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
44 def OnChange(self, evt):
45 panel.SetModified(true)
46 evt.Skip()
47 def GetValue(self):
48 return self.text.GetValue()
49 def SetValue(self, value):
50 self.text.SetValue(value)
51 def OnButtonChoices(self, evt):
52 dlg = wxDialog(self, -1, 'Choices')
53 topSizer = wxBoxSizer(wxVERTICAL)
54 listBox = wxCheckListBox(dlg, -1, choices=self.values, size=(250,200))
55 value = map(string.strip, string.split(self.text.GetValue(), '|'))
56 if value == ['']: value = []
57 ignored = []
58 for i in value:
59 try:
60 listBox.Check(self.values.index(i))
61 except ValueError:
62 # Try to find equal
63 if self.equal.has_key(i):
64 listBox.Check(self.values.index(self.equal[i]))
65 else:
66 print 'Unknown flag: %s: ignored.' % i
67 ignored.append(i)
68 topSizer.Add(listBox, 1, wxEXPAND)
69 sizer = wxBoxSizer()
70 buttonOk = wxButton(dlg, wxID_OK, 'OK')
71 buttonOk.SetDefault()
72 sizer.Add(buttonOk, 0, wxRIGHT, 10)
73 sizer.Add(0, 0, 1)
74 sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel'))
75 topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10)
76 dlg.SetAutoLayout(true)
77 dlg.SetSizer(topSizer)
78 topSizer.Fit(dlg)
79 dlg.Center()
80 if dlg.ShowModal() != wxID_OK: return
81 value = []
82 for i in range(listBox.Number()):
83 if listBox.IsChecked(i):
84 value.append(self.values[i])
85 # Add ignored flags
86 value.extend(ignored)
87 self.SetValue(reduce(lambda a,b: a+'|'+b, value))
88 panel.SetModified(true)
89
90 class ParamFlag(ParamBinaryOr):
91 values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
92 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
93 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
94 'wxALIGN_CENTRE_HORIZONTAL']
95 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
96 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
97 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'}
98 def __init__(self, parent, id, value, size, name):
99 ParamBinaryOr.__init__(self, parent, id, value, size, name)
100
101 class ParamStyle(ParamBinaryOr):
102 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
103 def __init__(self, parent, id, value, size, name):
104 self.values = currentXXX.winStyles + genericStyles
105 ParamBinaryOr.__init__(self, parent, id, value, size, name)
106
107 class ParamExStyle(ParamBinaryOr):
108 def __init__(self, parent, id, value, size, name):
109 if currentXXX:
110 self.values = currentXXX.exStyles # constant at the moment
111 else:
112 self.values = []
113 ParamBinaryOr.__init__(self, parent, id, value, size, name)
114
115 class ParamColour(PPanel):
116 def __init__(self, parent, id, value, size, name):
117 PPanel.__init__(self, parent, id, name)
118 self.ID_TEXT_CTRL = wxNewId()
119 self.ID_BUTTON = wxNewId()
120 self.SetBackgroundColour(panel.GetBackgroundColour())
121 sizer = wxBoxSizer()
122 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, str(value), size=wxSize(60,-1))
123 sizer.Add(self.text, 0, wxGROW | wxRIGHT, 10)
124 self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(40, -1))
125 sizer.Add(self.button, 0, wxGROW)
126 self.SetAutoLayout(true)
127 self.SetSizer(sizer)
128 sizer.Fit(self)
129 self.textModified = false
130 self.SetValue(value)
131 EVT_PAINT(self.button, self.OnPaintButton)
132 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
133 EVT_LEFT_DOWN(self.button, self.OnLeftDown)
134 def GetValue(self):
135 return self.value
136 def SetValue(self, value):
137 if not value: value = '#FFFFFF'
138 self.value = value
139 self.text.SetValue(str(value)) # update text ctrl
140 self.button.SetBackgroundColour(wxNamedColour(value))
141 self.button.Refresh()
142 def OnChange(self, evt):
143 panel.SetModified(true)
144 self.textModified = true
145 evt.Skip()
146 def OnPaintButton(self, evt):
147 dc = wxPaintDC(self.button)
148 dc.SetBrush(wxTRANSPARENT_BRUSH)
149 if panel.page2.IsEnabled() and self.IsEnabled(): dc.SetPen(wxBLACK_PEN)
150 else: dc.SetPen(wxGREY_PEN)
151 size = self.button.GetSize()
152 dc.DrawRectangle(0, 0, size.x, size.y)
153 def OnLeftDown(self, evt):
154 dlg = wxColourDialog(self)
155 if dlg.ShowModal() == wxID_OK:
156 self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
157 panel.SetModified(true)
158
159 ################################################################################
160
161 # Mapping from wx constants ro XML strings
162 fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
163 wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
164 wxMODERN: 'modern'}
165 fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
166 fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
167 def ReverseMap(m):
168 rm = {}
169 for k,v in m.items(): rm[v] = k
170 return rm
171 fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
172 fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
173 fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
174
175 class ParamFont(PPanel):
176 def __init__(self, parent, id, value, size, name):
177 PPanel.__init__(self, parent, id, name)
178 self.ID_TEXT_CTRL = wxNewId()
179 self.ID_BUTTON_SELECT = wxNewId()
180 self.SetBackgroundColour(panel.GetBackgroundColour())
181 sizer = wxBoxSizer()
182 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, str(value), size=wxSize(200,-1))
183 sizer.Add(self.text, 0, wxRIGHT, 10)
184 self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...')
185 sizer.Add(self.button)
186 self.SetAutoLayout(true)
187 self.SetSizer(sizer)
188 sizer.Fit(self)
189 self.textModified = false
190 EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
191 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
192 def OnChange(self, evt):
193 panel.SetModified(true)
194 self.textModified = true
195 evt.Skip()
196 def GetValue(self):
197 if self.textModified: # text has newer value
198 return eval(self.text.GetValue())
199 return self.value
200 def SetValue(self, value):
201 if not value: value = [''] * 7
202 self.value = value
203 self.text.SetValue(str(value)) # update text ctrl
204 def OnButtonSelect(self, evt):
205 if self.textModified: # text has newer value
206 self.value = eval(self.text.GetValue())
207 # Make initial font
208 try: size = int(self.value[0])
209 except ValueError: size = 12
210 try: family = fontFamiliesXml2wx[self.value[1]]
211 except KeyError: family = wxDEFAULT
212 try: style = fontStylesXml2wx[self.value[2]]
213 except KeyError: style = wxNORMAL
214 try: weight = fontWeightsXml2wx[self.value[3]]
215 except KeyError: weight = wxNORMAL
216 try: underlined = int(self.value[4])
217 except ValueError: underlined = 0
218 face = self.value[5]
219 mapper = wxFontMapper()
220 enc = wxFONTENCODING_DEFAULT
221 if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
222 if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
223 font = wxFont(size, family, style, weight, underlined, face, enc)
224 data = wxFontData()
225 data.SetInitialFont(font)
226 dlg = wxFontDialog(self, data)
227 if dlg.ShowModal() != wxID_OK: return
228 font = dlg.GetFontData().GetChosenFont()
229 value = [str(font.GetPointSize()), fontFamiliesWx2Xml[font.GetFamily()],
230 fontStylesWx2Xml[font.GetStyle()],
231 fontWeightsWx2Xml[font.GetWeight()],
232 str(font.GetUnderlined()), font.GetFaceName(),
233 wxFontMapper_GetEncodingName(font.GetEncoding())]
234 # Add ignored flags
235 self.SetValue(value)
236 panel.SetModified(true)
237 self.textModified = false
238
239 ################################################################################
240
241 class ParamInt(PPanel):
242 def __init__(self, parent, id, value, size, name):
243 PPanel.__init__(self, parent, id, name)
244 self.ID_SPIN_CTRL = wxNewId()
245 sizer = wxBoxSizer()
246 self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, value, size=wxSize(50,-1))
247 self.SetBackgroundColour(panel.GetBackgroundColour())
248 sizer.Add(self.spin)
249 self.SetAutoLayout(true)
250 self.SetSizer(sizer)
251 sizer.Fit(self)
252 EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
253 def GetValue(self):
254 return str(self.spin.GetValue())
255 def SetValue(self, value):
256 if not value: value = 0
257 self.spin.SetValue(int(value))
258 def OnChange(self, evt):
259 panel.SetModified(true)
260 evt.Skip()
261
262 class ParamText(wxTextCtrl):
263 def __init__(self, parent, id, value, size, name):
264 wxTextCtrl.__init__(self, parent, id, value, size=wxSize(200,-1), name=name)
265 EVT_TEXT(self, id, self.OnChange)
266 def OnChange(self, evt):
267 panel.SetModified(true)
268 evt.Skip()
269
270 class ParamAccel(wxTextCtrl):
271 def __init__(self, parent, id, value, size, name):
272 wxTextCtrl.__init__(self, parent, id, value, size=wxSize(50,-1), name=name)
273 EVT_TEXT(self, id, self.OnChange)
274 def OnChange(self, evt):
275 panel.SetModified(true)
276 evt.Skip()
277
278 class ParamPosSize(wxTextCtrl):
279 def __init__(self, parent, id, value, size, name):
280 wxTextCtrl.__init__(self, parent, id, value, size=wxSize(80,-1), name=name)
281 EVT_TEXT(self, id, self.OnChange)
282 def OnChange(self, evt):
283 panel.SetModified(true)
284 evt.Skip()
285
286 class ContentDialog(wxDialog):
287 def __init__(self, parent, value):
288 #wxPreDialog(self)
289 # Use another constructor
290 w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT')
291 self.this = w.this
292 w.thisown = 0
293 self.thisown = 1
294 #frame.res.LoadOnDialog(self, parent, 'ID_DIALOG_CONTENT')
295 self.Center()
296 self.list = self.FindWindowByName('ID_LIST')
297 # Set list items
298 for v in value:
299 self.list.Append(v)
300 self.SetAutoLayout(true)
301 # !!! self.SetSizer(sizer)
302 self.GetSizer().Fit(self)
303 # Callbacks
304 self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND')
305 self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE')
306 self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP')
307 self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN')
308 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
309 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
310 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
311 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
312 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
313 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
314 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
315 def OnButtonUp(self, evt):
316 i = self.list.GetSelection()
317 str = self.list.GetString(i)
318 self.list.Delete(i)
319 self.list.InsertItems([str], i-1)
320 self.list.SetSelection(i-1)
321 def OnButtonDown(self, evt):
322 i = self.list.GetSelection()
323 str = self.list.GetString(i)
324 self.list.Delete(i)
325 self.list.InsertItems([str], i+1)
326 self.list.SetSelection(i+1)
327 def OnButtonAppend(self, evt):
328 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
329 self.list.Append(str)
330 def OnButtonRemove(self, evt):
331 self.list.Delete(self.list.GetSelection())
332 def OnUpdateUI(self, evt):
333 if evt.GetId() == self.ID_BUTTON_REMOVE:
334 evt.Enable(self.list.GetSelection() != -1)
335 elif evt.GetId() == self.ID_BUTTON_UP:
336 evt.Enable(self.list.GetSelection() > 0)
337 elif evt.GetId() == self.ID_BUTTON_DOWN:
338 evt.Enable(self.list.GetSelection() != -1 and \
339 self.list.GetSelection() < self.list.Number() - 1)
340
341 class ParamContent(PPanel):
342 def __init__(self, parent, id, value, size, name):
343 PPanel.__init__(self, parent, id, name)
344 self.ID_TEXT_CTRL = wxNewId()
345 self.ID_BUTTON_EDIT = wxNewId()
346 self.SetBackgroundColour(panel.GetBackgroundColour())
347 sizer = wxBoxSizer()
348 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, str(value), size=wxSize(200,-1))
349 sizer.Add(self.text, 0, wxRIGHT, 10)
350 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...')
351 sizer.Add(self.button)
352 self.SetAutoLayout(true)
353 self.SetSizer(sizer)
354 sizer.Fit(self)
355 self.textModified = false
356 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
357 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
358 def OnChange(self, evt):
359 panel.SetModified(true)
360 self.textModified = true
361 evt.Skip()
362 def GetValue(self):
363 if self.textModified: # text has newer value
364 return eval(self.text.GetValue())
365 return self.value
366 def SetValue(self, value):
367 self.value = value
368 self.text.SetValue(str(value)) # update text ctrl
369 def OnButtonEdit(self, evt):
370 if self.textModified: # text has newer value
371 self.value = eval(self.text.GetValue())
372 dlg = ContentDialog(self, self.value)
373 if dlg.ShowModal() != wxID_OK: return
374 value = []
375 for i in range(dlg.list.Number()):
376 value.append(dlg.list.GetString(i))
377 # Add ignored flags
378 self.SetValue(value)
379 panel.SetModified(true)
380 self.textModified = false
381
382 # Boxless radiobox
383 class RadioBox(PPanel):
384 def __init__(self, parent, id, choices,
385 pos=wxDefaultPosition, size=wxDefaultSize, name='radiobox'):
386 PPanel.__init__(self, parent, id, name)
387 self.ID_RADIO_CHOICE = wxNewId() # economize on IDs, use names
388 self.SetBackgroundColour(panel.GetBackgroundColour())
389 self.choices = choices
390 topSizer = wxBoxSizer()
391 for i in choices:
392 topSizer.Add(wxRadioButton(self, self.ID_RADIO_CHOICE, i, name=i))
393 self.SetAutoLayout(true)
394 self.SetSizer(topSizer)
395 topSizer.Fit(self)
396 EVT_RADIOBUTTON(self, self.ID_RADIO_CHOICE, self.OnRadioChoice)
397 def SetStringSelection(self, value):
398 self.value = None
399 for i in self.choices:
400 w = self.FindWindowByName(i)
401 w.SetValue(i == value)
402 self.value = value
403 def OnRadioChoice(self, evt):
404 if not self.value: # procedure call
405 evt.Skip()
406 return
407 self.FindWindowByName(self.value).SetValue(false)
408 self.value = evt.GetEventObject().GetName()
409 panel.SetModified(true)
410 def GetStringSelection(self):
411 return self.value
412
413 class ParamBool(RadioBox):
414 values = {'yes': '1', 'no': '0'}
415 seulav = {'1': 'yes', '0': 'no'}
416 def __init__(self, parent, id, value, size, name):
417 RadioBox.__init__(self, parent, id, choices = self.values.keys(), name=name)
418 self.SetValue(value)
419 def GetValue(self):
420 return self.values[self.GetStringSelection()]
421 def SetValue(self, value):
422 if not value: value = '1'
423 self.SetStringSelection(self.seulav[value])
424
425 class ParamOrient(RadioBox):
426 values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
427 seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
428 def __init__(self, parent, id, value, size, name):
429 RadioBox.__init__(self, parent, id, choices = self.values.keys(), name=name)
430 self.SetValue(value)
431 def GetValue(self):
432 return self.values[self.GetStringSelection()]
433 def SetValue(self, value):
434 if not value: value = 'wxHORIZONTAL'
435 self.SetStringSelection(self.seulav[value])
436
437 paramDict = {
438 'flag': ParamFlag,
439 'style': ParamStyle, 'exstyle': ParamExStyle,
440 'pos': ParamPosSize, 'size': ParamPosSize,
441 'border': ParamInt, 'cols': ParamInt, 'rows': ParamInt,
442 'vgap': ParamInt, 'hgap': ParamInt,
443 'checkable': ParamBool, 'accel': ParamAccel,
444 'label': ParamText, 'title': ParamText, 'value': ParamText,
445 'content': ParamContent, 'selection': ParamInt,
446 'min': ParamInt, 'max': ParamInt,
447 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
448 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
449 'tooltip': ParamText
450 }
451