/[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 651 - (show 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 # 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 import resource
13
14 from Thuban import _
15
16 from wxPython.wx import *
17
18 from Thuban.Lib.connector import Publisher
19
20 from dialogs import NonModalDialog
21
22 from messages import DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
23
24 ID_BUTTON_DOCK = 4001
25 ID_BUTTON_CLOSE = 4002
26
27 PANEL_ID = 3141
28
29 DOCK_BMP = "dock_12"
30 UNDOCK_BMP = "undock_12"
31 CLOSE_BMP = "close_12"
32
33 class DockPanel(wxPanel):
34
35 def __init__(self, parent, id):
36
37 if not isinstance(parent, DockableWindow):
38 raise TypeError("")
39
40 wxPanel.__init__(self, parent.GetCurrentParent(), id)
41
42 #self.SetDockParent(None)
43 parent.SetPanel(self)
44
45 def SetDockParent(self, parent):
46 self.__dockParent = parent
47
48 def GetDockParent(self):
49 return self.__dockParent
50
51 def SetDock(self, dock):
52 #if dock == self.IsDocked(): return
53
54 if dock:
55 self.Dock()
56 else:
57 self.UnDock()
58
59 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 class DockableWindow(Publisher):
69
70 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 def __init__(self, parent, id, name,
82 title, dockWindow, orient): #, panel, docked = False, show = True):
83
84 if not isinstance(parent, DockFrame): raise TypeError("")
85
86 self.__parent = parent
87 self.__id = id
88 self.__name = name
89
90 self.__orientation = orient
91
92 self.__dockWindow = dockWindow
93 #self.__floatWindow = NonModalDialog(parent, name, title)
94 self.__floatWindow = wxFrame(parent, id, title)
95
96 self.__docked = False
97
98 self.__dockPanel = None
99
100 if self.__docked:
101 self.__topWindow = self.__dockWindow
102 else:
103 self.__topWindow = self.__floatWindow
104
105 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 if not isinstance(panel, DockPanel):
125 raise TypeError("")
126
127 self.__panel = panel
128 self.__panel.SetDockParent(self)
129 self.__CreateBorder()
130
131 self.SetDock(self.__docked)
132
133 def GetPanel(self):
134 return self.__panel
135
136 def GetCurrentParent(self):
137 return self.__topWindow
138
139 def SetDock(self, dock):
140
141 self.__CheckAllGood()
142
143 if dock:
144 self.Dock()
145 else:
146 self.UnDock()
147
148 def Dock(self):
149 self.__CheckAllGood()
150
151 wasVisible = self.IsShown()
152
153 if wasVisible: self.Show(False)
154
155 self.__docked = True
156
157 #
158 # save window information
159 #
160 self.__floatSize = self.GetSize()
161 self.__floatPosition = self.GetPosition()
162
163 #
164 # reparent
165 #
166 self.__topWindow = self.__dockWindow
167 self.__dockPanel.Reparent(self.__topWindow)
168
169 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
176 self.SetDockSize(self.__dockWindow.GetSize())
177
178 if wasVisible: self.Show(True)
179
180 #self.__parent._UpdateDocks()
181
182 self.issue(DOCKABLE_DOCKED, self.__id, self)
183
184 def UnDock(self):
185 self.__CheckAllGood()
186
187 wasVisible = self.IsShown()
188
189 if wasVisible: self.Show(False)
190
191 self.__docked = False
192
193 #
194 # reparent
195 #
196 self.__topWindow = self.__floatWindow
197 self.__dockPanel.Reparent(self.__topWindow)
198
199 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
206 if wasVisible: self.Show()
207
208 #
209 # restore window information
210 #
211 if self.__floatPosition is not None: self.SetPosition(self.__floatPosition)
212 if self.__floatSize is not None: self.SetSize(self.__floatSize)
213
214 self.__dockPanel.SetSize(self.__topWindow.GetClientSize())
215
216 self.issue(DOCKABLE_UNDOCKED, self.__id, self)
217
218 def IsDocked(self):
219 self.__CheckAllGood()
220
221 return self.__docked
222
223
224 def Show(self, show = True):
225 if show:
226 self.__DoShow()
227 else:
228 self.__DoHide()
229
230 def SetDockSize(self, rect = None):
231
232 #
233 # adjust the size to get the
234 w0, h0 = self.__dockPanel.GetBestSize()
235 w, h = self.__panel.GetBestSize()
236
237 #print (w0, h0), (w, h)
238
239 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
259
260 def Destroy(self):
261 self.__panel.Destroy()
262 self.__floatWindow.Destroy()
263 self.__dockWindow.Destroy()
264 self.__parent.OnDockDestroy(self)
265
266 ##
267 # Event handlers
268 #
269
270 def _OnButtonClose(self, event):
271 #self.Close()
272 self.Show(False)
273
274 def _OnClose(self, force = False):
275 self.Show(False)
276
277 def _OnToggleDock(self, event):
278 self.__CheckAllGood()
279
280 self.SetDock(not self.IsDocked())
281
282 ##
283 # Private methods
284 #
285
286 def __CheckAllGood(self):
287 if self.__panel is None:
288 raise TypeError("")
289
290 def __DoShow(self):
291 if self.IsShown(): return
292 #print "__DoShow()", self.IsShown()
293
294 self.__topWindow.Show()
295
296 #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 else:
322 sizer = wxBoxSizer(wxHORIZONTAL)
323 headerBoxOrient = wxVERTICAL
324
325
326 headerBox = wxStaticBoxSizer(
327 wxStaticBox(self.__dockPanel, -1, ""), headerBoxOrient)
328
329 #buttonBox = wxBoxSizer(wxHORIZONTAL)
330
331 #
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 style = wxALIGN_CENTRE)
337
338 font = text.GetFont()
339 font.SetPointSize(10)
340 text.SetFont(font)
341
342 #
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 self.bmpDock = \
347 resource.GetBitmapResource(DOCK_BMP, wxBITMAP_TYPE_XPM)
348 self.bmpUnDock = \
349 resource.GetBitmapResource(UNDOCK_BMP, wxBITMAP_TYPE_XPM)
350
351 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
363 self.__dockButton = wxButton(
364 self.__dockPanel, ID_BUTTON_DOCK,
365 "WW", style = wxBU_EXACTFIT | wxADJUST_MINSIZE)
366
367 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 if self.__orientation == wxLAYOUT_VERTICAL:
383 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
384 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 else:
389 headerBox.Add(closeX, 0, wxALIGN_RIGHT | wxBOTTOM, 4)
390 headerBox.Add(self.__dockButton, 0, wxALIGN_RIGHT, 0)
391 headerBox.Add(text, 0, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, 0)
392
393 sizer.Add(headerBox, 0, wxGROW, 0)
394
395 self.__panel.Reparent(self.__dockPanel)
396 self.__panel.SetId(PANEL_ID)
397
398 sizer.Add(self.__panel, 1, wxGROW, 0)
399
400 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 self.__update_lock = 0
419
420 self.SetMainWindow(None)
421
422
423 EVT_SIZE(self, self._OnSashSize)
424 EVT_CLOSE(self, self._OnClose)
425
426 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
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 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 def OnDockDestroy(self, win):
477 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 if self.__update_lock == 0:
487 wxLayoutAlgorithm().LayoutWindow(self, self.__mainWindow)
488
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 assert isinstance(panel, DockPanel)
501 win = panel.GetDockParent()
502 #print win
503 assert isinstance(win, DockableWindow)
504
505 assert win.IsDocked()
506
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