/[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 571 - (hide annotations)
Fri Mar 28 17:06: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: 11756 byte(s)
Complete rework on the dock code so that
        that it is fairly removed from the rest of the Thuban application.
        It is easy to add new docks which the rest of the program having
        to be aware of them.

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     #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 571 def Close(self):
245     self.__panel.Close(True)
246     self.__floatWindow.Destroy()
247     self.__dockWindow.Destroy()
248     self.__parent.OnDockClose(self)
249 jonathan 561
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     self.Close()
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     EVT_SIZE(self, self._OnSashSize)
368    
369     self.SetMainWindow(None)
370    
371     layout2oppSash = {
372     wxLAYOUT_NONE : wxSASH_NONE,
373     wxLAYOUT_TOP : wxSASH_BOTTOM,
374     wxLAYOUT_LEFT : wxSASH_RIGHT,
375     wxLAYOUT_RIGHT : wxSASH_LEFT,
376     wxLAYOUT_BOTTOM : wxSASH_TOP }
377    
378     def CreateDock(self, name, id, title, align):
379    
380     if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):
381     orient = wxLAYOUT_VERTICAL
382     else:
383     orient = wxLAYOUT_HORIZONTAL
384    
385     sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)
386     sash.SetOrientation(orient)
387     sash.SetAlignment(align)
388     #print align, DockFrame.layout2oppSash[align]
389     sash.SetSashVisible(DockFrame.layout2oppSash[align], True)
390     sash.SetSashBorder(DockFrame.layout2oppSash[align], True)
391    
392     win = DockableWindow(self, id, name, title, sash, orient)
393    
394     self.__RegisterDock(name, win)
395     EVT_SASH_DRAGGED(self, id, self._OnSashDragged)
396    
397     return win
398    
399     def FindRegisteredDock(self, name):
400     return self.openWindows.get(name)
401    
402     def OnDockClose(self, win):
403     del self.openWindows[win.GetName()]
404     self._UpdateDocks()
405    
406     def SetMainWindow(self, main):
407     self.__mainWindow = main
408     self._UpdateDocks()
409    
410     def _UpdateDocks(self):
411     #print "_UpdateDocks()"
412     wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
413    
414     def _OnSashDragged(self, event):
415     if event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE:
416     return
417    
418     id = event.GetId()
419     sash = self.FindWindowById(id)
420     #assert(isinstance(win, wxPanel))
421     dockPanel = sash.GetChildren()[0]
422     #print dockPanel
423     panel = dockPanel.FindWindowById(PANEL_ID)
424     #print panel
425     assert(isinstance(panel, DockPanel))
426     win = panel.GetDockParent()
427     #print win
428     assert(isinstance(win, DockableWindow))
429    
430     assert(win.IsDocked())
431    
432     rect = event.GetDragRect()
433    
434     win.SetDockSize(rect)
435    
436     self._UpdateDocks()
437    
438     def _OnSashSize(self, event):
439     self._UpdateDocks()
440    
441     def __RegisterDock(self, name, win):
442     if self.FindRegisteredDock(name) is not None:
443     raise ValueError(
444     "A dockable window is already registered under the name '%s'" % name)
445    
446     self.openWindows[name] = win
447    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26