]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/tools/XRCed/panel.py
Putting draft of wxImplDC and the wxDC using it
[wxWidgets.git] / wxPython / wx / tools / XRCed / panel.py
CommitLineData
d14a1e28
RD
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$
1fded56b 6
d14a1e28
RD
7from xxx import * # xxx imports globals and params
8from undo import *
29a41103 9from wx.html import HtmlWindow
d14a1e28
RD
10
11# Properties panel containing notebook
29a41103 12class Panel(wx.Notebook):
d14a1e28 13 def __init__(self, parent, id = -1):
29a41103
RD
14 if wx.Platform != '__WXMAC__': # some problems with this style on macs
15 wx.Notebook.__init__(self, parent, id, style=wx.NB_BOTTOM)
d14a1e28 16 else:
29a41103 17 wx.Notebook.__init__(self, parent, id)
d14a1e28
RD
18 global panel
19 g.panel = panel = self
20 self.modified = False
21
c08eb1d3 22 # Set common sizes
d14a1e28 23 import params
c08eb1d3
RR
24 cTmp = wx.Button(self, -1, '')
25 params.buttonSize = (self.DLG_SZE(buttonSizeD)[0], cTmp.GetSize()[1])
26 cTmp.Destroy()
27 cTmp = wx.TextCtrl(self, -1, '')
28 params.textSize = cTmp.GetSize()
29 cTmp.Destroy()
30 cTmp = wx.CheckBox(self, -1, 'growablerows ') # this is the longest
31 ParamPage.labelSize = cTmp.GetSize()
32 cTmp.Destroy()
33 del cTmp
d14a1e28
RD
34
35 # List of child windows
36 self.pages = []
37 # Create scrolled windows for pages
29a41103
RD
38 self.page1 = wx.ScrolledWindow(self, -1)
39 sizer = wx.BoxSizer()
40 sizer.Add(wx.BoxSizer()) # dummy sizer
d14a1e28
RD
41 self.page1.SetAutoLayout(True)
42 self.page1.SetSizer(sizer)
43 self.AddPage(self.page1, 'Properties')
44 # Second page
29a41103 45 self.page2 = wx.ScrolledWindow(self, -1)
2871fade 46 self.page2.Hide()
29a41103
RD
47 sizer = wx.BoxSizer()
48 sizer.Add(wx.BoxSizer()) # dummy sizer
d14a1e28
RD
49 self.page2.SetAutoLayout(True)
50 self.page2.SetSizer(sizer)
5cd66f07
RD
51 # Cache for already used panels
52 self.pageCache = {} # cached property panels
53 self.stylePageCache = {} # cached style panels
a78714eb 54
d14a1e28
RD
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():
5cd66f07
RD
60 sizer.Detach(w)
61 if isinstance(w, ParamPage):
62 if w.IsShown():
63 w.Hide()
64 else:
65 w.Destroy()
68ae5821 66 topSizer.Remove(sizer)
d14a1e28 67 # Create new windows
29a41103 68 sizer = wx.BoxSizer(wx.VERTICAL)
d14a1e28
RD
69 # Special case - resize html window
70 if g.conf.panic:
29a41103 71 topSizer.Add(sizer, 1, wx.EXPAND)
d14a1e28 72 else:
29a41103 73 topSizer.Add(sizer, 0, wx.ALL, 5)
d14a1e28 74 return sizer
a78714eb 75
d14a1e28
RD
76 def SetData(self, xxx):
77 self.pages = []
78 # First page
d14a1e28
RD
79 # Remove current objects and sizer
80 sizer = self.ResetPage(self.page1)
64b9ac75 81 if not xxx or (not xxx.allParams and not xxx.hasName and not xxx.hasChild):
d14a1e28 82 if g.tree.selection:
29a41103 83 sizer.Add(wx.StaticText(self.page1, -1, 'This item has no properties.'))
d14a1e28
RD
84 else: # nothing selected
85 # If first time, show some help
86 if g.conf.panic:
29a41103
RD
87 html = HtmlWindow(self.page1, -1, wx.DefaultPosition,
88 wx.DefaultSize, wx.SUNKEN_BORDER)
d14a1e28 89 html.SetPage(g.helpText)
29a41103 90 sizer.Add(html, 1, wx.EXPAND)
d14a1e28
RD
91 g.conf.panic = False
92 else:
29a41103 93 sizer.Add(wx.StaticText(self.page1, -1, 'Select a tree item.'))
d14a1e28
RD
94 else:
95 g.currentXXX = xxx.treeObject()
a4c013b2
RR
96 # Normal or SizerItem page
97 isGBSizerItem = isinstance(xxx.parent, xxxGridBagSizer)
75aa1946 98 cacheID = (xxx.panelName(), isGBSizerItem)
5cd66f07
RD
99 try:
100 page = self.pageCache[cacheID]
101 page.box.SetLabel(xxx.panelName())
102 page.Show()
103 except KeyError:
104 page = PropPage(self.page1, xxx.panelName(), xxx)
105 self.pageCache[cacheID] = page
d14a1e28
RD
106 page.SetValues(xxx)
107 self.pages.append(page)
29a41103 108 sizer.Add(page, 1, wx.EXPAND)
d14a1e28
RD
109 if xxx.hasChild:
110 # Special label for child objects - they may have different GUI
75aa1946 111 cacheID = (xxx.child.panelName(), xxx.__class__)
5cd66f07
RD
112 try:
113 page = self.pageCache[cacheID]
114 page.box.SetLabel(xxx.child.panelName())
115 page.Show()
116 except KeyError:
117 page = PropPage(self.page1, xxx.child.panelName(), xxx.child)
118 self.pageCache[cacheID] = page
d14a1e28
RD
119 page.SetValues(xxx.child)
120 self.pages.append(page)
29a41103 121 sizer.Add(page, 0, wx.EXPAND | wx.TOP, 5)
d14a1e28
RD
122 self.page1.Layout()
123 size = self.page1.GetSizer().GetMinSize()
124 self.page1.SetScrollbars(1, 1, size.width, size.height, 0, 0, True)
125
126 # Second page
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)
5cd66f07
RD
132 try:
133 page = self.stylePageCache[xxx.__class__]
134 page.Show()
135 except KeyError:
136 page = StylePage(self.page2, xxx.className + ' style', xxx)
137 self.stylePageCache[xxx.__class__] = page
d14a1e28
RD
138 page.SetValues(xxx)
139 self.pages.append(page)
29a41103 140 sizer.Add(page, 0, wx.EXPAND)
d14a1e28
RD
141 # Add page if not exists
142 if not self.GetPageCount() == 2:
143 self.AddPage(self.page2, 'Style')
144 self.page2.Layout()
1c7da10e
RD
145 if 'wxGTK' in wx.PlatformInfo:
146 self.page2.Show(True)
d14a1e28
RD
147 size = self.page2.GetSizer().GetMinSize()
148 self.page2.SetScrollbars(1, 1, size.width, size.height, 0, 0, True)
149 else:
150 # Remove page if exists
151 if self.GetPageCount() == 2:
152 self.SetSelection(0)
153 self.page1.Refresh()
154 self.RemovePage(1)
155 self.modified = False
5cd66f07 156
d14a1e28
RD
157 def Clear(self):
158 self.SetData(None)
159 self.modified = False
5cd66f07 160
d14a1e28
RD
161 # If some parameter has changed
162 def IsModified(self):
163 return self.modified
5cd66f07 164
d14a1e28
RD
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())
a023b456 169 g.frame.SetModified()
d14a1e28 170 self.modified = value
5cd66f07 171
d14a1e28
RD
172 def Apply(self):
173 for p in self.pages: p.Apply()
174
175################################################################################
176
177# General class for notebook pages
29a41103 178class ParamPage(wx.Panel):
c08eb1d3 179 labelSize = None
d14a1e28 180 def __init__(self, parent, xxx):
29a41103 181 wx.Panel.__init__(self, parent, -1)
d14a1e28
RD
182 self.xxx = xxx
183 # Register event handlers
184 for id in paramIDs.values():
29a41103 185 wx.EVT_CHECKBOX(self, id, self.OnCheckParams)
d14a1e28
RD
186 self.checks = {}
187 self.controls = {} # save python objects
188 self.controlName = None
189
190 def OnCheckParams(self, evt):
191 xxx = self.xxx
192 param = evt.GetEventObject().GetName()
193 w = self.controls[param]
194 w.Enable(True)
b372319f 195 objElem = xxx.node
d14a1e28
RD
196 if evt.IsChecked():
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
202 if param == 'font':
b372319f 203 xxx.params[param] = xxxParamFont(xxx.node, elem)
d14a1e28
RD
204 elif param in xxxObject.bitmapTags:
205 xxx.params[param] = xxxParamBitmap(elem)
206 else:
207 xxx.params[param] = xxxParam(elem)
208 # Find place to put new element: first present element after param
209 found = False
a3c8bbc1
RD
210 if xxx.hasStyle:
211 paramStyles = xxx.allParams + xxx.styles
212 else:
213 paramStyles = xxx.allParams
d14a1e28
RD
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':
217 found = True
218 break
219 if found:
220 nextTextElem = xxx.params[p].node
221 objElem.insertBefore(elem, nextTextElem)
222 else:
223 objElem.appendChild(elem)
224 else:
225 # Remove parameter
226 xxx.params[param].remove()
227 del xxx.params[param]
228 w.SetValue('')
7df24e78 229 w.SetModified(False) # mark as not changed
d14a1e28
RD
230 w.Enable(False)
231 # Set modified flag (provokes undo storing is necessary)
232 panel.SetModified(True)
233 def Apply(self):
234 xxx = self.xxx
235 if self.controlName:
236 name = self.controlName.GetValue()
237 if xxx.name != name:
238 xxx.name = name
b372319f 239 xxx.node.setAttribute('name', name)
d14a1e28
RD
240 for param, w in self.controls.items():
241 if w.modified:
242 paramObj = xxx.params[param]
243 value = w.GetValue()
244 if param in xxx.specials:
245 xxx.setSpecial(param, value)
246 else:
247 paramObj.update(value)
538a0c0d 248
d14a1e28
RD
249 # Save current state
250 def SaveState(self):
251 self.origChecks = map(lambda i: (i[0], i[1].GetValue()), self.checks.items())
f2ccaa22 252 self.origControls = map(lambda i: (i[0], i[1].GetValue(), i[1].enabled),
d14a1e28
RD
253 self.controls.items())
254 if self.controlName:
255 self.origName = self.controlName.GetValue()
256 # Return original values
257 def GetState(self):
258 if self.controlName:
259 return (self.origChecks, self.origControls, self.origName)
260 else:
261 return (self.origChecks, self.origControls)
262 # Set values from undo data
263 def SetState(self, state):
264 for k,v in state[0]:
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)
a023b456
RR
269 # Set all states to modified
270 if e and k in self.xxx.params: self.controls[k].modified = True
d14a1e28
RD
271 if self.controlName:
272 self.controlName.SetValue(state[2])
273
274################################################################################
275
276# Panel for displaying properties
277class PropPage(ParamPage):
c08eb1d3
RR
278 renameDict = {'orient':'orientation', 'option':'proportion',
279 'usenotebooksizer':'usesizer', 'dontattachtoframe':'dontattach',
280 }
d14a1e28
RD
281 def __init__(self, parent, label, xxx):
282 ParamPage.__init__(self, parent, xxx)
29a41103 283 self.box = wx.StaticBox(self, -1, label)
289128a4 284 self.box.SetFont(g.labelFont())
29a41103 285 topSizer = wx.StaticBoxSizer(self.box, wx.VERTICAL)
c08eb1d3 286 sizer = wx.FlexGridSizer(len(xxx.allParams), 2, 1, 5)
d14a1e28
RD
287 sizer.AddGrowableCol(1)
288 if xxx.hasName:
c08eb1d3 289 label = wx.StaticText(self, -1, 'XML ID:', size=self.labelSize)
d14a1e28 290 control = ParamText(self, 'XML_name', 200)
29a41103
RD
291 sizer.AddMany([ (label, 0, wx.ALIGN_CENTER_VERTICAL),
292 (control, 0, wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.GROW, 10) ])
d14a1e28
RD
293 self.controlName = control
294 for param in xxx.allParams:
295 present = xxx.params.has_key(param)
c08eb1d3 296 sParam = self.renameDict.get(param, param)
d14a1e28 297 if param in xxx.required:
b372319f
RR
298 if isinstance(xxx, xxxComment):
299 label = None
300 else:
c08eb1d3
RR
301 label = wx.StaticText(self, paramIDs[param], sParam,
302 size = self.labelSize, name = param)
d14a1e28 303 else:
29a41103 304 label = wx.CheckBox(self, paramIDs[param], sParam,
c08eb1d3 305 size = self.labelSize, name = param)
d14a1e28
RD
306 self.checks[param] = label
307 try:
308 typeClass = xxx.paramDict[param]
309 except KeyError:
310 try:
311 # Standart type
312 typeClass = paramDict[param]
313 except KeyError:
314 # Default
315 typeClass = ParamText
316 control = typeClass(self, param)
317 control.Enable(present)
b372319f
RR
318 # Comment has only one parameter
319 if isinstance(xxx, xxxComment):
fe295b0d
RR
320 # Bind char event to check Enter key
321 control.text.Bind(wx.EVT_CHAR, self.OnEnter)
b372319f
RR
322 sizer.Add(control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW)
323 else:
324 sizer.AddMany([ (label, 0, wx.ALIGN_CENTER_VERTICAL),
325 (control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW) ])
d14a1e28 326 self.controls[param] = control
29a41103 327 topSizer.Add(sizer, 1, wx.ALL | wx.EXPAND, 3)
d14a1e28
RD
328 self.SetSizer(topSizer)
329 topSizer.Fit(self)
fe295b0d 330
d14a1e28
RD
331 def SetValues(self, xxx):
332 self.xxx = xxx
333 self.origChecks = []
334 self.origControls = []
335 # Set values, checkboxes to False, disable defaults
336 if xxx.hasName:
337 self.controlName.SetValue(xxx.name)
338 self.origName = xxx.name
339 for param in xxx.allParams:
340 w = self.controls[param]
341 w.modified = False
342 try:
343 value = xxx.params[param].value()
344 w.Enable(True)
345 w.SetValue(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))
350 except KeyError:
ed650677 351 # Optional param not present in xxx - set empty value
d14a1e28
RD
352 self.checks[param].SetValue(False)
353 w.SetValue('')
354 w.Enable(False)
355 self.origChecks.append((param, False))
356 self.origControls.append((param, '', False))
357
fe295b0d
RR
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)
362 else:
363 evt.Skip()
364
d14a1e28
RD
365################################################################################
366
367# Style notebook page
368class StylePage(ParamPage):
c08eb1d3 369 renameDict = {'fg':'foreground', 'bg':'background'}
d14a1e28
RD
370 def __init__(self, parent, label, xxx):
371 ParamPage.__init__(self, parent, xxx)
29a41103 372 box = wx.StaticBox(self, -1, label)
289128a4 373 box.SetFont(g.labelFont())
29a41103 374 topSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
c08eb1d3 375 sizer = wx.FlexGridSizer(len(xxx.styles), 2, 1, 5)
d14a1e28
RD
376 sizer.AddGrowableCol(1)
377 for param in xxx.styles:
378 present = xxx.params.has_key(param)
c08eb1d3 379 sParam = self.renameDict.get(param, param)
29a41103 380 check = wx.CheckBox(self, paramIDs[param],
c08eb1d3 381 sParam, size = self.labelSize, name = param)
d14a1e28
RD
382 check.SetValue(present)
383 control = paramDict[param](self, name = param)
384 control.Enable(present)
29a41103
RD
385 sizer.AddMany([ (check, 0, wx.ALIGN_CENTER_VERTICAL),
386 (control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW) ])
d14a1e28
RD
387 self.checks[param] = check
388 self.controls[param] = control
29a41103 389 topSizer.Add(sizer, 1, wx.ALL | wx.EXPAND, 3)
d14a1e28
RD
390 self.SetAutoLayout(True)
391 self.SetSizer(topSizer)
392 topSizer.Fit(self)
fe295b0d 393
d14a1e28
RD
394 # Set data for a cahced page
395 def SetValues(self, xxx):
396 self.xxx = xxx
397 self.origChecks = []
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]
404 w.modified = False
405 if present:
406 value = xxx.params[param].value()
407 else:
408 value = ''
409 w.SetValue(value)
410 w.Enable(present)
411 self.origChecks.append((param, present))
412 self.origControls.append((param, value, present))
1fded56b 413