properties.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. """
  2. @package mapdisp.properties
  3. @brief Classes for map display properties management
  4. Classes:
  5. - properties::PropertyItem
  6. - properties::ChBRender
  7. - properties::ChBShowRegion
  8. - properties::ChBAlignExtent
  9. - properties::ChBResolution
  10. - properties::MapDisplayPropertiesDialog
  11. (C) 2021 by the GRASS Development Team
  12. This program is free software under the GNU General Public License
  13. (>=v2). Read the file COPYING that comes with GRASS for details.
  14. @author Vaclav Petras <wenzeslaus gmail.com>
  15. @author Anna Kratochvilova <kratochanna gmail.com>
  16. @author Linda Kladivova <lindakladivova gmail.com>
  17. """
  18. import wx
  19. import wx.lib.scrolledpanel as SP
  20. from gui_core.wrap import Button
  21. class PropertyItem:
  22. """Base class for Map Display properties widgets that use property signals"""
  23. def __init__(self, mapWindowProperties):
  24. self._properties = mapWindowProperties
  25. @property
  26. def mapWindowProperty(self):
  27. pass
  28. @mapWindowProperty.setter
  29. def mapWindowProperty(self, value):
  30. pass
  31. def mapWindowPropertyChanged(self):
  32. """Returns signal from MapWindowProperties."""
  33. pass
  34. def _setValue(self, value):
  35. self.widget.SetValue(value)
  36. def GetWidget(self):
  37. """Returns underlying widget.
  38. :return: widget or None if doesn't exist
  39. """
  40. return self.widget
  41. def _connect(self):
  42. self.mapWindowPropertyChanged().connect(self._setValue)
  43. def _disconnect(self):
  44. self.mapWindowPropertyChanged().disconnect(self._setValue)
  45. def _onToggleCheckBox(self, event):
  46. self._disconnect()
  47. self.mapWindowProperty = self.widget.GetValue()
  48. self._connect()
  49. class ChBRender(PropertyItem):
  50. """Checkbox to enable and disable auto-rendering."""
  51. def __init__(self, parent, mapWindowProperties):
  52. PropertyItem.__init__(self, mapWindowProperties)
  53. self.name = "render"
  54. self.widget = wx.CheckBox(
  55. parent=parent, id=wx.ID_ANY, label=_("Enable auto-rendering")
  56. )
  57. self.widget.SetValue(self.mapWindowProperty)
  58. self.widget.SetToolTip(wx.ToolTip(_("Enable/disable auto-rendering")))
  59. self.widget.Bind(wx.EVT_CHECKBOX, self._onToggleCheckBox)
  60. self._connect()
  61. @property
  62. def mapWindowProperty(self):
  63. return self._properties.autoRender
  64. @mapWindowProperty.setter
  65. def mapWindowProperty(self, value):
  66. self._properties.autoRender = value
  67. def mapWindowPropertyChanged(self):
  68. return self._properties.autoRenderChanged
  69. class ChBAlignExtent(PropertyItem):
  70. """Checkbox to select zoom behavior.
  71. Used by BufferedWindow (through MapFrame property).
  72. See tooltip for explanation.
  73. """
  74. def __init__(self, parent, mapWindowProperties):
  75. PropertyItem.__init__(self, mapWindowProperties)
  76. self.name = "alignExtent"
  77. self.widget = wx.CheckBox(
  78. parent=parent,
  79. id=wx.ID_ANY,
  80. label=_("Align region extent based on display size"),
  81. )
  82. self.widget.SetValue(self.mapWindowProperty)
  83. self.widget.SetToolTip(
  84. wx.ToolTip(
  85. _(
  86. "Align region extent based on display "
  87. "size from center point. "
  88. "Default value for new map displays can "
  89. "be set up in 'User GUI settings' dialog."
  90. )
  91. )
  92. )
  93. self.widget.Bind(wx.EVT_CHECKBOX, self._onToggleCheckBox)
  94. self._connect()
  95. @property
  96. def mapWindowProperty(self):
  97. return self._properties.alignExtent
  98. @mapWindowProperty.setter
  99. def mapWindowProperty(self, value):
  100. self._properties.alignExtent = value
  101. def mapWindowPropertyChanged(self):
  102. return self._properties.alignExtentChanged
  103. class ChBResolution(PropertyItem):
  104. """Checkbox to select used display resolution."""
  105. def __init__(self, parent, giface, mapWindowProperties):
  106. PropertyItem.__init__(self, mapWindowProperties)
  107. self.giface = giface
  108. self.name = "resolution"
  109. self.widget = wx.CheckBox(
  110. parent=parent,
  111. id=wx.ID_ANY,
  112. label=_("Constrain display resolution to computational settings"),
  113. )
  114. self.widget.SetValue(self.mapWindowProperty)
  115. self.widget.SetToolTip(
  116. wx.ToolTip(
  117. _(
  118. "Constrain display resolution "
  119. "to computational region settings. "
  120. "Default value for new map displays can "
  121. "be set up in 'User GUI settings' dialog."
  122. )
  123. )
  124. )
  125. self.widget.Bind(wx.EVT_CHECKBOX, self._onToggleCheckBox)
  126. self._connect()
  127. @property
  128. def mapWindowProperty(self):
  129. return self._properties.resolution
  130. @mapWindowProperty.setter
  131. def mapWindowProperty(self, value):
  132. self._properties.resolution = value
  133. def mapWindowPropertyChanged(self):
  134. return self._properties.resolutionChanged
  135. def _onToggleCheckBox(self, event):
  136. """Update display when toggle display mode"""
  137. super()._onToggleCheckBox(event)
  138. # redraw map if auto-rendering is enabled
  139. if self._properties.autoRender:
  140. self.giface.updateMap.emit()
  141. class ChBShowRegion(PropertyItem):
  142. """Checkbox to enable and disable showing of computational region."""
  143. def __init__(self, parent, giface, mapWindowProperties):
  144. PropertyItem.__init__(self, mapWindowProperties)
  145. self.giface = giface
  146. self.name = "region"
  147. self.widget = wx.CheckBox(
  148. parent=parent, id=wx.ID_ANY, label=_("Show computational extent")
  149. )
  150. self.widget.SetValue(self.mapWindowProperty)
  151. self.widget.SetToolTip(
  152. wx.ToolTip(
  153. _(
  154. "Show/hide computational "
  155. "region extent (set with g.region). "
  156. "Display region drawn as a blue box inside the "
  157. "computational region, "
  158. "computational region inside a display region "
  159. "as a red box)."
  160. )
  161. )
  162. )
  163. self.widget.Bind(wx.EVT_CHECKBOX, self._onToggleCheckBox)
  164. self._connect()
  165. @property
  166. def mapWindowProperty(self):
  167. return self._properties.showRegion
  168. @mapWindowProperty.setter
  169. def mapWindowProperty(self, value):
  170. self._properties.showRegion = value
  171. def mapWindowPropertyChanged(self):
  172. return self._properties.showRegionChanged
  173. def _onToggleCheckBox(self, event):
  174. """Shows/Hides extent (comp. region) in map canvas.
  175. Shows or hides according to checkbox value.
  176. """
  177. super()._onToggleCheckBox(event)
  178. # redraw map if auto-rendering is enabled
  179. if self._properties.autoRender:
  180. self.giface.updateMap.emit(render=False)
  181. class MapDisplayPropertiesDialog(wx.Dialog):
  182. """Map Display properties dialog"""
  183. def __init__(
  184. self,
  185. parent,
  186. giface,
  187. properties,
  188. title=_("Map Display Settings"),
  189. size=(-1, 250),
  190. style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
  191. ):
  192. wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
  193. self.parent = parent
  194. self.title = title
  195. self.size = size
  196. self.giface = giface
  197. self.mapWindowProperties = properties
  198. # notebook
  199. self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  200. # create notebook pages
  201. self._createDisplayPage(parent=self.notebook)
  202. self.btnClose = Button(self, wx.ID_CLOSE)
  203. self.SetEscapeId(wx.ID_CLOSE)
  204. self._layout()
  205. def _layout(self):
  206. """Layout window"""
  207. # sizers
  208. btnStdSizer = wx.StdDialogButtonSizer()
  209. btnStdSizer.AddButton(self.btnClose)
  210. btnStdSizer.Realize()
  211. mainSizer = wx.BoxSizer(wx.VERTICAL)
  212. mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  213. mainSizer.Add(btnStdSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
  214. self.SetSizer(mainSizer)
  215. self.SetMinSize(self.GetBestSize())
  216. self.SetSize(self.size)
  217. def _createDisplayPage(self, parent):
  218. """Create notebook page for display settings"""
  219. panel = SP.ScrolledPanel(parent=parent, id=wx.ID_ANY)
  220. panel.SetupScrolling(scroll_x=False, scroll_y=True)
  221. parent.AddPage(page=panel, text=_("General"))
  222. # General settings
  223. sizer = wx.BoxSizer(wx.VERTICAL)
  224. # Auto-rendering
  225. self.autoRendering = ChBRender(panel, self.mapWindowProperties)
  226. sizer.Add(
  227. self.autoRendering.GetWidget(),
  228. proportion=0,
  229. flag=wx.EXPAND | wx.ALL,
  230. border=3,
  231. )
  232. # Align extent to display size
  233. self.alignExtent = ChBAlignExtent(panel, self.mapWindowProperties)
  234. sizer.Add(
  235. self.alignExtent.GetWidget(),
  236. proportion=0,
  237. flag=wx.EXPAND | wx.ALL,
  238. border=3,
  239. )
  240. # Use computation resolution
  241. self.compResolution = ChBResolution(
  242. panel, self.giface, self.mapWindowProperties
  243. )
  244. sizer.Add(
  245. self.compResolution.GetWidget(),
  246. proportion=0,
  247. flag=wx.EXPAND | wx.ALL,
  248. border=3,
  249. )
  250. # Show computation extent
  251. self.showCompExtent = ChBShowRegion(
  252. panel, self.giface, self.mapWindowProperties
  253. )
  254. sizer.Add(
  255. self.showCompExtent.GetWidget(),
  256. proportion=0,
  257. flag=wx.EXPAND | wx.ALL,
  258. border=3,
  259. )
  260. panel.SetSizer(sizer)
  261. return panel