Browse Source

wxGUI: synchronize displays in wxIClass; improve implementation

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@54429 15284696-431f-4ddb-bdfa-cd5b030d7da7
Anna Petrášová 12 years ago
parent
commit
b7de7704e0

+ 3 - 0
gui/wxpython/core/events.py

@@ -30,6 +30,7 @@ This program is free software under the GNU General Public License
 
 
 
 
 from wx.lib.newevent import NewCommandEvent
 from wx.lib.newevent import NewCommandEvent
+from wx.lib.newevent import NewEvent
 
 
 
 
 # Notification event intended to update statusbar.
 # Notification event intended to update statusbar.
@@ -41,3 +42,5 @@ gShowNotification, EVT_SHOW_NOTIFICATION = NewCommandEvent()
 # attributes: name: map name, ltype: map type,
 # attributes: name: map name, ltype: map type,
 # add: if map should be added to layer tree (questionable attribute)
 # add: if map should be added to layer tree (questionable attribute)
 gMapCreated, EVT_MAP_CREATED = NewCommandEvent()
 gMapCreated, EVT_MAP_CREATED = NewCommandEvent()
+
+gZoomChanged, EVT_ZOOM_CHANGED = NewEvent()

+ 54 - 6
gui/wxpython/gui_core/mapdisp.py

@@ -25,8 +25,9 @@ import sys
 import wx
 import wx
 import wx.aui
 import wx.aui
 
 
-from core       import globalvar
-from core.debug import Debug
+from core        import globalvar
+from core.debug  import Debug
+from core.events import EVT_ZOOM_CHANGED
 
 
 from grass.script import core as grass
 from grass.script import core as grass
 
 
@@ -468,12 +469,13 @@ class DoubleMapFrame(MapFrameBase):
         self.firstMap = firstMap
         self.firstMap = firstMap
         self.secondMap = secondMap
         self.secondMap = secondMap
         self.Map = firstMap
         self.Map = firstMap
-                
+
         #
         #
         # initialize region values
         # initialize region values
         #
         #
         self._initMap(Map = self.firstMap)
         self._initMap(Map = self.firstMap)
         self._initMap(Map = self.secondMap)
         self._initMap(Map = self.secondMap)
+        self._bindRegions = False
     
     
     def _bindWindowsActivation(self):
     def _bindWindowsActivation(self):
         self.GetFirstWindow().Bind(wx.EVT_ENTER_WINDOW, self.ActivateFirstMap)
         self.GetFirstWindow().Bind(wx.EVT_ENTER_WINDOW, self.ActivateFirstMap)
@@ -514,17 +516,63 @@ class DoubleMapFrame(MapFrameBase):
         return self.MapWindow
         return self.MapWindow
     
     
     def ActivateFirstMap(self, event = None):
     def ActivateFirstMap(self, event = None):
-        """!Make first Map and MapWindow active"""
+        """!Make first Map and MapWindow active and (un)bind regions of the two Maps."""
         self.Map = self.firstMap
         self.Map = self.firstMap
         self.MapWindow = self.firstMapWindow
         self.MapWindow = self.firstMapWindow
         self.GetMapToolbar().SetActiveMap(0)
         self.GetMapToolbar().SetActiveMap(0)
-        
+
+        # bind/unbind regions
+        if self._bindRegions:
+            self.firstMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedFirstMap)
+        else:
+            self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
+        self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
+
     def ActivateSecondMap(self, event = None):
     def ActivateSecondMap(self, event = None):
-        """!Make second Map and MapWindow active"""
+        """!Make second Map and MapWindow active and (un)bind regions of the two Maps."""
         self.Map = self.secondMap
         self.Map = self.secondMap
         self.MapWindow = self.secondMapWindow
         self.MapWindow = self.secondMapWindow
         self.GetMapToolbar().SetActiveMap(1)
         self.GetMapToolbar().SetActiveMap(1)
 
 
+        if self._bindRegions:
+            self.secondMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedSecondMap)
+        else:
+            self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
+        self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
+
+    def SetBindRegions(self, on):
+        """!Set or unset binding display regions."""
+        self._bindRegions = on
+
+        if on:
+            if self.MapWindow == self.firstMapWindow:
+                self.firstMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedFirstMap)
+            else:
+                self.secondMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedSecondMap)
+        else:
+            self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
+            self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
+
+    def OnZoomChangedFirstMap(self, event):
+        """!Display region of the first window (Map) changed.
+
+        Synchronize the region of the second map and re-render it.
+        This is the default implementation which can be overridden.
+        """
+        region = self.GetFirstMap().GetCurrentRegion()
+        self.GetSecondMap().region.update(region)
+        self.Render(mapToRender = self.GetSecondWindow())
+
+    def OnZoomChangedSecondMap(self, event):
+        """!Display region of the second window (Map) changed.
+
+        Synchronize the region of the second map and re-render it.
+        This is the default implementation which can be overridden.
+        """
+        region = self.GetSecondMap().GetCurrentRegion()
+        self.GetFirstMap().region.update(region)
+        self.Render(mapToRender = self.GetFirstWindow())
+
     def OnZoomIn(self, event):
     def OnZoomIn(self, event):
         """!Zoom in the map.
         """!Zoom in the map.
         Set mouse cursor, zoombox attributes, and zoom direction
         Set mouse cursor, zoombox attributes, and zoom direction

+ 12 - 2
gui/wxpython/iclass/frame.py

@@ -342,7 +342,7 @@ class IClassMapFrame(DoubleMapFrame):
     def IsStandalone(self):
     def IsStandalone(self):
         """!Check if Map display is standalone"""
         """!Check if Map display is standalone"""
         return True
         return True
-    
+
     def OnUpdateActive(self, event):
     def OnUpdateActive(self, event):
         """!
         """!
         @todo move to DoubleMapFrame?
         @todo move to DoubleMapFrame?
@@ -370,7 +370,7 @@ class IClassMapFrame(DoubleMapFrame):
         if mapTb.GetActiveMap() != (win == self.secondMapWindow):
         if mapTb.GetActiveMap() != (win == self.secondMapWindow):
             mapTb.SetActiveMap((win == self.secondMapWindow))
             mapTb.SetActiveMap((win == self.secondMapWindow))
         self.StatusbarUpdate() 
         self.StatusbarUpdate() 
-        
+
     def GetMapToolbar(self):
     def GetMapToolbar(self):
         """!Returns toolbar with zooming tools"""
         """!Returns toolbar with zooming tools"""
         return self.toolbars['iClassMap']
         return self.toolbars['iClassMap']
@@ -399,6 +399,16 @@ class IClassMapFrame(DoubleMapFrame):
         zoommenu.AppendItem(zoomtarget)
         zoommenu.AppendItem(zoomtarget)
         self.Bind(wx.EVT_MENU, self.OnZoomToTraining, zoomtarget)
         self.Bind(wx.EVT_MENU, self.OnZoomToTraining, zoomtarget)
 
 
+        zoombind = wx.MenuItem(zoommenu, wx.ID_ANY, _("Display synchronization ON"))
+        zoommenu.AppendItem(zoombind)
+        self.Bind(wx.EVT_MENU, lambda event: self.SetBindRegions(True), zoombind)
+
+        zoomunbind = wx.MenuItem(zoommenu, wx.ID_ANY, _("Display synchronization OFF"))
+        zoommenu.AppendItem(zoomunbind)
+        self.Bind(wx.EVT_MENU, lambda event: self.SetBindRegions(False), zoomunbind)
+
+        zoomunbind.Enable(self._bindRegions)
+        zoombind.Enable(not self._bindRegions)
         # Popup the menu. If an item is selected then its handler
         # Popup the menu. If an item is selected then its handler
         # will be called before PopupMenu returns.
         # will be called before PopupMenu returns.
         self.PopupMenu(zoommenu)
         self.PopupMenu(zoommenu)

+ 5 - 0
gui/wxpython/mapdisp/mapwindow.py

@@ -34,6 +34,7 @@ from gui_core.dialogs   import SavedRegion
 from core.gcmd          import RunCommand, GException, GError, GMessage
 from core.gcmd          import RunCommand, GException, GError, GMessage
 from core.debug         import Debug
 from core.debug         import Debug
 from core.settings      import UserSettings
 from core.settings      import UserSettings
+from core.events        import gZoomChanged
 from gui_core.mapwindow import MapWindow
 from gui_core.mapwindow import MapWindow
 try:
 try:
     import grass.lib.gis as gislib
     import grass.lib.gis as gislib
@@ -1536,6 +1537,8 @@ class BufferedWindow(MapWindow, wx.Window):
         # update statusbar
         # update statusbar
         self.frame.StatusbarUpdate()
         self.frame.StatusbarUpdate()
 
 
+        wx.PostEvent(self, gZoomChanged())
+
     def ZoomHistory(self, n, s, e, w):
     def ZoomHistory(self, n, s, e, w):
         """!Manages a list of last 10 zoom extents
         """!Manages a list of last 10 zoom extents
 
 
@@ -1565,6 +1568,8 @@ class BufferedWindow(MapWindow, wx.Window):
         toolbar = self.frame.GetMapToolbar()
         toolbar = self.frame.GetMapToolbar()
         
         
         toolbar.Enable('zoomBack', enable)
         toolbar.Enable('zoomBack', enable)
+
+        wx.PostEvent(self, gZoomChanged())
         
         
         return removed
         return removed
 
 

+ 1 - 15
gui/wxpython/mapswipe/frame.py

@@ -65,8 +65,8 @@ class SwipeMapFrame(DoubleMapFrame):
         self.secondMapWindow = SwipeBufferedWindow(parent = self.splitter, giface = self._giface,
         self.secondMapWindow = SwipeBufferedWindow(parent = self.splitter, giface = self._giface,
                                                    Map = self.secondMap, frame = self)
                                                    Map = self.secondMap, frame = self)
         self.MapWindow = self.firstMapWindow # current by default
         self.MapWindow = self.firstMapWindow # current by default
-        self.firstMap.region = self.secondMap.region
         self.firstMapWindow.zoomhistory = self.secondMapWindow.zoomhistory
         self.firstMapWindow.zoomhistory = self.secondMapWindow.zoomhistory
+        self.SetBindRegions(True)
 
 
         self._mode = 'swipe'
         self._mode = 'swipe'
 
 
@@ -270,18 +270,6 @@ class SwipeMapFrame(DoubleMapFrame):
                   LeftDockable(True).RightDockable(True).
                   LeftDockable(True).RightDockable(True).
                   Right().Layer(1).BestSize((self.sliderV.GetBestSize())))
                   Right().Layer(1).BestSize((self.sliderV.GetBestSize())))
 
 
-    def UpdateRegion(self):
-        """!
-        Rerender the second window
-        when the region of the first changed.
-        """
-        Debug.msg(3, "SwipeMapFrame.UpdateRegion()")
-
-        if self.GetWindow() == self.GetSecondWindow():
-            self.Render(self.GetFirstWindow())
-        else:
-            self.Render(self.GetSecondWindow())
-
     def ZoomToMap(self):
     def ZoomToMap(self):
         """!
         """!
         Set display extents to match selected raster (including NULLs)
         Set display extents to match selected raster (including NULLs)
@@ -291,8 +279,6 @@ class SwipeMapFrame(DoubleMapFrame):
             self.GetFirstWindow().ZoomToMap(layers = self.firstMap.GetListOfLayers())
             self.GetFirstWindow().ZoomToMap(layers = self.firstMap.GetListOfLayers())
         if self.rasters['second']:
         if self.rasters['second']:
             self.GetSecondWindow().ZoomToMap(layers = self.secondMap.GetListOfLayers())
             self.GetSecondWindow().ZoomToMap(layers = self.secondMap.GetListOfLayers())
-        # needed again, don't know why
-        self.firstMap.region = self.secondMap.region
 
 
     def OnZoomToMap(self, event):
     def OnZoomToMap(self, event):
         """!Zoom to map"""
         """!Zoom to map"""

+ 0 - 21
gui/wxpython/mapswipe/mapwindow.py

@@ -113,16 +113,6 @@ class SwipeBufferedWindow(BufferedWindow):
         if not self.movingSash:
         if not self.movingSash:
             super(SwipeBufferedWindow, self).OnSize(event)
             super(SwipeBufferedWindow, self).OnSize(event)
 
 
-    def ZoomToMap(self, layers = None, ignoreNulls = False, render = True):
-        super(SwipeBufferedWindow, self).ZoomToMap(layers, ignoreNulls, render)
-        self.frame.UpdateRegion()
-
-    def ZoomBack(self):
-        """!Zoom last (previously stored position)
-        """
-        super(SwipeBufferedWindow, self).ZoomBack()
-        self.frame.UpdateRegion()
-
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
         """!Draws image (map) with translated coordinates.
         """!Draws image (map) with translated coordinates.
         """
         """
@@ -180,17 +170,6 @@ class SwipeBufferedWindow(BufferedWindow):
                                  'rotation': 0, 'text': name,
                                  'rotation': 0, 'text': name,
                                  'active': True}
                                  'active': True}
 
 
-    def MouseActions(self, event):
-        """!Handle mouse events and if needed let parent frame know"""
-        super(SwipeBufferedWindow, self).MouseActions(event)
-        if event.GetWheelRotation() != 0 or \
-           event.LeftUp() or \
-           event.MiddleUp():
-
-            self.frame.UpdateRegion()
-
-        event.Skip()
-        
     def MouseDraw(self, pdc = None, begin = None, end = None):
     def MouseDraw(self, pdc = None, begin = None, end = None):
         """!Overriden method to recompute coordinates back to original values
         """!Overriden method to recompute coordinates back to original values
         so that e.g. drawing of zoom box is done properly"""
         so that e.g. drawing of zoom box is done properly"""