This topic contains code sample that shows how to create new visual tool that allows to drag-and-drop image region between different image viewers.
Here is source codes of visual tool (AdvancedDragAndDropTool.cs file):
Code: Select all
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Vintasoft.Imaging;
using Vintasoft.Imaging.ImageProcessing;
using Vintasoft.Imaging.UI;
using Vintasoft.Imaging.UI.VisualTools;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;
namespace VintasoftDragDrop
{
/// <summary>
/// Visual tool that allows to drag image region and drop it to the same or different image viewer.
/// </summary>
public class AdvancedDragAndDropTool : RectangularSelectionTool
{
#region Constants
/// <summary>
/// The drag and drop effect of current visual tool.
/// </summary>
DragDropEffects DRAG_DROP_EFFECT = DragDropEffects.Copy | DragDropEffects.Move;
#endregion
#region Fields
/// <summary>
/// The cursor location on image.
/// </summary>
PointF _dragPointInImageSpace = PointF.Empty;
/// <summary>
/// The size of dragging image.
/// </summary>
RectangleF _draggingImageSize = RectangleF.Empty;
/// <summary>
/// Visual tool where drag-and-drop process is started.
/// </summary>
AdvancedDragAndDropTool _sourceTool = null;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AdvancedDragAndDropTool"/> class.
/// </summary>
public AdvancedDragAndDropTool()
: base()
{
AdvancedDragAndDropToolTransformer advancedDragAndDropToolTransformer = new AdvancedDragAndDropToolTransformer(this);
advancedDragAndDropToolTransformer.DraggingStarted += new EventHandler(advancedDragAndDropToolTransformer_DraggingStarted);
TransformController = advancedDragAndDropToolTransformer;
}
#endregion
#region Properties
/// <summary>
/// Gets the name of the visual tool.
/// </summary>
public override string Name
{
get
{
return "Image Drag And Drop Tool";
}
}
bool _isDragging = false;
/// <summary>
/// Gets a value indicating whether the image is dragging.
/// </summary>
public bool IsDragging
{
get
{
return _isDragging;
}
}
#endregion
#region Methods
#region PUBLIC
/// <summary>
/// Draws the visual tool on specified System.Drawing.Graphics.
/// </summary>
/// <param name="viewer">An image viewer.</param>
/// <param name="g">A graphics where this tool must be drawn.</param>
public override void Draw(ImageViewer viewer, Graphics g)
{
if (_isDragging)
{
if (viewer.Image == null)
return;
// draw image
Rectangle rectInControl = Rectangle.Round(viewer.RectangleToControl(GetDrawingBoxInImageSpace(viewer, _sourceTool)));
using (VintasoftImage draggingImage = _sourceTool.GetDraggingImage())
{
if (draggingImage == null)
return;
draggingImage.Draw(g, rectInControl);
}
// draw border
g.DrawRectangle(Pens.Red, rectInControl);
}
else
base.Draw(viewer, g);
}
#endregion
#region PROTECTED
/// <summary>
/// Raises the <see cref="VisualTool.Activated"/> event.
/// </summary>
/// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
this.ImageViewer.AllowDrop = true;
this.ImageViewer.DragEnter += new DragEventHandler(imageViewer_DragEnter);
this.ImageViewer.DragLeave += new EventHandler(ImageViewer_DragLeave);
this.ImageViewer.DragOver += new DragEventHandler(imageViewer_DragOver);
this.ImageViewer.DragDrop += new DragEventHandler(imageViewer_DragDrop);
}
/// <summary>
/// Raises the <see cref="VisualTool.Deactivated"/> event.
/// </summary>
/// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
protected override void OnDeactivated(EventArgs e)
{
base.OnDeactivated(e);
this.ImageViewer.AllowDrop = false;
this.ImageViewer.DragEnter -= new DragEventHandler(imageViewer_DragEnter);
this.ImageViewer.DragLeave -= new EventHandler(ImageViewer_DragLeave);
this.ImageViewer.DragOver -= new DragEventHandler(imageViewer_DragOver);
this.ImageViewer.DragDrop -= new DragEventHandler(imageViewer_DragDrop);
}
#endregion
#region PRIVATE
/// <summary>
/// Handles the DraggingStarted event of the advancedDragAndDropToolTransformer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void advancedDragAndDropToolTransformer_DraggingStarted(object sender, EventArgs e)
{
// get location of drag point
_dragPointInImageSpace = GetCursorPositionInImageSpace(ImageViewer);
// get size of dragging image
_draggingImageSize = GetDrawingBox(ImageViewer);
_sourceTool = this;
// start new interaction (dragging and dropping)
DragDropEffects effects = this.ImageViewer.DoDragDrop(this, DragDropEffects.Move);
}
/// <summary>
/// Handles the DragEnter event of the imageViewer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="DragEventArgs"/> instance containing the event data.</param>
private void imageViewer_DragEnter(object sender, DragEventArgs e)
{
if (ImageViewer.Image != null)
{
_sourceTool = (AdvancedDragAndDropTool)e.Data.GetData(typeof(AdvancedDragAndDropTool));
if (_sourceTool != null)
{
_isDragging = true;
e.Effect = DRAG_DROP_EFFECT;
}
}
}
/// <summary>
/// Handles the DragLeave event of the ImageViewer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void ImageViewer_DragLeave(object sender, EventArgs e)
{
_isDragging = false;
Rectangle = Rectangle.Empty;
InvalidateViewer();
}
/// <summary>
/// Handles the DragOver event of the imageViewer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="DragEventArgs"/> instance containing the event data.</param>
private void imageViewer_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(AdvancedDragAndDropTool)) &&
e.Effect == (DRAG_DROP_EFFECT))
Rectangle = GetDrawingBoxInImageSpace(ImageViewer, _sourceTool);
}
/// <summary>
/// Handles the DragDrop event of the imageViewer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="DragEventArgs"/> instance containing the event data.</param>
private void imageViewer_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(AdvancedDragAndDropTool)) &&
e.Effect == (DRAG_DROP_EFFECT))
{
Rectangle droppingRectInImageSpace = GetDrawingBoxInImageSpace(ImageViewer, _sourceTool);
if (droppingRectInImageSpace.IsEmpty)
return;
using (VintasoftImage draggingImage = _sourceTool.GetDraggingImage())
{
if (draggingImage == null)
return;
int offsetX = 0;
int offsetY = 0;
if (droppingRectInImageSpace.X < 0)
{
offsetX = -droppingRectInImageSpace.X;
droppingRectInImageSpace.X = 0;
}
if (droppingRectInImageSpace.Y < 0)
{
offsetY = -droppingRectInImageSpace.Y;
droppingRectInImageSpace.Y = 0;
}
if (offsetX != 0 || offsetY != 0)
draggingImage.Crop(new Rectangle(offsetX, offsetY, draggingImage.Width - offsetX, draggingImage.Height - offsetY));
OverlayCommand overlayCommand = new OverlayCommand(draggingImage, Point.Round(droppingRectInImageSpace.Location));
overlayCommand.ExecuteInPlace(ImageViewer.Image);
}
_isDragging = false;
InvalidateViewer();
}
}
/// <summary>
/// Calculates drawing box in image space.
/// </summary>
/// <param name="viewer">Image viewer.</param>
/// <param name="tool">Current visual tool.</param>
/// <param name="mouseLocationInScreen">Mouse position in screen coordinates.</param>
private Rectangle GetDrawingBoxInImageSpace(ImageViewer viewer, AdvancedDragAndDropTool tool)
{
if (viewer.Image == null)
return Rectangle.Empty;
int offsetXInControl = (int)Math.Round(tool._dragPointInImageSpace.X - tool._draggingImageSize.X);
int offsetYInControl = (int)Math.Round(tool._dragPointInImageSpace.Y - tool._draggingImageSize.Y);
Point mousePositionInImage = GetCursorPositionInImageSpace(viewer);
return new Rectangle(
mousePositionInImage.X - offsetXInControl,
mousePositionInImage.Y - offsetYInControl,
(int)Math.Round(tool._draggingImageSize.Width),
(int)Math.Round(tool._draggingImageSize.Height));
}
/// <summary>
/// Gets position of the cursor in image space.
/// </summary>
/// <param name="viewer">Image viewer.</param>
private Point GetCursorPositionInImageSpace(ImageViewer viewer)
{
Point mouseLocationInClient = viewer.FindForm().PointToClient(Cursor.Position);
Point mouseLocationInControl = new Point(mouseLocationInClient.X - viewer.Location.X,
mouseLocationInClient.Y - viewer.Location.Y);
return viewer.PointToImage(mouseLocationInControl);
}
/// <summary>
/// Gets the image region that should be dragged.
/// </summary>
private VintasoftImage GetDraggingImage()
{
VintasoftImage img = ImageViewer.Image;
if (img.IsProcessing)
{
this.TryFinishInteraction();
if (img.IsProcessing)
return null;
}
Rectangle imageRect = new Rectangle(0, 0, img.Width, img.Height);
Rectangle drawingBox = Rectangle.Round(_draggingImageSize);
drawingBox.Intersect(imageRect);
CropCommand cropCommand = new CropCommand(drawingBox);
return cropCommand.Execute(img);
}
#endregion
#endregion
}
}
Code: Select all
/// <summary>
/// An interactive transformer that allows to select image region in image viewer and
/// starts drag-and-drop operation when image region is moved.
/// </summary>
private class AdvancedDragAndDropToolTransformer : RectangularObjectTransformer
{
#region Fields
/// <summary>
/// Drag-and-drop visual tool.
/// </summary>
AdvancedDragAndDropTool _tool = null;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AdvancedDragAndDropToolTransformer"/> class.
/// </summary>
/// <param name="interactiveObject">An interative object.</param>
internal AdvancedDragAndDropToolTransformer(IRectangularInteractiveObject interactiveObject)
: base(interactiveObject)
{
if (interactiveObject is AdvancedDragAndDropTool)
_tool = (AdvancedDragAndDropTool)interactiveObject;
}
#endregion
#region Properties
/// <summary>
/// Gets a value indicating whether controller is visible.
/// </summary>
public override bool IsVisible
{
get
{
if (_tool != null)
return !_tool.IsDragging;
else
return true;
}
}
#endregion
#region Methods
/// <summary>
/// Performs an interaction between user and interaction area of interactive object.
/// </summary>
/// <param name="args">An interaction event args.</param>
protected override void PerformInteraction(InteractionEventArgs args)
{
// if visual tool interacts with selection
if (args.Area == MoveArea)
{
switch (args.Action)
{
// if selection is moving
case InteractionAreaAction.Move:
OnDraggingStarted();
return;
// if interaction with selection is canceled
case InteractionAreaAction.Cancel:
args.InteractionFinished = true;
return;
}
}
base.PerformInteraction(args);
}
/// <summary>
/// Raises the <see cref="AdvancedDragAndDropToolTransformer.DraggingStarted"/> event.
/// </summary>
private void OnDraggingStarted()
{
if (DraggingStarted != null)
DraggingStarted(this, EventArgs.Empty);
}
#endregion
#region Events
/// <summary>
/// Occurs when dragging is started.
/// </summary>
public event EventHandler DraggingStarted;
#endregion
}
Code: Select all
using System;
using System.Windows.Forms;
using Vintasoft.Imaging;
namespace VintasoftDragDrop
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
imageViewer1.SizeMode = Vintasoft.Imaging.UI.ImageSizeMode.BestFit;
imageViewer1.Image = new VintasoftImage("apple.jpg");
imageViewer1.VisualTool = new AdvancedDragAndDropTool();
imageViewer2.SizeMode = Vintasoft.Imaging.UI.ImageSizeMode.BestFit;
imageViewer2.Image = new VintasoftImage("apple.jpg");
imageViewer2.VisualTool = new AdvancedDragAndDropTool();
}
}
}
You can combine work of the AdvancedDragAndDropTool and AnnotationDragAndDropTool (viewtopic.php?f=24&t=2255) classes if you need drag-and-drop an image region or annotation from one image viewer to another.
Here is a code snippet that shows how to do this:
Code: Select all
imageViewer1.VisualTool = new CompositeVisualTool(
imageViewer1.AnnotationVisualTool,
new AnnotationDragAndDropTool(),
new AdvancedDragAndDropTool());
imageViewer2.VisualTool = new CompositeVisualTool(
imageViewer2.AnnotationVisualTool,
new AnnotationDragAndDropTool(),
new AdvancedDragAndDropTool());