Browse Source

wxGUI: Remove statusbar combobox and instead add statusbar settings to Map Display Settings (#2153)

Creates several radiobuttons in Map Display settings that control which item will be shown in statusbar.
Linda Kladivova 3 years ago
parent
commit
28a86c9276

+ 1 - 1
gui/wxpython/gcp/statusbar.py

@@ -34,7 +34,7 @@ class SbGoToGCP(SbItem):
     def __init__(self, mapframe, statusbar, position=0):
         SbItem.__init__(self, mapframe, statusbar, position)
         self.name = "gotoGCP"
-        self.label = _("Go to GCP No.")
+        self.label = _("Pan to GCP by number")
 
         self.widget = SpinCtrl(parent=self.statusbar, id=wx.ID_ANY, value="", min=0)
         self.widget.Hide()

+ 4 - 1
gui/wxpython/gui_core/mapdisp.py

@@ -498,7 +498,10 @@ class MapPanelBase(wx.Panel):
         from mapdisp.properties import MapDisplayPropertiesDialog
 
         dlg = MapDisplayPropertiesDialog(
-            parent=self, mapframe=self, properties=self.mapWindowProperties
+            parent=self,
+            mapframe=self,
+            properties=self.mapWindowProperties,
+            sbmanager=self.statusbarManager,
         )
         dlg.CenterOnParent()
         dlg.Show()

+ 1 - 1
gui/wxpython/image2target/ii2t_statusbar.py

@@ -34,7 +34,7 @@ class SbGoToGCP(SbItem):
     def __init__(self, mapframe, statusbar, position=0):
         SbItem.__init__(self, mapframe, statusbar, position)
         self.name = "gotoGCP"
-        self.label = _("Go to GCP No.")
+        self.label = _("Pan to GCP by number")
 
         self.widget = SpinCtrl(parent=self.statusbar, id=wx.ID_ANY, value="", min=0)
         self.widget.Hide()

+ 6 - 6
gui/wxpython/mapdisp/frame.py

@@ -150,7 +150,7 @@ class MapPanel(SingleMapPanel):
                 sb.SbMapScale,
                 sb.SbGoTo,
             ]
-            self.statusbarItemsHiddenInNviz = (
+            self.statusbarItemsDisabledInNviz = (
                 sb.SbDisplayGeometry,
                 sb.SbMapScale,
             )
@@ -448,8 +448,8 @@ class MapPanel(SingleMapPanel):
         )
         # update status bar
 
-        self.statusbarManager.HideStatusbarChoiceItemsByClass(
-            self.statusbarItemsHiddenInNviz
+        self.statusbarManager.DisableStatusbarItemsByClass(
+            self.statusbarItemsDisabledInNviz
         )
         self.statusbarManager.SetMode(0)
 
@@ -548,13 +548,13 @@ class MapPanel(SingleMapPanel):
             pass
 
         # update status bar
-        self.statusbarManager.ShowStatusbarChoiceItemsByClass(
-            self.statusbarItemsHiddenInNviz
-        )
+        self.statusbarManager.disabledItems = {}
         self.statusbarManager.SetMode(
             UserSettings.Get(group="display", key="statusbarMode", subkey="selection")
         )
         self.SetStatusText(_("Please wait, unloading data..."), 0)
+        self.statusbarManager.Update()
+
         # unloading messages from library cause highlight anyway
         self._giface.WriteCmdLog(
             _("Switching back to 2D view mode..."),

+ 60 - 3
gui/wxpython/mapdisp/properties.py

@@ -9,6 +9,8 @@ Classes:
  - properties::ChBShowRegion
  - properties::ChBAlignExtent
  - properties::ChBResolution
+ - properties::ChBProjection
+ - properties::RBShowInStatusbar
  - properties::MapDisplayPropertiesDialog
 
 (C) 2021 by the GRASS Development Team
@@ -277,6 +279,50 @@ class ChBProjection(PropertyItem):
             self.widget.SetLabel(self.defaultLabel)
 
 
+class RBShowInStatusbar:
+    """Radiobox managing widgets in statusbar."""
+
+    def __init__(self, parent, sbmanager):
+        self.name = "showInStatusbar"
+        self.statusbarManager = sbmanager
+
+        choices = self.statusbarManager.GetItemLabels()
+        self.widget = wx.RadioBox(
+            parent=parent,
+            id=wx.ID_ANY,
+            label="Displayed content",
+            choices=choices,
+            majorDimension=1,
+            style=wx.RA_SPECIFY_COLS,
+        )
+        self._setValue(self.statusbarManager.GetMode())
+        self._disableItems()
+
+        self.widget.Bind(wx.EVT_RADIOBOX, self._onToggleRadioBox)
+
+    def _setValue(self, mode):
+        self.widget.SetSelection(mode)
+
+    def GetValue(self):
+        return self.widget.GetSelection()
+
+    def _disableItems(self):
+        """Disables a radiobox options"""
+        for item in self.statusbarManager.disabledItems.keys():
+            self.widget.EnableItem(n=item, enable=False)
+
+    def GetWidget(self):
+        """Returns underlying widget.
+
+        :return: widget or None if doesn't exist
+        """
+        return self.widget
+
+    def _onToggleRadioBox(self, event):
+        self.statusbarManager.SetMode(self.GetValue())
+        self.statusbarManager.Update()
+
+
 class MapDisplayPropertiesDialog(wx.Dialog):
     """Map Display properties dialog"""
 
@@ -285,8 +331,9 @@ class MapDisplayPropertiesDialog(wx.Dialog):
         parent,
         mapframe,
         properties,
+        sbmanager,
         title=_("Map Display Settings"),
-        size=(-1, 250),
+        size=(-1, 300),
         style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
     ):
         wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
@@ -296,6 +343,7 @@ class MapDisplayPropertiesDialog(wx.Dialog):
         self.size = size
         self.mapframe = mapframe
         self.mapWindowProperties = properties
+        self.statusbarManager = sbmanager
 
         # notebook
         self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
@@ -382,10 +430,19 @@ class MapDisplayPropertiesDialog(wx.Dialog):
         panel.SetupScrolling(scroll_x=False, scroll_y=True)
         parent.AddPage(page=panel, text=_("Status bar"))
 
-        # General settings
         sizer = wx.BoxSizer(wx.VERTICAL)
 
-        # Auto-rendering
+        self.shownInStatusbar = RBShowInStatusbar(
+            parent=panel, sbmanager=self.statusbarManager
+        )
+        sizer.Add(
+            self.shownInStatusbar.GetWidget(),
+            proportion=0,
+            flag=wx.EXPAND | wx.ALL,
+            border=3,
+        )
+
+        # Display coordinates in different CRS
         self.projection = ChBProjection(panel, self.mapWindowProperties)
         sizer.Add(
             self.projection.GetWidget(),

+ 35 - 79
gui/wxpython/mapdisp/statusbar.py

@@ -52,8 +52,8 @@ class SbManager:
     """Statusbar manager for wx.Statusbar and SbItems.
 
     Statusbar manager manages items added by AddStatusbarItem method.
-    Provides progress bar (SbProgress) and choice (wx.Choice).
-    Items with position 0 are shown according to choice selection.
+    Provides progress bar (SbProgress).
+    Items with position 0 are shown according to selection in Map Display settings dialog.
     Only one item of the same class is supposed to be in statusbar.
     Manager user have to create statusbar on his own, add items to manager
     and call Update method to show particular widgets.
@@ -70,19 +70,16 @@ class SbManager:
     def __init__(self, mapframe, statusbar):
         """Connects manager to statusbar
 
-        Creates choice and progress bar.
+        Creates progress bar.
         """
         self.mapFrame = mapframe
         self.statusbar = statusbar
 
-        self.choice = wx.Choice(self.statusbar, wx.ID_ANY)
-
-        self.choice.Bind(wx.EVT_CHOICE, self.OnToggleStatus)
-
         self.statusbarItems = dict()
 
         self._postInitialized = False
         self._modeIndexSet = False
+        self._mode = 0
 
         self.progressbar = SbProgress(self.mapFrame, self.statusbar, self)
         self.progressbar.progressShown.connect(self._progressShown)
@@ -90,7 +87,7 @@ class SbManager:
 
         self._oldStatus = ""
 
-        self._hiddenItems = {}
+        self.disabledItems = {}
 
     def SetProperty(self, name, value):
         """Sets property represented by one of contained SbItems
@@ -119,15 +116,8 @@ class SbManager:
         return False
 
     def AddStatusbarItem(self, item):
-        """Adds item to statusbar
-
-        If item position is 0, item is managed by choice.
-
-        :func:`AddStatusbarItemsByClass`
-        """
+        """Adds item to statusbar"""
         self.statusbarItems[item.name] = item
-        if item.GetPosition() == 0:
-            self.choice.Append(item.label, clientData=item)  # attrError?
 
     def AddStatusbarItemsByClass(self, itemClasses, **kwargs):
         """Adds items to statusbar
@@ -141,46 +131,24 @@ class SbManager:
             item = Item(**kwargs)
             self.AddStatusbarItem(item)
 
-    def HideStatusbarChoiceItemsByClass(self, itemClasses):
-        """Hides items showed in choice
+    def DisableStatusbarItemsByClass(self, itemClasses):
+        """Fill list of item indexes that are disabled.
 
-        Hides items with position 0 (items showed in choice) by removing
-        them from choice.
-
-        :param itemClasses list of classes of items to be hided
-
-        :func:`ShowStatusbarChoiceItemsByClass`
-
-        .. todo::
-            consider adding similar function which would take item names
+        :param itemClasses list of classes of items to be disabled
         """
-        index = []
         for itemClass in itemClasses:
-            for i in range(0, self.choice.GetCount() - 1):
-                item = self.choice.GetClientData(i)
+            for i in range(0, len(self.statusbarItems.values())):
+                item = list(self.statusbarItems.values())[i]
                 if item.__class__ == itemClass:
-                    index.append(i)
-                    self._hiddenItems[i] = item
-        # must be sorted in reverse order to be removed correctly
-        for i in sorted(index, reverse=True):
-            self.choice.Delete(i)
+                    self.disabledItems[i] = item
 
-    def ShowStatusbarChoiceItemsByClass(self, itemClasses):
-        """Shows items showed in choice
-
-        Shows items with position 0 (items showed in choice) by adding
-        them to choice.
-        Items are restored in their old positions.
-
-        :param itemClasses list of classes of items to be showed
-
-        :func:`HideStatusbarChoiceItemsByClass`
-        """
-        # must be sorted to be inserted correctly
-        for pos in sorted(self._hiddenItems.keys()):
-            item = self._hiddenItems[pos]
-            if item.__class__ in itemClasses:
-                self.choice.Insert(item.label, pos, item)
+    def GetItemLabels(self):
+        """Get list of item labels"""
+        return [
+            value.label
+            for value in self.statusbarItems.values()
+            if value.GetPosition() == 0
+        ]
 
     def ShowItem(self, itemName):
         """Invokes showing of particular item
@@ -197,20 +165,18 @@ class SbManager:
         """Post-initialization method
 
         It sets internal user settings,
-        set choice's selection (from user settings) and does reposition.
-        It needs choice filled by items.
-        it is called automatically.
+        set selection (from map display settings) and does reposition.
+        It is called automatically.
         """
         UserSettings.Set(
             group="display",
             key="statusbarMode",
             subkey="choices",
-            value=self.choice.GetItems(),
+            value=self.GetItemLabels(),
             settings_type="internal",
         )
-
         if not self._modeIndexSet:
-            self.choice.SetSelection(
+            self.SetMode(
                 UserSettings.Get(
                     group="display", key="statusbarMode", subkey="selection"
                 )
@@ -220,10 +186,7 @@ class SbManager:
         self._postInitialized = True
 
     def Update(self):
-        """Updates statusbar
-
-        It always updates mask.
-        """
+        """Updates statusbar"""
         self.progressbar.Update()
 
         if not self._postInitialized:
@@ -233,12 +196,12 @@ class SbManager:
                 if not self.progressbar.IsShown():
                     item.Hide()
             else:
-                item.Update()  # mask, render
+                item.Update()  # render
 
         if self.progressbar.IsShown():
             pass
-        elif self.choice.GetCount() > 0:
-            item = self.choice.GetClientData(self.choice.GetSelection())
+        else:
+            item = list(self.statusbarItems.values())[self.GetMode()]
             item.Update()
 
     def Reposition(self):
@@ -252,7 +215,6 @@ class SbManager:
         for item in self.statusbarItems.values():
             widgets.append((item.GetPosition(), item.GetWidget()))
 
-        widgets.append((1, self.choice))
         widgets.append((1, self.progressbar.GetWidget()))
 
         for idx, win in widgets:
@@ -269,7 +231,7 @@ class SbManager:
                 # else:
                 x, y = rect.x + 3, rect.y - 1
                 w, h = wWin, rect.height + 2
-            else:  # choice || auto-rendering
+            else:  # auto-rendering
                 x, y = rect.x, rect.y
                 w, h = rect.width, rect.height + 1
                 if win == self.progressbar.GetWidget():
@@ -285,27 +247,21 @@ class SbManager:
 
     def _progressShown(self):
         self._oldStatus = self.statusbar.GetStatusText(0)
-        self.choice.GetClientData(self.choice.GetSelection()).Hide()
 
     def _progressHidden(self):
         self.statusbar.SetStatusText(self._oldStatus, 0)
-        self.choice.GetClientData(self.choice.GetSelection()).Show()
-
-    def OnToggleStatus(self, event):
-        """Toggle status text"""
-        self.Update()
 
-    def SetMode(self, modeIndex):
+    def SetMode(self, mode):
         """Sets current mode
 
-        Mode is usually driven by user through choice.
+        Mode is usually driven by user through map display settings.
         """
+        self._mode = mode
         self._modeIndexSet = True
-        self.choice.SetSelection(modeIndex)
 
     def GetMode(self):
         """Returns current mode"""
-        return self.choice.GetSelection()
+        return self._mode
 
     def SetProgress(self, range, value, text):
         """Update progress."""
@@ -381,7 +337,7 @@ class SbItem:
         self.mapFrame.StatusbarEnableLongHelp(longHelp)
 
     def Update(self):
-        """Called when statusbar action is activated (e.g. through wx.Choice)."""
+        """Called when statusbar action is activated (e.g. through Map Display settings)."""
         self._update(longHelp=False)
 
 
@@ -513,7 +469,7 @@ class SbGoTo(SbItem):
     def __init__(self, mapframe, statusbar, position=0):
         SbItem.__init__(self, mapframe, statusbar, position)
         self.name = "goto"
-        self.label = _("Go to")
+        self.label = _("Go to XY coordinates")
 
         self.widget = TextCtrl(
             parent=self.statusbar,
@@ -822,7 +778,7 @@ class SbRegionExtent(SbTextItem):
     def __init__(self, mapframe, statusbar, position=0):
         SbTextItem.__init__(self, mapframe, statusbar, position)
         self.name = "displayRegion"
-        self.label = _("Extent")
+        self.label = _("Display extent")
 
     def Show(self):
         precision = int(

+ 1 - 1
gui/wxpython/photo2image/ip2i_statusbar.py

@@ -34,7 +34,7 @@ class SbGoToGCP(SbItem):
     def __init__(self, mapframe, statusbar, position=0):
         SbItem.__init__(self, mapframe, statusbar, position)
         self.name = "gotoGCP"
-        self.label = _("Go to GCP No.")
+        self.label = _("Pan to GCP by number")
 
         self.widget = SpinCtrl(parent=self.statusbar, id=wx.ID_ANY, value="", min=0)
         self.widget.Hide()