1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
"""
@package main_window.notebook
@brief Custom AuiNotebook class and class for undocked AuiNotebook frame
Classes:
- notebook::MainPageFrame
- notebook::MainNotebook
(C) 2022 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@author Linda Kladivova <lindakladivova gmail.com>
@author Anna Petrasova <kratochanna gmail.com>
"""
import os
import wx
import wx.lib.agw.aui as aui
from core import globalvar
from gui_core.wrap import SimpleTabArt
from mapdisp.frame import MapPanel
class MainPageFrame(wx.Frame):
"""Frame for independent window."""
def __init__(self, parent, panel, size, pos, title, icon="grass", menu=None):
wx.Frame.__init__(self, parent=parent, size=size, pos=pos, title=title)
self.panel = panel
self.panel.Reparent(self)
self._layout()
# set system icon
self.SetIcon(
wx.Icon(os.path.join(globalvar.ICONDIR, icon + ".ico"), wx.BITMAP_TYPE_ICO)
)
if menu is not None:
self.SetMenuBar(menu)
self.panel.onFocus.emit()
self.Bind(wx.EVT_CLOSE, self.OnClose)
self._show()
def _layout(self):
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel, proportion=1, flag=wx.EXPAND)
self.SetSizer(sizer)
self.CentreOnParent()
def _show(self):
"""Show frame and contained panel"""
self.panel.Show()
self.Show()
def SetDockingCallback(self, function):
"""Set docking callback on reparented panel"""
self.panel.SetDockingCallback(function)
def OnClose(self, event):
"""Close frame and associated layer notebook page."""
if isinstance(self.panel, MapPanel):
self.panel.OnCloseWindow(event=None, askIfSaveWorkspace=True)
else:
self.panel.OnCloseWindow(event=None)
class MainNotebook(aui.AuiNotebook):
"""Main notebook class. Overrides some AuiNotebook classes.
Takes into consideration the dock/undock functionality.
"""
def __init__(
self,
parent,
agwStyle=aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER,
):
self.parent = parent
super().__init__(parent=self.parent, id=wx.ID_ANY, agwStyle=agwStyle)
self.SetArtProvider(SimpleTabArt())
# bindings
self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnClose)
# remember number of items in the menu
self._menuCount = self.parent.menubar.GetMenuCount()
def OnPageChanged(self, event):
page = self.GetCurrentPage()
page.onFocus.emit()
# set up menu
mbar = self.parent.menubar
if page.HasMenu():
# add new (or replace if exists) additional menu item related to this page
menu, menuName = page.GetMenu()
if mbar.GetMenuCount() == self._menuCount:
appendMenu = mbar.Insert
else:
appendMenu = mbar.Replace
appendMenu(self._menuCount - 1, menu, menuName)
elif mbar.GetMenuCount() > self._menuCount:
# remove additional menu item
mbar.Remove(self._menuCount - 1)
def UndockPage(self, page):
"""Undock active page to independent MainFrame object"""
index = self.GetPageIndex(page)
text = self.GetPageText(index)
original_size = page.GetSize()
original_pos = page.GetPosition()
icon = "grass_map" if isinstance(page, MapPanel) else "grass"
if page.HasMenu():
menu, _ = page.GetMenu()
else:
menu = None
self.RemovePage(index)
frame = MainPageFrame(
parent=self.parent,
panel=page,
size=original_size,
pos=original_pos,
title=text,
icon=icon,
menu=menu,
)
frame.SetDockingCallback(self.DockPage)
def DockPage(self, page):
"""Dock independent MainFrame object back to Aui.Notebook"""
frame = page.GetParent()
page.Reparent(self)
page.SetDockingCallback(self.UndockPage)
self.AddPage(page, frame.GetTitle())
if frame.GetMenuBar():
# avoid destroying menu if defined
frame.SetMenuBar(None)
frame.Destroy()
def AddPage(self, *args, **kwargs):
"""Overrides Aui.Notebook AddPage method.
Adds page to notebook and makes it current"""
super().AddPage(*args, **kwargs)
self.SetSelection(self.GetPageCount() - 1)
def SetSelectionToMainPage(self, page):
"""Decides whether to set selection to a MainNotebook page
or an undocked independent frame"""
self.SetSelection(self.GetPageIndex(page))
if not page.IsDocked():
frame = page.GetParent()
wx.CallLater(500, lambda: frame.Raise() if frame else None)
def DeleteMainPage(self, page):
"""Decides whether to delete a MainNotebook page
or close an undocked independent frame"""
if page.IsDocked():
self.DeletePage(self.GetPageIndex(page))
else:
frame = page.GetParent()
frame.Destroy()
def SetMainPageText(self, page, text):
"""Decides whether sets title to MainNotebook page
or an undocked independent frame"""
if page.IsDocked():
self.SetPageText(page_idx=self.GetPageIndex(page), text=text)
else:
frame = page.GetParent()
frame.SetTitle(text)
wx.CallLater(500, frame.Raise)
def OnClose(self, event):
"""Page of map notebook is being closed"""
page = self.GetCurrentPage()
if isinstance(page, MapPanel):
page.OnCloseWindow(event=None, askIfSaveWorkspace=True)
else:
page.OnCloseWindow(event=None)
event.Veto()
|