|
|
|
@ -35,6 +35,10 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -35,6 +35,10 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
public sealed class DesignPanel : Decorator, IDesignPanel, INotifyPropertyChanged |
|
|
|
|
{ |
|
|
|
|
#region Hit Testing
|
|
|
|
|
|
|
|
|
|
private List<DependencyObject> hitTestElements = new List<DependencyObject>(); |
|
|
|
|
private DependencyObject lastElement; |
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// this element is always hit (unless HitTestVisible is set to false)
|
|
|
|
|
/// </summary>
|
|
|
|
@ -54,7 +58,7 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -54,7 +58,7 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
void RunHitTest(Visual reference, Point point, HitTestFilterCallback filterCallback, HitTestResultCallback resultCallback) |
|
|
|
|
{ |
|
|
|
|
VisualTreeHelper.HitTest(reference, filterCallback, resultCallback, |
|
|
|
|
new PointHitTestParameters(point)); |
|
|
|
|
new PointHitTestParameters(point)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
HitTestFilterBehavior FilterHitTestInvisibleElements(DependencyObject potentialHitTestTarget) |
|
|
|
@ -70,9 +74,10 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -70,9 +74,10 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
|
|
|
|
|
if (designItem != null && designItem.IsDesignTimeLocked) { |
|
|
|
|
return HitTestFilterBehavior.ContinueSkipSelfAndChildren; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
hitTestElements.Add(element); |
|
|
|
|
|
|
|
|
|
return HitTestFilterBehavior.Continue; |
|
|
|
|
} |
|
|
|
@ -80,14 +85,17 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -80,14 +85,17 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Performs a custom hit testing lookup for the specified mouse event args.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public DesignPanelHitTestResult HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface) |
|
|
|
|
public DesignPanelHitTestResult HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface, HitTestType hitTestType) |
|
|
|
|
{ |
|
|
|
|
hitTestElements.Clear(); |
|
|
|
|
|
|
|
|
|
DesignPanelHitTestResult result = DesignPanelHitTestResult.NoHit; |
|
|
|
|
HitTest(mousePosition, testAdorners, testDesignSurface, |
|
|
|
|
delegate(DesignPanelHitTestResult r) { |
|
|
|
|
result = r; |
|
|
|
|
return false; |
|
|
|
|
}); |
|
|
|
|
delegate(DesignPanelHitTestResult r) { |
|
|
|
|
result = r; |
|
|
|
|
return false; |
|
|
|
|
}, hitTestType); |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -95,7 +103,7 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -95,7 +103,7 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
/// Performs a hit test on the design surface, raising <paramref name="callback"/> for each match.
|
|
|
|
|
/// Hit testing continues while the callback returns true.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface, Predicate<DesignPanelHitTestResult> callback) |
|
|
|
|
public void HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface, Predicate<DesignPanelHitTestResult> callback, HitTestType hitTestType) |
|
|
|
|
{ |
|
|
|
|
if (mousePosition.X < 0 || mousePosition.Y < 0 || mousePosition.X > this.RenderSize.Width || mousePosition.Y > this.RenderSize.Height) { |
|
|
|
|
return; |
|
|
|
@ -104,6 +112,8 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -104,6 +112,8 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
|
|
|
|
|
bool continueHitTest = true; |
|
|
|
|
|
|
|
|
|
hitTestElements.Clear(); |
|
|
|
|
|
|
|
|
|
if (testAdorners) { |
|
|
|
|
RunHitTest( |
|
|
|
|
_adornerLayer, mousePosition, FilterHitTestInvisibleElements, |
|
|
|
@ -135,6 +145,19 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -135,6 +145,19 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
|
|
|
|
|
ViewService viewService = _context.Services.View; |
|
|
|
|
DependencyObject obj = result.VisualHit; |
|
|
|
|
|
|
|
|
|
if (hitTestType == HitTestType.ElementSelection) |
|
|
|
|
{ |
|
|
|
|
if (Keyboard.IsKeyDown(Key.LeftAlt)) |
|
|
|
|
if (lastElement != null && lastElement != _context.RootItem.Component && |
|
|
|
|
hitTestElements.Contains(lastElement)) |
|
|
|
|
{ |
|
|
|
|
var idx = hitTestElements.IndexOf(lastElement) - 1; |
|
|
|
|
if (idx >= 0) |
|
|
|
|
obj = hitTestElements[idx]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while (obj != null) { |
|
|
|
|
if ((customResult.ModelHit = viewService.GetModel(obj)) != null) |
|
|
|
|
break; |
|
|
|
@ -143,6 +166,13 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -143,6 +166,13 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
if (customResult.ModelHit == null) { |
|
|
|
|
customResult.ModelHit = _context.RootItem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (hitTestType == HitTestType.ElementSelection) |
|
|
|
|
{ |
|
|
|
|
lastElement = obj; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
continueHitTest = callback(customResult); |
|
|
|
|
return continueHitTest ? HitTestResultBehavior.Continue : HitTestResultBehavior.Stop; |
|
|
|
|
} else { |
|
|
|
@ -223,7 +253,7 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -223,7 +253,7 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Enables / Disables the Raster Placement
|
|
|
|
|
/// </summary>
|
|
|
|
@ -341,14 +371,14 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -341,14 +371,14 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) |
|
|
|
|
{ |
|
|
|
|
e.Handled = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (placementOp == null) { |
|
|
|
|
dx = 0; |
|
|
|
|
dy = 0; |
|
|
|
|
placementOp = PlacementOperation.Start(Context.Services.Selection.SelectedItems, PlacementType.Move); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dx += (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; |
|
|
|
|
dy += (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; |
|
|
|
|
dx += (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? 10 : 1 : 0; |
|
|
|
@ -358,18 +388,18 @@ namespace ICSharpCode.WpfDesign.Designer
@@ -358,18 +388,18 @@ namespace ICSharpCode.WpfDesign.Designer
|
|
|
|
|
if (!Keyboard.IsKeyDown(Key.LeftCtrl)) |
|
|
|
|
{ |
|
|
|
|
info.Bounds = new Rect(info.OriginalBounds.Left + dx, |
|
|
|
|
info.OriginalBounds.Top + dy, |
|
|
|
|
info.OriginalBounds.Width, |
|
|
|
|
info.OriginalBounds.Height); |
|
|
|
|
info.OriginalBounds.Top + dy, |
|
|
|
|
info.OriginalBounds.Width, |
|
|
|
|
info.OriginalBounds.Height); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
info.Bounds = new Rect(info.OriginalBounds.Left, |
|
|
|
|
info.OriginalBounds.Top, |
|
|
|
|
info.OriginalBounds.Width + dx, |
|
|
|
|
info.OriginalBounds.Height + dy); |
|
|
|
|
info.OriginalBounds.Top, |
|
|
|
|
info.OriginalBounds.Width + dx, |
|
|
|
|
info.OriginalBounds.Height + dy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
placementOp.CurrentContainerBehavior.SetPosition(info); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|