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);
}
}
}