WinForms: Drag-and-drop an annotation from one annotation viewer to another.

Code samples for VintaSoft Annotation .NET Plug-in. Here you can request a code sample.

Moderator: Alex

Post Reply
Alex
Site Admin
Posts: 2300
Joined: Thu Jul 10, 2008 2:21 pm

WinForms: Drag-and-drop an annotation from one annotation viewer to another.

Post by Alex »

This topic contains code sample that shows how to create new visual tool that allows to drag-and-drop annotation between different annotation viewers.

Here is C# source codes of visual tool (AnnotationDragAndDropTool.cs file):

Code: Select all

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

using Vintasoft.Imaging;
using Vintasoft.Imaging.Annotation.UI;
using Vintasoft.Imaging.Annotation.UI.VisualTools;
using Vintasoft.Imaging.UI;
using Vintasoft.Imaging.UI.VisualTools;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;
using Vintasoft.Imaging.Utils;


namespace VintasoftDragDrop
{
    /// <summary>
    /// Visual tool that allows to drag annotation and drop it to the same or different image viewer.
    /// </summary>
    public class AnnotationDragAndDropTool : VisualTool
    {

        #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 annotation tool.
        /// </summary>
        AnnotationVisualTool _annotationTool = null;

        /// <summary>
        /// The dragging annotation view.
        /// </summary>
        AnnotationView _draggingAnnoView = null;

        /// <summary>
        /// The cursor location on image.
        /// </summary>
        PointF _dragPointInImageSpace = PointF.Empty;

        #endregion



        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="AnnotationDragAndDropTool"/> class.
        /// </summary>
        public AnnotationDragAndDropTool()
        {
        }

        #endregion



        #region Properties

        /// <summary>
        /// Gets the name of visual tool.
        /// </summary>
        public override string Name
        {
            get
            {
                return "Annotation Drag And Drop Tool";
            }
        }

        bool _enabled = false;
        /// <summary>
        /// Gets or sets a value indicating whether <see cref="T:Vintasoft.Imaging.UI.VisualTools.VisualTool" /> can
        /// respond to user interaction.
        /// </summary>
        /// <value>Default value is <b>true</b>.</value>
        public override bool Enabled
        {
            get
            {
                return base.Enabled && _enabled;
            }
            set
            {
                base.Enabled = value;
            }
        }

        #endregion



        #region Methods

        #region PROTECTED

        /// <summary>
        /// Raises the <see cref="E:Vintasoft.Imaging.UI.VisualTools.VisualTool.Activated" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnActivated(EventArgs e)
        {
            base.OnActivated(e);

            if (ImageViewer is AnnotationViewer)
            {
                AnnotationViewer annoViewer = (AnnotationViewer)ImageViewer;
                _annotationTool = annoViewer.AnnotationVisualTool;
                _enabled = _annotationTool != null;
                if (_annotationTool != null)
                    _annotationTool.FocusedAnnotationViewChanged += annotationTool_FocusedAnnotationViewChanged;
            }

            this.ImageViewer.AllowDrop = true;
            this.ImageViewer.DragLeave += ImageViewer_DragLeave;
            this.ImageViewer.DragEnter += ImageViewer_DragEnter;
            this.ImageViewer.DragDrop += ImageViewer_DragDrop;
            this.ImageViewer.DragOver += ImageViewer_DragOver;
        }

        /// <summary>
        /// Raises the <see cref="E:Vintasoft.Imaging.UI.VisualTools.VisualTool.Deactivated" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnDeactivated(EventArgs e)
        {
            base.OnDeactivated(e);

            if (_annotationTool != null)
            {
                _annotationTool.FocusedAnnotationViewChanged -= annotationTool_FocusedAnnotationViewChanged;
                _annotationTool = null;
                _enabled = false;
            }

            this.ImageViewer.AllowDrop = false;
            this.ImageViewer.DragLeave -= ImageViewer_DragLeave;
            this.ImageViewer.DragEnter -= ImageViewer_DragEnter;
            this.ImageViewer.DragDrop -= ImageViewer_DragDrop;
            this.ImageViewer.DragOver -= ImageViewer_DragOver;

        }

        #endregion


        #region PRIVATE

        /// <summary>
        /// Handles the FocusedAnnotationViewChanged event of the annoTool control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="AnnotationViewChangedEventArgs"/> instance containing the event data.</param>
        private void annotationTool_FocusedAnnotationViewChanged(object sender, AnnotationViewChangedEventArgs e)
        {
            if (e.OldValue != null)
            {
                if (e.OldValue.Transformer is IInteractionController)
                {
                    // unsubscribe events 
                    IInteractionController transformer = (IInteractionController)e.OldValue.Transformer;
                    transformer.Interaction -= transformer_Interaction;
                    transformer.InteractionFinished -= transformer_InteractionFinished;
                }
            }

            if (e.NewValue != null)
            {
                if (e.NewValue.Transformer is IInteractionController)
                {
                    // subscribe events
                    IInteractionController transformer = (IInteractionController)e.NewValue.Transformer;
                    transformer.Interaction += transformer_Interaction;
                    transformer.InteractionFinished += transformer_InteractionFinished;
                }
            }
        }

        /// <summary>
        /// Handles the Interaction event of the transformer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="InteractionEventArgs"/> instance containing the event data.</param>
        private void transformer_Interaction(object sender, InteractionEventArgs e)
        {
            // if annotation is move
            if (e.Action == InteractionAreaAction.Move && e.Area.InteractionName == "Move")
            {
                // get mouse position on control
                Point mouseLocationInClient = ImageViewer.FindForm().PointToClient(Cursor.Position);
                Point mouseLocationInControl = new Point(mouseLocationInClient.X - ImageViewer.Location.X,
                    mouseLocationInClient.Y - ImageViewer.Location.Y);
                // if mouse is leave
                if (ImageViewer.Size.Width > mouseLocationInControl.X ||
                    ImageViewer.Size.Height > mouseLocationInControl.Y)
                {
                    // save annotation view
                    _draggingAnnoView = _annotationTool.FocusedAnnotationView;
                    // finish interaction
                    e.InteractionFinished = true;
                }
            }
        }

        /// <summary>
        /// Handles the InteractionFinished event of the transformer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="InteractionEventArgs"/> instance containing the event data.</param>
        private void transformer_InteractionFinished(object sender, InteractionEventArgs e)
        {
            // if annotation is dragging
            if (_draggingAnnoView != null)
            {
                // save mouse position on image
                _dragPointInImageSpace = GetCursorPositionInImageSpace();
                // correct the mouse location relative to the annotation location
                _dragPointInImageSpace.X -= _draggingAnnoView.Location.X;
                _dragPointInImageSpace.Y -= _draggingAnnoView.Location.Y;
                // remove dragging annotation
                _annotationTool.SelectedAnnotations.Remove(_draggingAnnoView);
                _annotationTool.AnnotationViewCollection.Remove(_draggingAnnoView);
                // begin drag and drop operation
                ImageViewer.DoDragDrop(this, 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)
        {
            // if annotation is dragging
            if (_draggingAnnoView != null)
            {
                // if annotation is exist
                if (_annotationTool.AnnotationViewCollection.Contains(_draggingAnnoView))
                    // remove dragging annotation
                    _annotationTool.AnnotationViewCollection.Remove(_draggingAnnoView);
            }
        }

        /// <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 (e.Data.GetDataPresent(typeof(AnnotationDragAndDropTool)) &&
                e.AllowedEffect == DRAG_DROP_EFFECT)
            {
                // get source tool
                AnnotationDragAndDropTool tool = (AnnotationDragAndDropTool)e.Data.GetData(typeof(AnnotationDragAndDropTool));
                e.Effect = DRAG_DROP_EFFECT;

                // get dragging annotation
                _draggingAnnoView = tool._draggingAnnoView;
                // get annotation point
                _dragPointInImageSpace = tool._dragPointInImageSpace;

                // if annotation view collection does not contain annotatio view
                if (!_annotationTool.AnnotationViewCollection.Contains(_draggingAnnoView))
                    // add annotation
                    _annotationTool.AnnotationViewCollection.Add(_draggingAnnoView);

                // update location of annotation
                UpdateDraggingAnnoLocation();

                // set selected annotation
                _annotationTool.SelectedAnnotations.Clear();
                _annotationTool.SelectedAnnotations.Add(_draggingAnnoView);
                _annotationTool.SetFocusedAnnotationView(_draggingAnnoView.Data);
            }
        }

        /// <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(AnnotationDragAndDropTool)) &&
                e.Effect == DRAG_DROP_EFFECT &&
                _draggingAnnoView != null)
            {
                // update location of annotation
                UpdateDraggingAnnoLocation();
            }
        }

        /// <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(AnnotationDragAndDropTool)) &&
                e.Effect == DRAG_DROP_EFFECT &&
                _draggingAnnoView != null)
            {
                AnnotationDragAndDropTool tool = (AnnotationDragAndDropTool)e.Data.GetData(typeof(AnnotationDragAndDropTool));
                _annotationTool.CancelActiveInteraction();

                // update location of annotation
                UpdateDraggingAnnoLocation();

                tool._draggingAnnoView = null;
                tool._dragPointInImageSpace = Point.Empty;
                _draggingAnnoView = null;
                _dragPointInImageSpace = Point.Empty;
            }
        }

        /// <summary>
        /// Updates the location of dragging annotation.
        /// </summary>
        private void UpdateDraggingAnnoLocation()
        {
            // get position of cursor
            PointF location = GetCursorPositionInImageSpace();
            location.X -= _dragPointInImageSpace.X;
            location.Y -= _dragPointInImageSpace.Y;
            // set annotation location
            _draggingAnnoView.Data.Location = location;
        }

        /// <summary>
        /// Gets position of the cursor in image space to dib unit.
        /// </summary>
        private PointF GetCursorPositionInImageSpace()
        {
            Point mouseLocationInClient = ImageViewer.FindForm().PointToClient(Cursor.Position);
            Point mouseLocationInControl = new Point(mouseLocationInClient.X - ImageViewer.Location.X,
                mouseLocationInClient.Y - ImageViewer.Location.Y);
            Point mouseLocationInImageInPixels = ImageViewer.PointToImage(mouseLocationInControl);
            return ConvertToDip(ImageViewer.Image, mouseLocationInImageInPixels);
        }

        /// <summary>
        /// Converts point to device independent pixels.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="point">The point.</param>
        private PointF ConvertToDip(VintasoftImage image, PointF point)
        {
            Resolution resolution = image.Resolution;
            return new PointF((float)UnitOfMeasureConverter.ConvertToDeviceIndependentPixels(point.X, UnitOfMeasure.Pixels, resolution.Horizontal),
                              (float)UnitOfMeasureConverter.ConvertToDeviceIndependentPixels(point.Y, UnitOfMeasure.Pixels, resolution.Vertical));

        }

        /// <summary>
        /// Converts point from device independent pixels.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="point">The point.</param>
        private PointF ConvertFromDip(VintasoftImage image, PointF point)
        {
            Resolution resolution = image.Resolution;
            return new PointF((float)UnitOfMeasureConverter.ConvertToPixels(point.X, UnitOfMeasure.DeviceIndependentPixels, resolution.Horizontal),
                              (float)UnitOfMeasureConverter.ConvertToPixels(point.Y, UnitOfMeasure.DeviceIndependentPixels, resolution.Vertical));
        }

        #endregion

        #endregion

    }
}
And here is C# source codes of a form with 2 image viewers (Form1.cs file):

Code: Select all

using System;
using System.Windows.Forms;

using Vintasoft.Imaging;
using Vintasoft.Imaging.UI.VisualTools;
using Vintasoft.Imaging.Annotation.UI;

namespace VintasoftDragDrop
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }



        private void Form1_Load(object sender, EventArgs e)
        {
            annotationViewer1.SizeMode = Vintasoft.Imaging.UI.ImageSizeMode.BestFit;
            annotationViewer1.Image = new VintasoftImage("apple.jpg");
            annotationViewer1.VisualTool = new AnnotationDragAndDropTool();

            annotationViewer2.SizeMode = Vintasoft.Imaging.UI.ImageSizeMode.BestFit;
            annotationViewer2.Image = new VintasoftImage("apple.jpg");
            annotationViewer2.VisualTool = new AnnotationDragAndDropTool();
        }

    }
}

You can combine work of the AdvancedDragAndDropTool (viewtopic.php?f=22&t=2195) and AnnotationDragAndDropTool classes if you need drag-and-drop an image region or annotation from one image viewer to another.
Here is C# 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());
Post Reply