/[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 657 - (hide annotations)
Fri Apr 11 18:29:57 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/dock.py
File MIME type: text/x-python
File size: 14634 byte(s)
check in to test dock changes under windows.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26