2 # Purpose: XRC editor, Panel class and related
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
7 from xxx
import * # xxx imports globals and params
9 from wx
.html
import HtmlWindow
11 # Properties panel containing notebook
12 class Panel(wx
.Notebook
):
13 def __init__(self
, parent
, id = -1):
14 if wx
.Platform
!= '__WXMAC__': # some problems with this style on macs
15 wx
.Notebook
.__init
__(self
, parent
, id, style
=wx
.NB_BOTTOM
)
17 wx
.Notebook
.__init
__(self
, parent
, id)
19 g
.panel
= panel
= self
24 cTmp
= wx
.Button(self
, -1, '')
25 params
.buttonSize
= (self
.DLG_SZE(buttonSizeD
)[0], cTmp
.GetSize()[1])
27 cTmp
= wx
.TextCtrl(self
, -1, '')
28 params
.textSize
= cTmp
.GetSize()
30 cTmp
= wx
.CheckBox(self
, -1, 'growablerows ') # this is the longest
31 ParamPage
.labelSize
= cTmp
.GetSize()
35 # List of child windows
37 # Create scrolled windows for pages
38 self
.page1
= wx
.ScrolledWindow(self
, -1)
40 sizer
.Add(wx
.BoxSizer()) # dummy sizer
41 self
.page1
.SetAutoLayout(True)
42 self
.page1
.SetSizer(sizer
)
43 self
.AddPage(self
.page1
, 'Properties')
45 self
.page2
= wx
.ScrolledWindow(self
, -1)
48 sizer
.Add(wx
.BoxSizer()) # dummy sizer
49 self
.page2
.SetAutoLayout(True)
50 self
.page2
.SetSizer(sizer
)
51 # Cache for already used panels
52 self
.pageCache
= {} # cached property panels
53 self
.stylePageCache
= {} # cached style panels
55 # Delete child windows and recreate page sizer
56 def ResetPage(self
, page
):
57 topSizer
= page
.GetSizer()
58 sizer
= topSizer
.GetChildren()[0].GetSizer()
59 for w
in page
.GetChildren():
61 if isinstance(w
, ParamPage
):
66 topSizer
.Remove(sizer
)
68 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
69 # Special case - resize html window
71 topSizer
.Add(sizer
, 1, wx
.EXPAND
)
73 topSizer
.Add(sizer
, 0, wx
.ALL
, 5)
76 def SetData(self
, xxx
):
79 # Remove current objects and sizer
80 sizer
= self
.ResetPage(self
.page1
)
81 if not xxx
or (not xxx
.allParams
and not xxx
.hasName
and not xxx
.hasChild
):
83 sizer
.Add(wx
.StaticText(self
.page1
, -1, 'This item has no properties.'))
84 else: # nothing selected
85 # If first time, show some help
87 html
= HtmlWindow(self
.page1
, -1, wx
.DefaultPosition
,
88 wx
.DefaultSize
, wx
.SUNKEN_BORDER
)
89 html
.SetPage(g
.helpText
)
90 sizer
.Add(html
, 1, wx
.EXPAND
)
93 sizer
.Add(wx
.StaticText(self
.page1
, -1, 'Select a tree item.'))
95 g
.currentXXX
= xxx
.treeObject()
96 # Normal or SizerItem page
97 isGBSizerItem
= isinstance(xxx
.parent
, xxxGridBagSizer
)
98 cacheID
= (xxx
.panelName(), isGBSizerItem
)
100 page
= self
.pageCache
[cacheID
]
101 page
.box
.SetLabel(xxx
.panelName())
104 page
= PropPage(self
.page1
, xxx
.panelName(), xxx
)
105 self
.pageCache
[cacheID
] = page
107 self
.pages
.append(page
)
108 sizer
.Add(page
, 1, wx
.EXPAND
)
110 # Special label for child objects - they may have different GUI
111 cacheID
= (xxx
.child
.panelName(), xxx
.__class
__)
113 page
= self
.pageCache
[cacheID
]
114 page
.box
.SetLabel(xxx
.child
.panelName())
117 page
= PropPage(self
.page1
, xxx
.child
.panelName(), xxx
.child
)
118 self
.pageCache
[cacheID
] = page
119 page
.SetValues(xxx
.child
)
120 self
.pages
.append(page
)
121 sizer
.Add(page
, 0, wx
.EXPAND | wx
.TOP
, 5)
123 size
= self
.page1
.GetSizer().GetMinSize()
124 self
.page1
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
127 # Create if does not exist
128 if xxx
and xxx
.treeObject().hasStyle
:
129 xxx
= xxx
.treeObject()
130 # Simplest case: set data if class is the same
131 sizer
= self
.ResetPage(self
.page2
)
133 page
= self
.stylePageCache
[xxx
.__class
__]
136 page
= StylePage(self
.page2
, xxx
.className
+ ' style', xxx
)
137 self
.stylePageCache
[xxx
.__class
__] = page
139 self
.pages
.append(page
)
140 sizer
.Add(page
, 0, wx
.EXPAND
)
141 # Add page if not exists
142 if not self
.GetPageCount() == 2:
143 self
.AddPage(self
.page2
, 'Style')
145 if 'wxGTK' in wx
.PlatformInfo
:
146 self
.page2
.Show(True)
147 size
= self
.page2
.GetSizer().GetMinSize()
148 self
.page2
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
150 # Remove page if exists
151 if self
.GetPageCount() == 2:
155 self
.modified
= False
159 self
.modified
= False
161 # If some parameter has changed
162 def IsModified(self
):
165 def SetModified(self
, value
):
166 # Register undo object when modifying first time
167 if not self
.modified
and value
:
168 g
.undoMan
.RegisterUndo(UndoEdit())
169 g
.frame
.SetModified()
170 self
.modified
= value
173 for p
in self
.pages
: p
.Apply()
175 ################################################################################
177 # General class for notebook pages
178 class ParamPage(wx
.Panel
):
180 def __init__(self
, parent
, xxx
):
181 wx
.Panel
.__init
__(self
, parent
, -1)
183 # Register event handlers
184 for id in paramIDs
.values():
185 wx
.EVT_CHECKBOX(self
, id, self
.OnCheckParams
)
187 self
.controls
= {} # save python objects
188 self
.controlName
= None
190 def OnCheckParams(self
, evt
):
192 param
= evt
.GetEventObject().GetName()
193 w
= self
.controls
[param
]
197 # Ad new text node in order of allParams
198 w
.SetValue('') # set empty (default) value
199 w
.SetModified() # mark as changed
200 elem
= g
.tree
.dom
.createElement(param
)
201 # Some classes are special
203 xxx
.params
[param
] = xxxParamFont(xxx
.node
, elem
)
204 elif param
in xxxObject
.bitmapTags
:
205 xxx
.params
[param
] = xxxParamBitmap(elem
)
207 xxx
.params
[param
] = xxxParam(elem
)
208 # Find place to put new element: first present element after param
211 paramStyles
= xxx
.allParams
+ xxx
.styles
213 paramStyles
= xxx
.allParams
214 for p
in paramStyles
[paramStyles
.index(param
) + 1:]:
215 # Content params don't have same type
216 if xxx
.params
.has_key(p
) and p
!= 'content':
220 nextTextElem
= xxx
.params
[p
].node
221 objElem
.insertBefore(elem
, nextTextElem
)
223 objElem
.appendChild(elem
)
226 xxx
.params
[param
].remove()
227 del xxx
.params
[param
]
229 w
.SetModified(False) # mark as not changed
231 # Set modified flag (provokes undo storing is necessary)
232 panel
.SetModified(True)
236 name
= self
.controlName
.GetValue()
239 xxx
.node
.setAttribute('name', name
)
240 for param
, w
in self
.controls
.items():
242 paramObj
= xxx
.params
[param
]
244 if param
in xxx
.specials
:
245 xxx
.setSpecial(param
, value
)
247 paramObj
.update(value
)
251 self
.origChecks
= map(lambda i
: (i
[0], i
[1].GetValue()), self
.checks
.items())
252 self
.origControls
= map(lambda i
: (i
[0], i
[1].GetValue(), i
[1].enabled
),
253 self
.controls
.items())
255 self
.origName
= self
.controlName
.GetValue()
256 # Return original values
259 return (self
.origChecks
, self
.origControls
, self
.origName
)
261 return (self
.origChecks
, self
.origControls
)
262 # Set values from undo data
263 def SetState(self
, state
):
265 self
.checks
[k
].SetValue(v
)
266 for k
,v
,e
in state
[1]:
267 self
.controls
[k
].SetValue(v
)
268 self
.controls
[k
].Enable(e
)
269 # Set all states to modified
270 if e
and k
in self
.xxx
.params
: self
.controls
[k
].modified
= True
272 self
.controlName
.SetValue(state
[2])
274 ################################################################################
276 # Panel for displaying properties
277 class PropPage(ParamPage
):
278 renameDict
= {'orient':'orientation', 'option':'proportion',
279 'usenotebooksizer':'usesizer', 'dontattachtoframe':'dontattach',
281 def __init__(self
, parent
, label
, xxx
):
282 ParamPage
.__init
__(self
, parent
, xxx
)
283 self
.box
= wx
.StaticBox(self
, -1, label
)
284 self
.box
.SetFont(g
.labelFont())
285 topSizer
= wx
.StaticBoxSizer(self
.box
, wx
.VERTICAL
)
286 sizer
= wx
.FlexGridSizer(len(xxx
.allParams
), 2, 1, 5)
287 sizer
.AddGrowableCol(1)
289 label
= wx
.StaticText(self
, -1, 'XML ID:', size
=self
.labelSize
)
290 control
= ParamText(self
, 'XML_name', 200)
291 sizer
.AddMany([ (label
, 0, wx
.ALIGN_CENTER_VERTICAL
),
292 (control
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.BOTTOM | wx
.GROW
, 10) ])
293 self
.controlName
= control
294 for param
in xxx
.allParams
:
295 present
= xxx
.params
.has_key(param
)
296 sParam
= self
.renameDict
.get(param
, param
)
297 if param
in xxx
.required
:
298 if isinstance(xxx
, xxxComment
):
301 label
= wx
.StaticText(self
, paramIDs
[param
], sParam
,
302 size
= self
.labelSize
, name
= param
)
304 label
= wx
.CheckBox(self
, paramIDs
[param
], sParam
,
305 size
= self
.labelSize
, name
= param
)
306 self
.checks
[param
] = label
308 typeClass
= xxx
.paramDict
[param
]
312 typeClass
= paramDict
[param
]
315 typeClass
= ParamText
316 control
= typeClass(self
, param
)
317 control
.Enable(present
)
318 # Comment has only one parameter
319 if isinstance(xxx
, xxxComment
):
320 # Bind char event to check Enter key
321 control
.text
.Bind(wx
.EVT_CHAR
, self
.OnEnter
)
322 sizer
.Add(control
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.GROW
)
324 sizer
.AddMany([ (label
, 0, wx
.ALIGN_CENTER_VERTICAL
),
325 (control
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.GROW
) ])
326 self
.controls
[param
] = control
327 topSizer
.Add(sizer
, 1, wx
.ALL | wx
.EXPAND
, 3)
328 self
.SetSizer(topSizer
)
331 def SetValues(self
, xxx
):
334 self
.origControls
= []
335 # Set values, checkboxes to False, disable defaults
337 self
.controlName
.SetValue(xxx
.name
)
338 self
.origName
= xxx
.name
339 for param
in xxx
.allParams
:
340 w
= self
.controls
[param
]
343 value
= xxx
.params
[param
].value()
346 if not param
in xxx
.required
:
347 self
.checks
[param
].SetValue(True)
348 self
.origChecks
.append((param
, True))
349 self
.origControls
.append((param
, value
, True))
351 # Optional param not present in xxx - set empty value
352 self
.checks
[param
].SetValue(False)
355 self
.origChecks
.append((param
, False))
356 self
.origControls
.append((param
, '', False))
358 # This is called only for comment now
359 def OnEnter(self
, evt
):
360 if evt
.GetKeyCode() == 13:
361 g
.tree
.Apply(self
.xxx
, g
.tree
.selection
)
365 ################################################################################
367 # Style notebook page
368 class StylePage(ParamPage
):
369 renameDict
= {'fg':'foreground', 'bg':'background'}
370 def __init__(self
, parent
, label
, xxx
):
371 ParamPage
.__init
__(self
, parent
, xxx
)
372 box
= wx
.StaticBox(self
, -1, label
)
373 box
.SetFont(g
.labelFont())
374 topSizer
= wx
.StaticBoxSizer(box
, wx
.VERTICAL
)
375 sizer
= wx
.FlexGridSizer(len(xxx
.styles
), 2, 1, 5)
376 sizer
.AddGrowableCol(1)
377 for param
in xxx
.styles
:
378 present
= xxx
.params
.has_key(param
)
379 sParam
= self
.renameDict
.get(param
, param
)
380 check
= wx
.CheckBox(self
, paramIDs
[param
],
381 sParam
, size
= self
.labelSize
, name
= param
)
382 check
.SetValue(present
)
383 control
= paramDict
[param
](self
, name
= param
)
384 control
.Enable(present
)
385 sizer
.AddMany([ (check
, 0, wx
.ALIGN_CENTER_VERTICAL
),
386 (control
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.GROW
) ])
387 self
.checks
[param
] = check
388 self
.controls
[param
] = control
389 topSizer
.Add(sizer
, 1, wx
.ALL | wx
.EXPAND
, 3)
390 self
.SetAutoLayout(True)
391 self
.SetSizer(topSizer
)
394 # Set data for a cahced page
395 def SetValues(self
, xxx
):
398 self
.origControls
= []
399 for param
in xxx
.styles
:
400 present
= xxx
.params
.has_key(param
)
401 check
= self
.checks
[param
]
402 check
.SetValue(present
)
403 w
= self
.controls
[param
]
406 value
= xxx
.params
[param
].value()
411 self
.origChecks
.append((param
, present
))
412 self
.origControls
.append((param
, value
, present
))