/[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 631 - (hide annotations)
Wed Apr 9 10:10:38 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: 12461 byte(s)
It was decided that if the user closes
a dockable window the window should simply hide itself. That
way if the user wants to show the dock again it appears in the
same place as it was when it was closed.
(DockableWindow.Destroy): Call renamed method OnDockDestroy().
(DockableWindow._OnButtonClose): Hide the window instead of
        destroying it.
(DockableWindow._OnClose): Hide the window instead of destroying it.

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 620 self.__dockPanel.SetSize(self.__topWindow.GetClientSize())
201    
202 jonathan 571 self.issue(DOCKABLE_UNDOCKED, self.__id, self)
203 jonathan 561
204     def IsDocked(self):
205 jonathan 571 self.__CheckAllGood()
206 jonathan 561
207 jonathan 571 return self.__docked
208 jonathan 561
209    
210 jonathan 571 def Show(self, show = True):
211     if show:
212     self.__DoShow()
213     else:
214     self.__DoHide()
215 jonathan 561
216 jonathan 571 def SetDockSize(self, rect = None):
217 jonathan 561
218 jonathan 571 #
219     # adjust the size to get the
220     w0, h0 = self.__dockPanel.GetBestSize()
221     w, h = self.__panel.GetBestSize()
222 jonathan 561
223 jonathan 571 #print (w0, h0), (w, h)
224 jonathan 561
225 jonathan 571 if (w, h) < (w0, h0):
226     w = w0
227     h = h0
228    
229     if rect is not None:
230     rw = rect.width
231     rh = rect.height
232     #print " ", (rw, rh)
233     if rw < w: rw = w
234     if rh < h: rh = h
235     else:
236     rw = w
237     rh = h
238    
239     # these are to account for the border?!!?
240     rw += 8 # XXX: without this the sash isn't visible!?!?!?!
241     rh += 8 # XXX: without this the sash isn't visible!?!?!?!
242    
243     self.__dockWindow.SetDefaultSize(wxSize(rw, rh))
244 jonathan 561
245    
246 jonathan 577 def Destroy(self):
247     self.__panel.Destroy()
248 jonathan 571 self.__floatWindow.Destroy()
249     self.__dockWindow.Destroy()
250 jonathan 631 self.__parent.OnDockDestroy(self)
251 jonathan 577
252 jonathan 571 ##
253     # Event handlers
254     #
255 jonathan 561
256 jonathan 571 def _OnButtonClose(self, event):
257 jonathan 583 #self.Close()
258 jonathan 631 self.Show(False)
259 jonathan 561
260 jonathan 571 def _OnClose(self, force = False):
261 jonathan 631 self.Show(False)
262 jonathan 561
263 jonathan 571 def _OnToggleDock(self, event):
264     self.__CheckAllGood()
265 jonathan 561
266 jonathan 571 self.SetDock(not self.IsDocked())
267 jonathan 561
268 jonathan 571 ##
269     # Private methods
270     #
271 jonathan 561
272 jonathan 571 def __CheckAllGood(self):
273     if self.__panel is None:
274     raise TypeError("")
275 jonathan 561
276 jonathan 571 def __DoShow(self):
277     if self.IsShown(): return
278     #print "__DoShow()", self.IsShown()
279 jonathan 561
280 jonathan 571 self.__topWindow.Show()
281 jonathan 561
282 jonathan 571 #if self.IsDocked():
283     #self.SetDockSize()
284    
285     if self.__topWindow is self.__dockWindow:
286     self.__parent._UpdateDocks()
287    
288     def __DoHide(self):
289     if not self.IsShown(): return
290     #print "__DoHide()", self.IsShown()
291     self.__topWindow.Show(False)
292    
293     if self.__topWindow is self.__dockWindow:
294     self.__parent._UpdateDocks()
295    
296    
297     def __CreateBorder(self):
298    
299     #self.__panel.Reparent(self) # Make sure we hang on to the panel
300    
301     self.__dockPanel = wxPanel(self.__topWindow, -1, style=wxSUNKEN_BORDER)
302     #self.__dockPanel.SetBackgroundColour(wxColour(255, 0, 0))
303    
304     if self.__orientation == wxLAYOUT_VERTICAL:
305     sizer = wxBoxSizer(wxVERTICAL)
306     headerBoxOrient = wxHORIZONTAL
307 jonathan 561 else:
308 jonathan 571 sizer = wxBoxSizer(wxHORIZONTAL)
309     headerBoxOrient = wxVERTICAL
310    
311 jonathan 561
312 jonathan 571 headerBox = wxStaticBoxSizer(
313     wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
314 jonathan 561
315 jonathan 571 buttonBox = wxBoxSizer(wxHORIZONTAL)
316 jonathan 561
317 jonathan 571 #
318     # ideally, we should be able to rotate this text depending on
319     # our orientation
320     #
321     text = wxStaticText(self.__dockPanel, -1, self.GetTitle(),
322 jonathan 620 style = wxALIGN_CENTRE)
323 jonathan 561
324     #
325     # Perhaps using wxToggleButton would be better, but it's only
326     # supported under wxMSW and wxGTK as of v2.4.0.3
327     #
328 jonathan 571 self.__dockButton = wxButton(self.__dockPanel, ID_BUTTON_DOCK, "WWWWWW",
329     style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
330 jonathan 561
331 jonathan 571 closeX = wxButton(self.__dockPanel, ID_BUTTON_CLOSE, "X",
332     style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
333 jonathan 561
334 jonathan 571 buttonBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
335     buttonBox.Add(closeX, 0, wxALIGN_RIGHT, 0)
336 jonathan 561
337 jonathan 571 if self.__orientation == wxLAYOUT_VERTICAL:
338     headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
339     headerBox.Add(1, 20, 1, wxGROW)
340     headerBox.Add(buttonBox, 0, wxGROW | wxALIGN_RIGHT, 0)
341     else:
342     headerBox.Add(buttonBox, 0, wxGROW, 0)
343     headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
344 jonathan 561
345 jonathan 571 sizer.Add(headerBox, 0, wxGROW, 0)
346 jonathan 561
347 jonathan 571 self.__panel.Reparent(self.__dockPanel)
348     self.__panel.SetId(PANEL_ID)
349 jonathan 561
350 jonathan 571 sizer.Add(self.__panel, 1, wxGROW, 0)
351 jonathan 561
352 jonathan 571 sizer.Fit(self.__dockPanel)
353    
354     self.__dockPanel.SetSizer(sizer)
355     self.__dockPanel.SetAutoLayout(True)
356    
357     sizer.SetSizeHints(self.__dockPanel)
358    
359     EVT_BUTTON(self.__dockPanel, ID_BUTTON_DOCK, self._OnToggleDock)
360     EVT_BUTTON(self.__dockPanel, ID_BUTTON_CLOSE, self._OnButtonClose)
361    
362    
363     class DockFrame(wxFrame):
364    
365     def __init__(self, parent, id, title, position, size):
366     wxFrame.__init__(self, parent, id, title, position, size)
367    
368     self.openWindows = {}
369    
370 jonathan 577 self.__update_lock = 0
371 jonathan 571
372     self.SetMainWindow(None)
373    
374 jonathan 577
375     EVT_SIZE(self, self._OnSashSize)
376     EVT_CLOSE(self, self._OnClose)
377    
378 jonathan 571 layout2oppSash = {
379     wxLAYOUT_NONE : wxSASH_NONE,
380     wxLAYOUT_TOP : wxSASH_BOTTOM,
381     wxLAYOUT_LEFT : wxSASH_RIGHT,
382     wxLAYOUT_RIGHT : wxSASH_LEFT,
383     wxLAYOUT_BOTTOM : wxSASH_TOP }
384    
385 jonathan 577
386     def _OnClose(self, event):
387    
388     self.__update_lock += 1
389    
390     #
391     # child windows are not notified when the parent is destroyed
392     # as of v2.4.0.3 so we need to interate over our children
393     # and tell them to go away.
394     #
395     for key in self.openWindows.keys():
396     win = self.openWindows[key]
397     win.Destroy()
398    
399     self.__update_lock -= 1
400    
401     # should really call _UpdateDocks() here but we don't need to
402     # since we're going away
403    
404 jonathan 571 def CreateDock(self, name, id, title, align):
405    
406     if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):
407     orient = wxLAYOUT_VERTICAL
408     else:
409     orient = wxLAYOUT_HORIZONTAL
410    
411     sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)
412     sash.SetOrientation(orient)
413     sash.SetAlignment(align)
414     #print align, DockFrame.layout2oppSash[align]
415     sash.SetSashVisible(DockFrame.layout2oppSash[align], True)
416     sash.SetSashBorder(DockFrame.layout2oppSash[align], True)
417    
418     win = DockableWindow(self, id, name, title, sash, orient)
419    
420     self.__RegisterDock(name, win)
421     EVT_SASH_DRAGGED(self, id, self._OnSashDragged)
422    
423     return win
424    
425     def FindRegisteredDock(self, name):
426     return self.openWindows.get(name)
427    
428 jonathan 631 def OnDockDestroy(self, win):
429 jonathan 571 del self.openWindows[win.GetName()]
430     self._UpdateDocks()
431    
432     def SetMainWindow(self, main):
433     self.__mainWindow = main
434     self._UpdateDocks()
435    
436     def _UpdateDocks(self):
437     #print "_UpdateDocks()"
438 jonathan 577 if self.__update_lock == 0:
439     wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
440 jonathan 571
441     def _OnSashDragged(self, event):
442     if event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE:
443     return
444    
445     id = event.GetId()
446     sash = self.FindWindowById(id)
447     #assert(isinstance(win, wxPanel))
448     dockPanel = sash.GetChildren()[0]
449     #print dockPanel
450     panel = dockPanel.FindWindowById(PANEL_ID)
451     #print panel
452 jonathan 605 assert isinstance(panel, DockPanel)
453 jonathan 571 win = panel.GetDockParent()
454     #print win
455 jonathan 605 assert isinstance(win, DockableWindow)
456 jonathan 571
457 jonathan 605 assert win.IsDocked()
458 jonathan 571
459     rect = event.GetDragRect()
460    
461     win.SetDockSize(rect)
462    
463     self._UpdateDocks()
464    
465     def _OnSashSize(self, event):
466     self._UpdateDocks()
467    
468     def __RegisterDock(self, name, win):
469     if self.FindRegisteredDock(name) is not None:
470     raise ValueError(
471     "A dockable window is already registered under the name '%s'" % name)
472    
473     self.openWindows[name] = win
474    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26