ソースを参照

wxGUI/Single-Window GUI: arrangement of basic widgets (#1621)

Linda Kladivova 3 年 前
コミット
69b2fe5fb0
1 ファイル変更156 行追加155 行削除
  1. 156 155
      gui/wxpython/main_window/frame.py

+ 156 - 155
gui/wxpython/main_window/frame.py

@@ -25,8 +25,13 @@ import platform
 import re
 import re
 
 
 from core import globalvar
 from core import globalvar
+
+try:
+    from agw import aui
+except ImportError:
+    import wx.lib.agw.aui as aui
+
 import wx
 import wx
-import wx.aui
 
 
 try:
 try:
     import wx.lib.agw.flatnotebook as FN
     import wx.lib.agw.flatnotebook as FN
@@ -45,7 +50,7 @@ from core.utils import SetAddOnPath, GetLayerNameFromCmd, command2ltype, get_she
 from gui_core.preferences import MapsetAccess, PreferencesDialog
 from gui_core.preferences import MapsetAccess, PreferencesDialog
 from lmgr.layertree import LayerTree, LMIcons
 from lmgr.layertree import LayerTree, LMIcons
 from lmgr.menudata import LayerManagerMenuData, LayerManagerModuleTree
 from lmgr.menudata import LayerManagerMenuData, LayerManagerModuleTree
-from gui_core.widgets import GNotebook, FormNotebook
+from gui_core.widgets import GNotebook
 from core.gconsole import GConsole, EVT_IGNORED_CMD_RUN
 from core.gconsole import GConsole, EVT_IGNORED_CMD_RUN
 from core.giface import Notification
 from core.giface import Notification
 from gui_core.goutput import GConsoleWindow, GC_PROMPT
 from gui_core.goutput import GConsoleWindow, GC_PROMPT
@@ -136,7 +141,7 @@ class GMFrame(wx.Frame):
         self._menuTreeBuilder = LayerManagerMenuData(message_handler=add_menu_error)
         self._menuTreeBuilder = LayerManagerMenuData(message_handler=add_menu_error)
         # the search tree and command console
         # the search tree and command console
         self._moduleTreeBuilder = LayerManagerModuleTree(message_handler=add_menu_error)
         self._moduleTreeBuilder = LayerManagerModuleTree(message_handler=add_menu_error)
-        self._auimgr = wx.aui.AuiManager(self)
+        self._auimgr = aui.AuiManager(self)
 
 
         # list of open dialogs
         # list of open dialogs
         self.dialogs = dict()
         self.dialogs = dict()
@@ -144,84 +149,21 @@ class GMFrame(wx.Frame):
         self.dialogs["nvizPreferences"] = None
         self.dialogs["nvizPreferences"] = None
         self.dialogs["atm"] = list()
         self.dialogs["atm"] = list()
 
 
-        # create widgets
-        self._createMenuBar()
-        self.statusbar = self.CreateStatusBar(number=1)
-        self.notebook = self._createNotebook()
-        self._createDataCatalog(self.notebook)
-        self._createDisplay(self.notebook)
-        self._createSearchModule(self.notebook)
-        self._createConsole(self.notebook)
-        self._createPythonShell(self.notebook)
-        self._addPagesToNotebook()
-        self.toolbars = {
-            "workspace": LMWorkspaceToolbar(parent=self),
-            "tools": LMToolsToolbar(parent=self),
-            "misc": LMMiscToolbar(parent=self),
-            "nviz": LMNvizToolbar(parent=self),
-        }
-        self._toolbarsData = {
-            "workspace": (
-                "toolbarWorkspace",  # name
-                _("Workspace Toolbar"),  # caption
-                1,
-                0,
-            ),  # row, position
-            "tools": ("toolbarTools", _("Tools Toolbar"), 1, 1),
-            "misc": ("toolbarMisc", _("Misc Toolbar"), 1, 2),
-            "nviz": ("toolbarNviz", _("3D view Toolbar"), 1, 3),
-        }
-        toolbarsList = ("workspace", "tools", "misc", "nviz")
-        for toolbar in toolbarsList:
-            name, caption, row, position = self._toolbarsData[toolbar]
-            self._auimgr.AddPane(
-                self.toolbars[toolbar],
-                wx.aui.AuiPaneInfo()
-                .Name(name)
-                .Caption(caption)
-                .ToolbarPane()
-                .Top()
-                .Row(row)
-                .Position(position)
-                .LeftDockable(False)
-                .RightDockable(False)
-                .BottomDockable(False)
-                .TopDockable(True)
-                .CloseButton(False)
-                .Layer(2)
-                .BestSize((self.toolbars[toolbar].GetBestSize())),
-            )
+        # set pane sizes according to the full screen size of the primary monitor
+        size = wx.Display().GetGeometry().GetSize()
+        self.PANE_BEST_SIZE = tuple(t / 5 for t in size)
+        self.PANE_MIN_SIZE = tuple(t / 10 for t in size)
 
 
-        self._auimgr.GetPane("toolbarNviz").Hide()
-        # bindings
-        self.Bind(wx.EVT_CLOSE, self.OnCloseWindowOrExit)
-        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        # create widgets and build panes
+        self.CreateMenuBar()
+        self.CreateStatusBar(number=1)
+        self.BuildPanes()
+        self.BindEvents()
 
 
         self._giface.mapCreated.connect(self.OnMapCreated)
         self._giface.mapCreated.connect(self.OnMapCreated)
         self._giface.updateMap.connect(self._updateCurrentMap)
         self._giface.updateMap.connect(self._updateCurrentMap)
         self._giface.currentMapsetChanged.connect(self.OnMapsetChanged)
         self._giface.currentMapsetChanged.connect(self.OnMapsetChanged)
 
 
-        # minimal frame size
-        self.SetMinSize(globalvar.GM_WINDOW_MIN_SIZE)
-
-        # AUI stuff
-        self._auimgr.AddPane(
-            self.notebook,
-            wx.aui.AuiPaneInfo()
-            .Left()
-            .CentrePane()
-            .BestSize((-1, -1))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Row(1)
-            .Layer(0),
-        )
-
-        self._auimgr.Update()
-
-        wx.CallAfter(self.notebook.SetSelectionByName, "catalog")
-
         # use default window layout ?
         # use default window layout ?
         if UserSettings.Get(group="general", key="defWindowPos", subkey="enabled"):
         if UserSettings.Get(group="general", key="defWindowPos", subkey="enabled"):
             dim = UserSettings.Get(group="general", key="defWindowPos", subkey="dim")
             dim = UserSettings.Get(group="general", key="defWindowPos", subkey="dim")
@@ -238,6 +180,7 @@ class GMFrame(wx.Frame):
 
 
         self.Layout()
         self.Layout()
         self.Show()
         self.Show()
+        self.Maximize(True)
 
 
         # load workspace file if requested
         # load workspace file if requested
         if workspace:
         if workspace:
@@ -247,7 +190,7 @@ class GMFrame(wx.Frame):
             # start default initial display
             # start default initial display
             self.NewDisplay(show=False)
             self.NewDisplay(show=False)
 
 
-        # show map display widnow
+        # show map display window
         # -> OnSize() -> UpdateMap()
         # -> OnSize() -> UpdateMap()
         for mapdisp in self.GetMapDisplay(onlyCurrent=False):
         for mapdisp in self.GetMapDisplay(onlyCurrent=False):
             mapdisp.Show()
             mapdisp.Show()
@@ -291,7 +234,7 @@ class GMFrame(wx.Frame):
                 )
                 )
             )
             )
 
 
-    def _createMenuBar(self):
+    def CreateMenuBar(self):
         """Creates menu bar"""
         """Creates menu bar"""
         self.menubar = GMenu(
         self.menubar = GMenu(
             parent=self, model=self._menuTreeBuilder.GetModel(separators=True)
             parent=self, model=self._menuTreeBuilder.GetModel(separators=True)
@@ -347,13 +290,6 @@ class GMFrame(wx.Frame):
             return self._auimgr.GetPane(name).IsShown()
             return self._auimgr.GetPane(name).IsShown()
         return False
         return False
 
 
-    def _createNotebook(self):
-        """Initialize notebook widget"""
-        if sys.platform == "win32":
-            return GNotebook(parent=self, style=globalvar.FNPageDStyle)
-        else:
-            return FormNotebook(parent=self, style=wx.NB_BOTTOM)
-
     def _createDataCatalog(self, parent):
     def _createDataCatalog(self, parent):
         """Initialize Data Catalog widget"""
         """Initialize Data Catalog widget"""
         self.datacatalog = DataCatalog(parent=parent, giface=self._giface)
         self.datacatalog = DataCatalog(parent=parent, giface=self._giface)
@@ -424,36 +360,151 @@ class GMFrame(wx.Frame):
         else:
         else:
             self.pyshell = None
             self.pyshell = None
 
 
-    def _addPagesToNotebook(self):
-        """Add pages to notebook widget"""
-        # add 'data catalog' widget to main notebook page
-        self.notebook.AddPage(page=self.datacatalog, text=_("Data"), name="catalog")
+    def _createMapDisplay(self, parent):
+        """Set up Map Display"""
+        # blank panel for testing
+        self.mapdisplay = wx.Panel(parent=parent)
+
+    def BuildPanes(self):
+        """Build panes - toolbars as well as panels"""
+
+        # initialize all main widgets
+        self._createDataCatalog(parent=self)
+        self._createDisplay(parent=self)
+        self._createSearchModule(parent=self)
+        self._createConsole(parent=self)
+        self._createPythonShell(parent=self)
+        self._createMapDisplay(parent=self)
+        self.toolbars = {
+            "workspace": LMWorkspaceToolbar(parent=self),
+            "tools": LMToolsToolbar(parent=self),
+            "misc": LMMiscToolbar(parent=self),
+            "nviz": LMNvizToolbar(parent=self),
+        }
+        self._toolbarsData = {
+            "workspace": (
+                "toolbarWorkspace",  # name
+                _("Workspace Toolbar"),  # caption
+                1,
+                0,
+            ),  # row, position
+            "tools": ("toolbarTools", _("Tools Toolbar"), 1, 1),
+            "misc": ("toolbarMisc", _("Misc Toolbar"), 1, 2),
+            "nviz": ("toolbarNviz", _("3D view Toolbar"), 1, 3),
+        }
+
+        # add a bunch of panes
+        toolbarsList = ("workspace", "tools", "misc", "nviz")
+        for toolbar in toolbarsList:
+            name, caption, row, position = self._toolbarsData[toolbar]
+            self._auimgr.AddPane(
+                self.toolbars[toolbar],
+                aui.AuiPaneInfo()
+                .Name(name)
+                .Caption(caption)
+                .ToolbarPane()
+                .Top()
+                .Row(row)
+                .Position(position)
+                .LeftDockable(False)
+                .RightDockable(False)
+                .BottomDockable(False)
+                .TopDockable(True)
+                .CloseButton(False)
+                .Layer(2)
+                .BestSize((self.toolbars[toolbar].GetBestSize())),
+            )
 
 
-        # add 'display' widget to main notebook page
-        self.notebook.AddPage(page=self.displayPanel, text=_("Display"), name="layers")
+        self._auimgr.AddPane(
+            self.mapdisplay,
+            aui.AuiPaneInfo().Name("map display").CenterPane().PaneBorder(True),
+        )
 
 
-        # add 'modules' widget to main notebook page
-        if self.search:
-            self.notebook.AddPage(page=self.search, text=_("Modules"), name="search")
+        self._auimgr.AddPane(
+            self.datacatalog,
+            aui.AuiPaneInfo()
+            .Name("datacatalog")
+            .Caption("Data Catalog")
+            .Left()
+            .Layer(1)
+            .Position(1)
+            .BestSize(self.PANE_BEST_SIZE)
+            .MinSize(self.PANE_MIN_SIZE)
+            .CloseButton(False)
+            .MinimizeButton(True)
+            .MaximizeButton(True),
+        )
 
 
-        # add 'console' widget to main notebook page and add connect switch page signal
-        self.notebook.AddPage(page=self.goutput, text=_("Console"), name="output")
-        self.goutput.contentChanged.connect(
-            lambda notification: self._switchPage(notification)
+        self._auimgr.AddPane(
+            self.displayPanel,
+            aui.AuiPaneInfo()
+            .Name("display")
+            .Caption("Display")
+            .Left()
+            .Layer(1)
+            .Position(2)
+            .BestSize(self.PANE_BEST_SIZE)
+            .MinSize(self.PANE_MIN_SIZE)
+            .CloseButton(False)
+            .MinimizeButton(True)
+            .MaximizeButton(True),
         )
         )
 
 
-        # add 'python shell' widget to main notebook page
-        if self.pyshell:
-            self.notebook.AddPage(page=self.pyshell, text=_("Python"), name="pyshell")
+        self._auimgr.AddPane(
+            self.search,
+            aui.AuiPaneInfo()
+            .Name("modules")
+            .Caption("Modules")
+            .Right()
+            .Layer(2)
+            .Position(1)
+            .BestSize(self.PANE_BEST_SIZE)
+            .MinSize(self.PANE_MIN_SIZE)
+            .CloseButton(False)
+            .MinimizeButton(True)
+            .MaximizeButton(True),
+        )
 
 
-        # bindings
-        if sys.platform == "win32":
-            self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
-        else:
-            self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
+        self._auimgr.AddPane(
+            self.goutput,
+            aui.AuiPaneInfo()
+            .Name("console")
+            .Caption("Console")
+            .Right()
+            .Layer(2)
+            .Position(2)
+            .BestSize(self.PANE_BEST_SIZE)
+            .MinSize(self.PANE_MIN_SIZE)
+            .CloseButton(False)
+            .MinimizeButton(True)
+            .MaximizeButton(True),
+        )
+
+        self._auimgr.AddPane(
+            self.pyshell,
+            aui.AuiPaneInfo()
+            .Name("python")
+            .Caption("Python")
+            .Right()
+            .Layer(2)
+            .Position(3)
+            .BestSize(self.PANE_BEST_SIZE)
+            .MinSize(self.PANE_MIN_SIZE)
+            .CloseButton(False)
+            .MinimizeButton(True)
+            .MaximizeButton(True),
+        )
 
 
+        self._auimgr.GetPane("toolbarNviz").Hide()
         wx.CallAfter(self.datacatalog.LoadItems)
         wx.CallAfter(self.datacatalog.LoadItems)
 
 
+        self._auimgr.Update()
+
+    def BindEvents(self):
+        # bindings
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindowOrExit)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+
     def _show_demo_map(self):
     def _show_demo_map(self):
         """If in demolocation, add demo map to map display
         """If in demolocation, add demo map to map display
 
 
@@ -679,15 +730,6 @@ class GMFrame(wx.Frame):
 
 
         event.Skip()
         event.Skip()
 
 
-    def OnPageChanged(self, event):
-        """Page in notebook changed"""
-        page = event.GetSelection()
-        if page == self.notebook.GetPageIndexByName("output"):
-            wx.CallAfter(self.goutput.ResetFocus)
-        self.SetStatusText("", 0)
-
-        event.Skip()
-
     def OnCBPageClosing(self, event):
     def OnCBPageClosing(self, event):
         """Page of notebook is being closed
         """Page of notebook is being closed
         from Layer Manager (x button next to arrows)
         from Layer Manager (x button next to arrows)
@@ -715,21 +757,6 @@ class GMFrame(wx.Frame):
         self.notebookLayers.DeletePage(page_index)
         self.notebookLayers.DeletePage(page_index)
         self.notebookLayers.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnCBPageClosing)
         self.notebookLayers.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnCBPageClosing)
 
 
-    def _switchPageHandler(self, event, notification):
-        self._switchPage(notification=notification)
-        event.Skip()
-
-    def _switchPage(self, notification):
-        """Manages @c 'output' notebook page according to event notification."""
-        if notification == Notification.HIGHLIGHT:
-            self.notebook.HighlightPageByName("output")
-        if notification == Notification.MAKE_VISIBLE:
-            self.notebook.SetSelectionByName("output")
-        if notification == Notification.RAISE_WINDOW:
-            self.notebook.SetSelectionByName("output")
-            self.SetFocus()
-            self.Raise()
-
     def RunSpecialCmd(self, command):
     def RunSpecialCmd(self, command):
         """Run command from command line, check for GUI wrappers"""
         """Run command from command line, check for GUI wrappers"""
         if re.compile(r"^d\..*").search(command[0]):
         if re.compile(r"^d\..*").search(command[0]):
@@ -1888,7 +1915,6 @@ class GMFrame(wx.Frame):
         if not self.currentPage:
         if not self.currentPage:
             self.NewDisplay(show=True)
             self.NewDisplay(show=True)
 
 
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("raster")
         self.GetLayerTree().AddLayer("raster")
 
 
     def OnAddRasterMisc(self, event):
     def OnAddRasterMisc(self, event):
@@ -1920,7 +1946,6 @@ class GMFrame(wx.Frame):
         if not self.currentPage:
         if not self.currentPage:
             self.NewDisplay(show=True)
             self.NewDisplay(show=True)
 
 
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("vector")
         self.GetLayerTree().AddLayer("vector")
 
 
     def OnAddVectorMisc(self, event):
     def OnAddVectorMisc(self, event):
@@ -1941,12 +1966,10 @@ class GMFrame(wx.Frame):
 
 
     def OnAddVectorTheme(self, event):
     def OnAddVectorTheme(self, event):
         """Add thematic vector map to the current layer tree"""
         """Add thematic vector map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("thememap")
         self.GetLayerTree().AddLayer("thememap")
 
 
     def OnAddVectorChart(self, event):
     def OnAddVectorChart(self, event):
         """Add chart vector map to the current layer tree"""
         """Add chart vector map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("themechart")
         self.GetLayerTree().AddLayer("themechart")
 
 
     def OnAddOverlay(self, event):
     def OnAddOverlay(self, event):
@@ -1971,27 +1994,22 @@ class GMFrame(wx.Frame):
 
 
     def OnAddRaster3D(self, event):
     def OnAddRaster3D(self, event):
         """Add 3D raster map to the current layer tree"""
         """Add 3D raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("raster_3d")
         self.GetLayerTree().AddLayer("raster_3d")
 
 
     def OnAddRasterRGB(self, event):
     def OnAddRasterRGB(self, event):
         """Add RGB raster map to the current layer tree"""
         """Add RGB raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("rgb")
         self.GetLayerTree().AddLayer("rgb")
 
 
     def OnAddRasterHIS(self, event):
     def OnAddRasterHIS(self, event):
         """Add HIS raster map to the current layer tree"""
         """Add HIS raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("his")
         self.GetLayerTree().AddLayer("his")
 
 
     def OnAddRasterShaded(self, event):
     def OnAddRasterShaded(self, event):
         """Add shaded relief raster map to the current layer tree"""
         """Add shaded relief raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("shaded")
         self.GetLayerTree().AddLayer("shaded")
 
 
     def OnAddRasterArrow(self, event):
     def OnAddRasterArrow(self, event):
         """Add flow arrows raster map to the current layer tree"""
         """Add flow arrows raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         # here it seems that it should be retrieved from the mapwindow
         # here it seems that it should be retrieved from the mapwindow
         mapdisplay = self.GetMapDisplay()
         mapdisplay = self.GetMapDisplay()
         resolution = mapdisplay.mapWindowProperties.resolution
         resolution = mapdisplay.mapWindowProperties.resolution
@@ -2005,7 +2023,6 @@ class GMFrame(wx.Frame):
 
 
     def OnAddRasterNum(self, event):
     def OnAddRasterNum(self, event):
         """Add cell number raster map to the current layer tree"""
         """Add cell number raster map to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         mapdisplay = self.GetMapDisplay()
         mapdisplay = self.GetMapDisplay()
         resolution = mapdisplay.mapWindowProperties.resolution
         resolution = mapdisplay.mapWindowProperties.resolution
         if not resolution:
         if not resolution:
@@ -2030,7 +2047,6 @@ class GMFrame(wx.Frame):
         if not self.currentPage:
         if not self.currentPage:
             self.NewDisplay(show=True)
             self.NewDisplay(show=True)
 
 
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("command")
         self.GetLayerTree().AddLayer("command")
 
 
         # show map display
         # show map display
@@ -2042,7 +2058,6 @@ class GMFrame(wx.Frame):
         if not self.currentPage:
         if not self.currentPage:
             self.NewDisplay(show=True)
             self.NewDisplay(show=True)
 
 
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("group")
         self.GetLayerTree().AddLayer("group")
 
 
         # show map display
         # show map display
@@ -2050,17 +2065,14 @@ class GMFrame(wx.Frame):
 
 
     def OnAddGrid(self, event):
     def OnAddGrid(self, event):
         """Add grid map layer to the current layer tree"""
         """Add grid map layer to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("grid")
         self.GetLayerTree().AddLayer("grid")
 
 
     def OnAddGeodesic(self, event):
     def OnAddGeodesic(self, event):
         """Add geodesic line map layer to the current layer tree"""
         """Add geodesic line map layer to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("geodesic")
         self.GetLayerTree().AddLayer("geodesic")
 
 
     def OnAddRhumb(self, event):
     def OnAddRhumb(self, event):
         """Add rhumb map layer to the current layer tree"""
         """Add rhumb map layer to the current layer tree"""
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("rhumb")
         self.GetLayerTree().AddLayer("rhumb")
 
 
     def OnAddLabels(self, event):
     def OnAddLabels(self, event):
@@ -2069,7 +2081,6 @@ class GMFrame(wx.Frame):
         if not self.currentPage:
         if not self.currentPage:
             self.NewDisplay(show=True)
             self.NewDisplay(show=True)
 
 
-        self.notebook.SetSelectionByName("layers")
         self.GetLayerTree().AddLayer("labels")
         self.GetLayerTree().AddLayer("labels")
 
 
         # show map display
         # show map display
@@ -2145,16 +2156,6 @@ class GMFrame(wx.Frame):
         """Key pressed"""
         """Key pressed"""
         kc = event.GetKeyCode()
         kc = event.GetKeyCode()
 
 
-        if event.ControlDown():
-            if kc == wx.WXK_TAB:
-                # switch layer list / command output
-                if self.notebook.GetSelection() == self.notebook.GetPageIndexByName(
-                    "layers"
-                ):
-                    self.notebook.SetSelectionByName("output")
-                else:
-                    self.notebook.SetSelectionByName("layers")
-
         try:
         try:
             kc = chr(kc)
             kc = chr(kc)
         except ValueError:
         except ValueError: