[GRASS-SVN] r68923 - in grass/trunk/gui/wxpython: core gui_core lmgr mapdisp mapwin nviz
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Jul 9 16:28:30 PDT 2016
Author: annakrat
Date: 2016-07-09 16:28:30 -0700 (Sat, 09 Jul 2016)
New Revision: 68923
Modified:
grass/trunk/gui/wxpython/core/render.py
grass/trunk/gui/wxpython/gui_core/forms.py
grass/trunk/gui/wxpython/lmgr/frame.py
grass/trunk/gui/wxpython/mapdisp/frame.py
grass/trunk/gui/wxpython/mapdisp/toolbars.py
grass/trunk/gui/wxpython/mapwin/base.py
grass/trunk/gui/wxpython/mapwin/buffered.py
grass/trunk/gui/wxpython/mapwin/decorations.py
grass/trunk/gui/wxpython/nviz/mapwindow.py
grass/trunk/gui/wxpython/nviz/wxnviz.py
Log:
wxGUI: rewrited handling of decorations (legend, barscale), now multiple legends are possible
Modified: grass/trunk/gui/wxpython/core/render.py
===================================================================
--- grass/trunk/gui/wxpython/core/render.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/core/render.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -364,6 +364,7 @@
self.thread = gThread()
self.updateProgress = Signal('RenderLayerMgr.updateProgress')
+ self.renderingFailed = Signal('RenderLayerMgr.renderingFailed')
self._startTime = None
self._render_env = env
@@ -389,14 +390,16 @@
self._startTime = time.time()
self.thread.Run(callable=self._render, cmd=cmd_render, env=env_cmd,
- ondone=self.OnRenderDone)
+ ondone=self.OnRenderDone, userdata={'cmd': cmd})
self.layer.forceRender = False
def _render(self, cmd, env):
- try:
- return grass.run_command(cmd[0], env=env, **cmd[1])
- except CalledModuleError as e:
- return 1
+ p = grass.start_command(cmd[0], env=env, stderr=grass.PIPE, **cmd[1])
+ stdout, stderr = p.communicate()
+ if p.returncode:
+ return stderr
+ else:
+ return None
def Abort(self):
"""Abort rendering process"""
@@ -419,13 +422,14 @@
Emits updateProcess
"""
- Debug.msg(1, "RenderLayerMgr.OnRenderDone(%s): ret=%d time=%f" %
+ Debug.msg(1, "RenderLayerMgr.OnRenderDone(%s): err=%s time=%f" %
(self.layer, event.ret, time.time() - self._startTime))
- if event.ret != 0:
- try:
- os.remove(self.layer.mapfile)
- except:
- pass
+ if event.ret is not None:
+ cmd = cmdtuple_to_list(event.userdata['cmd'])
+ self.renderingFailed.emit(cmd=cmd, error=event.ret)
+ # don't remove layer if overlay, we need to keep the old one
+ if self.layer.type != 'overlay':
+ try_remove(self.layer.mapfile)
self.updateProgress.emit(layer=self.layer)
@@ -443,6 +447,7 @@
self.updateMap = Signal('RenderMapMgr.updateMap')
self.updateProgress = Signal('RenderMapMgr.updateProgress')
+ self.renderingFailed = Signal('RenderMapMgr.renderingFailed')
self.renderDone = Signal('RenderMapMgr.renderDone')
self.renderDone.connect(self.OnRenderDone)
@@ -519,6 +524,25 @@
return env
+ def RenderOverlays(self, force=False):
+ """Render only overlays
+
+ :param bool force: force rendering all map layers
+ """
+ if self._rendering:
+ Debug.msg(
+ 1, "RenderMapMgr().RenderOverlays(): cancelled (already rendering)")
+ return
+
+ wx.BeginBusyCursor()
+ self._rendering = True
+
+ env = self.GetRenderEnv()
+ self._init(env)
+ # no layer composition afterwards
+ if self._renderLayers(env, force, overlaysOnly=True) == 0:
+ self.renderDone.emit()
+
def Render(self, force=False, windres=False):
"""Render map composition
@@ -535,7 +559,7 @@
env = self.GetRenderEnv(windres)
self._init(env)
- if self._renderLayers(env, force, windres) == 0:
+ if self._renderLayers(env, force) == 0:
self.renderDone.emit()
def OnRenderDone(self):
@@ -652,7 +676,10 @@
'progresVal'] == self.progressInfo['range']:
self.renderDone.emit()
+ def RenderingFailed(self, cmd, error):
+ self.renderingFailed.emit(cmd=cmd, error=error)
+
class Map(object):
def __init__(self, gisrc=None):
@@ -1413,6 +1440,7 @@
string=True))))
if renderMgr:
renderMgr.updateProgress.connect(self.renderMgr.ReportProgress)
+ renderMgr.renderingFailed.connect(self.renderMgr.RenderingFailed)
overlay.forceRender = render
return overlay
@@ -1511,9 +1539,7 @@
def RenderOverlays(self, force):
"""Render overlays only (for nviz)"""
- for layer in self.overlays:
- if force or layer.forceRender:
- layer.Render()
+ self.renderMgr.RenderOverlays(force)
def AbortAllThreads(self):
"""Abort all layers threads e. g. donwloading data"""
Modified: grass/trunk/gui/wxpython/gui_core/forms.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/forms.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/gui_core/forms.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -873,7 +873,7 @@
'MapWindow'):
# display decorations and
# pressing OK or cancel after setting layer properties
- if self.task.name in ['d.barscale', 'd.legend', 'd.northarrow', 'd.histogram'] \
+ if self.task.name in ['d.barscale', 'd.legend', 'd.northarrow', 'd.histogram', 'd.text'] \
or len(self.parent.GetLayerInfo(self.layer, key='cmd')) >= 1:
self.Hide()
# canceled layer with nothing set
Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/lmgr/frame.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -651,10 +651,10 @@
Also close associated map display
"""
- if UserSettings.Get(group='manager', key='askOnQuit',
- subkey='enabled') and self.workspaceChanged:
- maptree = self.GetLayerTree()
-
+ # save changes in the workspace
+ maptree = self.GetLayerTree()
+ if self.workspaceChanged and UserSettings.Get(
+ group='manager', key='askOnQuit', subkey='enabled'):
if self.workspaceFile:
message = _("Do you want to save changes in the workspace?")
else:
@@ -749,9 +749,9 @@
if layertype == 'barscale':
if len(command) > 1:
- self.GetMapDisplay().AddBarscale(cmd=command, showDialog=False)
+ self.GetMapDisplay().AddBarscale(cmd=command)
else:
- self.GetMapDisplay().AddBarscale(showDialog=True)
+ self.GetMapDisplay().AddBarscale()
elif layertype == 'rastleg':
if len(command) > 1:
self.GetMapDisplay().AddLegend(cmd=command, showDialog=False)
@@ -759,9 +759,14 @@
self.GetMapDisplay().AddLegend(showDialog=True)
elif layertype == 'northarrow':
if len(command) > 1:
- self.GetMapDisplay().AddArrow(cmd=command, showDialog=False)
+ self.GetMapDisplay().AddArrow(cmd=command)
else:
- self.GetMapDisplay().AddArrow(showDialog=True)
+ self.GetMapDisplay().AddArrow()
+ elif layertype == 'text':
+ if len(command) > 1:
+ self.GetMapDisplay().AddDtext(cmd=command)
+ else:
+ self.GetMapDisplay().AddDtext()
elif layertype == 'redraw':
self.GetMapDisplay().OnRender(None)
elif layertype == 'export':
@@ -1485,6 +1490,8 @@
mapdisplay[i].AddBarscale(overlay['cmd'])
if overlay['cmd'][0] == "d.northarrow":
mapdisplay[i].AddArrow(overlay['cmd'])
+ if overlay['cmd'][0] == "d.text":
+ mapdisplay[i].AddDtext(overlay['cmd'])
# avoid double-rendering when loading workspace
# mdisp.MapWindow2D.UpdateMap()
@@ -2421,10 +2428,10 @@
self.Destroy()
return
- # save changes in the workspace
- maptree = self.GetLayerTree()
- if self.workspaceChanged and UserSettings.Get(
- group='manager', key='askOnQuit', subkey='enabled'):
+ if UserSettings.Get(group='manager', key='askOnQuit',
+ subkey='enabled') and self.workspaceChanged:
+ maptree = self.GetLayerTree()
+
if self.workspaceFile:
message = _("Do you want to save changes in the workspace?")
else:
Modified: grass/trunk/gui/wxpython/mapdisp/frame.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/frame.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/mapdisp/frame.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -43,8 +43,8 @@
from mapwin.base import MapWindowProperties
from gui_core.query import QueryDialog, PrepareQueryResults
from mapwin.buffered import BufferedMapWindow
-from mapwin.decorations import TextLayerDialog, \
- LegendController, BarscaleController, ArrowController
+from mapwin.decorations import LegendController, BarscaleController, \
+ ArrowController, DtextController
from modules.histogram import HistogramFrame
from wxplot.histogram import HistogramPlotFrame
from wxplot.profile import ProfileFrame
@@ -128,12 +128,7 @@
# init decoration objects
self.decorations = {}
- self.legend = LegendController(self.Map, self._giface)
- self.barscale = BarscaleController(self.Map, self._giface)
- self.arrow = ArrowController(self.Map, self._giface)
- self.decorations[self.legend.id] = self.legend
- self.decorations[self.barscale.id] = self.barscale
- self.decorations[self.arrow.id] = self.arrow
+ self._decorationWindows = {}
self.mapWindowProperties.autoRenderChanged.connect(
lambda value:
@@ -147,12 +142,8 @@
properties=self.mapWindowProperties, overlays=self.decorations)
self.MapWindow2D.mapQueried.connect(self.Query)
self.MapWindow2D.overlayActivated.connect(self._activateOverlay)
- self.MapWindow2D.overlayHidden.connect(self._hideOverlay)
- self.MapWindow2D.overlayHidden.connect(self._hideOverlay)
- for overlay in (self.legend, self.barscale, self.arrow):
- overlay.overlayChanged.connect(
- lambda: self.MapWindow2D.UpdateMap(
- render=False, renderVector=False))
+ self.MapWindow2D.overlayRemoved.connect(self._removeOverlay)
+ self.MapWindow2D.overlayRemoved.connect(self._removeOverlay)
self._setUpMapWindow(self.MapWindow2D)
self.MapWindow2D.mouseHandlerUnregistered.connect(self.ResetPointer)
@@ -254,6 +245,8 @@
#
self.Map.GetRenderMgr().updateProgress.connect(self.statusbarManager.SetProgress)
+ self.Map.GetRenderMgr().renderingFailed.connect(lambda cmd, error: self._giface.WriteError(
+ _("Failed to run command '{command}'. Details:\n{error}").format(command=' '.join(cmd), error=error)))
def GetMapWindow(self):
return self.MapWindow
@@ -414,8 +407,7 @@
self.MapWindow3D.ResetViewHistory()
self.MapWindow3D.UpdateView(None)
self.MapWindow3D.overlayActivated.connect(self._activateOverlay)
- self.MapWindow3D.overlayHidden.connect(self._hideOverlay)
- self.legend.overlayChanged.connect(self.MapWindow3D.UpdateOverlays)
+ self.MapWindow3D.overlayRemoved.connect(self._removeOverlay)
else:
self._switchMapWindow(self.MapWindow3D)
os.environ['GRASS_REGION'] = self.Map.SetRegion(
@@ -432,10 +424,14 @@
self.MapWindow3D.ResetViewHistory()
+ # connect signals for updating overlays
+ for overlay in self.decorations.values():
+ overlay.overlayChanged.connect(self.MapWindow3D.UpdateOverlays)
+ self.Map.GetRenderMgr().renderDone.connect(self.MapWindow3D._onUpdateOverlays)
+
self._giface.updateMap.disconnect(self.MapWindow2D.UpdateMap)
self._giface.updateMap.connect(self.MapWindow3D.UpdateMap)
self.MapWindow3D.overlays = self.MapWindow2D.overlays
- self.MapWindow3D.textdict = self.MapWindow2D.textdict
# update overlays needs to be called after because getClientSize
# is called during update and it must give reasonable values
wx.CallAfter(self.MapWindow3D.UpdateOverlays)
@@ -479,13 +475,16 @@
self.ending3dMode.emit()
try:
self.MapWindow2D.overlays = self.MapWindow3D.overlays
- self.MapWindow2D.textdict = self.MapWindow3D.textdict
except AttributeError:
pass
# TODO: here we end because self.MapWindow3D is None for a while
self._giface.updateMap.disconnect(self.MapWindow3D.UpdateMap)
self._giface.updateMap.connect(self.MapWindow2D.UpdateMap)
- self.legend.overlayChanged.disconnect(self.MapWindow3D.UpdateOverlays)
+ # disconnect overlays
+ for overlay in self.decorations.values():
+ overlay.overlayChanged.disconnect(self.MapWindow3D.UpdateOverlays)
+ self.Map.GetRenderMgr().renderDone.disconnect(self.MapWindow3D._onUpdateOverlays)
+ self.MapWindow3D.ClearTextures()
self.MapWindow.UpdateMap()
self._mgr.Update()
@@ -1195,113 +1194,60 @@
:param overlayId: id of overlay
"""
- if overlayId > 100:
- self.OnAddText(None)
- elif overlayId == 0:
- self.AddLegend(cmd=self.legend.cmd, showDialog=True)
- elif overlayId == 1:
- self.AddBarscale(showDialog=True)
- elif overlayId == 2:
- self.AddArrow(showDialog=True)
+ dlg = self.decorations[overlayId].dialog
+ if dlg.IsShown():
+ dlg.SetFocus()
+ dlg.Raise()
+ else:
+ dlg.Show()
- def _hideOverlay(self, overlayId):
+ def _removeOverlay(self, overlayId):
"""Hide overlay.
:param overlayId: id of overlay
"""
- self.decorations[overlayId].Hide()
+ del self._decorationWindows[self.decorations[overlayId].dialog]
+ self.decorations[overlayId].Remove()
+ del self.decorations[overlayId]
- def AddBarscale(self, cmd=None, showDialog=None):
+ def AddBarscale(self, cmd=None):
"""Handler for scale bar map decoration menu selection."""
if self.IsPaneShown('3d'):
self.MapWindow3D.SetDrawScalebar((70, 70))
return
- if self.barscale.IsShown() and showDialog is None:
- self.barscale.Hide()
- return
-
if cmd:
- self.barscale.cmd = cmd
+ show = False
+ else:
+ show = True
+ cmd = ['d.barscale']
- if not showDialog:
- self.barscale.Show()
- return
-
# Decoration overlay control dialog
- if self.barscale.dialog:
- if self.barscale.dialog.IsShown():
- self.barscale.dialog.SetFocus()
- self.barscale.dialog.Raise()
- else:
- self.barscale.dialog.Show()
- else:
- # If location is latlon, only display north arrow (scale won't work)
- # proj = self.Map.projinfo['proj']
- # if proj == 'll':
- # barcmd = 'd.barscale -n'
- # else:
- # barcmd = 'd.barscale'
+ GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
+ cmd, completed=(self.GetOptData, None, None))
- # decoration overlay control dialog
- GUI(parent=self, giface=self._giface, show=True, modal=False).ParseCommand(
- self.barscale.cmd, completed=(self.barscale.GetOptData, None, None))
-
self.MapWindow.mouse['use'] = 'pointer'
def AddLegend(self, cmd=None, showDialog=None):
"""Handler for legend map decoration menu selection."""
- if self.legend.IsShown() and showDialog is None:
- self.legend.Hide()
- return
+
if cmd:
- self.legend.cmd = cmd
+ show = False
else:
+ show = True
+ cmd = ['d.legend']
layers = self._giface.GetLayerList().GetSelectedLayers()
for layer in layers:
if layer.type == 'raster':
- isMap = False
- # replace map
- for i, legendParam in enumerate(self.legend.cmd[1:]):
- idx = i + 1
- param_val = legendParam.split('=')
- if len(param_val) != 2:
- continue
- param, val = param_val
- if param == 'raster':
- self.legend.cmd[idx] = 'raster={rast}'.format(
- rast=layer.maplayer.name)
- isMap = True
- elif param in ('use', 'range'):
- # clear range or use to avoid problems
- del self.legend.cmd[idx]
-
- if not isMap: # for the first time
- self.legend.cmd.append(
- 'raster=%s' %
- layer.maplayer.name)
+ cmd.append('raster={rast}'.format(rast=layer.maplayer.name))
break
- if not showDialog and self.legend.CmdIsValid():
- self.legend.Show()
- return
+ GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
+ cmd, completed=(self.GetOptData, None, None))
- # Decoration overlay control dialog
- # always create new one to avoid problem when switching between maps
- if self.legend.dialog:
- if self.legend.dialog.IsShown():
- self.legend.dialog.SetFocus()
- self.legend.dialog.Raise()
- else:
- self.legend.dialog.Destroy()
- self.legend.dialog = None
- if not self.legend.dialog:
- GUI(parent=self, giface=self._giface, show=True, modal=False).ParseCommand(
- self.legend.cmd, completed=(self.legend.GetOptData, None, None))
-
self.MapWindow.mouse['use'] = 'pointer'
- def AddArrow(self, cmd=None, showDialog=None):
+ def AddArrow(self, cmd=None):
"""Handler for north arrow menu selection."""
if self.IsPaneShown('3d'):
# here was opening of appearance page of nviz notebook
@@ -1310,96 +1256,68 @@
self.MapWindow3D.SetDrawArrow((70, 70))
return
- if self.arrow.IsShown() and showDialog is None:
- self.arrow.Hide()
- return
if cmd:
- self.arrow.cmd = cmd
+ show = False
+ else:
+ show = True
+ cmd = ['d.northarrow']
- if not showDialog:
- self.arrow.Show()
- return
-
# Decoration overlay control dialog
- if self.arrow.dialog:
- if self.arrow.dialog.IsShown():
- self.arrow.dialog.SetFocus()
- self.arrow.dialog.Raise()
- else:
- self.arrow.dialog.Show()
- else:
- GUI(parent=self, giface=self._giface, show=True, modal=False).ParseCommand(
- self.arrow.cmd, completed=(self.arrow.GetOptData, None, None))
+ GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
+ cmd, completed=(self.GetOptData, None, None))
self.MapWindow.mouse['use'] = 'pointer'
- def OnAddText(self, event):
- """Handler for text decoration menu selection.
- """
- if self.MapWindow.dragid > -1:
- id = self.MapWindow.dragid
- self.MapWindow.dragid = -1
+ def AddDtext(self, cmd=None):
+ """Handler for d.text menu selection."""
+ if cmd:
+ show = False
else:
- # index for overlay layer in render
- if len(self.MapWindow.textdict.keys()) > 0:
- id = max(self.MapWindow.textdict.keys()) + 1
- else:
- id = 101
+ show = True
+ cmd = ['d.text']
- self.dialogs['text'] = TextLayerDialog(parent=self, ovlId=id,
- title=_('Add text layer'),
- size=(400, 200))
- self.dialogs['text'].CenterOnParent()
+ # Decoration overlay control dialog
+ GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
+ cmd, completed=(self.GetOptData, None, None))
- # If OK button pressed in decoration control dialog
- if self.dialogs['text'].ShowModal() == wx.ID_OK:
- text = self.dialogs['text'].GetValues()['text']
- active = self.dialogs['text'].GetValues()['active']
+ self.MapWindow.mouse['use'] = 'pointer'
- # delete object if it has no text or is not active
- if text == '' or active == False:
- try:
- self.MapWindow2D.pdc.ClearId(id)
- self.MapWindow2D.pdc.RemoveId(id)
- del self.MapWindow.textdict[id]
- if self.IsPaneShown('3d'):
- self.MapWindow3D.UpdateOverlays()
- self.MapWindow.UpdateMap()
- else:
- self.MapWindow2D.UpdateMap(
- render=False, renderVector=False)
- except:
- pass
- return
+ def GetOptData(self, dcmd, layer, params, propwin):
+ """Called after options are set through module dialog.
- self.MapWindow.textdict[id] = self.dialogs['text'].GetValues()
+ :param dcmd: resulting command
+ :param layer: not used
+ :param params: module parameters (not used)
+ :param propwin: dialog window
+ """
- if self.IsPaneShown('3d'):
- self.MapWindow3D.UpdateOverlays()
- self.MapWindow3D.UpdateMap()
- else:
- self.MapWindow2D.pdc.ClearId(id)
- self.MapWindow2D.pdc.SetId(id)
- self.MapWindow2D.UpdateMap(render=False, renderVector=False)
+ if not dcmd:
+ return
+ if propwin in self._decorationWindows:
+ overlay = self._decorationWindows[propwin]
+ else:
+ cmd = dcmd[0]
+ if cmd == 'd.northarrow':
+ overlay = ArrowController(self.Map, self._giface)
+ elif cmd == 'd.barscale':
+ overlay = BarscaleController(self.Map, self._giface)
+ elif cmd == 'd.legend':
+ overlay = LegendController(self.Map, self._giface)
+ elif cmd == 'd.text':
+ overlay = DtextController(self.Map, self._giface)
- self.MapWindow.mouse['use'] = 'pointer'
+ self.decorations[overlay.id] = overlay
+ overlay.overlayChanged.connect(lambda: self.MapWindow2D.UpdateMap(
+ render=False, renderVector=False))
+ if self.MapWindow3D:
+ overlay.overlayChanged.connect(self.MapWindow3D.UpdateOverlays)
- def GetOptData(self, dcmd, type, params, propwin):
- """Callback method for decoration overlay command generated by
- dialog created in menuform.py
- """
- # Reset comand and rendering options in render.Map. Always render decoration.
- # Showing/hiding handled by PseudoDC
- self.Map.ChangeOverlay(
- ovltype=type,
- type='overlay',
- name='',
- command=dcmd,
- active=True,
- render=False)
- self.params[type] = params
- self.propwin[type] = propwin
+ overlay.dialog = propwin
+ self._decorationWindows[propwin] = overlay
+ overlay.cmd = dcmd
+ overlay.Show()
+
def OnZoomToMap(self, event):
"""Set display extents to match selected raster (including
NULLs) or vector map.
Modified: grass/trunk/gui/wxpython/mapdisp/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/toolbars.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/mapdisp/toolbars.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -32,11 +32,11 @@
label=_('Select vector feature(s)'),
desc=_('Select features interactively from vector map')),
'addBarscale': MetaIcon(img='scalebar-add',
- label=_('Show/hide scale bar')),
+ label=_('Add scale bar')),
'addLegend': MetaIcon(img='legend-add',
- label=_('Show/hide legend')),
+ label=_('Add legend')),
'addNorthArrow': MetaIcon(img='north-arrow-add',
- label=_('Show/hide north arrow')),
+ label=_('Add north arrow')),
'analyze': MetaIcon(img='layer-raster-analyze',
label=_('Analyze map'),
desc=_('Measuring, profiling, histogramming, ...')),
@@ -49,7 +49,7 @@
'scatter': MetaIcon(img='layer-raster-profile',
label=_("Create bivariate scatterplot of raster maps")),
'addText': MetaIcon(img='text-add',
- label=_('Add text layer')),
+ label=_('Add text')),
'histogram': MetaIcon(img='layer-raster-histogram',
label=_('Create histogram of raster map')),
'vnet': MetaIcon(img='vector-tools',
@@ -271,10 +271,10 @@
lambda evt: self.parent.AddLegend()),
(MapIcons["addBarscale"],
lambda evt: self.parent.AddBarscale()),
- (MapIcons["addNorthArrow"],
- lambda evt: self.parent.AddArrow()),
- (MapIcons["addText"],
- self.parent.OnAddText)))
+ (MapIcons["addNorthArrow"],
+ lambda evt: self.parent.AddArrow()),
+ (MapIcons["addText"],
+ lambda evt: self.parent.AddDtext())))
def ExitToolbars(self):
if self.parent.GetToolbar('vdigit'):
Modified: grass/trunk/gui/wxpython/mapwin/base.py
===================================================================
--- grass/trunk/gui/wxpython/mapwin/base.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/mapwin/base.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -125,7 +125,7 @@
# emitted after double click in pointer mode on legend, text, scalebar
self.overlayActivated = Signal('MapWindow.overlayActivated')
# emitted when overlay should be hidden
- self.overlayHidden = Signal('MapWindow.overlayHidden')
+ self.overlayRemoved = Signal('MapWindow.overlayRemoved')
# mouse attributes -- position on the screen, begin and end of
# dragging, and type of drawing
Modified: grass/trunk/gui/wxpython/mapwin/buffered.py
===================================================================
--- grass/trunk/gui/wxpython/mapwin/buffered.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/mapwin/buffered.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -160,15 +160,12 @@
self.img = None # wx.Image object (self.mapfile)
# decoration overlays
self.overlays = overlays
- self._overlayNames = {
- 0: _("legend"),
- 1: _("scale bar"),
- 2: _("north arrow")}
# images and their PseudoDC ID's for painting and dragging
self.imagedict = {}
self.select = {} # selecting/unselecting decorations for dragging
self.textdict = {} # text, font, and color indexed by id
+
# zoom objects
self.zoomhistory = [] # list of past zoom extents
self.currzoom = 0 # current set of extents in zoom history being used
@@ -274,27 +271,20 @@
pos = self.ScreenToClient(event.GetPosition())
idlist = self.pdc.FindObjects(pos[0], pos[1], self.hitradius)
- separator = True
- if idlist and idlist[0] in (0, 1, 2): # legend, scale bar, north arrow
- if separator:
- menu.AppendSeparator()
- separator = False
- self._hide = wx.NewId()
+ if self.overlays and idlist and [i for i in idlist if i in self.overlays.keys()]: # legend, scale bar, north arrow, dtext
+ menu.AppendSeparator()
+ removeId = wx.NewId()
self.Bind(wx.EVT_MENU,
- lambda evt: self.overlayHidden.emit(overlayId=idlist[0]),
- id=self._hide)
- menu.Append(
- self._hide,
- _("Hide {overlay}").format(
- overlay=self._overlayNames[
- idlist[0]]))
+ lambda evt: self.overlayRemoved.emit(overlayId=idlist[0]),
+ id=removeId)
+ menu.Append(removeId, self.overlays[idlist[0]].removeLabel)
- if idlist[0] == 0:
- self._resizeLegend = wx.NewId()
+ if self.overlays[idlist[0]].name == 'legend':
+ resizeLegendId = wx.NewId()
self.Bind(wx.EVT_MENU,
lambda evt: self.overlays[idlist[0]].StartResizing(),
- id=self._resizeLegend)
- menu.Append(self._resizeLegend, _("Resize legend"))
+ id=resizeLegendId)
+ menu.Append(resizeLegendId, _("Resize legend"))
self.PopupMenu(menu)
menu.Destroy()
@@ -1071,20 +1061,22 @@
if isinstance(r, list):
r = wx.Rect(r[0], r[1], r[2], r[3])
- if id > 100: # text dragging
+ if id in self.textdict: # text dragging
rtop = (r[0], r[1] - r[3], r[2], r[3])
r = r.Union(rtop)
rleft = (r[0] - r[2], r[1], r[2], r[3])
r = r.Union(rleft)
+
self.pdc.TranslateId(id, dx, dy)
r2 = self.pdc.GetIdBounds(id)
if isinstance(r2, list):
r2 = wx.Rect(r[0], r[1], r[2], r[3])
- if id > 100: # text
+ if id in self.textdict: # text
self.textdict[id]['bbox'] = r2
self.textdict[id]['coords'][0] += dx
self.textdict[id]['coords'][1] += dy
+
r = r.Union(r2)
r.Inflate(4, 4)
self.RefreshRect(r, False)
@@ -1514,6 +1506,7 @@
idlist.remove(99)
if idlist != []:
self.dragid = idlist[0] # drag whatever is on top
+
else:
pass
coords = self.Pixel2Cell(self.mouse['begin'])
@@ -1561,13 +1554,12 @@
self.dragid >= 0):
# end drag of overlay decoration
- if self.dragid < 99 and self.dragid in self.overlays:
+ if self.overlays and self.dragid in self.overlays:
self.overlays[
self.dragid].coords = self.pdc.GetIdBounds(
self.dragid)
- elif self.dragid > 100 and self.dragid in self.textdict:
- self.textdict[self.dragid][
- 'bbox'] = self.pdc.GetIdBounds(self.dragid)
+ elif self.dragid in self.textdict:
+ self.textdict[self.dragid]['bbox'] = self.pdc.GetIdBounds(self.dragid)
else:
pass
self.dragid = None
@@ -1689,6 +1681,13 @@
self.digit:
self._onMouseMoving(event)
+ pos = event.GetPosition()
+ idlist = self.pdc.FindObjects(pos[0], pos[1], self.hitradius)
+ if self.overlays and idlist and [i for i in idlist if i in self.overlays.keys()]: # legend, scale bar, north arrow, dtext
+ self.SetToolTipString("Double click in Pointer mode to set object"
+ " properties,\nright click to remove")
+ else:
+ self.SetToolTip(None)
event.Skip()
def OnCopyCoordinates(self, event):
Modified: grass/trunk/gui/wxpython/mapwin/decorations.py
===================================================================
--- grass/trunk/gui/wxpython/mapwin/decorations.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/mapwin/decorations.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -22,7 +22,6 @@
from core.utils import _
import wx
-from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
from grass.pydispatch.signal import Signal
try:
@@ -32,12 +31,6 @@
hasPIL = False
-class OverlayId:
- legendId = 0
- barscaleId = 1
- arrowId = 2
-
-
class OverlayController(object):
"""Base class for decorations (barscale, legend) controller."""
@@ -52,7 +45,8 @@
self._defaultAt = ''
self._cmd = None # to be set by user
self._name = None # to be defined by subclass
- self._id = None # to be defined by subclass
+ self._removeLabel = None # to be defined by subclass
+ self._id = wx.NewId()
self._dialog = None
# signals that overlay or its visibility changed
@@ -97,6 +91,11 @@
name = property(fget=GetName)
+ def GetRemoveLabel(self):
+ return self._removeLabel
+
+ removeLabel = property(fget=GetRemoveLabel)
+
def GetId(self):
return self._id
@@ -145,22 +144,12 @@
self._overlay.SetActive(False)
self.overlayChanged.emit()
- def GetOptData(self, dcmd, layer, params, propwin):
- """Called after options are set through module dialog.
+ def Remove(self):
+ if self._dialog:
+ self._dialog.Destroy()
+ self._renderer.DeleteOverlay(self._overlay)
+ self.overlayChanged.emit()
- :param dcmd: resulting command
- :param layer: not used
- :param params: module parameters (not used)
- :param propwin: dialog window
- """
- if not dcmd:
- return
-
- self._cmd = dcmd
- self._dialog = propwin
-
- self.Show()
-
def _add(self):
self._overlay = self._renderer.AddOverlay(
id=self._id,
@@ -189,6 +178,7 @@
"Please install Python Imaging Library (PIL)\n"
"for better control of legend and other decorations."))
return 0, 0
+
for param in self._cmd:
if not param.startswith('at'):
continue
@@ -199,12 +189,35 @@
return x, y
+class DtextController(OverlayController):
+
+ def __init__(self, renderer, giface):
+ OverlayController.__init__(self, renderer, giface)
+ self._name = 'text'
+ self._removeLabel = _("Remove text")
+ self._defaultAt = 'at=50,50'
+ self._cmd = ['d.text', self._defaultAt]
+
+ def CmdIsValid(self):
+ inputs = 0
+ for param in self._cmd[1:]:
+ param = param.split('=')
+ if len(param) == 1:
+ inputs += 1
+ else:
+ if param[0] == 'text' and len(param) == 2:
+ inputs += 1
+ if inputs >= 1:
+ return True
+ return False
+
+
class BarscaleController(OverlayController):
def __init__(self, renderer, giface):
OverlayController.__init__(self, renderer, giface)
- self._id = OverlayId.barscaleId
self._name = 'barscale'
+ self._removeLabel = _("Remove scale bar")
# different from default because the reference point is not in the
# middle
self._defaultAt = 'at=0,98'
@@ -215,8 +228,8 @@
def __init__(self, renderer, giface):
OverlayController.__init__(self, renderer, giface)
- self._id = OverlayId.arrowId
self._name = 'arrow'
+ self._removeLabel = _("Remove north arrow")
# different from default because the reference point is not in the
# middle
self._defaultAt = 'at=85.0,25.0'
@@ -227,8 +240,8 @@
def __init__(self, renderer, giface):
OverlayController.__init__(self, renderer, giface)
- self._id = OverlayId.legendId
self._name = 'legend'
+ self._removeLabel = _("Remove legend")
# TODO: synchronize with d.legend?
self._defaultAt = 'at=5,50,7,10'
self._cmd = ['d.legend', self._defaultAt]
@@ -313,202 +326,3 @@
self._giface.GetMapDisplay().GetMapToolbar().SelectDefault()
# redraw
self.overlayChanged.emit()
-
-
-class TextLayerDialog(wx.Dialog):
- """!Controls setting options and displaying/hiding map overlay decorations
- """
-
- def __init__(self, parent, ovlId, title, name='text', size=wx.DefaultSize,
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
-
- wx.Dialog.__init__(
- self,
- parent=parent,
- id=wx.ID_ANY,
- title=title,
- style=style,
- size=size)
-
- self.ovlId = ovlId
- self.parent = parent
-
- if self.ovlId in self.parent.MapWindow.textdict.keys():
- self.currText = self.parent.MapWindow.textdict[self.ovlId]['text']
- self.currFont = self.parent.MapWindow.textdict[self.ovlId]['font']
- self.currClr = self.parent.MapWindow.textdict[self.ovlId]['color']
- self.currRot = self.parent.MapWindow.textdict[
- self.ovlId]['rotation']
- self.currCoords = self.parent.MapWindow.textdict[
- self.ovlId]['coords']
- self.currBB = self.parent.MapWindow.textdict[self.ovlId]['bbox']
- else:
- self.currClr = wx.BLACK
- self.currText = ''
- self.currFont = self.GetFont()
- self.currRot = 0.0
- self.currCoords = [10, 10]
- self.currBB = wx.Rect()
-
- self.sizer = wx.BoxSizer(wx.VERTICAL)
- box = wx.GridBagSizer(vgap=5, hgap=5)
-
- # show/hide
- self.chkbox = wx.CheckBox(parent=self, id=wx.ID_ANY,
- label=_('Show text object'))
- if self.parent.Map.GetOverlay(self.ovlId) is None:
- self.chkbox.SetValue(True)
- else:
- self.chkbox.SetValue(
- self.parent.MapWindow.overlays[
- self.ovlId]['layer'].IsActive())
- box.Add(item=self.chkbox, span=(1, 2),
- pos=(0, 0))
-
- # text entry
- box.Add(
- item=wx.StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_("Text:")),
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- 1,
- 0))
-
- self.textentry = ExpandoTextCtrl(
- parent=self, id=wx.ID_ANY, value="", size=(300, -1))
- self.textentry.SetFont(self.currFont)
- self.textentry.SetForegroundColour(self.currClr)
- self.textentry.SetValue(self.currText)
- # get rid of unneeded scrollbar when text box first opened
- self.textentry.SetClientSize((300, -1))
-
- box.Add(item=self.textentry,
- flag=wx.EXPAND,
- pos=(1, 1))
-
- # rotation
- box.Add(
- item=wx.StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_("Rotation:")),
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- 2,
- 0))
- self.rotation = wx.SpinCtrl(
- parent=self, id=wx.ID_ANY, value="", pos=(
- 30, 50), size=(
- 75, -1), style=wx.SP_ARROW_KEYS)
- self.rotation.SetRange(-360, 360)
- self.rotation.SetValue(int(self.currRot))
- box.Add(item=self.rotation,
- flag=wx.ALIGN_RIGHT,
- pos=(2, 1))
-
- # font
- box.Add(
- item=wx.StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_("Font:")),
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- 3,
- 0))
- fontbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set font"))
- box.Add(item=fontbtn,
- flag=wx.ALIGN_RIGHT,
- pos=(3, 1))
-
- box.AddGrowableCol(1)
- box.AddGrowableRow(1)
- self.sizer.Add(item=box, proportion=1,
- flag=wx.ALL | wx.EXPAND, border=10)
-
- # note
- box = wx.BoxSizer(wx.HORIZONTAL)
- label = wx.StaticText(
- parent=self, id=wx.ID_ANY, label=_(
- "Drag text with mouse in pointer mode "
- "to position.\nDouble-click to change options"))
- box.Add(item=label, proportion=0,
- flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
- self.sizer.Add(
- item=box, proportion=0, flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER | wx.ALL, border=5)
-
- line = wx.StaticLine(parent=self, id=wx.ID_ANY,
- size=(20, -1), style=wx.LI_HORIZONTAL)
- self.sizer.Add(item=line, proportion=0,
- flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5)
-
- btnsizer = wx.StdDialogButtonSizer()
-
- btn = wx.Button(parent=self, id=wx.ID_OK)
- btn.SetDefault()
- btnsizer.AddButton(btn)
-
- btn = wx.Button(parent=self, id=wx.ID_CANCEL)
- btnsizer.AddButton(btn)
- btnsizer.Realize()
-
- self.sizer.Add(item=btnsizer, proportion=0,
- flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
-
- self.SetSizer(self.sizer)
- self.sizer.Fit(self)
-
- # bindings
- self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textentry)
- self.Bind(wx.EVT_BUTTON, self.OnSelectFont, fontbtn)
- self.Bind(wx.EVT_TEXT, self.OnText, self.textentry)
- self.Bind(wx.EVT_SPINCTRL, self.OnRotation, self.rotation)
-
- self.SetMinSize((400, 230))
-
- def OnRefit(self, event):
- """Resize text entry to match text"""
- self.sizer.Fit(self)
-
- def OnText(self, event):
- """Change text string"""
- self.currText = event.GetString()
-
- def OnRotation(self, event):
- """Change rotation"""
- self.currRot = event.GetInt()
-
- event.Skip()
-
- def OnSelectFont(self, event):
- """Change font"""
- data = wx.FontData()
- data.EnableEffects(True)
- data.SetColour(self.currClr) # set colour
- data.SetInitialFont(self.currFont)
-
- dlg = wx.FontDialog(self, data)
-
- if dlg.ShowModal() == wx.ID_OK:
- data = dlg.GetFontData()
- self.currFont = data.GetChosenFont()
- self.currClr = data.GetColour()
-
- self.textentry.SetFont(self.currFont)
- self.textentry.SetForegroundColour(self.currClr)
-
- self.Layout()
-
- dlg.Destroy()
-
- def GetValues(self):
- """Get text properties"""
- return {'text': self.currText,
- 'font': self.currFont,
- 'color': self.currClr,
- 'rotation': self.currRot,
- 'coords': self.currCoords,
- 'active': self.chkbox.IsChecked()}
Modified: grass/trunk/gui/wxpython/nviz/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/nviz/mapwindow.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/nviz/mapwindow.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -160,7 +160,6 @@
self.imagelist = []
self.overlay = wx.Overlay()
#self.pdc = wx.PseudoDC()
- self.textdict = {}
self.dragid = -1
self.hitradius = 5
# layer manager toolwindow
@@ -473,125 +472,36 @@
if texture.IsActive():
texture.Draw()
- def GetLegendRect(self):
- """Estimates legend size for dragging"""
- size = None
- if 0 in self.overlays:
- for param in self.overlays[0].cmd[1:]:
- if param.startswith("at="):
- size = map(float, param.split("=")[-1].split(','))
- break
- if size:
- wSize = self.GetClientSizeTuple()
- x, y = size[
- 2] / 100. * wSize[0], wSize[1] - (size[1] / 100. * wSize[1])
- x += self.overlays[1].coords[0]
- y += self.overlays[1].coords[1]
- w = (size[3] - size[2]) / 100. * wSize[0]
- h = (size[1] - size[0]) / 100. * wSize[1]
-
- rect = wx.Rect(x, y, w, h)
- return rect
-
- return wx.Rect()
-
- def DrawTextImage(self, textDict, relCoords):
- """Draw overlay text"""
- bmp = wx.EmptyBitmap(textDict['bbox'][2], textDict['bbox'][3])
- memDC = wx.MemoryDC()
- memDC.SelectObject(bmp)
-
- mask = self.view['background']['color']
- if mask == textDict['color']:
- mask = wx.WHITE
- memDC.SetBackground(wx.Brush(mask))
- memDC.Clear()
- memDC.SetFont(textDict['font'])
- memDC.SetTextForeground(textDict['color'])
- if textDict['rotation'] == 0:
- memDC.DrawText(textDict['text'], 0, 0)
- else:
- memDC.DrawRotatedText(textDict['text'], relCoords[0], relCoords[1],
- textDict['rotation'])
- bmp.SetMaskColour(mask)
- memDC.DrawBitmap(bmp, 0, 0, 1)
-
- filename = grass.tempfile(create=False) + '.png'
- bmp.SaveFile(filename, wx.BITMAP_TYPE_PNG)
- memDC.SelectObject(wx.NullBitmap)
-
- return filename
-
def UpdateOverlays(self):
- """Converts rendered overlay files and text labels to wx.Image
- and then to textures so that they can be rendered by OpenGL.
- Updates self.imagelist"""
+ """Renders overlays (legend, text).
+ Once this is done _onUpdateOverlays is called"""
self.Map.ChangeMapSize(self.GetClientSize())
self.Map.RenderOverlays(force=True)
- # delete textures
- for texture in self.imagelist:
- # inactive overlays, remove text labels
- if texture.GetId() < 100:
- if not self.overlays[texture.GetId()].IsShown():
- texture.SetActive(False)
- else:
- texture.SetActive(True)
- else: # text label
- if texture.GetId() not in self.textdict:
- self.imagelist.remove(texture)
-
- # update images (only legend so far)
+ def _onUpdateOverlays(self):
+ """Converts rendered overlay files and text labels to wx.Image
+ and then to textures so that they can be rendered by OpenGL.
+ Updates self.imagelist"""
+ # update images (legend and text)
for oid, overlay in self.overlays.iteritems():
- if not overlay.IsShown() or oid in (1, 2): # 0 for barscale
+ if not overlay.IsShown() or overlay.name in ('barscale', 'northarrow'):
continue
if oid not in [t.GetId() for t in self.imagelist]: # new
- self.CreateTexture(overlay=overlay.layer)
+ self.CreateTexture(overlay=overlay)
else:
for t in self.imagelist:
if t.GetId() == oid: # check if it is the same
if not t.Corresponds(overlay):
self.imagelist.remove(t)
- t = self.CreateTexture(overlay=overlay.layer)
+ t = self.CreateTexture(overlay=overlay)
- # update text labels
- for textId in self.textdict.keys():
- if textId not in [t.GetId() for t in self.imagelist]: # new
- self.CreateTexture(textId=textId)
- else:
- for t in self.imagelist:
- if t.GetId() == textId: # check if it is the same
- self.textdict[textId]['bbox'] = t.textDict['bbox']
- if not t.Corresponds(self.textdict[textId]):
- self.imagelist.remove(t)
- t = self.CreateTexture(textId=textId)
- # always set coordinates, needed for synchr. 2D and 3D
- # modes
- t.SetCoords(self.textdict[textId]['coords'])
self.Refresh()
- def CreateTexture(self, overlay=None, textId=None):
- """Create texture from overlay image or from textdict"""
- if overlay: # legend
- texture = wxnviz.ImageTexture(
- filepath=overlay.mapfile,
- overlayId=overlay.id,
- coords=list(
- self.overlays[
- overlay.id].coords),
- cmd=overlay.GetCmd())
- if overlay.id == 0: # legend
- texture.SetBounds(self.GetLegendRect())
- else: # text
- coords, bbox, relCoords = self.TextBounds(self.textdict[textId])
- self.textdict[textId]['coords'] = coords
- self.textdict[textId]['bbox'] = bbox
- file = self.DrawTextImage(self.textdict[textId], relCoords)
- texture = wxnviz.TextTexture(
- filepath=file, overlayId=textId, coords=coords,
- textDict=self.textdict[textId])
- bbox.OffsetXY(*relCoords)
- texture.SetBounds(bbox)
+ def CreateTexture(self, overlay):
+ """Create texture from overlay image"""
+ texture = wxnviz.ImageTexture(
+ filepath=overlay.layer.mapfile, overlayId=overlay.id,
+ coords=list(overlay.coords), cmd=overlay.GetCmd())
if not texture.textureId: # texture too big
GMessage(
@@ -605,6 +515,9 @@
return texture
+ def ClearTextures(self):
+ self.imagelist = []
+
def FindObjects(self, mouseX, mouseY, radius):
"""Find object which was clicked on"""
for texture in self.imagelist:
@@ -783,11 +696,12 @@
self.SetDrawScalebar((pos[0], size[1] - pos[1]))
if self.mouse['use'] == 'pointer':
- # get decoration or text id
+ # get decoration id
self.dragid = self.FindObjects(
self.mouse['tmp'][0],
self.mouse['tmp'][1],
self.hitradius)
+
if self.mouse['use'] == 'fly':
if not self.timerFly.IsRunning():
self.timerFly.Start(self.fly['interval'])
@@ -895,17 +809,11 @@
if self.dragid >= 0:
dx = self.mouse['end'][0] - self.mouse['begin'][0]
dy = self.mouse['end'][1] - self.mouse['begin'][1]
- if self.dragid < 99:
+ if self.dragid in self.overlays:
coords = self.overlays[self.dragid].coords
self.overlays[
self.dragid].coords = [
coords[0] + dx, coords[1] + dy]
- else: # text
- coords = self.textdict[self.dragid]['coords']
- self.textdict[
- self.dragid]['coords'] = [
- coords[0] + dx,
- coords[1] + dy]
self.dragid = -1
self.render['quick'] = False
self.Refresh(False)
@@ -2764,13 +2672,6 @@
"""
self.lmgr.nviz.OnResetView(None)
- def TextBounds(self, textinfo):
- """Return text boundary data
-
- :param textinfo: text metadata (text, font, color, rotation)
- """
- return self.parent.MapWindow2D.TextBounds(textinfo, relcoords=True)
-
def DisactivateWin(self):
"""Use when the class instance is hidden in MapFrame."""
pass
Modified: grass/trunk/gui/wxpython/nviz/wxnviz.py
===================================================================
--- grass/trunk/gui/wxpython/nviz/wxnviz.py 2016-07-09 22:28:28 UTC (rev 68922)
+++ grass/trunk/gui/wxpython/nviz/wxnviz.py 2016-07-09 23:28:30 UTC (rev 68923)
@@ -49,7 +49,7 @@
from grass.lib.raster import *
from core.debug import Debug
-from core.utils import _
+from core.utils import _, autoCropImageFromFile
import grass.script as grass
log = None
@@ -2041,12 +2041,11 @@
:param coords: image coordinates
"""
self.path = filepath
- self.image = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
- self.width = self.image.GetWidth()
- self.height = self.image.GetHeight()
+ self.image = autoCropImageFromFile(filepath)
+ self.width = self.orig_width = self.image.GetWidth()
+ self.height = self.orig_height = self.image.GetHeight()
self.id = overlayId
- self.coords = [0, 0]
- self.bounds = wx.Rect()
+ self.coords = coords
self.active = True
# alpha needs to be initialized
@@ -2131,12 +2130,8 @@
self.height,
self.textureId)
- def SetBounds(self, rect):
- """Set Bounding Rectangle"""
- self.bounds = rect
-
def HitTest(self, x, y, radius):
- copy = wx.Rect(*self.bounds)
+ copy = wx.Rect(self.coords[0], self.coords[1], self.orig_width, self.orig_height)
copy.Inflate(radius, radius)
return copy.ContainsXY(x, y)
@@ -2144,7 +2139,6 @@
"""Move texture on the screen"""
self.coords[0] += dx
self.coords[1] += dy
- self.bounds.OffsetXY(dx, dy)
def SetCoords(self, coords):
"""Set coordinates"""
@@ -2188,37 +2182,3 @@
def Corresponds(self, item):
return sorted(self.GetCmd()) == sorted(item.GetCmd())
-
-
-class TextTexture(Texture):
- """Class representing OpenGL texture as a text label"""
-
- def __init__(self, filepath, overlayId, coords, textDict):
- """Load image to texture
-
- :param filepath: path to image file
- :param overlayId: id of overlay (101 and more for text)
- :param coords: text coordinates
- :param textDict: text properties
- """
- Texture.__init__(
- self,
- filepath=filepath,
- overlayId=overlayId,
- coords=coords)
-
- self.textDict = textDict
-
- def GetTextDict(self):
- """Returns text properties."""
- return self.textDict
-
- def Corresponds(self, item):
- t = self.GetTextDict()
- for prop in t.keys():
- if prop in ('coords', 'bbox'):
- continue
- if t[prop] != item[prop]:
- return False
-
- return True
More information about the grass-commit
mailing list