/[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 620 - (show annotations)
Mon Apr 7 10:14:25 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: 12453 byte(s)
Fix Windows problem.

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.__dockPanel.SetSize(self.__topWindow.GetClientSize())
201
202 self.issue(DOCKABLE_UNDOCKED, self.__id, self)
203
204 def IsDocked(self):
205 self.__CheckAllGood()
206
207 return self.__docked
208
209
210 def Show(self, show = True):
211 if show:
212 self.__DoShow()
213 else:
214 self.__DoHide()
215
216 def SetDockSize(self, rect = None):
217
218 #
219 # adjust the size to get the
220 w0, h0 = self.__dockPanel.GetBestSize()
221 w, h = self.__panel.GetBestSize()
222
223 #print (w0, h0), (w, h)
224
225 if (w, h) < (w0, h0):
226 w = w0
227 h = h0
228
229 if rect is not None:
230 rw = rect.width
231 rh = rect.height
232 #print " ", (rw, rh)
233 if rw < w: rw = w
234 if rh < h: rh = h
235 else:
236 rw = w
237 rh = h
238
239 # these are to account for the border?!!?
240 rw += 8 # XXX: without this the sash isn't visible!?!?!?!
241 rh += 8 # XXX: without this the sash isn't visible!?!?!?!
242
243 self.__dockWindow.SetDefaultSize(wxSize(rw, rh))
244
245
246 def Destroy(self):
247 self.__panel.Destroy()
248 self.__floatWindow.Destroy()
249 self.__dockWindow.Destroy()
250 self.__parent.OnDockClose(self)
251
252 ##
253 # Event handlers
254 #
255
256 def _OnButtonClose(self, event):
257 #self.Close()
258 self.Destroy()
259
260 def _OnClose(self, force = False):
261 self.Destroy()
262
263 def _OnToggleDock(self, event):
264 self.__CheckAllGood()
265
266 self.SetDock(not self.IsDocked())
267
268 ##
269 # Private methods
270 #
271
272 def __CheckAllGood(self):
273 if self.__panel is None:
274 raise TypeError("")
275
276 def __DoShow(self):
277 if self.IsShown(): return
278 #print "__DoShow()", self.IsShown()
279
280 self.__topWindow.Show()
281
282 #if self.IsDocked():
283 #self.SetDockSize()
284
285 if self.__topWindow is self.__dockWindow:
286 self.__parent._UpdateDocks()
287
288 def __DoHide(self):
289 if not self.IsShown(): return
290 #print "__DoHide()", self.IsShown()
291 self.__topWindow.Show(False)
292
293 if self.__topWindow is self.__dockWindow:
294 self.__parent._UpdateDocks()
295
296
297 def __CreateBorder(self):
298
299 #self.__panel.Reparent(self) # Make sure we hang on to the panel
300
301 self.__dockPanel = wxPanel(self.__topWindow, -1, style=wxSUNKEN_BORDER)
302 #self.__dockPanel.SetBackgroundColour(wxColour(255, 0, 0))
303
304 if self.__orientation == wxLAYOUT_VERTICAL:
305 sizer = wxBoxSizer(wxVERTICAL)
306 headerBoxOrient = wxHORIZONTAL
307 else:
308 sizer = wxBoxSizer(wxHORIZONTAL)
309 headerBoxOrient = wxVERTICAL
310
311
312 headerBox = wxStaticBoxSizer(
313 wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
314
315 buttonBox = wxBoxSizer(wxHORIZONTAL)
316
317 #
318 # ideally, we should be able to rotate this text depending on
319 # our orientation
320 #
321 text = wxStaticText(self.__dockPanel, -1, self.GetTitle(),
322 style = wxALIGN_CENTRE)
323
324 #
325 # Perhaps using wxToggleButton would be better, but it's only
326 # supported under wxMSW and wxGTK as of v2.4.0.3
327 #
328 self.__dockButton = wxButton(self.__dockPanel, ID_BUTTON_DOCK, "WWWWWW",
329 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
330
331 closeX = wxButton(self.__dockPanel, ID_BUTTON_CLOSE, "X",
332 style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
333
334 buttonBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
335 buttonBox.Add(closeX, 0, wxALIGN_RIGHT, 0)
336
337 if self.__orientation == wxLAYOUT_VERTICAL:
338 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
339 headerBox.Add(1, 20, 1, wxGROW)
340 headerBox.Add(buttonBox, 0, wxGROW | wxALIGN_RIGHT, 0)
341 else:
342 headerBox.Add(buttonBox, 0, wxGROW, 0)
343 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
344
345 sizer.Add(headerBox, 0, wxGROW, 0)
346
347 self.__panel.Reparent(self.__dockPanel)
348 self.__panel.SetId(PANEL_ID)
349
350 sizer.Add(self.__panel, 1, wxGROW, 0)
351
352 sizer.Fit(self.__dockPanel)
353
354 self.__dockPanel.SetSizer(sizer)
355 self.__dockPanel.SetAutoLayout(True)
356
357 sizer.SetSizeHints(self.__dockPanel)
358
359 EVT_BUTTON(self.__dockPanel, ID_BUTTON_DOCK, self._OnToggleDock)
360 EVT_BUTTON(self.__dockPanel, ID_BUTTON_CLOSE, self._OnButtonClose)
361
362
363 class DockFrame(wxFrame):
364
365 def __init__(self, parent, id, title, position, size):
366 wxFrame.__init__(self, parent, id, title, position, size)
367
368 self.openWindows = {}
369
370 self.__update_lock = 0
371
372 self.SetMainWindow(None)
373
374
375 EVT_SIZE(self, self._OnSashSize)
376 EVT_CLOSE(self, self._OnClose)
377
378 layout2oppSash = {
379 wxLAYOUT_NONE : wxSASH_NONE,
380 wxLAYOUT_TOP : wxSASH_BOTTOM,
381 wxLAYOUT_LEFT : wxSASH_RIGHT,
382 wxLAYOUT_RIGHT : wxSASH_LEFT,
383 wxLAYOUT_BOTTOM : wxSASH_TOP }
384
385
386 def _OnClose(self, event):
387
388 self.__update_lock += 1
389
390 #
391 # child windows are not notified when the parent is destroyed
392 # as of v2.4.0.3 so we need to interate over our children
393 # and tell them to go away.
394 #
395 for key in self.openWindows.keys():
396 win = self.openWindows[key]
397 win.Destroy()
398
399 self.__update_lock -= 1
400
401 # should really call _UpdateDocks() here but we don't need to
402 # since we're going away
403
404 def CreateDock(self, name, id, title, align):
405
406 if align in (wxLAYOUT_NONE, wxLAYOUT_LEFT, wxLAYOUT_RIGHT):
407 orient = wxLAYOUT_VERTICAL
408 else:
409 orient = wxLAYOUT_HORIZONTAL
410
411 sash = wxSashLayoutWindow(self, id, style=wxNO_BORDER|wxSW_3D)
412 sash.SetOrientation(orient)
413 sash.SetAlignment(align)
414 #print align, DockFrame.layout2oppSash[align]
415 sash.SetSashVisible(DockFrame.layout2oppSash[align], True)
416 sash.SetSashBorder(DockFrame.layout2oppSash[align], True)
417
418 win = DockableWindow(self, id, name, title, sash, orient)
419
420 self.__RegisterDock(name, win)
421 EVT_SASH_DRAGGED(self, id, self._OnSashDragged)
422
423 return win
424
425 def FindRegisteredDock(self, name):
426 return self.openWindows.get(name)
427
428 def OnDockClose(self, win):
429 del self.openWindows[win.GetName()]
430 self._UpdateDocks()
431
432 def SetMainWindow(self, main):
433 self.__mainWindow = main
434 self._UpdateDocks()
435
436 def _UpdateDocks(self):
437 #print "_UpdateDocks()"
438 if self.__update_lock == 0:
439 wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
440
441 def _OnSashDragged(self, event):
442 if event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE:
443 return
444
445 id = event.GetId()
446 sash = self.FindWindowById(id)
447 #assert(isinstance(win, wxPanel))
448 dockPanel = sash.GetChildren()[0]
449 #print dockPanel
450 panel = dockPanel.FindWindowById(PANEL_ID)
451 #print panel
452 assert isinstance(panel, DockPanel)
453 win = panel.GetDockParent()
454 #print win
455 assert isinstance(win, DockableWindow)
456
457 assert win.IsDocked()
458
459 rect = event.GetDragRect()
460
461 win.SetDockSize(rect)
462
463 self._UpdateDocks()
464
465 def _OnSashSize(self, event):
466 self._UpdateDocks()
467
468 def __RegisterDock(self, name, win):
469 if self.FindRegisteredDock(name) is not None:
470 raise ValueError(
471 "A dockable window is already registered under the name '%s'" % name)
472
473 self.openWindows[name] = win
474

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26