123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- """
- @package mapdisp.properties
- @brief Classes for map display properties management
- Classes:
- - properties::PropertyItem
- - properties::ChBRender
- - properties::ChBShowRegion
- - properties::ChBAlignExtent
- - properties::ChBResolution
- - properties::ChBProjection
- - properties::RBShowInStatusbar
- - properties::MapDisplayPropertiesDialog
- (C) 2021 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 Vaclav Petras <wenzeslaus gmail.com>
- @author Anna Kratochvilova <kratochanna gmail.com>
- @author Linda Kladivova <lindakladivova gmail.com>
- """
- import wx
- import wx.lib.scrolledpanel as SP
- from gui_core.wrap import Button
- class PropertyItem:
- """Base class for Map Display properties widgets that use property signals"""
- def __init__(self, mapWindowProperties):
- self._properties = mapWindowProperties
- @property
- def mapWindowProperty(self):
- pass
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- pass
- def mapWindowPropertyChanged(self):
- """Returns signal from MapWindowProperties."""
- pass
- 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 _connect(self):
- self.mapWindowPropertyChanged().connect(self._setValue)
- def _disconnect(self):
- self.mapWindowPropertyChanged().disconnect(self._setValue)
- def _onToggle(self, event):
- self._disconnect()
- self.mapWindowProperty = self.GetValue()
- self._connect()
- class ChBRender(PropertyItem):
- """Checkbox to enable and disable auto-rendering."""
- def __init__(self, parent, mapWindowProperties):
- PropertyItem.__init__(self, mapWindowProperties)
- self.name = "render"
- self.widget = wx.CheckBox(
- parent=parent, id=wx.ID_ANY, label=_("Enable auto-rendering")
- )
- self.widget.SetValue(self.mapWindowProperty)
- self.widget.SetToolTip(wx.ToolTip(_("Enable/disable auto-rendering")))
- self.widget.Bind(wx.EVT_CHECKBOX, self._onToggle)
- self._connect()
- @property
- def mapWindowProperty(self):
- return self._properties.autoRender
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.autoRender = value
- def mapWindowPropertyChanged(self):
- return self._properties.autoRenderChanged
- class ChBAlignExtent(PropertyItem):
- """Checkbox to select zoom behavior.
- Used by BufferedWindow (through MapFrame property).
- See tooltip for explanation.
- """
- def __init__(self, parent, mapWindowProperties):
- PropertyItem.__init__(self, mapWindowProperties)
- self.name = "alignExtent"
- self.widget = wx.CheckBox(
- parent=parent,
- id=wx.ID_ANY,
- label=_("Align region extent based on display size"),
- )
- self.widget.SetValue(self.mapWindowProperty)
- self.widget.SetToolTip(
- wx.ToolTip(
- _(
- "Align region extent based on display "
- "size from center point. "
- "Default value for new map displays can "
- "be set up in 'User GUI settings' dialog."
- )
- )
- )
- self.widget.Bind(wx.EVT_CHECKBOX, self._onToggle)
- self._connect()
- @property
- def mapWindowProperty(self):
- return self._properties.alignExtent
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.alignExtent = value
- def mapWindowPropertyChanged(self):
- return self._properties.alignExtentChanged
- class ChBResolution(PropertyItem):
- """Checkbox to select used display resolution."""
- def __init__(self, parent, mapframe, mapWindowProperties):
- PropertyItem.__init__(self, mapWindowProperties)
- self.mapFrame = mapframe
- self.name = "resolution"
- self.widget = wx.CheckBox(
- parent=parent,
- id=wx.ID_ANY,
- label=_("Constrain display resolution to computational settings"),
- )
- self.widget.SetValue(self.mapWindowProperty)
- self.widget.SetToolTip(
- wx.ToolTip(
- _(
- "Constrain display resolution "
- "to computational region settings. "
- "Default value for new map displays can "
- "be set up in 'User GUI settings' dialog."
- )
- )
- )
- self.widget.Bind(wx.EVT_CHECKBOX, self._onToggle)
- self._connect()
- @property
- def mapWindowProperty(self):
- return self._properties.resolution
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.resolution = value
- def mapWindowPropertyChanged(self):
- return self._properties.resolutionChanged
- def _onToggle(self, event):
- """Update display when toggle display mode"""
- super()._onToggle(event)
- # redraw map if auto-rendering is enabled
- if self._properties.autoRender:
- self.mapFrame.GetWindow().UpdateMap()
- class ChBShowRegion(PropertyItem):
- """Checkbox to enable and disable showing of computational region."""
- def __init__(self, parent, mapframe, mapWindowProperties):
- PropertyItem.__init__(self, mapWindowProperties)
- self.mapFrame = mapframe
- self.name = "showRegion"
- self.widget = wx.CheckBox(
- parent=parent, id=wx.ID_ANY, label=_("Show computational extent")
- )
- self.widget.SetValue(self.mapWindowProperty)
- self.widget.SetToolTip(
- wx.ToolTip(
- _(
- "Show/hide computational "
- "region extent (set with g.region). "
- "Display region drawn as a blue box inside the "
- "computational region, "
- "computational region inside a display region "
- "as a red box)."
- )
- )
- )
- self.widget.Bind(wx.EVT_CHECKBOX, self._onToggle)
- self._connect()
- @property
- def mapWindowProperty(self):
- return self._properties.showRegion
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.showRegion = value
- def mapWindowPropertyChanged(self):
- return self._properties.showRegionChanged
- def _onToggle(self, event):
- """Shows/Hides extent (comp. region) in map canvas.
- Shows or hides according to checkbox value.
- """
- super()._onToggle(event)
- # redraw map if auto-rendering is enabled
- if self._properties.autoRender:
- self.mapFrame.GetWindow().UpdateMap(render=False)
- class ChBProjection(PropertyItem):
- """Checkbox to enable user defined projection"""
- def __init__(self, parent, mapWindowProperties):
- PropertyItem.__init__(self, mapWindowProperties)
- self.name = "useDefinedProjection"
- self.defaultLabel = _("Display coordinates in different CRS")
- self.widget = wx.CheckBox(parent=parent, id=wx.ID_ANY, label=self.defaultLabel)
- self.widget.SetValue(self.mapWindowProperty)
- self.widget.SetToolTip(
- wx.ToolTip(
- _(
- "Reproject coordinates displayed "
- "in the statusbar. Coordinate reference system can be "
- "specified in GUI preferences dialog "
- "(tab 'Projection')"
- )
- )
- )
- self.widget.Bind(wx.EVT_CHECKBOX, self._onToggle)
- self._connect()
- @property
- def mapWindowProperty(self):
- return self._properties.useDefinedProjection
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.useDefinedProjection = value
- def mapWindowPropertyChanged(self):
- return self._properties.useDefinedProjectionChanged
- def _onToggle(self, event):
- super()._onToggle(event)
- epsg = self._properties.epsg
- if epsg:
- label = _("{label} (EPSG: {epsg})").format(
- label=self.defaultLabel, epsg=epsg
- )
- self.widget.SetLabel(label)
- else:
- self.widget.SetLabel(self.defaultLabel)
- class RBShowInStatusbar(PropertyItem):
- """Radiobox managing widgets in statusbar."""
- def __init__(self, parent, mapWindowProperties, sbmanager):
- PropertyItem.__init__(self, mapWindowProperties)
- 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.mapWindowProperty)
- self._disableItems()
- self.widget.Bind(wx.EVT_RADIOBOX, self._onToggle)
- self._connect()
- 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)
- @property
- def mapWindowProperty(self):
- return self._properties.sbItem
- @mapWindowProperty.setter
- def mapWindowProperty(self, value):
- self._properties.sbItem = value
- def mapWindowPropertyChanged(self):
- return self._properties.sbItemChanged
- class MapDisplayPropertiesDialog(wx.Dialog):
- """Map Display properties dialog"""
- def __init__(
- self,
- parent,
- mapframe,
- properties,
- sbmanager,
- title=_("Map Display Settings"),
- 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)
- self.parent = parent
- self.title = title
- 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)
- # create notebook pages
- self._createDisplayPage(parent=self.notebook)
- self._createStatusBarPage(parent=self.notebook)
- self.btnClose = Button(self, wx.ID_CLOSE)
- self.SetEscapeId(wx.ID_CLOSE)
- self._layout()
- def _layout(self):
- """Layout window"""
- # sizers
- btnStdSizer = wx.StdDialogButtonSizer()
- btnStdSizer.AddButton(self.btnClose)
- btnStdSizer.Realize()
- mainSizer = wx.BoxSizer(wx.VERTICAL)
- mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
- mainSizer.Add(btnStdSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
- self.SetSizer(mainSizer)
- self.SetMinSize(self.GetBestSize())
- self.SetSize(self.size)
- def _createDisplayPage(self, parent):
- """Create notebook page for display settings"""
- panel = SP.ScrolledPanel(parent=parent, id=wx.ID_ANY)
- panel.SetupScrolling(scroll_x=False, scroll_y=True)
- parent.AddPage(page=panel, text=_("General"))
- # General settings
- sizer = wx.BoxSizer(wx.VERTICAL)
- # Auto-rendering
- self.autoRendering = ChBRender(panel, self.mapWindowProperties)
- sizer.Add(
- self.autoRendering.GetWidget(),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=3,
- )
- # Align extent to display size
- self.alignExtent = ChBAlignExtent(panel, self.mapWindowProperties)
- sizer.Add(
- self.alignExtent.GetWidget(),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=3,
- )
- # Use computation resolution
- self.compResolution = ChBResolution(
- panel, self.mapframe, self.mapWindowProperties
- )
- sizer.Add(
- self.compResolution.GetWidget(),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=3,
- )
- # Show computation extent
- self.showCompExtent = ChBShowRegion(
- panel, self.mapframe, self.mapWindowProperties
- )
- sizer.Add(
- self.showCompExtent.GetWidget(),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=3,
- )
- panel.SetSizer(sizer)
- def _createStatusBarPage(self, parent):
- """Create notebook page for statusbar settings"""
- panel = SP.ScrolledPanel(parent=parent, id=wx.ID_ANY)
- panel.SetupScrolling(scroll_x=False, scroll_y=True)
- parent.AddPage(page=panel, text=_("Status bar"))
- sizer = wx.BoxSizer(wx.VERTICAL)
- self.shownInStatusbar = RBShowInStatusbar(
- parent=panel,
- mapWindowProperties=self.mapWindowProperties,
- 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(),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=3,
- )
- panel.SetSizer(sizer)
|