From aa59343fa8160ad73544da1c432923aef7310739 Mon Sep 17 00:00:00 2001 From: tbulle Date: Wed, 6 Aug 2014 14:22:45 +0200 Subject: [PATCH] changed implementation of PanelSelectionHandler so that custom panelselectionhandlers can inherit that class if they are built in the same project. Also added a Partial Selectionhandler that selects objects that are partially selected if both mousebuttons are pressed. PartialPanelSelectionHandler is activated by adding a custom extension in your project like this: [ExtensionFor(typeof(Panel), OverrideExtension = typeof(PanelSelectionHandler))] public class CustomPartialPanelSelectionHandler : PartialPanelSelectionHandler { } --- .../Extensions/PanelSelectionHandler.cs | 15 ++- .../PartialPanelSelectionHandler.cs | 108 ++++++++++++++++++ .../Project/WpfDesign.Designer.csproj | 1 + 3 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PartialPanelSelectionHandler.cs diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs index ddd3bb9d0b..3dce10d8ee 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs @@ -52,13 +52,13 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } - sealed class RangeSelectionGesture : ClickOrDragMouseGesture + internal class RangeSelectionGesture : ClickOrDragMouseGesture { - DesignItem container; - AdornerPanel adornerPanel; - SelectionFrame selectionFrame; + protected DesignItem container; + protected AdornerPanel adornerPanel; + protected SelectionFrame selectionFrame; - GrayOutDesignerExceptActiveArea grayOut; + protected GrayOutDesignerExceptActiveArea grayOut; public RangeSelectionGesture(DesignItem container) { @@ -100,7 +100,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions Math.Abs(startPoint.Y - endPoint.Y) ); - ICollection items = GetChildDesignItemsInContainer(container, new RectangleGeometry(frameRect)); + ICollection items = GetChildDesignItemsInContainer(new RectangleGeometry(frameRect)); if (items.Count == 0) { items.Add(container); } @@ -109,8 +109,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions Stop(); } - static ICollection GetChildDesignItemsInContainer( - DesignItem container, Geometry geometry) + protected virtual ICollection GetChildDesignItemsInContainer(Geometry geometry) { HashSet resultItems = new HashSet(); ViewService viewService = container.Services.View; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PartialPanelSelectionHandler.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PartialPanelSelectionHandler.cs new file mode 100644 index 0000000000..26159e559d --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PartialPanelSelectionHandler.cs @@ -0,0 +1,108 @@ +/* + * Created by SharpDevelop. + * User: trubra + * Date: 2014-08-06 + * Time: 14:13 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Collections.Generic; +using System.Diagnostics; +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 +{ + public class PartialPanelSelectionHandler : BehaviorExtension, IHandlePointerToolMouseDown + { + protected override void OnInitialized() + { + base.OnInitialized(); + this.ExtendedItem.AddBehavior(typeof(IHandlePointerToolMouseDown), this); + } + + public new void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result) + { + if (e.ChangedButton == MouseButton.Left && MouseGestureBase.IsOnlyButtonPressed(e, MouseButton.Left)) + { + e.Handled = true; + new PartialRangeSelectionGesture(result.ModelHit).Start(designPanel, e); + } + } + } + + /// + /// + /// + internal class PartialRangeSelectionGesture : RangeSelectionGesture + { + public PartialRangeSelectionGesture(DesignItem container) + : base(container) + { + } + + protected override ICollection GetChildDesignItemsInContainer(Geometry geometry) + { + HashSet resultItems = new HashSet(); + 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 || (Mouse.RightButton== MouseButtonState.Pressed && ((GeometryHitTestResult)result).IntersectionDetail == IntersectionDetail.Intersects)) + { + // 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; + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index ee6c301f7f..8f016aaea9 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -84,6 +84,7 @@ Configuration\GlobalAssemblyInfo.cs + RightClickContextMenu.xaml Code