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 } }