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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 605 by jonathan, Fri Apr 4 12:16:13 2003 UTC revision 1527 by jonathan, Wed Jul 30 15:43:28 2003 UTC
# Line 5  Line 5 
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
7    
8  """Classes for creating dockable windows"""  """Classes for creating dockable windows.
9    
10    The DockFrame is the main window that will be the parent for the
11    dockable windows.
12    
13    The DockPanel is a panel that all windows that wish to be dockable
14    should derive from.
15    """
16    
17  __version__ = "$Revision$"  __version__ = "$Revision$"
18    
19    import resource
20    
21  from Thuban import _  from Thuban import _
22    
23  from wxPython.wx import *  from wxPython.wx import *
# Line 19  from dialogs import NonModalDialog Line 28  from dialogs import NonModalDialog
28    
29  from messages import DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED  from messages import DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
30    
 import gc  
   
31  ID_BUTTON_DOCK = 4001  ID_BUTTON_DOCK = 4001
32  ID_BUTTON_CLOSE = 4002  ID_BUTTON_CLOSE = 4002
33    
34  PANEL_ID = 3141  PANEL_ID = 3141
35    
36    DOCK_BMP   = "dock_12"
37    UNDOCK_BMP = "undock_12"
38    CLOSE_BMP  = "close_12"
39    
40  class DockPanel(wxPanel):  class DockPanel(wxPanel):
41        """A DockPanel is a panel that should be derived from to create panels
42        that can be docked in a DockFrame.
43        """
44    
45      def __init__(self, parent, id):      def __init__(self, parent, id):
46            """parent should be a DockableWindow created from
47            DockFrame.CreateDock().
48            """
49    
50          if not isinstance(parent, DockableWindow):          if not isinstance(parent, DockableWindow):
51              raise TypeError("")              raise TypeError("")
52    
53          wxPanel.__init__(self, parent.GetCurrentParent(), id)          wxPanel.__init__(self, parent.GetCurrentParent(), id)
54    
55            self.parent = parent
56    
57          #self.SetDockParent(None)          #self.SetDockParent(None)
58          parent.SetPanel(self)          #parent.SetPanel(self)
59    
60        def Create(self):
61            self.parent.SetPanel(self)
62            
63      def SetDockParent(self, parent):      def SetDockParent(self, parent):
64          self.__dockParent = parent          self.__dockParent = parent
65    
# Line 45  class DockPanel(wxPanel): Line 67  class DockPanel(wxPanel):
67          return self.__dockParent          return self.__dockParent
68    
69      def SetDock(self, dock):      def SetDock(self, dock):
70            """Specifically set the docked state of the panel
71            to dock (True or False).
72            """
73          #if dock == self.IsDocked(): return          #if dock == self.IsDocked(): return
74    
75          if dock:          if dock:
# Line 53  class DockPanel(wxPanel): Line 78  class DockPanel(wxPanel):
78              self.UnDock()              self.UnDock()
79    
80      def Dock(self):      def Dock(self):
81            """Dock the panel in the DockFrame."""
82          self.GetDockParent().Dock()          self.GetDockParent().Dock()
83    
84      def UnDock(self):      def UnDock(self):
85            """Undock the panel in the DockFrame."""
86          self.GetDockParent().UnDock()          self.GetDockParent().UnDock()
87    
88      def IsDocked(self):      def IsDocked(self):
89            """Return True if the panel is docked."""
90          return self.GetDockParent().IsDocked()          return self.GetDockParent().IsDocked()
91    
92  class DockableWindow(Publisher):  class DockableWindow(Publisher):
93    
94      def __getattr__(self, attr):      def __getattr__(self, attr):
   
         #print attr  
95          return getattr(self.__topWindow, attr)          return getattr(self.__topWindow, attr)
         #try:  
         #except AttributeError:  
             #raise  
             #return self.__dict__[attr]  
             #return getattr(self, attr)  
             #pass  
96    
97      def __init__(self, parent, id, name,      def __init__(self, parent, id, name, title, dockWindow, orient):
98                   title, dockWindow, orient): #, panel, docked = False, show = True):          """Create the dockable window.
99    
100            Initially, the window is hidden, but in an undocked state.
101            """
102    
103          if not isinstance(parent, DockFrame): raise TypeError("")          if not isinstance(parent, DockFrame): raise TypeError("")
104    
# Line 86  class DockableWindow(Publisher): Line 109  class DockableWindow(Publisher):
109          self.__orientation = orient          self.__orientation = orient
110    
111          self.__dockWindow  = dockWindow          self.__dockWindow  = dockWindow
         #self.__floatWindow = NonModalDialog(parent, name, title)  
112          self.__floatWindow = wxFrame(parent, id, title)          self.__floatWindow = wxFrame(parent, id, title)
113    
114          self.__docked      = False          self.__docked      = False
   
         self.__dockPanel  = None  
   
115          if self.__docked:          if self.__docked:
116              self.__topWindow = self.__dockWindow              self.__topWindow = self.__dockWindow
117          else:          else:
# Line 101  class DockableWindow(Publisher): Line 120  class DockableWindow(Publisher):
120          self.__floatSize     = None          self.__floatSize     = None
121          self.__floatPosition = None          self.__floatPosition = None
122    
123            self.__dockPanel  = None
124          self.__panel = None          self.__panel = None
125    
126          self.__dockWindow.Hide()          self.__dockWindow.Hide()
# Line 142  class DockableWindow(Publisher): Line 162  class DockableWindow(Publisher):
162              self.UnDock()              self.UnDock()
163    
164      def Dock(self):      def Dock(self):
165            """Dock the window."""
166          self.__CheckAllGood()          self.__CheckAllGood()
167    
168          wasVisible = self.IsShown()          wasVisible = self.IsShown()
# Line 162  class DockableWindow(Publisher): Line 183  class DockableWindow(Publisher):
183          self.__topWindow = self.__dockWindow          self.__topWindow = self.__dockWindow
184          self.__dockPanel.Reparent(self.__topWindow)          self.__dockPanel.Reparent(self.__topWindow)
185    
186          self.__dockButton.SetLabel(_("Undock"))          self.__dockButton.SetBitmapLabel(self.__bmpUnDock)
187            self.__dockButton.SetBitmapFocus(self.__bmpUnDock)
188            self.__dockButton.SetBitmapSelected(self.__bmpUnDock)
189            self.__dockButton.SetBitmapDisabled(self.__bmpUnDock)
190            self.__dockButton.SetToolTip(wxToolTip(_("Undock")))
191    
192          self.SetDockSize(self.__dockWindow.GetSize())          self.SetDockSize(self.__dockWindow.GetSize())
193    
194          if wasVisible: self.Show(True)          if wasVisible: self.Show(True)
195    
         #self.__parent._UpdateDocks()  
   
196          self.issue(DOCKABLE_DOCKED, self.__id, self)          self.issue(DOCKABLE_DOCKED, self.__id, self)
197    
198      def UnDock(self):      def UnDock(self):
199            """Undock the window."""
200          self.__CheckAllGood()          self.__CheckAllGood()
201    
202          wasVisible = self.IsShown()          wasVisible = self.IsShown()
# Line 187  class DockableWindow(Publisher): Line 211  class DockableWindow(Publisher):
211          self.__topWindow = self.__floatWindow          self.__topWindow = self.__floatWindow
212          self.__dockPanel.Reparent(self.__topWindow)          self.__dockPanel.Reparent(self.__topWindow)
213    
214          self.__dockButton.SetLabel(_("Dock"))          self.__dockButton.SetBitmapLabel(self.__bmpDock)
215            self.__dockButton.SetBitmapFocus(self.__bmpDock)
216            self.__dockButton.SetBitmapSelected(self.__bmpDock)
217            self.__dockButton.SetBitmapDisabled(self.__bmpDock)
218            self.__dockButton.SetToolTip(wxToolTip(_("Dock")))
219    
220          if wasVisible: self.Show()          if wasVisible: self.Show()
221    
222          #          #
223          # restore window information          # restore window information
224          #          #
225          if self.__floatPosition is not None: self.SetPosition(self.__floatPosition)          if self.__floatPosition is not None:
226          if self.__floatSize     is not None: self.SetSize(self.__floatSize)              self.SetPosition(self.__floatPosition)
227            if self.__floatSize is not None:
228                self.SetSize(self.__floatSize)
229    
230            self.__dockPanel.SetSize(self.__topWindow.GetClientSize())
231    
232          self.issue(DOCKABLE_UNDOCKED, self.__id, self)          self.issue(DOCKABLE_UNDOCKED, self.__id, self)
233    
234      def IsDocked(self):      def IsDocked(self):
235          self.__CheckAllGood()          self.__CheckAllGood()
   
236          return self.__docked          return self.__docked
237    
   
238      def Show(self, show = True):      def Show(self, show = True):
239            """Show or hide the window."""
240          if show:          if show:
241              self.__DoShow()              self.__DoShow()
242          else:          else:
243              self.__DoHide()              self.__DoHide()
244    
245      def SetDockSize(self, rect = None):      def SetDockSize(self, rect = None):
246            """Set the size of the dock window to rect."""
247    
         #  
         # adjust the size to get the  
248          w0, h0 = self.__dockPanel.GetBestSize()          w0, h0 = self.__dockPanel.GetBestSize()
249          w, h = self.__panel.GetBestSize()          w, h = self.__panel.GetBestSize()
250    
         #print (w0, h0), (w, h)  
   
251          if (w, h) < (w0, h0):          if (w, h) < (w0, h0):
252              w = w0              w = w0
253              h = h0              h = h0
254                                                                                          
255          if rect is not None:          if rect is not None:
256              rw = rect.width              rw = rect.width
257              rh = rect.height              rh = rect.height
             #print "   ", (rw, rh)  
258              if rw < w: rw = w              if rw < w: rw = w
259              if rh < h: rh = h              if rh < h: rh = h
260          else:          else:
# Line 245  class DockableWindow(Publisher): Line 272  class DockableWindow(Publisher):
272          self.__panel.Destroy()          self.__panel.Destroy()
273          self.__floatWindow.Destroy()          self.__floatWindow.Destroy()
274          self.__dockWindow.Destroy()          self.__dockWindow.Destroy()
275          self.__parent.OnDockClose(self)          self.__parent.OnDockDestroy(self)
276                    
277      ##      ##
278      # Event handlers      # Event handlers
# Line 253  class DockableWindow(Publisher): Line 280  class DockableWindow(Publisher):
280    
281      def _OnButtonClose(self, event):      def _OnButtonClose(self, event):
282          #self.Close()          #self.Close()
283          self.Destroy()          self.Show(False)
284    
285      def _OnClose(self, force = False):      def _OnClose(self, force = False):
286          self.Destroy()          self.Show(False)
287    
288      def _OnToggleDock(self, event):      def _OnToggleDock(self, event):
289          self.__CheckAllGood()          self.__CheckAllGood()
# Line 273  class DockableWindow(Publisher): Line 300  class DockableWindow(Publisher):
300    
301      def __DoShow(self):      def __DoShow(self):
302          if self.IsShown(): return          if self.IsShown(): return
         #print "__DoShow()", self.IsShown()  
303    
304          self.__topWindow.Show()          self.__topWindow.Show()
305    
         #if self.IsDocked():  
             #self.SetDockSize()  
   
306          if self.__topWindow is self.__dockWindow:          if self.__topWindow is self.__dockWindow:
307              self.__parent._UpdateDocks()              self.__parent._UpdateDocks()
308                            
309      def __DoHide(self):      def __DoHide(self):
310          if not self.IsShown(): return          if not self.IsShown(): return
311          #print "__DoHide()", self.IsShown()  
312          self.__topWindow.Show(False)          self.__topWindow.Show(False)
313    
314          if self.__topWindow is self.__dockWindow:          if self.__topWindow is self.__dockWindow:
315              self.__parent._UpdateDocks()              self.__parent._UpdateDocks()
316    
   
317      def __CreateBorder(self):      def __CreateBorder(self):
318    
         #self.__panel.Reparent(self) # Make sure we hang on to the panel  
   
319          self.__dockPanel = wxPanel(self.__topWindow, -1, style=wxSUNKEN_BORDER)          self.__dockPanel = wxPanel(self.__topWindow, -1, style=wxSUNKEN_BORDER)
320          #self.__dockPanel.SetBackgroundColour(wxColour(255, 0, 0))  
321            self.__panel.Reparent(self.__dockPanel)
322            self.__panel.SetId(PANEL_ID)
323    
324          if self.__orientation == wxLAYOUT_VERTICAL:          if self.__orientation == wxLAYOUT_VERTICAL:
325              sizer = wxBoxSizer(wxVERTICAL)              sizer = wxBoxSizer(wxVERTICAL)
# Line 310  class DockableWindow(Publisher): Line 332  class DockableWindow(Publisher):
332          headerBox = wxStaticBoxSizer(          headerBox = wxStaticBoxSizer(
333                          wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)                          wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
334    
         buttonBox = wxBoxSizer(wxHORIZONTAL)  
   
335          #          #
336          # ideally, we should be able to rotate this text depending on          # ideally, we should be able to rotate this text depending on
337          # our orientation          # our orientation
338          #          #
339          text = wxStaticText(self.__dockPanel, -1, self.GetTitle(),          text = wxStaticText(self.__dockPanel, -1, self.GetTitle(),
340                               style = wxSIMPLE_BORDER | wxALIGN_CENTRE)                               style = wxALIGN_CENTRE)
341            font = text.GetFont()
342            font.SetPointSize(10)
343            text.SetFont(font)
344    
345          #          #
346          # Perhaps using wxToggleButton would be better, but it's only          # load the dock/undock/close bitmaps
347          # supported under wxMSW and wxGTK as of v2.4.0.3          # and create the buttons
348          #          #
349          self.__dockButton = wxButton(self.__dockPanel, ID_BUTTON_DOCK, "WWWWWW",          self.__bmpDock   = \
350                                       style = wxBU_EXACTFIT | wxADJUST_MINSIZE)              resource.GetBitmapResource(DOCK_BMP, wxBITMAP_TYPE_XPM)
351            self.__bmpUnDock = \
352                resource.GetBitmapResource(UNDOCK_BMP, wxBITMAP_TYPE_XPM)
353    
354            if self.__docked:
355                bmp = self.__bmpDock
356            else:
357                bmp = self.__bmpUnDock
358    
359          closeX = wxButton(self.__dockPanel, ID_BUTTON_CLOSE, "X",          self.__dockButton = wxBitmapButton(
360                           style = wxBU_EXACTFIT | wxADJUST_MINSIZE)              self.__dockPanel, ID_BUTTON_DOCK,
361                bmp,
362                size = wxSize(bmp.GetWidth() + 4, bmp.GetHeight() + 4),
363                style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
364    
365          buttonBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)          bmp = resource.GetBitmapResource(CLOSE_BMP, wxBITMAP_TYPE_XPM)
         buttonBox.Add(closeX, 0, wxALIGN_RIGHT, 0)  
366    
367            closeX = wxBitmapButton(self.__dockPanel, ID_BUTTON_CLOSE, bmp,
368                              size = wxSize(bmp.GetWidth() + 4,
369                                            bmp.GetHeight() + 4),
370                              style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
371            closeX.SetToolTip(wxToolTip(_("Close")))
372    
373            #
374            # fill in the sizer in an order appropriate to the orientation
375            #
376          if self.__orientation == wxLAYOUT_VERTICAL:          if self.__orientation == wxLAYOUT_VERTICAL:
377              headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)              headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
378              headerBox.Add(1, 20, 1, wxGROW)              headerBox.Add(1, 5, 1, wxGROW)
379              headerBox.Add(buttonBox, 0, wxGROW | wxALIGN_RIGHT, 0)              headerBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
380                headerBox.Add(closeX, 0, wxALIGN_RIGHT | wxLEFT, 4)
381          else:          else:
382              headerBox.Add(buttonBox, 0, wxGROW, 0)              headerBox.Add(closeX, 0, wxALIGN_RIGHT | wxBOTTOM, 4)
383                headerBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
384              headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)              headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
385    
386          sizer.Add(headerBox, 0, wxGROW, 0)          sizer.Add(headerBox, 0, wxGROW, 0)
   
         self.__panel.Reparent(self.__dockPanel)  
         self.__panel.SetId(PANEL_ID)  
   
387          sizer.Add(self.__panel, 1, wxGROW, 0)          sizer.Add(self.__panel, 1, wxGROW, 0)
388    
         sizer.Fit(self.__dockPanel)  
389    
         self.__dockPanel.SetSizer(sizer)  
390          self.__dockPanel.SetAutoLayout(True)          self.__dockPanel.SetAutoLayout(True)
391            self.__dockPanel.SetSizer(sizer)
392          sizer.SetSizeHints(self.__dockPanel)          sizer.SetSizeHints(self.__dockPanel)
393            sizer.SetSizeHints(self.__floatWindow)
394    
395          EVT_BUTTON(self.__dockPanel, ID_BUTTON_DOCK, self._OnToggleDock)          EVT_BUTTON(self.__dockPanel, ID_BUTTON_DOCK, self._OnToggleDock)
396          EVT_BUTTON(self.__dockPanel, ID_BUTTON_CLOSE, self._OnButtonClose)          EVT_BUTTON(self.__dockPanel, ID_BUTTON_CLOSE, self._OnButtonClose)
397    
398    
399  class DockFrame(wxFrame):  class DockFrame(wxFrame):
400        """A DockFrame is a frame that will contain dockable panels."""
401    
402      def __init__(self, parent, id, title, position, size):      def __init__(self, parent, id, title, position, size):
403          wxFrame.__init__(self, parent, id, title, position, size)          wxFrame.__init__(self, parent, id, title, position, size)
# Line 371  class DockFrame(wxFrame): Line 410  class DockFrame(wxFrame):
410    
411    
412          EVT_SIZE(self, self._OnSashSize)          EVT_SIZE(self, self._OnSashSize)
413          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self.OnClose)
414    
415      layout2oppSash = {      layout2oppSash = {
416              wxLAYOUT_NONE   : wxSASH_NONE,              wxLAYOUT_NONE   : wxSASH_NONE,
# Line 381  class DockFrame(wxFrame): Line 420  class DockFrame(wxFrame):
420              wxLAYOUT_BOTTOM : wxSASH_TOP }              wxLAYOUT_BOTTOM : wxSASH_TOP }
421    
422    
423      def _OnClose(self, event):      def OnClose(self, event):
424    
425          self.__update_lock += 1          self.__update_lock += 1
426    
# Line 400  class DockFrame(wxFrame): Line 439  class DockFrame(wxFrame):
439          # since we're going away          # since we're going away
440    
441      def CreateDock(self, name, id, title, align):      def CreateDock(self, name, id, title, align):
442            """Create a new dock. align specifies where the dock will
443            be placed. It can be one of wxLAYOUT_NONE, wxLAYOUT_LEFT,
444            wxLAYOUT_RIGHT.
445            """
446    
447          if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):          if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):
448              orient = wxLAYOUT_VERTICAL              orient = wxLAYOUT_VERTICAL
# Line 409  class DockFrame(wxFrame): Line 452  class DockFrame(wxFrame):
452          sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)          sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)
453          sash.SetOrientation(orient)          sash.SetOrientation(orient)
454          sash.SetAlignment(align)          sash.SetAlignment(align)
         #print align, DockFrame.layout2oppSash[align]  
455          sash.SetSashVisible(DockFrame.layout2oppSash[align], True)          sash.SetSashVisible(DockFrame.layout2oppSash[align], True)
456          sash.SetSashBorder(DockFrame.layout2oppSash[align], True)          sash.SetSashBorder(DockFrame.layout2oppSash[align], True)
457    
# Line 421  class DockFrame(wxFrame): Line 463  class DockFrame(wxFrame):
463          return win          return win
464    
465      def FindRegisteredDock(self, name):      def FindRegisteredDock(self, name):
466            """Return a reference to a dock that has name."""
467          return self.openWindows.get(name)          return self.openWindows.get(name)
468    
469      def OnDockClose(self, win):      def OnDockDestroy(self, win):
470          del self.openWindows[win.GetName()]          del self.openWindows[win.GetName()]
471          self._UpdateDocks()          self._UpdateDocks()
472    
# Line 432  class DockFrame(wxFrame): Line 475  class DockFrame(wxFrame):
475          self._UpdateDocks()          self._UpdateDocks()
476                    
477      def _UpdateDocks(self):      def _UpdateDocks(self):
         #print "_UpdateDocks()"  
478          if self.__update_lock == 0:          if self.__update_lock == 0:
479              wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)              wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
480    
# Line 444  class DockFrame(wxFrame): Line 486  class DockFrame(wxFrame):
486          sash = self.FindWindowById(id)          sash = self.FindWindowById(id)
487          #assert(isinstance(win, wxPanel))          #assert(isinstance(win, wxPanel))
488          dockPanel = sash.GetChildren()[0]          dockPanel = sash.GetChildren()[0]
         #print dockPanel  
489          panel = dockPanel.FindWindowById(PANEL_ID)          panel = dockPanel.FindWindowById(PANEL_ID)
         #print panel  
490          assert isinstance(panel, DockPanel)          assert isinstance(panel, DockPanel)
491          win = panel.GetDockParent()          win = panel.GetDockParent()
         #print win  
492          assert isinstance(win, DockableWindow)          assert isinstance(win, DockableWindow)
493    
494          assert win.IsDocked()          assert win.IsDocked()

Legend:
Removed from v.605  
changed lines
  Added in v.1527

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26