]>
Commit | Line | Data |
---|---|---|
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 | ||
7 | import string | |
8 | import os.path | |
9 | from globals import * | |
10 | from types import * | |
11 | from wxPython.xrc import * | |
12 | ||
b2371711 | 13 | genericStyles = [ |
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 | ||
24 | genericExStyles = [ | |
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 | |
33 | buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor | |
34 | ||
35 | # Class that can properly disable children | |
36 | class 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 | ||
56 | class 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 | ||
108 | class 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 | ||
121 | class 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 | ||
127 | class ParamNonGenericStyle(ParamBinaryOr): | |
128 | def __init__(self, parent, name): | |
129 | self.values = g.currentXXX.winStyles | |
130 | ParamBinaryOr.__init__(self, parent, name) | |
131 | ||
132 | class 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 | ||
140 | class 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 | |
186 | fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative', | |
187 | wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss', | |
188 | wxMODERN: 'modern'} | |
189 | fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'} | |
190 | fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'} | |
191 | def ReverseMap(m): | |
192 | rm = {} | |
193 | for k,v in m.items(): rm[v] = k | |
194 | return rm | |
195 | fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml) | |
196 | fontStylesXml2wx = ReverseMap(fontStylesWx2Xml) | |
197 | fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml) | |
198 | ||
199 | class 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 | ||
297 | class 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) | |
317 | class 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 |
360 | class 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 | ||
390 | class 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 | ||
411 | class ParamAccel(ParamText): | |
412 | def __init__(self, parent, name): | |
413 | ParamText.__init__(self, parent, name, 100) | |
414 | ||
415 | class ParamPosSize(ParamText): | |
416 | def __init__(self, parent, name): | |
417 | ParamText.__init__(self, parent, name, 80) | |
418 | ||
419 | class ParamLabel(ParamText): | |
420 | def __init__(self, parent, name): | |
421 | ParamText.__init__(self, parent, name, 200) | |
422 | ||
423 | class ParamEncoding(ParamText): | |
424 | def __init__(self, parent, name): | |
425 | ParamText.__init__(self, parent, name, 100) | |
426 | ||
427 | class 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 | |
478 | class 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 | |
537 | class 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 | |
589 | class 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 | ||
610 | class 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 | |
658 | class 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 | |
680 | class 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 | ||
707 | class 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 | ||
718 | class 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 |
729 | class 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 |
740 | class 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 | ||
786 | class 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 | ||
871 | paramDict = { | |
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 | } |