/[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 651 - (hide annotations)
Fri Apr 11 14:27:53 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: 14369 byte(s)
Use new bitmaps for the control buttons.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26