Skip to content

Commit

Permalink
(GH-330) Fix for: Effect adorner gets clipped at the window edges
Browse files Browse the repository at this point in the history
The position of the Effect adorner will now be recalculated so that it be always visible inside the main root element.
  • Loading branch information
punker76 committed Sep 10, 2019
1 parent ee5f520 commit 60602cc
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 47 deletions.
55 changes: 52 additions & 3 deletions src/GongSolutions.WPF.DragDrop/DragAdorner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ internal class DragAdorner : Adorner
public DragAdorner(UIElement adornedElement, UIElement adornment, Point translation, DragDropEffects effects = DragDropEffects.None)
: base(adornedElement)
{
this._translation = translation;
this.Translation = translation;
this.m_AdornerLayer = AdornerLayer.GetAdornerLayer(adornedElement);
this.m_AdornerLayer.Add(this);
this.m_Adornment = adornment;
this.IsHitTestVisible = false;
this.Effects = effects;
}

public Point Translation { get; private set; }

public DragDropEffects Effects { get; private set; }

public Point MousePosition
Expand Down Expand Up @@ -47,11 +49,59 @@ public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
var result = new GeneralTransformGroup();
result.Children.Add(base.GetDesiredTransform(transform));
result.Children.Add(new TranslateTransform(this.MousePosition.X + this._translation.X, this.MousePosition.Y + this._translation.Y));
result.Children.Add(new TranslateTransform(this.MousePosition.X + this.Translation.X, this.MousePosition.Y + this.Translation.Y));

return result;
}

internal void Move(Point newAdornerPosition, Point anchorPoint, ref Point adornerMousePosition, ref Size adornerSize)
{
if (newAdornerPosition.X >= 0 && newAdornerPosition.Y >= 0)
{
adornerMousePosition = newAdornerPosition;
}

if (this.RenderSize.Width > 0 && this.RenderSize.Height > 0)
{
adornerSize = this.RenderSize;
}

var offsetX = adornerSize.Width * -anchorPoint.X;
var offsetY = adornerSize.Height * -anchorPoint.Y;
adornerMousePosition.Offset(offsetX, offsetY);

if (adornerMousePosition.X < 0)
{
adornerMousePosition.X = 0;
}
else
{
var maxAdornerPosX = this.AdornedElement.RenderSize.Width;
var adornerPosRightX = (adornerMousePosition.X + this.Translation.X + adornerSize.Width);
if (adornerPosRightX > maxAdornerPosX)
{
adornerMousePosition.Offset(-adornerPosRightX + maxAdornerPosX, 0);
}
}

if (adornerMousePosition.Y < 0)
{
adornerMousePosition.Y = 0;
}
else
{
var maxAdornerPosY = this.AdornedElement.RenderSize.Height;
var adornerPosRightY = (adornerMousePosition.Y + this.Translation.Y + adornerSize.Height);
if (adornerPosRightY > maxAdornerPosY)
{
adornerMousePosition.Offset(0, -adornerPosRightY + maxAdornerPosY);
}
}

this.MousePosition = adornerMousePosition;
this.InvalidateVisual();
}

protected override Visual GetVisualChild(int index)
{
return this.m_Adornment;
Expand All @@ -71,6 +121,5 @@ protected override int VisualChildrenCount
private readonly AdornerLayer m_AdornerLayer;
private readonly UIElement m_Adornment;
private Point m_MousePosition;
private Point _translation;
}
}
51 changes: 7 additions & 44 deletions src/GongSolutions.WPF.DragDrop/DragDrop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,42 +524,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy
CreateDragAdorner(dropInfo);
}

if (DragAdorner != null)
{
var tempAdornerPos = e.GetPosition(DragAdorner.AdornedElement);

if (tempAdornerPos.X >= 0 && tempAdornerPos.Y >= 0)
{
_adornerPos = tempAdornerPos;
}

// Fixed the flickering adorner - Size changes to zero 'randomly'...?
if (DragAdorner.RenderSize.Width > 0 && DragAdorner.RenderSize.Height > 0)
{
_adornerSize = DragAdorner.RenderSize;
}

if (dragInfo != null)
{
// move the adorner
var offsetX = _adornerSize.Width * -GetDragMouseAnchorPoint(dragInfo.VisualSource).X;
var offsetY = _adornerSize.Height * -GetDragMouseAnchorPoint(dragInfo.VisualSource).Y;
_adornerPos.Offset(offsetX, offsetY);
var maxAdornerPosX = DragAdorner.AdornedElement.RenderSize.Width;
var adornerPosRightX = (_adornerPos.X + _adornerSize.Width);
if (adornerPosRightX > maxAdornerPosX)
{
_adornerPos.Offset(-adornerPosRightX + maxAdornerPosX, 0);
}
if (_adornerPos.Y < 0)
{
_adornerPos.Y = 0;
}
}

DragAdorner.MousePosition = _adornerPos;
DragAdorner.InvalidateVisual();
}
DragAdorner?.Move(e.GetPosition(DragAdorner.AdornedElement), dragInfo != null ? GetDragMouseAnchorPoint(dragInfo.VisualSource) : default(Point), ref _adornerMousePosition, ref _adornerSize);

Scroll(dropInfo, e);

Expand Down Expand Up @@ -623,13 +588,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy
CreateEffectAdorner(dropInfo);
}

if (EffectAdorner != null)
{
var adornerPos = e.GetPosition(EffectAdorner.AdornedElement);
//adornerPos.Offset(20, 20);
EffectAdorner.MousePosition = adornerPos;
EffectAdorner.InvalidateVisual();
}
EffectAdorner?.Move(e.GetPosition(EffectAdorner.AdornedElement), default(Point), ref _effectAdornerMousePosition, ref _effectAdornerSize);

e.Effects = dropInfo.Effects;
e.Handled = !dropInfo.NotHandled;
Expand Down Expand Up @@ -732,7 +691,11 @@ private static DropTargetAdorner DropTargetAdorner
private static DragInfo m_DragInfo;
private static bool m_DragInProgress;
private static object m_ClickSupressItem;
private static Point _adornerPos;

private static Point _adornerMousePosition;
private static Size _adornerSize;

private static Point _effectAdornerMousePosition;
private static Size _effectAdornerSize;
}
}

0 comments on commit 60602cc

Please sign in to comment.