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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 571 - (show 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 # 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 from dialogs import NonModalDialog
19
20 from messages import DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
21
22 import gc
23
24 ID_BUTTON_DOCK = 4001
25 ID_BUTTON_CLOSE = 4002
26
27 PANEL_ID = 3141
28
29 class DockPanel(wxPanel):
30
31 def __init__(self, parent, id):
32
33 if not isinstance(parent, DockableWindow):
34 raise TypeError("")
35
36 wxPanel.__init__(self, parent.GetCurrentParent(), id)
37
38 #self.SetDockParent(None)
39 parent.SetPanel(self)
40
41 def SetDockParent(self, parent):
42 self.__dockParent = parent
43
44 def GetDockParent(self):
45 return self.__dockParent
46
47 def SetDock(self, dock):
48 #if dock == self.IsDocked(): return
49
50 if dock:
51 self.Dock()
52 else:
53 self.UnDock()
54
55 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 class DockableWindow(Publisher):
65
66 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 def __init__(self, parent, id, name,
78 title, dockWindow, orient): #, panel, docked = False, show = True):
79
80 if not isinstance(parent, DockFrame): raise TypeError("")
81
82 self.__parent = parent
83 self.__id = id
84 self.__name = name
85
86 self.__orientation = orient
87
88 self.__dockWindow = dockWindow
89 #self.__floatWindow = NonModalDialog(parent, name, title)
90 self.__floatWindow = wxFrame(parent, id, title)
91
92 self.__docked = False
93
94 self.__dockPanel = None
95
96 if self.__docked:
97 self.__topWindow = self.__dockWindow
98 else:
99 self.__topWindow = self.__floatWindow
100
101 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 if not isinstance(panel, DockPanel):
121 raise TypeError("")
122
123 self.__panel = panel
124 self.__panel.SetDockParent(self)
125 self.__CreateBorder()
126
127 self.SetDock(self.__docked)
128
129 def GetPanel(self):
130 return self.__panel
131
132 def GetCurrentParent(self):
133 return self.__topWindow
134
135 def SetDock(self, dock):
136
137 self.__CheckAllGood()
138
139 if dock:
140 self.Dock()
141 else:
142 self.UnDock()
143
144 def Dock(self):
145 self.__CheckAllGood()
146
147 wasVisible = self.IsShown()
148
149 if wasVisible: self.Show(False)
150
151 self.__docked = True
152
153 #
154 # save window information
155 #
156 self.__floatSize = self.GetSize()
157 self.__floatPosition = self.GetPosition()
158
159 #
160 # reparent
161 #
162 self.__topWindow = self.__dockWindow
163 self.__dockPanel.Reparent(self.__topWindow)
164
165 self.__dockButton.SetLabel(_("Undock"))
166
167 self.SetDockSize(self.__dockWindow.GetSize())
168
169 if wasVisible: self.Show(True)
170
171 #self.__parent._UpdateDocks()
172
173 self.issue(DOCKABLE_DOCKED, self.__id, self)
174
175 def UnDock(self):
176 self.__CheckAllGood()
177
178 wasVisible = self.IsShown()
179
180 if wasVisible: self.Show(False)
181
182 self.__docked = False
183
184 #
185 # reparent
186 #
187 self.__topWindow = self.__floatWindow
188 self.__dockPanel.Reparent(self.__topWindow)
189
190 self.__dockButton.SetLabel(_("Dock"))
191
192 if wasVisible: self.Show()
193
194 #
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
200 self.issue(DOCKABLE_UNDOCKED, self.__id, self)
201
202 def IsDocked(self):
203 self.__CheckAllGood()
204
205 return self.__docked
206
207
208 def Show(self, show = True):
209 if show:
210 self.__DoShow()
211 else:
212 self.__DoHide()
213
214 def SetDockSize(self, rect = None):
215
216 #
217 # adjust the size to get the
218 w0, h0 = self.__dockPanel.GetBestSize()
219 w, h = self.__panel.GetBestSize()
220
221 #print (w0, h0), (w, h)
222
223 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
243
244 def Close(self):
245 self.__panel.Close(True)
246 self.__floatWindow.Destroy()
247 self.__dockWindow.Destroy()
248 self.__parent.OnDockClose(self)
249
250 ##
251 # Event handlers
252 #
253
254 def _OnButtonClose(self, event):
255 self.Close()
256
257 def _OnClose(self, force = False):
258 self.Close()
259
260 def _OnToggleDock(self, event):
261 self.__CheckAllGood()
262
263 self.SetDock(not self.IsDocked())
264
265 ##
266 # Private methods
267 #
268
269 def __CheckAllGood(self):
270 if self.__panel is None:
271 raise TypeError("")
272
273 def __DoShow(self):
274 if self.IsShown(): return
275 #print "__DoShow()", self.IsShown()
276
277 self.__topWindow.Show()
278
279 #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 else:
305 sizer = wxBoxSizer(wxHORIZONTAL)
306 headerBoxOrient = wxVERTICAL
307
308
309 headerBox = wxStaticBoxSizer(
310 wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
311
312 buttonBox = wxBoxSizer(wxHORIZONTAL)
313
314 #
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
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 self.__dockButton = wxButton(self.__dockPanel, ID_BUTTON_DOCK, "WWWWWW",
326 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
327
328 closeX = wxButton(self.__dockPanel, ID_BUTTON_CLOSE, "X",
329 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
330
331 buttonBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
332 buttonBox.Add(closeX, 0, wxALIGN_RIGHT, 0)
333
334 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
342 sizer.Add(headerBox, 0, wxGROW, 0)
343
344 self.__panel.Reparent(self.__dockPanel)
345 self.__panel.SetId(PANEL_ID)
346
347 sizer.Add(self.__panel, 1, wxGROW, 0)
348
349 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