using System.Collections.Generic; namespace SharpMap.UI.Tools.Zooming { /// /// Object for keeping track of the zoom history /// public class ZoomHistoryTool : ZoomTool { private ZoomState currentZoomState; private readonly Stack undoStack = new Stack(); private readonly Stack redoStack = new Stack(); private bool isZoomChangeTriggeredByNavigation; public ZoomHistoryTool() { Name = "ZoomHistory"; } /// /// Undo last zoom and update redo-stack /// public void PreviousZoomState() { if (undoStack.Count > 0) { ZoomState previousState = undoStack.Pop(); if (previousState != null) { if (currentZoomState != null) { redoStack.Push(currentZoomState); } isZoomChangeTriggeredByNavigation = true; Map.Center = previousState.Center; Map.Zoom = previousState.Zoom; } } } /// /// Redo last zoom and update undo-stack /// public void NextZoomState() { if (redoStack.Count > 0) { ZoomState nextState = redoStack.Pop(); if (nextState != null) { if (currentZoomState != null) { undoStack.Push(currentZoomState); } isZoomChangeTriggeredByNavigation = true; Map.Center = nextState.Center; Map.Zoom = nextState.Zoom; } } } /// /// Number of undo zoom steps that is available /// public int UndoCount { get { return (undoStack.Count); } } /// /// Number of redo zoom steps that is available /// public int RedoCount { get { return (redoStack.Count); } } /// /// Used to store current ZoomState if it changes /// /// public void MapRendered(Map map) { // More logically this should be done in MapViewOnChange() but that event does not fire // when zoom rectangle or zoompan is performed if (!isZoomChangeTriggeredByNavigation) { if ((currentZoomState == null) || !currentZoomState.Zoom.Equals(map.Zoom) || !currentZoomState.Center.Equals(map.Center)) { if (currentZoomState != null) { undoStack.Push(currentZoomState); redoStack.Clear(); } } } isZoomChangeTriggeredByNavigation = false; currentZoomState = new ZoomState(map.Zoom, map.Center); } } }