using System;
using System.Collections.Generic;
using System.Text;
namespace OSGeo.MapGuide.Viewer
{
///
/// Represents a temporary change in map state. Used primarily to set the current in-memory viewer map
/// into a temporary different display state for rendering and plotting.
///
/// Implements IDisposable semantics allowing for temporary map state to be explicity defined within a
/// C# using block with auto-reversion
///
public abstract class MgTransientMapState : IDisposable
{
private Stack _states;
///
/// The original state
///
protected MgMapDisplayParameters _origState;
///
/// Constructor
///
protected MgTransientMapState()
{
_states = new Stack();
}
///
/// Gets the current display state
///
///
protected abstract MgMapDisplayParameters GetCurrentState();
///
/// Applies the view center
///
///
///
protected abstract void ApplyViewCenter(double x, double y);
///
/// Applies the view scale
///
///
protected abstract void ApplyViewScale(double scale);
///
/// Applies the display size
///
///
///
protected abstract void ApplyDisplaySize(int width, int height);
///
/// Applies the DPI
///
///
protected abstract void ApplyDPI(int dpi);
private void ApplyState(MgMapDisplayParameters state)
{
ApplyViewCenter(state.X, state.Y);
ApplyViewScale(state.Scale);
ApplyDisplaySize(state.Width, state.Height);
if (state.DPI.HasValue)
ApplyDPI(state.DPI.Value);
}
///
/// Gets the size of temporary state transitions on the map state stack
///
public int Depth { get { return _states.Count; } }
///
/// Pushes the given state onto the map state stack. The map takes on the display parameters specified
/// in this given state.
///
///
public void PushState(MgMapDisplayParameters state)
{
if (state == null)
throw new ArgumentNullException("state"); //NOXLATE
var oldState = GetCurrentState();
ApplyState(state);
_states.Push(new MgdMapStateTransition() { OldState = oldState, NewState = state });
}
///
/// Pops the latest state from the map state stack. The map state is restored to
/// the previously applied state.
///
/// The state that was previously applied
public MgMapDisplayParameters PopState()
{
if (_states.Count == 0)
return null;
var trans = _states.Pop();
ApplyState(trans.OldState);
return trans.NewState;
}
///
/// Reverts the map to the original display state
///
public void Dispose()
{
while (_states.Count > 0)
{
this.PopState();
}
ApplyState(_origState);
}
}
///
/// Represents a temporary map display state
///
///
public abstract class MgTransientMapState : MgTransientMapState where T : MgMapBase
{
///
/// The map instance
///
protected T _map;
///
/// Constructor
///
///
protected MgTransientMapState(T map)
{
_map = map;
_origState = GetCurrentState();
}
///
/// Gets the current display state
///
///
protected override MgMapDisplayParameters GetCurrentState()
{
var pt = _map.ViewCenter;
var coord = pt.Coordinate;
return new MgMapDisplayParameters(coord.X, coord.Y, _map.ViewScale, _map.DisplayWidth, _map.DisplayHeight, _map.DisplayDpi);
}
}
internal class MgdMapStateTransition
{
public MgMapDisplayParameters NewState { get; set; }
public MgMapDisplayParameters OldState { get; set; }
}
///
/// Represents display parameters for a map
///
public class MgMapDisplayParameters
{
///
/// The view center X coordinate
///
public double X { get; private set; }
///
/// The view center Y coordinate
///
public double Y { get; private set; }
///
/// The view scale
///
public double Scale { get; private set; }
///
/// The display width
///
public int Width { get; private set; }
///
/// The display height
///
public int Height { get; private set; }
///
/// The display DPI
///
public int? DPI { get; private set; }
///
/// Constructor
///
///
///
///
///
///
public MgMapDisplayParameters(double x, double y, double scale, int width, int height)
{
this.X = x;
this.Y = y;
this.Scale = scale;
this.Width = width;
this.Height = height;
}
///
/// Constructor
///
///
///
///
///
///
///
public MgMapDisplayParameters(double x, double y, double scale, int width, int height, int dpi)
: this(x, y, scale, width, height)
{
this.DPI = dpi;
}
}
}