]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/tools/XRCed/panel.py
b9abd4b2bddf88314034ab3e9f05a1b73ccbeb80
[wxWidgets.git] / wxPython / wxPython / tools / XRCed / panel.py
1 # Name: panel.py
2 # Purpose: XRC editor, Panel class and related
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
4 # Created: 02.12.2002
5 # RCS-ID: $Id$
6
7 from xxx import * # xxx imports globals and params
8 from undo import *
9 from wxPython.html import wxHtmlWindow
10
11 # Properties panel containing notebook
12 class Panel(wxNotebook):
13 def __init__(self, parent, id = -1):
14 if wxPlatform != '__WXMAC__': # some problems with this style on macs
15 wxNotebook.__init__(self, parent, id, style=wxNB_BOTTOM)
16 else:
17 wxNotebook.__init__(self, parent, id)
18 global panel
19 g.panel = panel = self
20 self.modified = False
21
22 # Set common button size for parameter buttons
23 import params
24 params.buttonSize = self.DLG_SZE(buttonSize)
25
26 # List of child windows
27 self.pages = []
28 # Create scrolled windows for pages
29 self.page1 = wxScrolledWindow(self, -1)
30 sizer = wxBoxSizer()
31 sizer.Add(wxBoxSizer()) # dummy sizer
32 self.page1.SetAutoLayout(True)
33 self.page1.SetSizer(sizer)
34 self.AddPage(self.page1, 'Properties')
35 # Second page
36 self.page2 = wxScrolledWindow(self, -1)
37 sizer = wxBoxSizer()
38 sizer.Add(wxBoxSizer()) # dummy sizer
39 self.page2.SetAutoLayout(True)
40 self.page2.SetSizer(sizer)
41 # Cache for already used panels
42 self.pageCache = {} # cached property panels
43 self.stylePageCache = {} # cached style panels
44 # Dummy parent window for cache pages
45 self.cacheParent = wxFrame(None, -1, 'i am invisible')
46 # Delete child windows and recreate page sizer
47 def ResetPage(self, page):
48 topSizer = page.GetSizer()
49 sizer = topSizer.GetChildren()[0].GetSizer()
50 for w in page.GetChildren():
51 sizer.RemoveWindow(w)
52 if isinstance(w, ParamPage):
53 # With SetParent, we wouldn't need this
54 w.Reparent(self.cacheParent)
55 else:
56 w.Destroy()
57 topSizer.RemoveSizer(sizer)
58 # Create new windows
59 sizer = wxBoxSizer(wxVERTICAL)
60 # Special case - resize html window
61 if g.conf.panic:
62 topSizer.Add(sizer, 1, wxEXPAND)
63 else:
64 topSizer.Add(sizer, 0, wxALL, 5)
65 return sizer
66 def SetData(self, xxx):
67 self.pages = []
68 # First page
69 # Set cached or new page
70 # Remove current objects and sizer
71 sizer = self.ResetPage(self.page1)
72 if not xxx or (not xxx.allParams and not xxx.hasName):
73 if g.tree.selection:
74 sizer.Add(wxStaticText(self.page1, -1, 'This item has no properties.'))
75 else: # nothing selected
76 # If first time, show some help
77 if g.conf.panic:
78 html = wxHtmlWindow(self.page1, -1, wxDefaultPosition,
79 wxDefaultSize, wxSUNKEN_BORDER)
80 html.SetPage(g.helpText)
81 sizer.Add(html, 1, wxEXPAND)
82 g.conf.panic = False
83 else:
84 sizer.Add(wxStaticText(self.page1, -1, 'Select a tree item.'))
85 else:
86 g.currentXXX = xxx.treeObject()
87 try:
88 page = self.pageCache[xxx.__class__]
89 page.Reparent(self.page1)
90 except KeyError:
91 page = PropPage(self.page1, xxx.className, xxx)
92 self.pageCache[xxx.__class__] = page
93 page.SetValues(xxx)
94 self.pages.append(page)
95 sizer.Add(page, 1, wxEXPAND)
96 if xxx.hasChild:
97 # Special label for child objects - they may have different GUI
98 cacheID = (xxx.child.__class__, xxx.__class__)
99 try:
100 page = self.pageCache[cacheID]
101 page.Reparent(self.page1)
102 except KeyError:
103 page = PropPage(self.page1, xxx.child.className, xxx.child)
104 self.pageCache[cacheID] = page
105 page.SetValues(xxx.child)
106 self.pages.append(page)
107 sizer.Add(page, 0, wxEXPAND | wxTOP, 5)
108 self.page1.Layout()
109 size = self.page1.GetSizer().GetMinSize()
110 self.page1.SetScrollbars(1, 1, size.x, size.y, 0, 0, True)
111
112 # Second page
113 # Create if does not exist
114 if xxx and xxx.treeObject().hasStyle:
115 xxx = xxx.treeObject()
116 # Simplest case: set data if class is the same
117 sizer = self.ResetPage(self.page2)
118 try:
119 page = self.stylePageCache[xxx.__class__]
120 page.Reparent(self.page2)
121 except KeyError:
122 page = StylePage(self.page2, xxx.className + ' style', xxx)
123 self.stylePageCache[xxx.__class__] = page
124 page.SetValues(xxx)
125 self.pages.append(page)
126 sizer.Add(page, 0, wxEXPAND)
127 # Add page if not exists
128 if not self.GetPageCount() == 2:
129 self.AddPage(self.page2, 'Style')
130 self.page2.Layout()
131 size = self.page2.GetSizer().GetMinSize()
132 self.page2.SetScrollbars(1, 1, size.x, size.y, 0, 0, True)
133 else:
134 # Remove page if exists
135 if self.GetPageCount() == 2:
136 self.SetSelection(0)
137 self.page1.Refresh()
138 self.RemovePage(1)
139 self.modified = False
140 def Clear(self):
141 self.SetData(None)
142 self.modified = False
143 # If some parameter has changed
144 def IsModified(self):
145 return self.modified
146 def SetModified(self, value):
147 # Register undo object when modifying first time
148 if not self.modified and value:
149 g.undoMan.RegisterUndo(UndoEdit())
150 self.modified = value
151 def Apply(self):
152 for p in self.pages: p.Apply()
153
154 ################################################################################
155
156 # General class for notebook pages
157 class ParamPage(wxPanel):
158 def __init__(self, parent, xxx):
159 wxPanel.__init__(self, parent, -1)
160 self.xxx = xxx
161 # Register event handlers
162 for id in paramIDs.values():
163 EVT_CHECKBOX(self, id, self.OnCheckParams)
164 self.checks = {}
165 self.controls = {} # save python objects
166 self.controlName = None
167
168 def OnCheckParams(self, evt):
169 xxx = self.xxx
170 param = evt.GetEventObject().GetName()
171 w = self.controls[param]
172 w.Enable(True)
173 objElem = xxx.element
174 if evt.IsChecked():
175 # Ad new text node in order of allParams
176 w.SetValue('') # set empty (default) value
177 w.SetModified() # mark as changed
178 elem = g.tree.dom.createElement(param)
179 # Some classes are special
180 if param == 'font':
181 xxx.params[param] = xxxParamFont(xxx.element, elem)
182 elif param in xxxObject.bitmapTags:
183 xxx.params[param] = xxxParamBitmap(elem)
184 else:
185 xxx.params[param] = xxxParam(elem)
186 # Find place to put new element: first present element after param
187 found = False
188 paramStyles = xxx.allParams + xxx.styles
189 for p in paramStyles[paramStyles.index(param) + 1:]:
190 # Content params don't have same type
191 if xxx.params.has_key(p) and p != 'content':
192 found = True
193 break
194 if found:
195 nextTextElem = xxx.params[p].node
196 objElem.insertBefore(elem, nextTextElem)
197 else:
198 objElem.appendChild(elem)
199 else:
200 # Remove parameter
201 xxx.params[param].remove()
202 del xxx.params[param]
203 w.SetValue('')
204 w.modified = False # mark as not changed
205 w.Enable(False)
206 # Set modified flag (provokes undo storing is necessary)
207 panel.SetModified(True)
208 def Apply(self):
209 xxx = self.xxx
210 if self.controlName:
211 name = self.controlName.GetValue()
212 if xxx.name != name:
213 xxx.name = name
214 xxx.element.setAttribute('name', name)
215 for param, w in self.controls.items():
216 if w.modified:
217 paramObj = xxx.params[param]
218 value = w.GetValue()
219 if param in xxx.specials:
220 xxx.setSpecial(param, value)
221 else:
222 paramObj.update(value)
223 # Save current state
224 def SaveState(self):
225 self.origChecks = map(lambda i: (i[0], i[1].GetValue()), self.checks.items())
226 self.origControls = map(lambda i: (i[0], i[1].GetValue(), i[1].IsEnabled()),
227 self.controls.items())
228 if self.controlName:
229 self.origName = self.controlName.GetValue()
230 # Return original values
231 def GetState(self):
232 if self.controlName:
233 return (self.origChecks, self.origControls, self.origName)
234 else:
235 return (self.origChecks, self.origControls)
236 # Set values from undo data
237 def SetState(self, state):
238 for k,v in state[0]:
239 self.checks[k].SetValue(v)
240 for k,v,e in state[1]:
241 self.controls[k].SetValue(v)
242 self.controls[k].Enable(e)
243 if e: self.controls[k].modified = True
244 if self.controlName:
245 self.controlName.SetValue(state[2])
246
247 ################################################################################
248
249 # Panel for displaying properties
250 class PropPage(ParamPage):
251 def __init__(self, parent, label, xxx):
252 ParamPage.__init__(self, parent, xxx)
253 box = wxStaticBox(self, -1, label)
254 box.SetFont(labelFont)
255 topSizer = wxStaticBoxSizer(box, wxVERTICAL)
256 sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1)
257 sizer.AddGrowableCol(1)
258 if xxx.hasName:
259 label = wxStaticText(self, -1, 'XML ID:', size=(100,-1))
260 control = ParamText(self, 'XML_name', 200)
261 sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
262 (control, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW, 5) ])
263 self.controlName = control
264 for param in xxx.allParams:
265 present = xxx.params.has_key(param)
266 if param in xxx.required:
267 label = wxStaticText(self, paramIDs[param], param + ':',
268 size = (100,-1), name = param)
269 else:
270 # Notebook has one very loooooong parameter
271 if param == 'usenotebooksizer': sParam = 'usesizer:'
272 else: sParam = param + ':'
273 label = wxCheckBox(self, paramIDs[param], sParam,
274 size = (100,-1), name = param)
275 self.checks[param] = label
276 try:
277 typeClass = xxx.paramDict[param]
278 except KeyError:
279 try:
280 # Standart type
281 typeClass = paramDict[param]
282 except KeyError:
283 # Default
284 typeClass = ParamText
285 control = typeClass(self, param)
286 control.Enable(present)
287 sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
288 (control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ])
289 self.controls[param] = control
290 topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
291 self.SetAutoLayout(True)
292 self.SetSizer(topSizer)
293 topSizer.Fit(self)
294 def SetValues(self, xxx):
295 self.xxx = xxx
296 self.origChecks = []
297 self.origControls = []
298 # Set values, checkboxes to False, disable defaults
299 if xxx.hasName:
300 self.controlName.SetValue(xxx.name)
301 self.origName = xxx.name
302 for param in xxx.allParams:
303 w = self.controls[param]
304 w.modified = False
305 try:
306 value = xxx.params[param].value()
307 w.Enable(True)
308 w.SetValue(value)
309 if not param in xxx.required:
310 self.checks[param].SetValue(True)
311 self.origChecks.append((param, True))
312 self.origControls.append((param, value, True))
313 except KeyError:
314 self.checks[param].SetValue(False)
315 w.SetValue('')
316 w.Enable(False)
317 self.origChecks.append((param, False))
318 self.origControls.append((param, '', False))
319
320 ################################################################################
321
322 # Style notebook page
323 class StylePage(ParamPage):
324 def __init__(self, parent, label, xxx):
325 ParamPage.__init__(self, parent, xxx)
326 box = wxStaticBox(self, -1, label)
327 box.SetFont(labelFont)
328 topSizer = wxStaticBoxSizer(box, wxVERTICAL)
329 sizer = wxFlexGridSizer(len(xxx.styles), 2, 1, 1)
330 sizer.AddGrowableCol(1)
331 for param in xxx.styles:
332 present = xxx.params.has_key(param)
333 check = wxCheckBox(self, paramIDs[param],
334 param + ':', size = (100,-1), name = param)
335 check.SetValue(present)
336 control = paramDict[param](self, name = param)
337 control.Enable(present)
338 sizer.AddMany([ (check, 0, wxALIGN_CENTER_VERTICAL),
339 (control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ])
340 self.checks[param] = check
341 self.controls[param] = control
342 topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
343 self.SetAutoLayout(True)
344 self.SetSizer(topSizer)
345 topSizer.Fit(self)
346 # Set data for a cahced page
347 def SetValues(self, xxx):
348 self.xxx = xxx
349 self.origChecks = []
350 self.origControls = []
351 for param in xxx.styles:
352 present = xxx.params.has_key(param)
353 check = self.checks[param]
354 check.SetValue(present)
355 w = self.controls[param]
356 w.modified = False
357 if present:
358 value = xxx.params[param].value()
359 else:
360 value = ''
361 w.SetValue(value)
362 w.Enable(present)
363 self.origChecks.append((param, present))
364 self.origControls.append((param, value, present))
365