using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Nevron.Dom;
using Nevron.GraphicsCore;
using Nevron.Diagram.Filters;
using Nevron.Diagram.Batches;
namespace Nevron.Diagram.WinForm
{
///
/// The NDragDropTargetTool class represents a tool,
/// which is used to extend the drawing view as a drag drop target
///
[Serializable]
public class NDragDropTargetTool : NDrawingDragDropTool
{
#region Constructors
///
/// Default constructor
///
public NDragDropTargetTool()
: base(NDWFR.ToolDragDropTarget)
{
}
#endregion
#region Interface implementations
#region INDragDropEventProcessor
///
/// Processes the drag over event
///
///
/// If the mouse left the view window this method will destroy the preview.
/// Otherwise it will create it (if not created) and translate it.
/// Then it will update the drag drop effect
///
///
/// true if the event was processed, otherwise false
public override bool ProcessDragOver(DragEventArgs e)
{
// start/end move preview
if (m_View.Window.Contains(m_View.GetMousePositionInDevice()) == false)
{
if (IsPreviewCreated)
{
EndMove(false);
}
}
else
{
if (IsPreviewCreated == false)
{
StartMove(e.Data);
}
Move();
}
m_View.SmartRefresh();
// update effect
if (m_Document.ActiveLayer == null)
return false;
if (m_Document.DataObjectAdaptors.GetAdaptorForDataObject(e.Data) == null)
return false;
// if the allowed effect is only move or copy -> use it
if (e.AllowedEffect == DragDropEffects.Move || e.AllowedEffect == DragDropEffects.Copy)
{
e.Effect = e.AllowedEffect;
return true;
}
// SHIFT KeyState for move.
if ((e.KeyState & 4) == 4 && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
{
e.Effect = DragDropEffects.Move;
return true;
}
// CTL KeyState for copy.
if ((e.KeyState & 8) == 8 && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
{
e.Effect = DragDropEffects.Copy;
return true;
}
// By default, the drop action should be move, if allowed.
if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
{
e.Effect = DragDropEffects.Move;
return true;
}
return false;
}
///
/// Processes the drag leave event
///
///
/// Overriden to destroy the possibly created data object preview
///
///
/// true if the event was processed, otherwise false
public override bool ProcessDragLeave(EventArgs e)
{
EndMove(false);
return false;
}
///
/// Processes the drag drop event
///
///
/// Overriden to the drag drop data object in the document active layer
///
///
/// true if the event was processed, otherwise false
public override bool ProcessDragDrop(DragEventArgs e)
{
if (e.Effect != DragDropEffects.Copy && e.Effect != DragDropEffects.Move)
{
EndMove(false);
return false;
}
m_Document.StartTransaction(NDR.TransactionDropElements);
try
{
EndMove(true);
}
catch (Exception ex)
{
Trace.WriteLine("Failed to drop. Exception was: " + ex.Message);
m_Document.Rollback();
return false;
}
m_Document.Commit();
m_Document.SmartRefreshAllViews();
return true;
}
#endregion
#endregion
#region Protected overridable
///
/// Starts to move a preview of the objects contained in the specified data object
///
///
protected virtual void StartMove(IDataObject dataObject)
{
try
{
// get a drawing data object
NDataObjectAdaptor adapter = m_Document.DataObjectAdaptors.GetAdaptorForDataObject(dataObject);
NDrawingDataObject ddo = (adapter.Adapt(dataObject) as NDrawingDataObject);
// save the adapted connections for end move
m_Connections = ddo.Connections;
// create a move preview for the drawing data objects elements
// which can be moved anyware in the drawing
NDrawingMovePreview movePreview = m_View.m_PreviewManager.StartMovePreview(new NNodeList(ddo.Elements));
movePreview.DiscardMovePermissions = true;
}
catch (Exception ex)
{
Trace.WriteLine("Failed to create drag drop data preview. Exception was: " + ex.Message);
}
}
///
/// Moves the preview
///
///
protected virtual bool Move()
{
NPointF center = m_View.m_PreviewManager.m_Preview.m_StartBounds.Center;
NPointF mouseScene = m_View.GetMousePositionInScene();
float transX = mouseScene.X - center.X;
float transY = mouseScene.Y - center.Y;
return m_View.m_PreviewManager.MovePreview(transX, transY);
}
///
/// Ends the preview move and optionally commits the result
///
///
protected virtual void EndMove(bool commit)
{
NDrawingPreviewManager manager = m_View.m_PreviewManager;
if (manager.m_Preview == null)
return;
// if the preview effect is not to be commited
// -> simply destroy the preview
if (commit == false)
{
manager.EndMovePreview(false, false);
return;
}
// otherwise add the previed elements in the document
m_Document.StartTransaction(NDR.TransactionDropElements);
try
{
// inject the connections stored in start mode
// and commit - dublicate the move result
manager.Preview.Connections = m_Connections;
NNodeList elements = manager.EndMovePreview(true, true);
// single select the inserted elements
if (elements != null)
{
m_View.Selection.SingleSelect(elements);
}
// focus the view
m_View.Focus();
}
catch (Exception ex)
{
Trace.WriteLine("Failed to drop. Exception was: " + ex.Message);
m_Document.Rollback();
return;
}
m_Document.Commit();
m_Document.SmartRefreshAllViews();
}
///
/// Determines whether the preview is created
///
protected virtual bool IsPreviewCreated
{
get
{
return m_View.m_PreviewManager.m_Preview != null;
}
}
#endregion
#region Fields
internal NConnectionCollection m_Connections;
#endregion
}
}