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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (hide annotations)
Mon Mar 31 18:31:33 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: 12382 byte(s)
(DockableWindow.UnDock): Restore size and
        position (although position doesn't work yet under GTK).
(DockableWindow.Destroy): New. Called when the window must be
        closed. Namely needed when the DockFrame closes and must close
        its children.
(DockFrame): Listen for EVT_CLOSE and destroy all children.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26