X-Git-Url: http://iramuteq.org/git?p=iramuteq;a=blobdiff_plain;f=aui%2Ftabmdi.py;fp=aui%2Ftabmdi.py;h=ef09e9fc8e1a13aea66e8dcf34f6a9f02e5c0f5b;hp=0000000000000000000000000000000000000000;hb=7fb5b2b86f6c9a0617208ee85211177c23d12f47;hpb=22f93a602f3584ddc6ba68114556212c90307a50 diff --git a/aui/tabmdi.py b/aui/tabmdi.py new file mode 100644 index 0000000..ef09e9f --- /dev/null +++ b/aui/tabmdi.py @@ -0,0 +1,666 @@ +__author__ = "Andrea Gavana " +__date__ = "31 March 2009" + + +import wx + +import auibook +from aui_constants import * + +_ = wx.GetTranslation + +#----------------------------------------------------------------------------- +# AuiMDIParentFrame +#----------------------------------------------------------------------------- + +class AuiMDIParentFrame(wx.Frame): + + def __init__(self, parent, id=wx.ID_ANY, title="", pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE|wx.VSCROLL|wx.HSCROLL, + name="AuiMDIParentFrame"): + + wx.Frame.__init__(self, parent, id, title, pos, size, style, name=name) + self.Init() + + self.Bind(wx.EVT_MENU, self.DoHandleMenu, id=wx.ID_ANY) + + # this style can be used to prevent a window from having the standard MDI + # "Window" menu + if not style & wx.FRAME_NO_WINDOW_MENU: + + self._pWindowMenu = wx.Menu() + self._pWindowMenu.Append(wxWINDOWCLOSE, _("Cl&ose")) + self._pWindowMenu.Append(wxWINDOWCLOSEALL, _("Close All")) + self._pWindowMenu.AppendSeparator() + self._pWindowMenu.Append(wxWINDOWNEXT, _("&Next")) + self._pWindowMenu.Append(wxWINDOWPREV, _("&Previous")) + + self._pClientWindow = self.OnCreateClient() + + + def SetArtProvider(self, provider): + + if self._pClientWindow: + self._pClientWindow.SetArtProvider(provider) + + + def GetArtProvider(self): + + if not self._pClientWindow: + return None + + return self._pClientWindow.GetArtProvider() + + + def GetNotebook(self): + + return self._pClientWindow + + + def SetWindowMenu(self, pMenu): + + # Replace the window menu from the currently loaded menu bar. + pMenuBar = self.GetMenuBar() + + if self._pWindowMenu: + self.RemoveWindowMenu(pMenuBar) + del self._pWindowMenu + self._pWindowMenu = None + + if pMenu: + self._pWindowMenu = pMenu + self.AddWindowMenu(pMenuBar) + + + def GetWindowMenu(self): + + return self._pWindowMenu + + + def SetMenuBar(self, pMenuBar): + + # Remove the Window menu from the old menu bar + self.RemoveWindowMenu(self.GetMenuBar()) + + # Add the Window menu to the new menu bar. + self.AddWindowMenu(pMenuBar) + + wx.Frame.SetMenuBar(self, pMenuBar) + + + def SetChildMenuBar(self, pChild): + + if not pChild: + + # No Child, set Our menu bar back. + if self._pMyMenuBar: + self.SetMenuBar(self._pMyMenuBar) + else: + self.SetMenuBar(self.GetMenuBar()) + + # Make sure we know our menu bar is in use + self._pMyMenuBar = None + + else: + + if pChild.GetMenuBar() == None: + return + + # Do we need to save the current bar? + if self._pMyMenuBar == None: + self._pMyMenuBar = self.GetMenuBar() + + self.SetMenuBar(pChild.GetMenuBar()) + + + def ProcessEvent(self, event): + + # stops the same event being processed repeatedly + if self._pLastEvt == event: + return False + + self._pLastEvt = event + + # let the active child (if any) process the event first. + res = False + if self._pActiveChild and event.IsCommandEvent() and \ + event.GetEventObject() != self._pClientWindow and \ + event.GetEventType() not in [wx.wxEVT_ACTIVATE, wx.wxEVT_SET_FOCUS, + wx.wxEVT_KILL_FOCUS, wx.wxEVT_CHILD_FOCUS, + wx.wxEVT_COMMAND_SET_FOCUS, wx.wxEVT_COMMAND_KILL_FOCUS]: + + res = self._pActiveChild.GetEventHandler().ProcessEvent(event) + + if not res: + + # if the event was not handled this frame will handle it, + # which is why we need the protection code at the beginning + # of this method + res = self.GetEventHandler().ProcessEvent(event) + + self._pLastEvt = None + + return res + + + def GetActiveChild(self): + + return self._pActiveChild + + + def SetActiveChild(self, pChildFrame): + + self._pActiveChild = pChildFrame + + + def GetClientWindow(self): + + return self._pClientWindow + + + def OnCreateClient(self): + + return AuiMDIClientWindow(self) + + + def ActivateNext(self): + + if self._pClientWindow and self._pClientWindow.GetSelection() != wx.NOT_FOUND: + + active = self._pClientWindow.GetSelection() + 1 + if active >= self._pClientWindow.GetPageCount(): + active = 0 + + self._pClientWindow.SetSelection(active) + + + def ActivatePrevious(self): + + if self._pClientWindow and self._pClientWindow.GetSelection() != wx.NOT_FOUND: + + active = self._pClientWindow.GetSelection() - 1 + if active < 0: + active = self._pClientWindow.GetPageCount() - 1 + + self._pClientWindow.SetSelection(active) + + + def Init(self): + + self._pLastEvt = None + + self._pClientWindow = None + self._pActiveChild = None + self._pWindowMenu = None + self._pMyMenuBar = None + + + def RemoveWindowMenu(self, pMenuBar): + + if pMenuBar and self._pWindowMenu: + + # Remove old window menu + pos = pMenuBar.FindMenu(_("&Window")) + if pos != wx.NOT_FOUND: + pMenuBar.Remove(pos) + + + def AddWindowMenu(self, pMenuBar): + + if pMenuBar and self._pWindowMenu: + + pos = pMenuBar.FindMenu(wx.GetStockLabel(wx.ID_HELP, wx.STOCK_NOFLAGS)) + if pos == wx.NOT_FOUND: + pMenuBar.Append(self._pWindowMenu, _("&Window")) + else: + pMenuBar.Insert(pos, self._pWindowMenu, _("&Window")) + + + def DoHandleMenu(self, event): + + evId = event.GetId() + + if evId == wxWINDOWCLOSE: + if self._pActiveChild: + self._pActiveChild.Close() + + elif evId == wxWINDOWCLOSEALL: + + while self._pActiveChild: + if not self._pActiveChild.Close(): + return # failure + + elif evId == wxWINDOWNEXT: + self.ActivateNext() + + elif evId == wxWINDOWPREV: + self.ActivatePrevious() + + else: + event.Skip() + + + def Tile(self, orient=wx.HORIZONTAL): + + client_window = self.GetClientWindow() + if not client_window: + raise Exception("Missing MDI Client Window") + + cur_idx = client_window.GetSelection() + if cur_idx == -1: + return + + if orient == wx.VERTICAL: + + client_window.Split(cur_idx, wx.LEFT) + + elif orient == wx.HORIZONTAL: + + client_window.Split(cur_idx, wx.TOP) + + +#----------------------------------------------------------------------------- +# AuiMDIChildFrame +#----------------------------------------------------------------------------- + +class AuiMDIChildFrame(wx.PyPanel): + + def __init__(self, parent, id=wx.ID_ANY, title="", pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name="AuiMDIChildFrame"): + + pClientWindow = parent.GetClientWindow() + if pClientWindow is None: + raise Exception("Missing MDI client window.") + + self.Init() + + # see comment in constructor + if style & wx.MINIMIZE: + self._activate_on_create = False + + cli_size = pClientWindow.GetClientSize() + + # create the window off-screen to prevent flicker + wx.PyPanel.__init__(self, pClientWindow, id, wx.Point(cli_size.x+1, cli_size.y+1), + size, wx.NO_BORDER, name=name) + + self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) + self.Show(False) + self.SetMDIParentFrame(parent) + + # this is the currently active child + parent.SetActiveChild(self) + self._title = title + + pClientWindow.AddPage(self, title, self._activate_on_create) + pClientWindow.Refresh() + + self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight) + self.Bind(wx.EVT_ACTIVATE, self.OnActivate) + self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + + + def Init(self): + + # There are two ways to create an tabbed mdi child fram without + # making it the active document. Either Show(False) can be called + # before Create() (as is customary on some ports with wxFrame-type + # windows), or wx.MINIMIZE can be passed in the style flags. Note that + # AuiMDIChildFrame is not really derived from wxFrame, as MDIChildFrame + # is, but those are the expected symantics. No style flag is passed + # onto the panel underneath. + + self._activate_on_create = True + + self._pMDIParentFrame = None + self._pMenuBar = None + + self._mdi_currect = None + self._mdi_newrect = wx.Rect() + self._icon = None + self._icon_bundle = None + + + def Destroy(self): + + pParentFrame = self.GetMDIParentFrame() + if not pParentFrame: + raise Exception("Missing MDI Parent Frame") + + pClientWindow = pParentFrame.GetClientWindow() + if not pClientWindow: + raise Exception("Missing MDI Client Window") + + if pParentFrame.GetActiveChild() == self: + + # deactivate ourself + event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, False, self.GetId()) + event.SetEventObject(self) + self.GetEventHandler().ProcessEvent(event) + + pParentFrame.SetActiveChild(None) + pParentFrame.SetChildMenuBar(None) + + for pos in xrange(pClientWindow.GetPageCount()): + if pClientWindow.GetPage(pos) == self: + return pClientWindow.DeletePage(pos) + + return False + + + def SetMenuBar(self, menu_bar): + + pOldMenuBar = self._pMenuBar + self._pMenuBar = menu_bar + + if self._pMenuBar: + + pParentFrame = self.GetMDIParentFrame() + if not pParentFrame: + raise Exception("Missing MDI Parent Frame") + + self._pMenuBar.Reparent(pParentFrame) + if pParentFrame.GetActiveChild() == self: + + # replace current menu bars + if pOldMenuBar: + pParentFrame.SetChildMenuBar(None) + + pParentFrame.SetChildMenuBar(self) + + + def GetMenuBar(self): + + return self._pMenuBar + + + def SetTitle(self, title): + + self._title = title + + pParentFrame = self.GetMDIParentFrame() + if not pParentFrame: + raise Exception("Missing MDI Parent Frame") + + pClientWindow = pParentFrame.GetClientWindow() + if pClientWindow is not None: + + for pos in xrange(pClientWindow.GetPageCount()): + if pClientWindow.GetPage(pos) == self: + pClientWindow.SetPageText(pos, self._title) + break + + + def GetTitle(self): + + return self._title + + + def SetIcons(self, icons): + + # get icon with the system icon size + self.SetIcon(icons.GetIcon(-1)) + self._icon_bundle = icons + + + def GetIcons(self): + + return self._icon_bundle + + + def SetIcon(self, icon): + + pParentFrame = self.GetMDIParentFrame() + if not pParentFrame: + raise Exception("Missing MDI Parent Frame") + + self._icon = icon + + bmp = wx.BitmapFromIcon(self._icon) + + pClientWindow = pParentFrame.GetClientWindow() + if pClientWindow is not None: + idx = pClientWindow.GetPageIndex(self) + if idx != -1: + pClientWindow.SetPageBitmap(idx, bmp) + + + def GetIcon(self): + + return self._icon + + + def Activate(self): + + pParentFrame = self.GetMDIParentFrame() + if not pParentFrame: + raise Exception("Missing MDI Parent Frame") + + pClientWindow = pParentFrame.GetClientWindow() + if pClientWindow is not None: + + for pos in xrange(pClientWindow.GetPageCount()): + if pClientWindow.GetPage(pos) == self: + pClientWindow.SetSelection(pos) + break + + + def OnMenuHighlight(self, event): + + if self._pMDIParentFrame: + + # we don't have any help text for this item, + # but may be the MDI frame does? + self._pMDIParentFrame.OnMenuHighlight(event) + + + def OnActivate(self, event): + + # do nothing + pass + + + def OnCloseWindow(self, event): + + pParentFrame = self.GetMDIParentFrame() + if pParentFrame: + if pParentFrame.GetActiveChild() == self: + + pParentFrame.SetActiveChild(None) + pParentFrame.SetChildMenuBar(None) + + pClientWindow = pParentFrame.GetClientWindow() + idx = pClientWindow.GetPageIndex(self) + + if idx != wx.NOT_FOUND: + pClientWindow.RemovePage(idx) + + self.Destroy() + + + def SetMDIParentFrame(self, parentFrame): + + self._pMDIParentFrame = parentFrame + + + def GetMDIParentFrame(self): + + return self._pMDIParentFrame + + + def CreateStatusBar(self, number=1, style=1, winid=1, name=""): + + return None + + + def GetStatusBar(self): + + return None + + + def SetStatusText(self, text, number=0): + + pass + + + def SetStatusWidths(self, widths_field): + + pass + + + # no toolbar bars + def CreateToolBar(self, style=1, winid=-1, name=""): + + return None + + + def GetToolBar(self): + + return None + + + # no maximize etc + def Maximize(self, maximize=True): + + pass + + + def Restore(self): + + pass + + + def Iconize(self, iconize=True): + + pass + + + def IsMaximized(self): + + return True + + + def IsIconized(self): + + return False + + + def ShowFullScreen(self, show=True, style=0): + + return False + + + def IsFullScreen(self): + + return False + + + def IsTopLevel(self): + + return False + + + # renamed from Show(). + def ActivateOnCreate(self, activate_on_create): + + self._activate_on_create = activate_on_create + return True + + + def Show(self, show=True): + + wx.PyPanel.Show(self, show) + + + def ApplyMDIChildFrameRect(self): + + if self._mdi_currect != self._mdi_newrect: + self.SetDimensions(*self._mdi_newrect) + self._mdi_currect = wx.Rect(*self._mdi_newrect) + + +#----------------------------------------------------------------------------- +# AuiMDIClientWindow +#----------------------------------------------------------------------------- + +class AuiMDIClientWindow(auibook.AuiNotebook): + + def __init__(self, parent, agwStyle=0): + + auibook.AuiNotebook.__init__(self, parent, wx.ID_ANY, wx.Point(0, 0), wx.Size(100, 100), + agwStyle=AUI_NB_DEFAULT_STYLE|wx.NO_BORDER) + + caption_icon_size = wx.Size(wx.SystemSettings.GetMetric(wx.SYS_SMALLICON_X), + wx.SystemSettings.GetMetric(wx.SYS_SMALLICON_Y)) + self.SetUniformBitmapSize(caption_icon_size) + + bkcolour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_APPWORKSPACE) + self.SetOwnBackgroundColour(bkcolour) + + self._mgr.GetArtProvider().SetColour(AUI_DOCKART_BACKGROUND_COLOUR, bkcolour) + + self.Bind(auibook.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged) + self.Bind(auibook.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose) + self.Bind(wx.EVT_SIZE, self.OnSize) + + + def SetSelection(self, nPage): + + return auibook.AuiNotebook.SetSelection(self, nPage) + + + def PageChanged(self, old_selection, new_selection): + + # don't do anything if the page doesn't actually change + if old_selection == new_selection: + return + + # notify old active child that it has been deactivated + if old_selection != -1 and old_selection < self.GetPageCount(): + + old_child = self.GetPage(old_selection) + if not old_child: + raise Exception("AuiMDIClientWindow.PageChanged - null page pointer") + + event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, False, old_child.GetId()) + event.SetEventObject(old_child) + old_child.GetEventHandler().ProcessEvent(event) + + # notify new active child that it has been activated + if new_selection != -1: + + active_child = self.GetPage(new_selection) + if not active_child: + raise Exception("AuiMDIClientWindow.PageChanged - null page pointer") + + event = wx.ActivateEvent(wx.wxEVT_ACTIVATE, True, active_child.GetId()) + event.SetEventObject(active_child) + active_child.GetEventHandler().ProcessEvent(event) + + if active_child.GetMDIParentFrame(): + active_child.GetMDIParentFrame().SetActiveChild(active_child) + active_child.GetMDIParentFrame().SetChildMenuBar(active_child) + + + def OnPageClose(self, event): + + wnd = self.GetPage(event.GetSelection()) + wnd.Close() + + # regardless of the result of wnd.Close(), we've + # already taken care of the close operations, so + # suppress further processing + event.Veto() + + + def OnPageChanged(self, event): + + self.PageChanged(event.GetOldSelection(), event.GetSelection()) + + + def OnSize(self, event): + + auibook.AuiNotebook.OnSize(self, event) + + for pos in xrange(self.GetPageCount()): + self.GetPage(pos).ApplyMDIChildFrameRect()