瀏覽代碼

wxGUI: Move SbMask widget to main window/layer manager statusbar (#2089)

Co-authored-by: Anna Petrasova <kratochanna@gmail.com>
Linda Kladivova 3 年之前
父節點
當前提交
251bce4254

+ 13 - 3
gui/wxpython/core/gconsole.py

@@ -371,8 +371,6 @@ class GConsole(wx.EvtHandler):
         # Signal when some map is created or updated by a module.
         # Signal when some map is created or updated by a module.
         # attributes: name: map name, ltype: map type,
         # attributes: name: map name, ltype: map type,
         self.mapCreated = Signal("GConsole.mapCreated")
         self.mapCreated = Signal("GConsole.mapCreated")
-        # emitted when map display should be re-render
-        self.updateMap = Signal("GConsole.updateMap")
         # emitted when log message should be written
         # emitted when log message should be written
         self.writeLog = Signal("GConsole.writeLog")
         self.writeLog = Signal("GConsole.writeLog")
         # emitted when command log message should be written
         # emitted when command log message should be written
@@ -788,7 +786,19 @@ class GConsole(wx.EvtHandler):
                                 element=prompt,
                                 element=prompt,
                             )
                             )
         if name == "r.mask":
         if name == "r.mask":
-            self.updateMap.emit()
+            action = "new"
+            for p in task.get_options()["flags"]:
+                if p.get("name") == "r" and p.get("value"):
+                    action = "delete"
+            gisenv = grass.gisenv()
+            self._giface.grassdbChanged.emit(
+                grassdb=gisenv["GISDBASE"],
+                location=gisenv["LOCATION_NAME"],
+                mapset=gisenv["MAPSET"],
+                action=action,
+                map="MASK",
+                element="raster",
+            )
 
 
         event.Skip()
         event.Skip()
 
 

+ 0 - 1
gui/wxpython/gui_core/forms.py

@@ -570,7 +570,6 @@ class TaskFrame(wx.Frame):
         self._gconsole = self.notebookpanel._gconsole
         self._gconsole = self.notebookpanel._gconsole
         if self._gconsole:
         if self._gconsole:
             self._gconsole.mapCreated.connect(self.OnMapCreated)
             self._gconsole.mapCreated.connect(self.OnMapCreated)
-            self._gconsole.updateMap.connect(lambda: self._giface.updateMap.emit())
         self.goutput = self.notebookpanel.goutput
         self.goutput = self.notebookpanel.goutput
         if self.goutput:
         if self.goutput:
             self.goutput.showNotification.connect(
             self.goutput.showNotification.connect(

+ 3 - 6
gui/wxpython/gui_core/mapdisp.py

@@ -321,8 +321,8 @@ class MapPanelBase(wx.Panel):
         # create statusbar and its manager
         # create statusbar and its manager
         statusbar = wx.StatusBar(self, id=wx.ID_ANY)
         statusbar = wx.StatusBar(self, id=wx.ID_ANY)
         statusbar.SetMinHeight(24)
         statusbar.SetMinHeight(24)
-        statusbar.SetFieldsCount(4)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
+        statusbar.SetFieldsCount(3)
+        statusbar.SetStatusWidths([-6, -2, -1])
         self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
         self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
 
 
         # fill statusbar manager
         # fill statusbar manager
@@ -330,10 +330,7 @@ class MapPanelBase(wx.Panel):
             statusbarItems, mapframe=self, statusbar=statusbar
             statusbarItems, mapframe=self, statusbar=statusbar
         )
         )
         self.statusbarManager.AddStatusbarItem(
         self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbRender(self, statusbar=statusbar, position=3)
+            sb.SbRender(self, statusbar=statusbar, position=2)
         )
         )
         self.statusbarManager.Update()
         self.statusbarManager.Update()
         return statusbar
         return statusbar

+ 23 - 1
gui/wxpython/lmgr/frame.py

@@ -62,6 +62,7 @@ from gui_core.menu import Menu as GMenu
 from core.debug import Debug
 from core.debug import Debug
 from lmgr.toolbars import LMWorkspaceToolbar, LMToolsToolbar
 from lmgr.toolbars import LMWorkspaceToolbar, LMToolsToolbar
 from lmgr.toolbars import LMMiscToolbar, LMNvizToolbar, DisplayPanelToolbar
 from lmgr.toolbars import LMMiscToolbar, LMNvizToolbar, DisplayPanelToolbar
+from lmgr.statusbar import SbMain
 from lmgr.workspace import WorkspaceManager
 from lmgr.workspace import WorkspaceManager
 from lmgr.pyshell import PyShellWindow
 from lmgr.pyshell import PyShellWindow
 from lmgr.giface import (
 from lmgr.giface import (
@@ -152,7 +153,7 @@ class GMFrame(wx.Frame):
 
 
         # create widgets
         # create widgets
         self._createMenuBar()
         self._createMenuBar()
-        self.statusbar = self.CreateStatusBar(number=1)
+        self.statusbar = SbMain(parent=self, giface=self._giface)
         self.notebook = self._createNotebook()
         self.notebook = self._createNotebook()
         self._createDataCatalog(self.notebook)
         self._createDataCatalog(self.notebook)
         self._createDisplay(self.notebook)
         self._createDisplay(self.notebook)
@@ -199,6 +200,23 @@ class GMFrame(wx.Frame):
             )
             )
 
 
         self._auimgr.GetPane("toolbarNviz").Hide()
         self._auimgr.GetPane("toolbarNviz").Hide()
+
+        # Add statusbar
+        self._auimgr.AddPane(
+            self.statusbar.GetWidget(),
+            wx.aui.AuiPaneInfo()
+            .Bottom()
+            .MinSize(30, 30)
+            .Fixed()
+            .Name("statusbar")
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .ToolbarPane()
+            .Dockable(False)
+            .PaneBorder(False)
+            .Gripper(False),
+        )
+
         # bindings
         # bindings
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindowOrExit)
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindowOrExit)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
@@ -329,6 +347,10 @@ class GMFrame(wx.Frame):
             return self._auimgr.GetPane(name).IsShown()
             return self._auimgr.GetPane(name).IsShown()
         return False
         return False
 
 
+    def SetStatusText(self, *args):
+        """Overide SbMain statusbar method"""
+        self.statusbar.SetStatusText(*args)
+
     def _createNotebook(self):
     def _createNotebook(self):
         """Initialize notebook widget"""
         """Initialize notebook widget"""
         if sys.platform == "win32":
         if sys.platform == "win32":

+ 146 - 0
gui/wxpython/lmgr/statusbar.py

@@ -0,0 +1,146 @@
+"""
+@package frame.statusbar
+
+@brief Classes for main window statusbar management
+
+Classes:
+ - statusbar::SbMain
+ - statusbar::SbMask
+
+(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>
+@author Vaclav Petras <wenzeslaus gmail.com>
+"""
+
+import wx
+
+import grass.script as gs
+
+from core.gcmd import RunCommand
+from gui_core.wrap import Button
+
+
+class SbMain:
+    """Statusbar for main window."""
+
+    def __init__(self, parent, giface):
+        self.parent = parent
+        self.giface = giface
+        self.widget = wx.StatusBar(self.parent, id=wx.ID_ANY)
+        self.widget.SetMinHeight(24)
+        self.widget.SetFieldsCount(2)
+        self.widget.SetStatusWidths([-1, 100])
+        self.mask = SbMask(self.widget, self.giface)
+        self.widget.Bind(wx.EVT_SIZE, self.OnSize)
+        self._repositionStatusbar()
+
+    def GetWidget(self):
+        """Returns underlying widget.
+
+        :return: widget or None if doesn't exist
+        """
+        return self.widget
+
+    def _repositionStatusbar(self):
+        """Reposition widgets in main window statusbar"""
+        rect1 = self.GetWidget().GetFieldRect(1)
+        rect1.x += 1
+        rect1.y += 1
+        self.mask.GetWidget().SetRect(rect1)
+
+    def Refresh(self):
+        """Refresh statusbar. So far it refreshes just a mask."""
+        self.mask.Refresh()
+
+    def OnSize(self, event):
+        """Adjust main window statusbar on changing size"""
+        self._repositionStatusbar()
+
+    def SetStatusText(self, *args):
+        """Overide wx.StatusBar method"""
+        self.GetWidget().SetStatusText(*args)
+
+
+class SbMask:
+    """Button to show whether mask is activated and remove mask with
+    left mouse click
+    """
+
+    def __init__(self, parent, giface):
+        self.name = "mask"
+        self.mask_layer = "MASK"
+        self.parent = parent
+        self.giface = giface
+        self.widget = Button(
+            parent=parent, id=wx.ID_ANY, label=_(self.mask_layer), style=wx.NO_BORDER
+        )
+        self.widget.Bind(wx.EVT_BUTTON, self.OnRemoveMask)
+        self.widget.SetForegroundColour(wx.Colour(255, 0, 0))
+        self.widget.SetToolTip(tip=_("Left mouse click to remove the MASK"))
+        self.giface.currentMapsetChanged.connect(self.Refresh)
+        self.giface.grassdbChanged.connect(self._dbChanged)
+        self.Refresh()
+
+    def _dbChanged(self, map=None, newname=None):
+        if map == self.mask_layer or newname == self.mask_layer:
+            self.Refresh()
+            self.giface.updateMap.emit()
+
+    def Show(self):
+        """Invokes showing of underlying widget.
+
+        In derived classes it can do what is appropriate for it,
+        e.g. showing text on statusbar (only).
+        """
+        self.widget.Show()
+
+    def Hide(self):
+        self.widget.Hide()
+
+    def SetValue(self, value):
+        self.widget.SetValue(value)
+
+    def GetValue(self):
+        return self.widget.GetValue()
+
+    def GetWidget(self):
+        """Returns underlying widget.
+
+        :return: widget or None if doesn't exist
+        """
+        return self.widget
+
+    def Refresh(self):
+        """Show mask in the statusbar if mask file found"""
+        if gs.find_file(
+            name=self.mask_layer, element="cell", mapset=gs.gisenv()["MAPSET"]
+        )["name"]:
+            self.Show()
+        else:
+            self.Hide()
+
+    def OnRemoveMask(self, event):
+        dlg = wx.MessageDialog(
+            self.parent,
+            message=_("Are you sure that you want to remove the MASK?"),
+            caption=_("Remove MASK"),
+            style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION,
+        )
+        if dlg.ShowModal() != wx.ID_YES:
+            dlg.Destroy()
+            return
+        RunCommand("r.mask", flags="r")
+        gisenv = gs.gisenv()
+        self.giface.grassdbChanged.emit(
+            grassdb=gisenv["GISDBASE"],
+            location=gisenv["LOCATION_NAME"],
+            mapset=gisenv["MAPSET"],
+            map=self.mask_layer,
+            action="delete",
+            element="raster",
+        )

+ 25 - 5
gui/wxpython/main_window/frame.py

@@ -67,6 +67,7 @@ from gui_core.menu import Menu as GMenu
 from core.debug import Debug
 from core.debug import Debug
 from lmgr.toolbars import LMWorkspaceToolbar, LMToolsToolbar
 from lmgr.toolbars import LMWorkspaceToolbar, LMToolsToolbar
 from lmgr.toolbars import LMMiscToolbar, LMNvizToolbar, DisplayPanelToolbar
 from lmgr.toolbars import LMMiscToolbar, LMNvizToolbar, DisplayPanelToolbar
+from lmgr.statusbar import SbMain
 from lmgr.workspace import WorkspaceManager
 from lmgr.workspace import WorkspaceManager
 from lmgr.pyshell import PyShellWindow
 from lmgr.pyshell import PyShellWindow
 from lmgr.giface import (
 from lmgr.giface import (
@@ -96,7 +97,7 @@ class GMFrame(wx.Frame):
         id=wx.ID_ANY,
         id=wx.ID_ANY,
         title=None,
         title=None,
         workspace=None,
         workspace=None,
-        size=globalvar.GM_WINDOW_SIZE,
+        size=wx.Display().GetGeometry().GetSize(),
         style=wx.DEFAULT_FRAME_STYLE,
         style=wx.DEFAULT_FRAME_STYLE,
         **kwargs,
         **kwargs,
     ):
     ):
@@ -107,6 +108,7 @@ class GMFrame(wx.Frame):
             self.baseTitle = _("GRASS GIS")
             self.baseTitle = _("GRASS GIS")
 
 
         self.iconsize = (16, 16)
         self.iconsize = (16, 16)
+        self.size = size
 
 
         self.displayIndex = 0  # index value for map displays and layer trees
         self.displayIndex = 0  # index value for map displays and layer trees
         self.currentPage = None  # currently selected page for layer tree notebook
         self.currentPage = None  # currently selected page for layer tree notebook
@@ -154,13 +156,11 @@ class GMFrame(wx.Frame):
         self.dialogs["atm"] = list()
         self.dialogs["atm"] = list()
 
 
         # set pane sizes according to the full screen size of the primary monitor
         # set pane sizes according to the full screen size of the primary monitor
-        size = wx.Display().GetGeometry().GetSize()
-        self.PANE_BEST_SIZE = tuple(t // 3 for t in size)
-        self.PANE_MIN_SIZE = tuple(t // 5 for t in size)
+        self.PANE_BEST_SIZE = tuple(t // 3 for t in self.size)
+        self.PANE_MIN_SIZE = tuple(t // 5 for t in self.size)
 
 
         # create widgets and build panes
         # create widgets and build panes
         self.CreateMenuBar()
         self.CreateMenuBar()
-        self.CreateStatusBar(number=1)
         self.BuildPanes()
         self.BuildPanes()
         self.BindEvents()
         self.BindEvents()
 
 
@@ -270,6 +270,10 @@ class GMFrame(wx.Frame):
             return self._auimgr.GetPane(name).IsShown()
             return self._auimgr.GetPane(name).IsShown()
         return False
         return False
 
 
+    def SetStatusText(self, *args):
+        """Overide SbMain statusbar method"""
+        self.statusbar.SetStatusText(*args)
+
     def _createMapNotebook(self):
     def _createMapNotebook(self):
         """Create Map Display notebook"""
         """Create Map Display notebook"""
         # create the notebook off-window to avoid flicker
         # create the notebook off-window to avoid flicker
@@ -526,6 +530,7 @@ class GMFrame(wx.Frame):
         """Build panes - toolbars as well as panels"""
         """Build panes - toolbars as well as panels"""
         self._auimgr.SetAutoNotebookTabArt(SimpleTabArt())
         self._auimgr.SetAutoNotebookTabArt(SimpleTabArt())
         # initialize all main widgets
         # initialize all main widgets
+        self.statusbar = SbMain(parent=self, giface=self._giface)
         self._createMapNotebook()
         self._createMapNotebook()
         self._createDataCatalog(parent=self)
         self._createDataCatalog(parent=self)
         self._createDisplay(parent=self)
         self._createDisplay(parent=self)
@@ -578,6 +583,21 @@ class GMFrame(wx.Frame):
         )
         )
 
 
         self._auimgr.AddPane(
         self._auimgr.AddPane(
+            self.statusbar.GetWidget(),
+            aui.AuiPaneInfo()
+            .Bottom()
+            .MinSize(30, 30)
+            .Fixed()
+            .Name("statusbar")
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .ToolbarPane()
+            .Dockable(False)
+            .PaneBorder(False)
+            .Gripper(False),
+        )
+
+        self._auimgr.AddPane(
             self.datacatalog,
             self.datacatalog,
             aui.AuiPaneInfo()
             aui.AuiPaneInfo()
             .Name("datacatalog")
             .Name("datacatalog")

+ 2 - 51
gui/wxpython/mapdisp/statusbar.py

@@ -14,7 +14,6 @@ Classes:
  - statusbar::SbMapScale
  - statusbar::SbMapScale
  - statusbar::SbGoTo
  - statusbar::SbGoTo
  - statusbar::SbProjection
  - statusbar::SbProjection
- - statusbar::SbMask
  - statusbar::SbTextItem
  - statusbar::SbTextItem
  - statusbar::SbDisplayGeometry
  - statusbar::SbDisplayGeometry
  - statusbar::SbCoordinates
  - statusbar::SbCoordinates
@@ -37,9 +36,7 @@ import wx
 from core import utils
 from core import utils
 from core.gcmd import RunCommand
 from core.gcmd import RunCommand
 from core.settings import UserSettings
 from core.settings import UserSettings
-from gui_core.wrap import Button, TextCtrl
-
-from grass.script import core as grass
+from gui_core.wrap import TextCtrl
 
 
 from grass.pydispatch.signal import Signal
 from grass.pydispatch.signal import Signal
 
 
@@ -281,9 +278,7 @@ class SbManager:
                 w, h = rect.width, rect.height + 1
                 w, h = rect.width, rect.height + 1
                 if win == self.progressbar.GetWidget():
                 if win == self.progressbar.GetWidget():
                     wWin = rect.width - 6
                     wWin = rect.width - 6
-                if idx == 2:  # mask
-                    x += 5
-                elif idx == 3:  # render
+                if idx == 2:  # render
                     x += 5
                     x += 5
             win.SetPosition((x, y))
             win.SetPosition((x, y))
             win.SetSize((w, h))
             win.SetSize((w, h))
@@ -892,50 +887,6 @@ class SbProjection(SbItem):
         self.mapFrame.StatusbarEnableLongHelp(False)
         self.mapFrame.StatusbarEnableLongHelp(False)
 
 
 
 
-class SbMask(SbItem):
-    """Button to show whether mask is activated and remove mask with
-    left mouse click
-    """
-
-    def __init__(self, mapframe, statusbar, position=0):
-        SbItem.__init__(self, mapframe, statusbar, position)
-        self.name = "mask"
-
-        self.widget = Button(
-            parent=self.statusbar, id=wx.ID_ANY, label=_("MASK"), style=wx.NO_BORDER
-        )
-        self.widget.Bind(wx.EVT_BUTTON, self.OnRemoveMask)
-        self.widget.SetForegroundColour(wx.Colour(255, 0, 0))
-        self.widget.SetToolTip(tip=_("Left mouse click to remove the MASK"))
-        self.widget.Hide()
-
-    def Update(self):
-        if grass.find_file(
-            name="MASK", element="cell", mapset=grass.gisenv()["MAPSET"]
-        )["name"]:
-            self.Show()
-        else:
-            self.Hide()
-
-    def OnRemoveMask(self, event):
-        if grass.find_file(
-            name="MASK", element="cell", mapset=grass.gisenv()["MAPSET"]
-        )["name"]:
-
-            dlg = wx.MessageDialog(
-                self.mapFrame,
-                message=_("Are you sure that you want to remove the MASK?"),
-                caption=_("Remove MASK"),
-                style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION,
-            )
-            if dlg.ShowModal() != wx.ID_YES:
-                dlg.Destroy()
-                return
-            RunCommand("r.mask", flags="r")
-            self.Hide()
-            self.mapFrame.OnRender(event=None)
-
-
 class SbTextItem(SbItem):
 class SbTextItem(SbItem):
     """Base class for items without widgets.
     """Base class for items without widgets.