protected override Size ArrangeOverride(Size finalSize) { double height = 0; double width = 0; for (int i = 0; i < Children.Count; i++) { Point pt = new Point(0, 0); Size size = Children[i].DesiredSize; if (Children[i].GetType() == typeof(Connector)) { ((UIElement)Children[i]).Arrange(new Rect(pt, size)); } else { pt = FreeFormPanel.GetLocation(Children[i]); ((UIElement)Children[i]).Arrange(new Rect(pt, size)); } if (width < (size.Width + pt.X)) { width = size.Width + pt.X; } if (height < (size.Height + pt.Y)) { height = size.Height + pt.Y; } } width = (width < this.MinWidth) ? this.MinWidth : width; width = (width < this.Width) ? (this.Width < Double.MaxValue ? this.Width : width) : width; height = (height < this.MinHeight) ? this.MinHeight : height; height = (height < this.Height) ? (this.Height < Double.MaxValue ? this.Height : height) : height; return(new Size(width, height)); }
//The Connector editor is to be destroyed. Remove the adorners on the editor. activeEditPoint=null sets BeingEdited property to false. public void Remove() { this.activeEditPoint = null; RemoveAdorners(); this.EditPoints.Clear(); this.Connector.IsSelected = false; // Restore the IsHitTestVisible property this.SetIsHitTestVisibleForOverlappingStartDots(true); this.Connector = null; this.parentPanel = null; }
public static Point CalculateDropLocation(Point mousePosition, Point originalDropLocation, Connector connector, Size droppedSize, HashSet <Point> shapeLocations) { UIElement srcShape = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner; UIElement destShape = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner; Point srcLocation = FreeFormPanel.GetLocation(srcShape); Point destLocation = FreeFormPanel.GetLocation(destShape); Size srcSize = FreeFormPanel.GetChildSize(srcShape); Size destSize = FreeFormPanel.GetChildSize(destShape); return(CalculateDropLocation(mousePosition, originalDropLocation, droppedSize, srcLocation, destLocation, srcSize, destSize, shapeLocations)); }
void SetIsHitTestVisibleForOverlappingStartDots(bool hitTestVisible) { ConnectionPoint srcConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(this.Connector); foreach (Connector overlappingConnector in srcConnectionPoint.AttachedConnectors) { if (overlappingConnector.StartDot != null) { overlappingConnector.StartDot.IsHitTestVisible = hitTestVisible; } } }
internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, List <ConnectionPoint> connectionPoints, FreeFormPanel panel) { ConnectionPoint hitConnectionPoint = null; FreeFormPanel outmost = panel.GetOutmostPanel(); foreach (ConnectionPoint connPoint in connectionPoints) { if (connPoint != null && connPoint.IsEnabled) { if (new Rect(panel.TranslatePoint(connPoint.Location, outmost) + connPoint.HitTestOffset, connPoint.HitTestSize).Contains(hitPoint)) { hitConnectionPoint = connPoint; break; } } } return(hitConnectionPoint); }
public ConnectorEditor(FreeFormPanel panel, Connector connector) { if (panel == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("panel")); } if (connector == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("connector")); } this.editPoints = new List<EditPoint>(); this.parentPanel = panel; this.editedConnector = connector; this.activeEditPoint = null; connector.IsSelected = true; // When the ConnectorEditor is active, we allow reconnecting the start point of the Connector instead // of creating a new transition that shares the same trigger. So we need to disable tooltips and // highlighting effects for all overlapping start dots. this.SetIsHitTestVisibleForOverlappingStartDots(false); DisplayEditPoints(); }
public ConnectorEditor(FreeFormPanel panel, Connector connector) { if (panel == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("panel")); } if (connector == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("connector")); } this.editPoints = new List <EditPoint>(); this.parentPanel = panel; this.editedConnector = connector; this.activeEditPoint = null; connector.IsSelected = true; // When the ConnectorEditor is active, we allow reconnecting the start point of the Connector instead // of creating a new transition that shares the same trigger. So we need to disable tooltips and // highlighting effects for all overlapping start dots. this.SetIsHitTestVisibleForOverlappingStartDots(false); DisplayEditPoints(); }
public static void CalculateEntryExitEdges(Point mousePosition, Connector connector, out EdgeLocation entryEdge, out EdgeLocation exitEdge) { UIElement srcShape = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner; UIElement destShape = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner; Point srcLocation = FreeFormPanel.GetLocation(srcShape); Point destLocation = FreeFormPanel.GetLocation(destShape); Size srcSize = FreeFormPanel.GetChildSize(srcShape); Size destSize = FreeFormPanel.GetChildSize(destShape); Point srcCenter = new Point(srcLocation.X + (srcSize.Width / 2), srcLocation.Y + (srcSize.Height / 2)); Point destCenter = new Point(destLocation.X + (destSize.Width / 2), destLocation.Y + (destSize.Height / 2)); entryEdge = CalculateEdgeLocation(mousePosition, srcCenter); exitEdge = CalculateEdgeLocation(mousePosition, destCenter); if (exitEdge == entryEdge) { switch (entryEdge) { case EdgeLocation.Top: exitEdge = EdgeLocation.Bottom; break; case EdgeLocation.Bottom: exitEdge = EdgeLocation.Top; break; case EdgeLocation.Left: exitEdge = EdgeLocation.Right; break; case EdgeLocation.Right: exitEdge = EdgeLocation.Left; break; } } }
void OnFreeFormPanelLoaded(object sender, RoutedEventArgs eventArgs) { //Adding the following check because of 137896: Inside tab control multiple Loaded events happen without an Unloaded event. if (this.panel != null) { CleanupFlowchart(); } this.panel = (FreeFormPanel)sender; if (this.ShowExpanded) { PopulateFlowchartChildren(); } }
//Unregister all events. Reset startNodeAdded to enable reuse of the designer. void CleanupFlowchart() { this.startNodeAdded = false; this.panel.Children.Clear(); this.flowNodeToUIElement.Clear(); // Cleaning up the designers as they might be re-used. foreach (UIElement element in this.modelElement.Values) { element.MouseEnter -= new MouseEventHandler(ChildElement_MouseEnter); element.MouseLeave -= new MouseEventHandler(ChildElement_MouseLeave); } this.panel.LocationChanged -= new LocationChangedEventHandler(OnFreeFormPanelLocationChanged); this.panel.ConnectorMoved -= new ConnectorMovedEventHandler(OnFreeFormPanelConnectorMoved); this.panel.LayoutUpdated -= new EventHandler(OnFreeFormPanelLayoutUpdated); this.panel.RequiredSizeChanged -= new RequiredSizeChangedEventHandler(OnFreeFormPanelRequiredSizeChanged); this.panel = null; ModelTreeManager modelTreeManager = (this.ModelItem as IModelTreeItem).ModelTreeManager; modelTreeManager.EditingScopeCompleted -= new EventHandler<EditingScopeEventArgs>(ModelTreeManager_EditingScopeCompleted); this.ViewStateService.ViewStateChanged -= new ViewStateChangedEventHandler(OnViewStateChanged); }
public AutoConnectHelper(FreeFormPanel panel) { this.panel = panel; }
internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, List<ConnectionPoint> connectionPoints, FreeFormPanel panel) { ConnectionPoint hitConnectionPoint = null; FreeFormPanel outmost = panel.GetOutmostPanel(); foreach (ConnectionPoint connPoint in connectionPoints) { if (connPoint != null && connPoint.IsEnabled) { if (new Rect(panel.TranslatePoint(connPoint.Location, outmost) + connPoint.HitTestOffset, connPoint.HitTestSize).Contains(hitPoint)) { hitConnectionPoint = connPoint; break; } } } return hitConnectionPoint; }
public AutoConnectAdorner(UIElement adornedElement, FreeFormPanel panel, AutoConnectDirections directions) : base(adornedElement) { this.panel = panel; this.directions = directions; Size size = FreeFormPanel.GetChildSize(this.AdornedElement); this.adornedElementRect = new Rect(new Point(0, 0), size); this.hitTestRects = new Rect[] { new Rect(-HitTestHeight, (size.Height / 2) - (HitTestWidth / 2), HitTestHeight, HitTestWidth), new Rect(size.Width, (size.Height / 2) - (HitTestWidth / 2), HitTestHeight, HitTestWidth), new Rect((size.Width / 2) - (HitTestWidth / 2), -HitTestHeight, HitTestWidth, HitTestHeight), new Rect((size.Width / 2) - (HitTestWidth / 2), size.Height, HitTestWidth, HitTestHeight) }; this.renderGeometries = new PathGeometry[] { new PathGeometry() { Figures = { new PathFigure() { StartPoint = new Point(-DropTargetOffset - TriangleHeight, size.Height / 2), Segments = { new LineSegment() { Point = new Point(-DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)) }, new LineSegment() { Point = new Point(-DropTargetOffset, (size.Height / 2) + (TriangleBaseLength / 2)) }, new LineSegment() { Point = new Point(-DropTargetOffset - TriangleHeight, size.Height / 2) } } } } }, new PathGeometry() { Figures = { new PathFigure() { StartPoint = new Point(size.Width + DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)), Segments = { new LineSegment() { Point = new Point(size.Width + DropTargetOffset + TriangleHeight, size.Height / 2) }, new LineSegment() { Point = new Point(size.Width + DropTargetOffset, (size.Height / 2) + (TriangleBaseLength / 2)) }, new LineSegment() { Point = new Point(size.Width + DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)) } } } } }, new PathGeometry() { Figures = { new PathFigure() { StartPoint = new Point((size.Width / 2) - (TriangleBaseLength / 2), -DropTargetOffset), Segments = { new LineSegment() { Point = new Point((size.Width / 2), -DropTargetOffset - TriangleHeight) }, new LineSegment() { Point = new Point((size.Width / 2) + (TriangleBaseLength / 2), -DropTargetOffset) }, new LineSegment() { Point = new Point((size.Width / 2) - (TriangleBaseLength / 2), -DropTargetOffset) } } } } }, new PathGeometry() { Figures = { new PathFigure() { StartPoint = new Point((size.Width / 2) - (TriangleBaseLength / 2), size.Height + DropTargetOffset), Segments = { new LineSegment() { Point = new Point((size.Width / 2) + (TriangleBaseLength / 2), size.Height + DropTargetOffset) }, new LineSegment() { Point = new Point((size.Width / 2), size.Height + TriangleHeight + DropTargetOffset) }, new LineSegment() { Point = new Point((size.Width / 2) - (TriangleBaseLength / 2), size.Height + DropTargetOffset) } } } } } }; }
internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, ConnectionPointsAdorner adorner) { FreeFormPanel panel = VisualTreeUtils.FindVisualAncestor <FreeFormPanel>(adorner.AdornedElement); return(ConnectionPointHitTest(hitPoint, adorner.ConnectionPoints, panel)); }
void UpdateEditPoints(Point newPoint) { if (this.editPoints.Count < 2 || this.editPoints[0].Type != EditPoint.EditPointTypes.ConnectionEditPoint || this.editPoints[this.editPoints.Count - 1].Type != EditPoint.EditPointTypes.ConnectionEditPoint) { Fx.Assert(false, "EditPoints are invalid"); return; } if (this.activeEditPoint != null) { int activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); EditPoint previous = (activeEditPointIndex > 0) ? this.editPoints[activeEditPointIndex - 1] : null; EditPoint next = (activeEditPointIndex < this.editPoints.Count - 1) ? this.editPoints[activeEditPointIndex + 1] : null; //Note that extra edit points are only added if we are connected to connection point if (previous != null && previous.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints(previous.Location, (next != null) ? next.Location : this.activeEditPoint.Location)) / 4; if (orientation == Orientation.Horizontal) { editPointOffset *= (previous.Location.X < this.activeEditPoint.Location.X) ? 1 : -1; } else { editPointOffset *= (previous.Location.Y < this.activeEditPoint.Location.Y) ? 1 : -1; } activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X + editPointOffset, previous.Location.Y) : new Point(previous.Location.X, previous.Location.Y + editPointOffset); previous = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation); this.editPoints.InsertRange(activeEditPointIndex, new EditPoint[] { new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation), previous }); } if (next != null && next.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints((previous != null) ? previous.Location : this.activeEditPoint.Location, next.Location)) / 4; if (orientation == Orientation.Horizontal) { editPointOffset *= (this.activeEditPoint.Location.X < next.Location.X) ? -1 : 1; } else { editPointOffset *= (this.activeEditPoint.Location.Y < next.Location.Y) ? -1 : 1; } activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint); Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(next.Location.X + editPointOffset, next.Location.Y) : new Point(next.Location.X, next.Location.Y + editPointOffset); next = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation); this.editPoints.InsertRange(activeEditPointIndex + 1, new EditPoint[] { next, new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation) }); } if (this.activeEditPoint.Type == EditPoint.EditPointTypes.ConnectionEditPoint) { Fx.Assert(this.editPoints[0].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong."); Fx.Assert(this.editPoints[editPoints.Count - 1].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong."); this.activeEditPoint.Location = newPoint; Fx.Assert(this.editPoints.Count > 0, "Some edit point should exist"); ConnectionPoint targetConnPt = null; Point[] points = null; Point begin = this.editPoints[0].Location; Point end = this.editPoints[this.editPoints.Count - 1].Location; if (typeof(ConnectionPointsAdorner).IsAssignableFrom(Mouse.DirectlyOver.GetType())) { ConnectionPointsAdorner connPtsAdorner = Mouse.DirectlyOver as ConnectionPointsAdorner; targetConnPt = FreeFormPanel.ConnectionPointHitTest(newPoint, connPtsAdorner); } if (activeEditPointIndex == 0) { // We are dragging the source point of a connector. ConnectionPoint destConnPt = FreeFormPanel.GetDestinationConnectionPoint(this.editedConnector); if (targetConnPt != null) { points = ConnectorRouter.Route(parentPanel, targetConnPt, destConnPt); this.activeEditPoint.Location = targetConnPt.Location; } else { points = ConnectorRouter.Route(parentPanel, begin, destConnPt); } } else { // We are dragging the destination point of a connector. ConnectionPoint srcConnPt = FreeFormPanel.GetSourceConnectionPoint(this.editedConnector); if (targetConnPt != null) { points = ConnectorRouter.Route(parentPanel, srcConnPt, targetConnPt); this.activeEditPoint.Location = targetConnPt.Location; } else { points = ConnectorRouter.Route(parentPanel, srcConnPt, end); } } //When we start editing the end point we need to clear the slate and start over List <EditPoint> newEditPoints = new List <EditPoint>(); if (points != null && points.Length > 1) { RemoveEditPoints(EditPoint.EditPointTypes.MultiSegmentEditPoint); for (int i = 1; i < points.Length - 1; ++i) { newEditPoints.Add(new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, points[i])); } this.editPoints.InsertRange(1, newEditPoints.ToArray()); } } else if (this.activeEditPoint.Type == EditPoint.EditPointTypes.MultiSegmentEditPoint) { if (previous != null && previous.Type != EditPoint.EditPointTypes.ConnectionEditPoint && next != null && next.Type != EditPoint.EditPointTypes.ConnectionEditPoint) { //Update the previous point double slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location); Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; previous.Location = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X, newPoint.Y) : new Point(newPoint.X, previous.Location.Y); //Update the next point slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location); orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical; next.Location = (orientation == Orientation.Horizontal) ? new Point(next.Location.X, newPoint.Y) : new Point(newPoint.X, next.Location.Y); //Update the current point this.activeEditPoint.Location = newPoint; } else { Fx.Assert(false, "Should not be here. UpdateEditPoints failed."); } } } // Remove all the redundant edit points RemoveCoincidingEditPoints(); bool validEditPoints = ValidateEditPoints(); Fx.Assert(validEditPoints, "Validating EditPoints failed."); }