Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2414 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
13 changed files with 305 additions and 46 deletions
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// Gray out everything except a specific area.
|
||||
/// </summary>
|
||||
sealed class GrayOutDesignerExceptActiveArea : FrameworkElement |
||||
{ |
||||
//Geometry infiniteRectangle = new RectangleGeometry(new Rect(0, 0, double.PositiveInfinity, double.PositiveInfinity));
|
||||
Geometry infiniteRectangle = new RectangleGeometry(new Rect(0, 0, 10000, 10000)); |
||||
Geometry activeAreaGeometry; |
||||
Geometry combinedGeometry; |
||||
Brush grayOutBrush; |
||||
|
||||
public GrayOutDesignerExceptActiveArea() |
||||
{ |
||||
Color c = SystemColors.GrayTextColor; |
||||
c.R = (byte)Math.Max(0, c.R - 20); |
||||
c.G = (byte)Math.Max(0, c.G - 20); |
||||
c.B = (byte)Math.Max(0, c.B - 20); |
||||
c.A = 30; |
||||
this.GrayOutBrush = new SolidColorBrush(c); |
||||
} |
||||
|
||||
public Brush GrayOutBrush { |
||||
get { return grayOutBrush; } |
||||
set { grayOutBrush = value; } |
||||
} |
||||
|
||||
public Geometry ActiveAreaGeometry { |
||||
get { return activeAreaGeometry; } |
||||
set { |
||||
activeAreaGeometry = value; |
||||
combinedGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, infiniteRectangle, activeAreaGeometry); |
||||
} |
||||
} |
||||
|
||||
public void SetActiveArea(UIElement activeContainer) |
||||
{ |
||||
this.ActiveAreaGeometry = new RectangleGeometry(new Rect(activeContainer.RenderSize), 0, 0, (Transform)activeContainer.TransformToVisual(this)); |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry); |
||||
} |
||||
|
||||
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, IDesignPanel designPanel, UIElement activeContainer) |
||||
{ |
||||
if (designPanel != null) { |
||||
grayOut = new GrayOutDesignerExceptActiveArea(); |
||||
designPanel.MarkerCanvas.Children.Add(grayOut); |
||||
grayOut.SetActiveArea(activeContainer); |
||||
} |
||||
} |
||||
|
||||
internal static void Stop(ref GrayOutDesignerExceptActiveArea grayOut, IDesignPanel designPanel) |
||||
{ |
||||
if (grayOut != null) { |
||||
designPanel.MarkerCanvas.Children.Remove(grayOut); |
||||
grayOut = null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,162 @@
@@ -0,0 +1,162 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
|
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
using ICSharpCode.WpfDesign.Designer.Services; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Handles selection multiple controls inside a Panel.
|
||||
/// </summary>
|
||||
[ExtensionFor(typeof(Panel))] |
||||
public class PanelSelectionHandler : BehaviorExtension, IHandlePointerToolMouseDown |
||||
{ |
||||
/// <inherit/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
this.ExtendedItem.AddBehavior(typeof(IHandlePointerToolMouseDown), this); |
||||
} |
||||
|
||||
/// <inherit/>
|
||||
public void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result) |
||||
{ |
||||
new RangeSelectionGesture(result.ModelHit).Start(designPanel, e); |
||||
} |
||||
} |
||||
|
||||
sealed class RangeSelectionGesture : MouseGestureBase |
||||
{ |
||||
DesignItem container; |
||||
AdornerPanel adornerPanel; |
||||
DragFrame selectionFrame; |
||||
Point startPoint; |
||||
GrayOutDesignerExceptActiveArea grayOut; |
||||
|
||||
public RangeSelectionGesture(DesignItem container) |
||||
{ |
||||
this.container = container; |
||||
} |
||||
|
||||
protected override void OnStarted(MouseButtonEventArgs e) |
||||
{ |
||||
startPoint = e.GetPosition(container.View); |
||||
|
||||
adornerPanel = new AdornerPanel(); |
||||
adornerPanel.SetAdornedElement(container.View, container); |
||||
|
||||
selectionFrame = new DragFrame(); |
||||
SetPlacement(e.GetPosition(container.View)); |
||||
adornerPanel.Children.Add(selectionFrame); |
||||
|
||||
designPanel.Adorners.Add(adornerPanel); |
||||
|
||||
GrayOutDesignerExceptActiveArea.Start(ref grayOut, designPanel, container.View); |
||||
} |
||||
|
||||
protected override void OnMouseMove(object sender, MouseEventArgs e) |
||||
{ |
||||
SetPlacement(e.GetPosition(container.View)); |
||||
} |
||||
|
||||
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) |
||||
{ |
||||
Point endPoint = e.GetPosition(container.View); |
||||
Rect frameRect = new Rect( |
||||
Math.Min(startPoint.X, endPoint.X), |
||||
Math.Min(startPoint.Y, endPoint.Y), |
||||
Math.Abs(startPoint.X - endPoint.X), |
||||
Math.Abs(startPoint.Y - endPoint.Y) |
||||
); |
||||
|
||||
ICollection<DesignItem> items = GetChildDesignItemsInContainer(container, new RectangleGeometry(frameRect)); |
||||
if (items.Count == 0) { |
||||
items.Add(container); |
||||
} |
||||
services.Selection.SetSelectedComponents(items, SelectionTypes.Auto); |
||||
Stop(); |
||||
} |
||||
|
||||
static ICollection<DesignItem> GetChildDesignItemsInContainer( |
||||
DesignItem container, Geometry geometry) |
||||
{ |
||||
HashSet<DesignItem> resultItems = new HashSet<DesignItem>(); |
||||
ViewService viewService = container.Services.View; |
||||
|
||||
HitTestFilterCallback filterCallback = delegate(DependencyObject potentialHitTestTarget) { |
||||
FrameworkElement element = potentialHitTestTarget as FrameworkElement; |
||||
if (element != null) { |
||||
// ensure we are able to select elements with width/height=0
|
||||
if (element.ActualWidth == 0 || element.ActualHeight == 0) { |
||||
DependencyObject tmp = element; |
||||
DesignItem model = null; |
||||
while (tmp != null) { |
||||
model = viewService.GetModel(tmp); |
||||
if (model != null) break; |
||||
tmp = VisualTreeHelper.GetParent(tmp); |
||||
} |
||||
if (model != container) { |
||||
resultItems.Add(model); |
||||
return HitTestFilterBehavior.ContinueSkipChildren; |
||||
} |
||||
} |
||||
} |
||||
return HitTestFilterBehavior.Continue; |
||||
}; |
||||
|
||||
HitTestResultCallback resultCallback = delegate(HitTestResult result) { |
||||
if (((GeometryHitTestResult) result).IntersectionDetail == IntersectionDetail.FullyInside) { |
||||
// find the model for the visual contained in the selection area
|
||||
DependencyObject tmp = result.VisualHit; |
||||
DesignItem model = null; |
||||
while (tmp != null) { |
||||
model = viewService.GetModel(tmp); |
||||
if (model != null) break; |
||||
tmp = VisualTreeHelper.GetParent(tmp); |
||||
} |
||||
if (model != container) { |
||||
resultItems.Add(model); |
||||
} |
||||
} |
||||
return HitTestResultBehavior.Continue; |
||||
}; |
||||
|
||||
VisualTreeHelper.HitTest(container.View, filterCallback, resultCallback, new GeometryHitTestParameters(geometry)); |
||||
return resultItems; |
||||
} |
||||
|
||||
void SetPlacement(Point endPoint) |
||||
{ |
||||
RelativePlacement p = new RelativePlacement(); |
||||
p.XOffset = Math.Min(startPoint.X, endPoint.X); |
||||
p.YOffset = Math.Min(startPoint.Y, endPoint.Y); |
||||
p.WidthOffset = Math.Max(startPoint.X, endPoint.X) - p.XOffset; |
||||
p.HeightOffset = Math.Max(startPoint.Y, endPoint.Y) - p.YOffset; |
||||
AdornerPanel.SetPlacement(selectionFrame, p); |
||||
} |
||||
|
||||
protected override void OnStopped() |
||||
{ |
||||
if (adornerPanel != null) { |
||||
designPanel.Adorners.Remove(adornerPanel); |
||||
adornerPanel = null; |
||||
} |
||||
GrayOutDesignerExceptActiveArea.Stop(ref grayOut, designPanel); |
||||
selectionFrame = null; |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue