toolbars.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. """
  2. @package mapdisp.toolbars
  3. @brief Map display frame - toolbars
  4. Classes:
  5. - toolbars::MapToolbar
  6. (C) 2007-2015 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. @author Michael Barton
  10. @author Jachym Cepicky
  11. @author Martin Landa <landa.martin gmail.com>
  12. """
  13. import wx
  14. from gui_core.toolbars import BaseToolbar, BaseIcons
  15. from nviz.main import haveNviz
  16. from vdigit.main import haveVDigit
  17. from icons.icon import MetaIcon
  18. MapIcons = {
  19. "query": MetaIcon(
  20. img="info",
  21. label=_("Query raster/vector map(s)"),
  22. desc=_("Query selected raster/vector map(s)"),
  23. ),
  24. "select": MetaIcon(
  25. img="select",
  26. label=_("Select vector feature(s)"),
  27. desc=_("Select features interactively from vector map"),
  28. ),
  29. "addBarscale": MetaIcon(img="scalebar-add", label=_("Add scale bar")),
  30. "addRasterLegend": MetaIcon(img="legend-add", label=_("Add raster legend")),
  31. "addVectorLegend": MetaIcon(img="legend-add", label=_("Add vector legend")),
  32. "addNorthArrow": MetaIcon(img="north-arrow-add", label=_("Add north arrow")),
  33. "analyze": MetaIcon(
  34. img="layer-raster-analyze",
  35. label=_("Analyze map"),
  36. desc=_("Measuring, profiling, histogramming, ..."),
  37. ),
  38. "measureDistance": MetaIcon(img="measure-length", label=_("Measure distance")),
  39. "measureArea": MetaIcon(img="area-measure", label=_("Measure area")),
  40. "profile": MetaIcon(img="layer-raster-profile", label=_("Profile surface map")),
  41. "scatter": MetaIcon(
  42. img="layer-raster-profile",
  43. label=_("Create bivariate scatterplot of raster maps"),
  44. ),
  45. "addText": MetaIcon(img="text-add", label=_("Add text")),
  46. "histogram": MetaIcon(
  47. img="layer-raster-histogram", label=_("Create histogram of raster map")
  48. ),
  49. "vnet": MetaIcon(img="vector-tools", label=_("Vector network analysis tool")),
  50. }
  51. NvizIcons = {
  52. "rotate": MetaIcon(
  53. img="3d-rotate",
  54. label=_("Rotate 3D scene"),
  55. desc=_("Drag with mouse to rotate 3D scene"),
  56. ),
  57. "flyThrough": MetaIcon(
  58. img="flythrough",
  59. label=_("Fly-through mode"),
  60. desc=_(
  61. "Drag with mouse, hold Ctrl down for different mode"
  62. " or Shift to accelerate"
  63. ),
  64. ),
  65. "zoomIn": BaseIcons["zoomIn"].SetLabel(desc=_("Click mouse to zoom")),
  66. "zoomOut": BaseIcons["zoomOut"].SetLabel(desc=_("Click mouse to unzoom")),
  67. }
  68. class MapToolbar(BaseToolbar):
  69. """Map Display toolbar"""
  70. def __init__(self, parent, toolSwitcher, giface):
  71. """Map Display constructor
  72. :param parent: reference to MapFrame
  73. """
  74. BaseToolbar.__init__(self, parent=parent, toolSwitcher=toolSwitcher) # MapFrame
  75. self.InitToolbar(self._toolbarData())
  76. self._default = self.pointer
  77. self._giface = giface
  78. # optional tools
  79. toolNum = 0
  80. choices = [
  81. _("2D view"),
  82. ]
  83. self.toolId = {"2d": toolNum}
  84. toolNum += 1
  85. if haveNviz:
  86. choices.append(_("3D view"))
  87. self.toolId["3d"] = toolNum
  88. toolNum += 1
  89. else:
  90. from nviz.main import errorMsg
  91. self._giface.WriteCmdLog(_("3D view mode not available"))
  92. self._giface.WriteWarning(_("Reason: %s") % str(errorMsg))
  93. self.toolId["3d"] = -1
  94. if haveVDigit:
  95. choices.append(_("Vector digitizer"))
  96. self.toolId["vdigit"] = toolNum
  97. toolNum += 1
  98. else:
  99. from vdigit.main import errorMsg
  100. self._giface.WriteCmdLog(_("Vector digitizer not available"))
  101. self._giface.WriteWarning(_("Reason: %s") % errorMsg)
  102. self._giface.WriteLog(
  103. _(
  104. "Note that the wxGUI's vector digitizer is disabled in this installation. "
  105. "Please keep an eye out for updated versions of GRASS. "
  106. 'In the meantime you can use "v.edit" for non-interactive editing '
  107. "from the Develop vector map menu."
  108. ),
  109. wrap=60,
  110. )
  111. self.toolId["vdigit"] = -1
  112. choices.append(_("Raster digitizer"))
  113. self.toolId["rdigit"] = toolNum
  114. self.combo = wx.ComboBox(
  115. parent=self,
  116. id=wx.ID_ANY,
  117. choices=choices,
  118. style=wx.CB_READONLY,
  119. size=(110, -1),
  120. )
  121. self.combo.SetSelection(0)
  122. self.comboid = self.AddControl(self.combo)
  123. self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectTool, self.comboid)
  124. # realize the toolbar
  125. self.Realize()
  126. # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
  127. self.combo.Hide()
  128. self.combo.Show()
  129. for tool in (
  130. self.pointer,
  131. self.select,
  132. self.query,
  133. self.pan,
  134. self.zoomIn,
  135. self.zoomOut,
  136. ):
  137. self.toolSwitcher.AddToolToGroup(group="mouseUse", toolbar=self, tool=tool)
  138. self.EnableTool(self.zoomBack, False)
  139. self.FixSize(width=90)
  140. def _toolbarData(self):
  141. """Toolbar data"""
  142. return self._getToolbarData(
  143. (
  144. (
  145. ("renderMap", BaseIcons["render"].label),
  146. BaseIcons["render"],
  147. self.parent.OnRender,
  148. ),
  149. (
  150. ("pointer", BaseIcons["pointer"].label),
  151. BaseIcons["pointer"],
  152. self.parent.OnPointer,
  153. wx.ITEM_CHECK,
  154. ),
  155. (
  156. ("select", MapIcons["select"].label),
  157. MapIcons["select"],
  158. self.parent.OnSelect,
  159. wx.ITEM_CHECK,
  160. ),
  161. (
  162. ("query", MapIcons["query"].label),
  163. MapIcons["query"],
  164. self.parent.OnQuery,
  165. wx.ITEM_CHECK,
  166. ),
  167. (
  168. ("pan", BaseIcons["pan"].label),
  169. BaseIcons["pan"],
  170. self.parent.OnPan,
  171. wx.ITEM_CHECK,
  172. ),
  173. (
  174. ("zoomIn", BaseIcons["zoomIn"].label),
  175. BaseIcons["zoomIn"],
  176. self.parent.OnZoomIn,
  177. wx.ITEM_CHECK,
  178. ),
  179. (
  180. ("zoomOut", BaseIcons["zoomOut"].label),
  181. BaseIcons["zoomOut"],
  182. self.parent.OnZoomOut,
  183. wx.ITEM_CHECK,
  184. ),
  185. (
  186. ("zoomExtent", BaseIcons["zoomExtent"].label),
  187. BaseIcons["zoomExtent"],
  188. self.parent.OnZoomToMap,
  189. ),
  190. (
  191. ("zoomRegion", BaseIcons["zoomRegion"].label),
  192. BaseIcons["zoomRegion"],
  193. self.parent.OnZoomToWind,
  194. ),
  195. (
  196. ("zoomBack", BaseIcons["zoomBack"].label),
  197. BaseIcons["zoomBack"],
  198. self.parent.OnZoomBack,
  199. ),
  200. (
  201. ("zoomMenu", BaseIcons["zoomMenu"].label),
  202. BaseIcons["zoomMenu"],
  203. self.parent.OnZoomMenu,
  204. ),
  205. (
  206. ("analyze", MapIcons["analyze"].label),
  207. MapIcons["analyze"],
  208. self.OnAnalyze,
  209. ),
  210. (
  211. ("overlay", BaseIcons["overlay"].label),
  212. BaseIcons["overlay"],
  213. self.OnDecoration,
  214. ),
  215. (
  216. ("saveFile", BaseIcons["saveFile"].label),
  217. BaseIcons["saveFile"],
  218. self.parent.SaveToFile,
  219. ),
  220. (
  221. ("mapDispSettings", BaseIcons["mapDispSettings"].label),
  222. BaseIcons["mapDispSettings"],
  223. self.parent.OnMapDisplayProperties,
  224. ),
  225. )
  226. )
  227. def InsertTool(self, data):
  228. """Insert tool to toolbar
  229. :param data: toolbar data"""
  230. data = self._getToolbarData(data)
  231. for tool in data:
  232. self.CreateTool(*tool)
  233. self.Realize()
  234. self.parent._mgr.GetPane("mapToolbar").BestSize(self.GetBestSize())
  235. self.parent._mgr.Update()
  236. def RemoveTool(self, tool):
  237. """Remove tool from toolbar
  238. :param tool: tool id"""
  239. self.DeleteTool(tool)
  240. self.parent._mgr.GetPane("mapToolbar").BestSize(self.GetBestSize())
  241. self.parent._mgr.Update()
  242. def ChangeToolsDesc(self, mode2d):
  243. """Change description of zoom tools for 2D/3D view"""
  244. if mode2d:
  245. icons = BaseIcons
  246. else:
  247. icons = NvizIcons
  248. for i, data in enumerate(self._data):
  249. for tool in ("zoomIn", "zoomOut"):
  250. if data[0] == tool:
  251. tmp = list(data)
  252. tmp[4] = icons[tool].GetDesc()
  253. self._data[i] = tuple(tmp)
  254. def OnSelectTool(self, event):
  255. """Select / enable tool available in tools list"""
  256. tool = event.GetSelection()
  257. if tool == self.toolId["2d"]:
  258. self.ExitToolbars()
  259. self.Enable2D(True)
  260. elif tool == self.toolId["3d"] and not (
  261. self.parent.MapWindow3D and self.parent.IsPaneShown("3d")
  262. ):
  263. self.ExitToolbars()
  264. self.parent.AddNviz()
  265. elif tool == self.toolId["vdigit"] and not self.parent.GetToolbar("vdigit"):
  266. self.ExitToolbars()
  267. self.parent.AddToolbar("vdigit")
  268. self.parent.MapWindow.SetFocus()
  269. elif tool == self.toolId["rdigit"]:
  270. self.ExitToolbars()
  271. self.parent.AddRDigit()
  272. def OnAnalyze(self, event):
  273. """Analysis tools menu"""
  274. self._onMenu(
  275. (
  276. (MapIcons["measureDistance"], self.parent.OnMeasureDistance),
  277. (MapIcons["measureArea"], self.parent.OnMeasureArea),
  278. (MapIcons["profile"], self.parent.OnProfile),
  279. (MapIcons["scatter"], self.parent.OnScatterplot),
  280. (MapIcons["histogram"], self.parent.OnHistogramPyPlot),
  281. (BaseIcons["histogram"], self.parent.OnHistogram),
  282. (MapIcons["vnet"], self.parent.OnVNet),
  283. )
  284. )
  285. def OnDecoration(self, event):
  286. """Decorations overlay menu"""
  287. self._onMenu(
  288. (
  289. (MapIcons["addRasterLegend"], lambda evt: self.parent.AddLegendRast()),
  290. (MapIcons["addVectorLegend"], lambda evt: self.parent.AddLegendVect()),
  291. (MapIcons["addBarscale"], lambda evt: self.parent.AddBarscale()),
  292. (MapIcons["addNorthArrow"], lambda evt: self.parent.AddArrow()),
  293. (MapIcons["addText"], lambda evt: self.parent.AddDtext()),
  294. )
  295. )
  296. def ExitToolbars(self):
  297. if self.parent.GetToolbar("vdigit"):
  298. self.parent.toolbars["vdigit"].OnExit()
  299. self.parent.RemoveNviz()
  300. if self.parent.GetToolbar("rdigit"):
  301. self.parent.QuitRDigit()
  302. def Enable2D(self, enabled):
  303. """Enable/Disable 2D display mode specific tools"""
  304. for tool in (self.zoomRegion, self.zoomMenu, self.analyze, self.select):
  305. self.EnableTool(tool, enabled)
  306. self.ChangeToolsDesc(enabled)
  307. if enabled:
  308. self.combo.SetValue(_("2D view"))