This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
gwen-dotnet/Gwen/DragDrop/DragAndDrop.cs

245 lines
8.3 KiB
C#

using System;
//using System.Drawing;
//using System.Windows.Forms;
using Gwen.Control;
using Gwen.Input;
namespace Gwen.DragDrop
{
/// <summary>
/// Drag and drop handling.
/// </summary>
public static class DragAndDrop
{
public static Package CurrentPackage;
public static Base HoveredControl;
public static Base SourceControl;
private static Base m_LastPressedControl;
private static Base m_NewHoveredControl;
private static Point m_LastPressedPos;
private static int m_MouseX;
private static int m_MouseY;
private static bool onDrop(int x, int y)
{
bool success = false;
if (HoveredControl != null)
{
HoveredControl.DragAndDrop_HoverLeave(CurrentPackage);
success = HoveredControl.DragAndDrop_HandleDrop(CurrentPackage, x, y);
}
// Report back to the source control, to tell it if we've been successful.
SourceControl.DragAndDrop_EndDragging(success, x, y);
CurrentPackage = null;
SourceControl = null;
return true;
}
private static bool ShouldStartDraggingControl( int x, int y )
{
// We're not holding a control down..
if (m_LastPressedControl == null)
return false;
// Not been dragged far enough
int length = Math.Abs(x - m_LastPressedPos.X) + Math.Abs(y - m_LastPressedPos.Y);
if (length < 5)
return false;
// Create the dragging package
CurrentPackage = m_LastPressedControl.DragAndDrop_GetPackage(m_LastPressedPos.X, m_LastPressedPos.Y);
// We didn't create a package!
if (CurrentPackage == null)
{
m_LastPressedControl = null;
SourceControl = null;
return false;
}
// Now we're dragging something!
SourceControl = m_LastPressedControl;
InputHandler.MouseFocus = null;
m_LastPressedControl = null;
CurrentPackage.DrawControl = null;
// Some controls will want to decide whether they should be dragged at that moment.
// This function is for them (it defaults to true)
if (!SourceControl.DragAndDrop_ShouldStartDrag())
{
SourceControl = null;
CurrentPackage = null;
return false;
}
SourceControl.DragAndDrop_StartDragging(CurrentPackage, m_LastPressedPos.X, m_LastPressedPos.Y);
return true;
}
private static void UpdateHoveredControl(Base control, int x, int y)
{
//
// We use this global variable to represent our hovered control
// That way, if the new hovered control gets deleted in one of the
// Hover callbacks, we won't be left with a hanging pointer.
// This isn't ideal - but it's minimal.
//
m_NewHoveredControl = control;
// Nothing to change..
if (HoveredControl == m_NewHoveredControl)
return;
// We changed - tell the old hovered control that it's no longer hovered.
if (HoveredControl != null && HoveredControl != m_NewHoveredControl)
HoveredControl.DragAndDrop_HoverLeave(CurrentPackage);
// If we're hovering where the control came from, just forget it.
// By changing it to null here we're not going to show any error cursors
// it will just do nothing if you drop it.
if (m_NewHoveredControl == SourceControl)
m_NewHoveredControl = null;
// Check to see if the new potential control can accept this type of package.
// If not, ignore it and show an error cursor.
while (m_NewHoveredControl != null && !m_NewHoveredControl.DragAndDrop_CanAcceptPackage(CurrentPackage))
{
// We can't drop on this control, so lets try to drop
// onto its parent..
m_NewHoveredControl = m_NewHoveredControl.Parent;
// Its parents are dead. We can't drop it here.
// Show the NO WAY cursor.
if (m_NewHoveredControl == null)
{
//Platform.Neutral.SetCursor(Cursors.No);
}
}
// Become out new hovered control
HoveredControl = m_NewHoveredControl;
// If we exist, tell us that we've started hovering.
if (HoveredControl != null)
{
HoveredControl.DragAndDrop_HoverEnter(CurrentPackage, x, y);
}
m_NewHoveredControl = null;
}
public static bool Start(Base control, Package package)
{
if (CurrentPackage != null)
{
return false;
}
CurrentPackage = package;
SourceControl = control;
return true;
}
public static bool OnMouseButton(Base hoveredControl, int x, int y, bool down)
{
if (!down)
{
m_LastPressedControl = null;
// Not carrying anything, allow normal actions
if (CurrentPackage == null)
return false;
// We were carrying something, drop it.
onDrop(x, y);
return true;
}
if (hoveredControl == null)
return false;
if (!hoveredControl.DragAndDrop_Draggable())
return false;
// Store the last clicked on control. Don't do anything yet,
// we'll check it in OnMouseMoved, and if it moves further than
// x pixels with the mouse down, we'll start to drag.
m_LastPressedPos = new Point(x, y);
m_LastPressedControl = hoveredControl;
return false;
}
public static void OnMouseMoved(Base hoveredControl, int x, int y)
{
// Always keep these up to date, they're used to draw the dragged control.
m_MouseX = x;
m_MouseY = y;
// If we're not carrying anything, then check to see if we should
// pick up from a control that we're holding down. If not, then forget it.
if (CurrentPackage == null && !ShouldStartDraggingControl(x, y))
return;
// Swap to this new hovered control and notify them of the change.
UpdateHoveredControl(hoveredControl, x, y);
if (HoveredControl == null)
return;
// Update the hovered control every mouse move, so it can show where
// the dropped control will land etc..
HoveredControl.DragAndDrop_Hover(CurrentPackage, x, y);
// Override the cursor - since it might have been set my underlying controls
// Ideally this would show the 'being dragged' control. TODO
//Platform.Neutral.SetCursor(Cursors.Default);
hoveredControl.Redraw();
}
public static void RenderOverlay(Canvas canvas, Skin.Base skin)
{
if (CurrentPackage == null)
return;
if (CurrentPackage.DrawControl == null)
return;
Point old = skin.Renderer.RenderOffset;
skin.Renderer.AddRenderOffset(new Rectangle(
m_MouseX - SourceControl.X - CurrentPackage.HoldOffset.X,
m_MouseY - SourceControl.Y - CurrentPackage.HoldOffset.Y, 0, 0));
CurrentPackage.DrawControl.DoRender(skin);
skin.Renderer.RenderOffset = old;
}
public static void ControlDeleted(Base control)
{
if (SourceControl == control)
{
SourceControl = null;
CurrentPackage = null;
HoveredControl = null;
m_LastPressedControl = null;
}
if (m_LastPressedControl == control)
m_LastPressedControl = null;
if (HoveredControl == control)
HoveredControl = null;
if (m_NewHoveredControl == control)
m_NewHoveredControl = null;
}
}
}