1 __author__ = "Andrea Gavana <andrea.gavana@gmail.com>"
2 __date__ = "31 March 2009"
8 from aui_constants import *
12 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
16 class AuiMDIParentFrame(wx.Frame):
18 def __init__(self, parent, id=wx.ID_ANY, title="", pos=wx.DefaultPosition,
19 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE|wx.VSCROLL|wx.HSCROLL,
20 name="AuiMDIParentFrame"):
22 wx.Frame.__init__(self, parent, id, title, pos, size, style, name=name)
25 self.Bind(wx.EVT_MENU, self.DoHandleMenu, id=wx.ID_ANY)
27 # this style can be used to prevent a window from having the standard MDI
29 if not style & wx.FRAME_NO_WINDOW_MENU:
31 self._pWindowMenu = wx.Menu()
32 self._pWindowMenu.Append(wxWINDOWCLOSE, _("Cl&ose"))
33 self._pWindowMenu.Append(wxWINDOWCLOSEALL, _("Close All"))
34 self._pWindowMenu.AppendSeparator()
35 self._pWindowMenu.Append(wxWINDOWNEXT, _("&Next"))
36 self._pWindowMenu.Append(wxWINDOWPREV, _("&Previous"))
38 self._pClientWindow = self.OnCreateClient()
41 def SetArtProvider(self, provider):
43 if self._pClientWindow:
44 self._pClientWindow.SetArtProvider(provider)
47 def GetArtProvider(self):
49 if not self._pClientWindow:
52 return self._pClientWindow.GetArtProvider()
55 def GetNotebook(self):
57 return self._pClientWindow
60 def SetWindowMenu(self, pMenu):
62 # Replace the window menu from the currently loaded menu bar.
63 pMenuBar = self.GetMenuBar()
66 self.RemoveWindowMenu(pMenuBar)
68 self._pWindowMenu = None
71 self._pWindowMenu = pMenu
72 self.AddWindowMenu(pMenuBar)
75 def GetWindowMenu(self):
77 return self._pWindowMenu
80 def SetMenuBar(self, pMenuBar):
82 # Remove the Window menu from the old menu bar
83 self.RemoveWindowMenu(self.GetMenuBar())
85 # Add the Window menu to the new menu bar.
86 self.AddWindowMenu(pMenuBar)
88 wx.Frame.SetMenuBar(self, pMenuBar)
91 def SetChildMenuBar(self, pChild):
95 # No Child, set Our menu bar back.
97 self.SetMenuBar(self._pMyMenuBar)
99 self.SetMenuBar(self.GetMenuBar())
101 # Make sure we know our menu bar is in use
102 self._pMyMenuBar = None
106 if pChild.GetMenuBar() == None:
109 # Do we need to save the current bar?
110 if self._pMyMenuBar == None:
111 self._pMyMenuBar = self.GetMenuBar()
113 self.SetMenuBar(pChild.GetMenuBar())
116 def ProcessEvent(self, event):
118 # stops the same event being processed repeatedly
119 if self._pLastEvt == event:
122 self._pLastEvt = event
124 # let the active child (if any) process the event first.
126 if self._pActiveChild and event.IsCommandEvent() and \
127 event.GetEventObject() != self._pClientWindow and \
128 event.GetEventType() not in [wx.wxEVT_ACTIVATE, wx.wxEVT_SET_FOCUS,
129 wx.wxEVT_KILL_FOCUS, wx.wxEVT_CHILD_FOCUS,
130 wx.wxEVT_COMMAND_SET_FOCUS, wx.wxEVT_COMMAND_KILL_FOCUS]:
132 res = self._pActiveChild.GetEventHandler().ProcessEvent(event)
136 # if the event was not handled this frame will handle it,
137 # which is why we need the protection code at the beginning
139 res = self.GetEventHandler().ProcessEvent(event)
141 self._pLastEvt = None
146 def GetActiveChild(self):
148 return self._pActiveChild
151 def SetActiveChild(self, pChildFrame):
153 self._pActiveChild = pChildFrame
156 def GetClientWindow(self):
158 return self._pClientWindow
161 def OnCreateClient(self):
163 return AuiMDIClientWindow(self)
166 def ActivateNext(self):
168 if self._pClientWindow and self._pClientWindow.GetSelection() != wx.NOT_FOUND:
170 active = self._pClientWindow.GetSelection() + 1
171 if active >= self._pClientWindow.GetPageCount():
174 self._pClientWindow.SetSelection(active)
177 def ActivatePrevious(self):
179 if self._pClientWindow and self._pClientWindow.GetSelection() != wx.NOT_FOUND:
181 active = self._pClientWindow.GetSelection() - 1
183 active = self._pClientWindow.GetPageCount() - 1
185 self._pClientWindow.SetSelection(active)
190 self._pLastEvt = None
192 self._pClientWindow = None
193 self._pActiveChild = None
194 self._pWindowMenu = None
195 self._pMyMenuBar = None
198 def RemoveWindowMenu(self, pMenuBar):
200 if pMenuBar and self._pWindowMenu:
202 # Remove old window menu
203 pos = pMenuBar.FindMenu(_("&Window"))
204 if pos != wx.NOT_FOUND:
208 def AddWindowMenu(self, pMenuBar):
210 if pMenuBar and self._pWindowMenu:
212 pos = pMenuBar.FindMenu(wx.GetStockLabel(wx.ID_HELP, wx.STOCK_NOFLAGS))
213 if pos == wx.NOT_FOUND:
214 pMenuBar.Append(self._pWindowMenu, _("&Window"))
216 pMenuBar.Insert(pos, self._pWindowMenu, _("&Window"))
219 def DoHandleMenu(self, event):
223 if evId == wxWINDOWCLOSE:
224 if self._pActiveChild:
225 self._pActiveChild.Close()
227 elif evId == wxWINDOWCLOSEALL:
229 while self._pActiveChild:
230 if not self._pActiveChild.Close():
233 elif evId == wxWINDOWNEXT:
236 elif evId == wxWINDOWPREV:
237 self.ActivatePrevious()
243 def Tile(self, orient=wx.HORIZONTAL):
245 client_window = self.GetClientWindow()
246 if not client_window:
247 raise Exception("Missing MDI Client Window")
249 cur_idx = client_window.GetSelection()
253 if orient == wx.VERTICAL:
255 client_window.Split(cur_idx, wx.LEFT)
257 elif orient == wx.HORIZONTAL:
259 client_window.Split(cur_idx, wx.TOP)
262 #-----------------------------------------------------------------------------
264 #-----------------------------------------------------------------------------
266 class AuiMDIChildFrame(wx.PyPanel):
268 def __init__(self, parent, id=wx.ID_ANY, title="", pos=wx.DefaultPosition,
269 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name="AuiMDIChildFrame"):
271 pClientWindow = parent.GetClientWindow()
272 if pClientWindow is None:
273 raise Exception("Missing MDI client window.")
277 # see comment in constructor
278 if style & wx.MINIMIZE:
279 self._activate_on_create = False
281 cli_size = pClientWindow.GetClientSize()
283 # create the window off-screen to prevent flicker
284 wx.PyPanel.__init__(self, pClientWindow, id, wx.Point(cli_size.x+1, cli_size.y+1),
285 size, wx.NO_BORDER, name=name)
287 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
289 self.SetMDIParentFrame(parent)
291 # this is the currently active child
292 parent.SetActiveChild(self)
295 pClientWindow.AddPage(self, title, self._activate_on_create)
296 pClientWindow.Refresh()
298 self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
299 self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
300 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
305 # There are two ways to create an tabbed mdi child fram without
306 # making it the active document. Either Show(False) can be called
307 # before Create() (as is customary on some ports with wxFrame-type
308 # windows), or wx.MINIMIZE can be passed in the style flags. Note that
309 # AuiMDIChildFrame is not really derived from wxFrame, as MDIChildFrame
310 # is, but those are the expected symantics. No style flag is passed
311 # onto the panel underneath.
313 self._activate_on_create = True
315 self._pMDIParentFrame = None
316 self._pMenuBar = None
318 self._mdi_currect = None
319 self._mdi_newrect = wx.Rect()
321 self._icon_bundle = None
326 pParentFrame = self.GetMDIParentFrame()
328 raise Exception("Missing MDI Parent Frame")
330 pClientWindow = pParentFrame.GetClientWindow()
331 if not pClientWindow:
332 raise Exception("Missing MDI Client Window")
334 if pParentFrame.GetActiveChild() == self:
337 event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, False, self.GetId())
338 event.SetEventObject(self)
339 self.GetEventHandler().ProcessEvent(event)
341 pParentFrame.SetActiveChild(None)
342 pParentFrame.SetChildMenuBar(None)
344 for pos in xrange(pClientWindow.GetPageCount()):
345 if pClientWindow.GetPage(pos) == self:
346 return pClientWindow.DeletePage(pos)
351 def SetMenuBar(self, menu_bar):
353 pOldMenuBar = self._pMenuBar
354 self._pMenuBar = menu_bar
358 pParentFrame = self.GetMDIParentFrame()
360 raise Exception("Missing MDI Parent Frame")
362 self._pMenuBar.Reparent(pParentFrame)
363 if pParentFrame.GetActiveChild() == self:
365 # replace current menu bars
367 pParentFrame.SetChildMenuBar(None)
369 pParentFrame.SetChildMenuBar(self)
372 def GetMenuBar(self):
374 return self._pMenuBar
377 def SetTitle(self, title):
381 pParentFrame = self.GetMDIParentFrame()
383 raise Exception("Missing MDI Parent Frame")
385 pClientWindow = pParentFrame.GetClientWindow()
386 if pClientWindow is not None:
388 for pos in xrange(pClientWindow.GetPageCount()):
389 if pClientWindow.GetPage(pos) == self:
390 pClientWindow.SetPageText(pos, self._title)
399 def SetIcons(self, icons):
401 # get icon with the system icon size
402 self.SetIcon(icons.GetIcon(-1))
403 self._icon_bundle = icons
408 return self._icon_bundle
411 def SetIcon(self, icon):
413 pParentFrame = self.GetMDIParentFrame()
415 raise Exception("Missing MDI Parent Frame")
419 bmp = wx.BitmapFromIcon(self._icon)
421 pClientWindow = pParentFrame.GetClientWindow()
422 if pClientWindow is not None:
423 idx = pClientWindow.GetPageIndex(self)
425 pClientWindow.SetPageBitmap(idx, bmp)
435 pParentFrame = self.GetMDIParentFrame()
437 raise Exception("Missing MDI Parent Frame")
439 pClientWindow = pParentFrame.GetClientWindow()
440 if pClientWindow is not None:
442 for pos in xrange(pClientWindow.GetPageCount()):
443 if pClientWindow.GetPage(pos) == self:
444 pClientWindow.SetSelection(pos)
448 def OnMenuHighlight(self, event):
450 if self._pMDIParentFrame:
452 # we don't have any help text for this item,
453 # but may be the MDI frame does?
454 self._pMDIParentFrame.OnMenuHighlight(event)
457 def OnActivate(self, event):
463 def OnCloseWindow(self, event):
465 pParentFrame = self.GetMDIParentFrame()
467 if pParentFrame.GetActiveChild() == self:
469 pParentFrame.SetActiveChild(None)
470 pParentFrame.SetChildMenuBar(None)
472 pClientWindow = pParentFrame.GetClientWindow()
473 idx = pClientWindow.GetPageIndex(self)
475 if idx != wx.NOT_FOUND:
476 pClientWindow.RemovePage(idx)
481 def SetMDIParentFrame(self, parentFrame):
483 self._pMDIParentFrame = parentFrame
486 def GetMDIParentFrame(self):
488 return self._pMDIParentFrame
491 def CreateStatusBar(self, number=1, style=1, winid=1, name=""):
496 def GetStatusBar(self):
501 def SetStatusText(self, text, number=0):
506 def SetStatusWidths(self, widths_field):
512 def CreateToolBar(self, style=1, winid=-1, name=""):
517 def GetToolBar(self):
523 def Maximize(self, maximize=True):
533 def Iconize(self, iconize=True):
538 def IsMaximized(self):
543 def IsIconized(self):
548 def ShowFullScreen(self, show=True, style=0):
553 def IsFullScreen(self):
558 def IsTopLevel(self):
563 # renamed from Show().
564 def ActivateOnCreate(self, activate_on_create):
566 self._activate_on_create = activate_on_create
570 def Show(self, show=True):
572 wx.PyPanel.Show(self, show)
575 def ApplyMDIChildFrameRect(self):
577 if self._mdi_currect != self._mdi_newrect:
578 self.SetDimensions(*self._mdi_newrect)
579 self._mdi_currect = wx.Rect(*self._mdi_newrect)
582 #-----------------------------------------------------------------------------
584 #-----------------------------------------------------------------------------
586 class AuiMDIClientWindow(auibook.AuiNotebook):
588 def __init__(self, parent, agwStyle=0):
590 auibook.AuiNotebook.__init__(self, parent, wx.ID_ANY, wx.Point(0, 0), wx.Size(100, 100),
591 agwStyle=AUI_NB_DEFAULT_STYLE|wx.NO_BORDER)
593 caption_icon_size = wx.Size(wx.SystemSettings.GetMetric(wx.SYS_SMALLICON_X),
594 wx.SystemSettings.GetMetric(wx.SYS_SMALLICON_Y))
595 self.SetUniformBitmapSize(caption_icon_size)
597 bkcolour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_APPWORKSPACE)
598 self.SetOwnBackgroundColour(bkcolour)
600 self._mgr.GetArtProvider().SetColour(AUI_DOCKART_BACKGROUND_COLOUR, bkcolour)
602 self.Bind(auibook.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
603 self.Bind(auibook.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose)
604 self.Bind(wx.EVT_SIZE, self.OnSize)
607 def SetSelection(self, nPage):
609 return auibook.AuiNotebook.SetSelection(self, nPage)
612 def PageChanged(self, old_selection, new_selection):
614 # don't do anything if the page doesn't actually change
615 if old_selection == new_selection:
618 # notify old active child that it has been deactivated
619 if old_selection != -1 and old_selection < self.GetPageCount():
621 old_child = self.GetPage(old_selection)
623 raise Exception("AuiMDIClientWindow.PageChanged - null page pointer")
625 event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, False, old_child.GetId())
626 event.SetEventObject(old_child)
627 old_child.GetEventHandler().ProcessEvent(event)
629 # notify new active child that it has been activated
630 if new_selection != -1:
632 active_child = self.GetPage(new_selection)
634 raise Exception("AuiMDIClientWindow.PageChanged - null page pointer")
636 event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, True, active_child.GetId())
637 event.SetEventObject(active_child)
638 active_child.GetEventHandler().ProcessEvent(event)
640 if active_child.GetMDIParentFrame():
641 active_child.GetMDIParentFrame().SetActiveChild(active_child)
642 active_child.GetMDIParentFrame().SetChildMenuBar(active_child)
645 def OnPageClose(self, event):
647 wnd = self.GetPage(event.GetSelection())
650 # regardless of the result of wnd.Close(), we've
651 # already taken care of the close operations, so
652 # suppress further processing
656 def OnPageChanged(self, event):
658 self.PageChanged(event.GetOldSelection(), event.GetSelection())
661 def OnSize(self, event):
663 auibook.AuiNotebook.OnSize(self, event)
665 for pos in xrange(self.GetPageCount()):
666 self.GetPage(pos).ApplyMDIChildFrameRect()