/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/dock.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/dock.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 605 - (show annotations)
Fri Apr 4 12:16:13 2003 UTC (21 years, 11 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/dock.py
File MIME type: text/x-python
File size: 12403 byte(s)
Fix assert calls.

1 # Copyright (c) 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 """Classes for creating dockable windows"""
9
10 __version__ = "$Revision$"
11
12 from Thuban import _
13
14 from wxPython.wx import *
15
16 from Thuban.Lib.connector import Publisher
17
18 from dialogs import NonModalDialog
19
20 from messages import DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
21
22 import gc
23
24 ID_BUTTON_DOCK = 4001
25 ID_BUTTON_CLOSE = 4002
26
27 PANEL_ID = 3141
28
29 class DockPanel(wxPanel):
30
31 def __init__(self, parent, id):
32
33 if not isinstance(parent, DockableWindow):
34 raise TypeError("")
35
36 wxPanel.__init__(self, parent.GetCurrentParent(), id)
37
38 #self.SetDockParent(None)
39 parent.SetPanel(self)
40
41 def SetDockParent(self, parent):
42 self.__dockParent = parent
43
44 def GetDockParent(self):
45 return self.__dockParent
46
47 def SetDock(self, dock):
48 #if dock == self.IsDocked(): return
49
50 if dock:
51 self.Dock()
52 else:
53 self.UnDock()
54
55 def Dock(self):
56 self.GetDockParent().Dock()
57
58 def UnDock(self):
59 self.GetDockParent().UnDock()
60
61 def IsDocked(self):
62 return self.GetDockParent().IsDocked()
63
64 class DockableWindow(Publisher):
65
66 def __getattr__(self, attr):
67
68 #print attr
69 return getattr(self.__topWindow, attr)
70 #try:
71 #except AttributeError:
72 #raise
73 #return self.__dict__[attr]
74 #return getattr(self, attr)
75 #pass
76
77 def __init__(self, parent, id, name,
78 title, dockWindow, orient): #, panel, docked = False, show = True):
79
80 if not isinstance(parent, DockFrame): raise TypeError("")
81
82 self.__parent = parent
83 self.__id = id
84 self.__name = name
85
86 self.__orientation = orient
87
88 self.__dockWindow = dockWindow
89 #self.__floatWindow = NonModalDialog(parent, name, title)
90 self.__floatWindow = wxFrame(parent, id, title)
91
92 self.__docked = False
93
94 self.__dockPanel = None
95
96 if self.__docked:
97 self.__topWindow = self.__dockWindow
98 else:
99 self.__topWindow = self.__floatWindow
100
101 self.__floatSize = None
102 self.__floatPosition = None
103
104 self.__panel = None
105
106 self.__dockWindow.Hide()
107 self.__floatWindow.Hide()
108
109 EVT_CLOSE(self, self._OnClose)
110
111 ##
112 # Public methods
113 #
114
115 def GetName(self):
116 return self.__name
117
118 def SetPanel(self, panel):
119
120 if not isinstance(panel, DockPanel):
121 raise TypeError("")
122
123 self.__panel = panel
124 self.__panel.SetDockParent(self)
125 self.__CreateBorder()
126
127 self.SetDock(self.__docked)
128
129 def GetPanel(self):
130 return self.__panel
131
132 def GetCurrentParent(self):
133 return self.__topWindow
134
135 def SetDock(self, dock):
136
137 self.__CheckAllGood()
138
139 if dock:
140 self.Dock()
141 else:
142 self.UnDock()
143
144 def Dock(self):
145 self.__CheckAllGood()
146
147 wasVisible = self.IsShown()
148
149 if wasVisible: self.Show(False)
150
151 self.__docked = True
152
153 #
154 # save window information
155 #
156 self.__floatSize = self.GetSize()
157 self.__floatPosition = self.GetPosition()
158
159 #
160 # reparent
161 #
162 self.__topWindow = self.__dockWindow
163 self.__dockPanel.Reparent(self.__topWindow)
164
165 self.__dockButton.SetLabel(_("Undock"))
166
167 self.SetDockSize(self.__dockWindow.GetSize())
168
169 if wasVisible: self.Show(True)
170
171 #self.__parent._UpdateDocks()
172
173 self.issue(DOCKABLE_DOCKED, self.__id, self)
174
175 def UnDock(self):
176 self.__CheckAllGood()
177
178 wasVisible = self.IsShown()
179
180 if wasVisible: self.Show(False)
181
182 self.__docked = False
183
184 #
185 # reparent
186 #
187 self.__topWindow = self.__floatWindow
188 self.__dockPanel.Reparent(self.__topWindow)
189
190 self.__dockButton.SetLabel(_("Dock"))
191
192 if wasVisible: self.Show()
193
194 #
195 # restore window information
196 #
197 if self.__floatPosition is not None: self.SetPosition(self.__floatPosition)
198 if self.__floatSize is not None: self.SetSize(self.__floatSize)
199
200 self.issue(DOCKABLE_UNDOCKED, self.__id, self)
201
202 def IsDocked(self):
203 self.__CheckAllGood()
204
205 return self.__docked
206
207
208 def Show(self, show = True):
209 if show:
210 self.__DoShow()
211 else:
212 self.__DoHide()
213
214 def SetDockSize(self, rect = None):
215
216 #
217 # adjust the size to get the
218 w0, h0 = self.__dockPanel.GetBestSize()
219 w, h = self.__panel.GetBestSize()
220
221 #print (w0, h0), (w, h)
222
223 if (w, h) < (w0, h0):
224 w = w0
225 h = h0
226
227 if rect is not None:
228 rw = rect.width
229 rh = rect.height
230 #print " ", (rw, rh)
231 if rw < w: rw = w
232 if rh < h: rh = h
233 else:
234 rw = w
235 rh = h
236
237 # these are to account for the border?!!?
238 rw += 8 # XXX: without this the sash isn't visible!?!?!?!
239 rh += 8 # XXX: without this the sash isn't visible!?!?!?!
240
241 self.__dockWindow.SetDefaultSize(wxSize(rw, rh))
242
243
244 def Destroy(self):
245 self.__panel.Destroy()
246 self.__floatWindow.Destroy()
247 self.__dockWindow.Destroy()
248 self.__parent.OnDockClose(self)
249
250 ##
251 # Event handlers
252 #
253
254 def _OnButtonClose(self, event):
255 #self.Close()
256 self.Destroy()
257
258 def _OnClose(self, force = False):
259 self.Destroy()
260
261 def _OnToggleDock(self, event):
262 self.__CheckAllGood()
263
264 self.SetDock(not self.IsDocked())
265
266 ##
267 # Private methods
268 #
269
270 def __CheckAllGood(self):
271 if self.__panel is None:
272 raise TypeError("")
273
274 def __DoShow(self):
275 if self.IsShown(): return
276 #print "__DoShow()", self.IsShown()
277
278 self.__topWindow.Show()
279
280 #if self.IsDocked():
281 #self.SetDockSize()
282
283 if self.__topWindow is self.__dockWindow:
284 self.__parent._UpdateDocks()
285
286 def __DoHide(self):
287 if not self.IsShown(): return
288 #print "__DoHide()", self.IsShown()
289 self.__topWindow.Show(False)
290
291 if self.__topWindow is self.__dockWindow:
292 self.__parent._UpdateDocks()
293
294
295 def __CreateBorder(self):
296
297 #self.__panel.Reparent(self) # Make sure we hang on to the panel
298
299 self.__dockPanel = wxPanel(self.__topWindow, -1, style=wxSUNKEN_BORDER)
300 #self.__dockPanel.SetBackgroundColour(wxColour(255, 0, 0))
301
302 if self.__orientation == wxLAYOUT_VERTICAL:
303 sizer = wxBoxSizer(wxVERTICAL)
304 headerBoxOrient = wxHORIZONTAL
305 else:
306 sizer = wxBoxSizer(wxHORIZONTAL)
307 headerBoxOrient = wxVERTICAL
308
309
310 headerBox = wxStaticBoxSizer(
311 wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
312
313 buttonBox = wxBoxSizer(wxHORIZONTAL)
314
315 #
316 # ideally, we should be able to rotate this text depending on
317 # our orientation
318 #
319 text = wxStaticText(self.__dockPanel, -1, self.GetTitle(),
320 style = wxSIMPLE_BORDER | wxALIGN_CENTRE)
321
322 #
323 # Perhaps using wxToggleButton would be better, but it's only
324 # supported under wxMSW and wxGTK as of v2.4.0.3
325 #
326 self.__dockButton = wxButton(self.__dockPanel, ID_BUTTON_DOCK, "WWWWWW",
327 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
328
329 closeX = wxButton(self.__dockPanel, ID_BUTTON_CLOSE, "X",
330 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
331
332 buttonBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
333 buttonBox.Add(closeX, 0, wxALIGN_RIGHT, 0)
334
335 if self.__orientation == wxLAYOUT_VERTICAL:
336 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
337 headerBox.Add(1, 20, 1, wxGROW)
338 headerBox.Add(buttonBox, 0, wxGROW | wxALIGN_RIGHT, 0)
339 else:
340 headerBox.Add(buttonBox, 0, wxGROW, 0)
341 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
342
343 sizer.Add(headerBox, 0, wxGROW, 0)
344
345 self.__panel.Reparent(self.__dockPanel)
346 self.__panel.SetId(PANEL_ID)
347
348 sizer.Add(self.__panel, 1, wxGROW, 0)
349
350 sizer.Fit(self.__dockPanel)
351
352 self.__dockPanel.SetSizer(sizer)
353 self.__dockPanel.SetAutoLayout(True)
354
355 sizer.SetSizeHints(self.__dockPanel)
356
357 EVT_BUTTON(self.__dockPanel, ID_BUTTON_DOCK, self._OnToggleDock)
358 EVT_BUTTON(self.__dockPanel, ID_BUTTON_CLOSE, self._OnButtonClose)
359
360
361 class DockFrame(wxFrame):
362
363 def __init__(self, parent, id, title, position, size):
364 wxFrame.__init__(self, parent, id, title, position, size)
365
366 self.openWindows = {}
367
368 self.__update_lock = 0
369
370 self.SetMainWindow(None)
371
372
373 EVT_SIZE(self, self._OnSashSize)
374 EVT_CLOSE(self, self._OnClose)
375
376 layout2oppSash = {
377 wxLAYOUT_NONE : wxSASH_NONE,
378 wxLAYOUT_TOP : wxSASH_BOTTOM,
379 wxLAYOUT_LEFT : wxSASH_RIGHT,
380 wxLAYOUT_RIGHT : wxSASH_LEFT,
381 wxLAYOUT_BOTTOM : wxSASH_TOP }
382
383
384 def _OnClose(self, event):
385
386 self.__update_lock += 1
387
388 #
389 # child windows are not notified when the parent is destroyed
390 # as of v2.4.0.3 so we need to interate over our children
391 # and tell them to go away.
392 #
393 for key in self.openWindows.keys():
394 win = self.openWindows[key]
395 win.Destroy()
396
397 self.__update_lock -= 1
398
399 # should really call _UpdateDocks() here but we don't need to
400 # since we're going away
401
402 def CreateDock(self, name, id, title, align):
403
404 if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):
405 orient = wxLAYOUT_VERTICAL
406 else:
407 orient = wxLAYOUT_HORIZONTAL
408
409 sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)
410 sash.SetOrientation(orient)
411 sash.SetAlignment(align)
412 #print align, DockFrame.layout2oppSash[align]
413 sash.SetSashVisible(DockFrame.layout2oppSash[align], True)
414 sash.SetSashBorder(DockFrame.layout2oppSash[align], True)
415
416 win = DockableWindow(self, id, name, title, sash, orient)
417
418 self.__RegisterDock(name, win)
419 EVT_SASH_DRAGGED(self, id, self._OnSashDragged)
420
421 return win
422
423 def FindRegisteredDock(self, name):
424 return self.openWindows.get(name)
425
426 def OnDockClose(self, win):
427 del self.openWindows[win.GetName()]
428 self._UpdateDocks()
429
430 def SetMainWindow(self, main):
431 self.__mainWindow = main
432 self._UpdateDocks()
433
434 def _UpdateDocks(self):
435 #print "_UpdateDocks()"
436 if self.__update_lock == 0:
437 wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
438
439 def _OnSashDragged(self, event):
440 if event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE:
441 return
442
443 id = event.GetId()
444 sash = self.FindWindowById(id)
445 #assert(isinstance(win, wxPanel))
446 dockPanel = sash.GetChildren()[0]
447 #print dockPanel
448 panel = dockPanel.FindWindowById(PANEL_ID)
449 #print panel
450 assert isinstance(panel, DockPanel)
451 win = panel.GetDockParent()
452 #print win
453 assert isinstance(win, DockableWindow)
454
455 assert win.IsDocked()
456
457 rect = event.GetDragRect()
458
459 win.SetDockSize(rect)
460
461 self._UpdateDocks()
462
463 def _OnSashSize(self, event):
464 self._UpdateDocks()
465
466 def __RegisterDock(self, name, win):
467 if self.FindRegisteredDock(name) is not None:
468 raise ValueError(
469 "A dockable window is already registered under the name '%s'" % name)
470
471 self.openWindows[name] = win
472

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26