using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using DotSpatial.Topology;
using Point = System.Drawing.Point;
namespace Core.Components.DotSpatial
{
///
/// that can zoom into the map using left mouse clicks or rectangle dragging. It zooms out on right mouse clicks.
///
/// This is a copy of with the following changes:
///
/// - It does not zoom out on right mouse clicks.
/// - It does not zoom when the location of the cursus on is equal to the location set at
/// .
public class MapFunctionSelectionZoom : MapFunction
{
private readonly Pen selectionPen;
private Point currentPoint;
private Coordinate geoStartPoint;
private bool isDragging;
private Point startPoint = Point.Empty;
///
/// Creates a new instance of .
///
public MapFunctionSelectionZoom(IMap inMap) : base(inMap)
{
selectionPen = new Pen(Color.Black)
{
DashStyle = DashStyle.Dash
};
YieldStyle = YieldStyles.LeftButton | YieldStyles.RightButton;
}
protected override void OnDraw(MapDrawArgs e)
{
if (isDragging)
{
var rectangle = Opp.RectangleFromPoints(startPoint, currentPoint);
rectangle.Width -= 1;
rectangle.Height -= 1;
e.Graphics.DrawRectangle(Pens.White, rectangle);
e.Graphics.DrawRectangle(selectionPen, rectangle);
}
base.OnDraw(e);
}
protected override void OnMouseDown(GeoMouseArgs e)
{
if (e.Button == MouseButtons.Left)
{
startPoint = e.Location;
currentPoint = startPoint;
geoStartPoint = e.GeographicLocation;
isDragging = true;
Map.IsBusy = true;
}
base.OnMouseDown(e);
}
protected override void OnMouseMove(GeoMouseArgs e)
{
if (isDragging)
{
int x = Math.Min(Math.Min(startPoint.X, currentPoint.X), e.X);
int y = Math.Min(Math.Min(startPoint.Y, currentPoint.Y), e.Y);
int mx = Math.Max(Math.Max(startPoint.X, currentPoint.X), e.X);
int my = Math.Max(Math.Max(startPoint.Y, currentPoint.Y), e.Y);
currentPoint = e.Location;
Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
}
base.OnMouseMove(e);
}
protected override void OnMouseUp(GeoMouseArgs e)
{
if (!(e.Map.IsZoomedToMaxExtent && e.Button == MouseButtons.Right))
{
e.Map.IsZoomedToMaxExtent = false;
var handled = false;
currentPoint = e.Location;
Map.Invalidate();
if (isDragging)
{
if (startPoint == currentPoint)
{
handled = true;
}
else if (geoStartPoint != null)
{
IEnvelope env = new Envelope(geoStartPoint.X, e.GeographicLocation.X,
geoStartPoint.Y, e.GeographicLocation.Y);
if (Math.Abs(e.X - startPoint.X) > 1 && Math.Abs(e.Y - startPoint.Y) > 1)
{
e.Map.ViewExtents = env.ToExtent();
handled = true;
}
}
}
isDragging = false;
if (handled == false)
{
Rectangle r = e.Map.MapFrame.View;
var w = r.Width;
var h = r.Height;
if (e.Button == MouseButtons.Left)
{
r.Inflate(-r.Width/4, -r.Height/4);
// The mouse cursor should anchor the geographic location during zoom.
r.X += (e.X/2) - w/4;
r.Y += (e.Y/2) - h/4;
e.Map.MapFrame.View = r;
}
else if (e.Button == MouseButtons.Right)
{
startPoint = Point.Empty;
}
e.Map.MapFrame.ResetExtents();
}
}
base.OnMouseUp(e);
Map.IsBusy = false;
}
}
}