Example #1
0
 protected void UpdateConnections(GraphicElement el)
 {
     el.Connections.ForEach(c =>
     {
         // Connection point on shape.
         ConnectionPoint cp = el.GetConnectionPoints().Single(cp2 => cp2.Type == c.ElementConnectionPoint.Type);
         c.ToElement.MoveAnchor(cp, c.ToConnectionPoint);
     });
 }
Example #2
0
 public void UpdateConnections(GraphicElement el)
 {
     el.Connections.ForEach(c =>
     {
         // Connection point on shape.
         var cps = el.GetConnectionPoints().Where(cp2 => cp2.Type == c.ElementConnectionPoint.Type);
         cps.ForEach(cp => c.ToElement.MoveAnchor(cp, c.ToConnectionPoint));
     });
 }
Example #3
0
        public override bool Snap(GripType type, ref Point delta)
        {
            // Snapping permitted only when one and only one element is selected.
            if (selectedElements.Count != 1)
            {
                return(false);
            }

            bool           snapped         = false;
            GraphicElement selectedElement = selectedElements[0];

            // Look for connection points on nearby elements.
            // If a connection point is nearby, and the delta is moving toward that connection point, then snap to that connection point.

            // So, it seems odd that we're using the connection points of the line, rather than the anchors.
            // However, this is actually simpler, and a line's connection points should at least include the endpoint anchors.
            IEnumerable <ConnectionPoint> connectionPoints = selectedElement.GetConnectionPoints().Where(p => type == GripType.None || p.Type == type);

            nearElements = GetNearbyElements(connectionPoints);
            ShowConnectionPoints(nearElements.Select(e => e.NearElement), true);
            ShowConnectionPoints(currentlyNear.Where(e => !nearElements.Any(e2 => e.NearElement == e2.NearElement)).Select(e => e.NearElement), false);
            currentlyNear = nearElements;

            // Issue #6
            // TODO: Again, sort of kludgy.
            UpdateWithNearElementConnectionPoints(nearElements);
            nearElements = nearElements.OrderBy(si => si.AbsDx + si.AbsDy).ToList();    // abs(dx) + abs(dy) as a fast "distance" sorter, no need for sqrt(dx^2 + dy^2)

            foreach (SnapInfo si in nearElements)
            {
                ConnectionPoint nearConnectionPoint = si.NearElement.GetConnectionPoints().FirstOrDefault(cp => cp.Point.IsNear(si.LineConnectionPoint.Point, SNAP_CONNECTION_POINT_RANGE));

                if (nearConnectionPoint != null)
                {
                    Point sourceConnectionPoint = si.LineConnectionPoint.Point;
                    int   neardx     = nearConnectionPoint.Point.X - sourceConnectionPoint.X; // calculate to match possible delta sign
                    int   neardy     = nearConnectionPoint.Point.Y - sourceConnectionPoint.Y;
                    int   neardxsign = neardx.Sign();
                    int   neardysign = neardy.Sign();
                    int   deltaxsign = delta.X.Sign();
                    int   deltaysign = delta.Y.Sign();

                    // Are we attached already or moving toward the shape's connection point?
                    if ((neardxsign == 0 || deltaxsign == 0 || neardxsign == deltaxsign) &&
                        (neardysign == 0 || deltaysign == 0 || neardysign == deltaysign))
                    {
                        // If attached, are we moving away from the connection point to detach it?
                        if (neardxsign == 0 && neardxsign == 0 && (delta.X.Abs() >= SNAP_DETACH_VELOCITY || delta.Y.Abs() >= SNAP_DETACH_VELOCITY))
                        {
                            Disconnect(selectedElement, type);
                        }
                        else
                        {
                            // Not already connected?
                            if (neardxsign != 0 || neardysign != 0)
                            {
                                // Remove any current connections.  See issue #41
                                Disconnect(selectedElement, type);
                                si.NearElement.Connections.Add(new Connection()
                                {
                                    ToElement = selectedElement, ToConnectionPoint = si.LineConnectionPoint, ElementConnectionPoint = nearConnectionPoint
                                });
                                selectedElement.SetConnection(si.LineConnectionPoint.Type, si.NearElement);
                            }

                            delta   = new Point(neardx, neardy);
                            snapped = true;
                            break;
                        }
                    }
                }
            }

            return(snapped);
        }
Example #4
0
        protected SnapAction Snap(GripType type, Point delta, bool isByKeyPress)
        {
            SnapAction action = null;

            // Snapping permitted only when one and only one element is selected.
            if (controller.SelectedElements.Count != 1)
            {
                return(null);
            }
            if (controller.IsSnapToBeIgnored)
            {
                return(null);
            }

            // bool snapped = false;
            GraphicElement selectedElement = controller.SelectedElements[0];

            // Look for connection points on nearby elements.
            // If a connection point is nearby, and the delta is moving toward that connection point, then snap to that connection point.

            // So, it seems odd that we're using the connection points of the line, rather than the anchors.
            // However, this is actually simpler, and a line's connection points should at least include the endpoint anchors.
            IEnumerable <ConnectionPoint> connectionPoints = selectedElement.GetConnectionPoints().Where(p => type == GripType.None || p.Type == type);

            nearElements = GetNearbyElements(connectionPoints);
            ShowConnectionPoints(nearElements.Select(e => e.NearElement), true);
            ShowConnectionPoints(currentlyNear.Where(e => !nearElements.Any(e2 => e.NearElement == e2.NearElement)).Select(e => e.NearElement), false);
            currentlyNear = nearElements;

            // Issue #6
            // TODO: Again, sort of kludgy.
            UpdateWithNearElementConnectionPoints(nearElements);
            nearElements = nearElements.OrderBy(si => si.AbsDx + si.AbsDy).ToList();    // abs(dx) + abs(dy) as a fast "distance" sorter, no need for sqrt(dx^2 + dy^2)

            foreach (SnapInfo si in nearElements)
            {
                ConnectionPoint nearConnectionPoint = si.NearElement.GetConnectionPoints().FirstOrDefault(cp => cp.Point.IsNear(si.LineConnectionPoint.Point, SNAP_CONNECTION_POINT_RANGE));

                if (nearConnectionPoint != null)
                {
                    Point sourceConnectionPoint = si.LineConnectionPoint.Point;
                    int   neardx     = nearConnectionPoint.Point.X - sourceConnectionPoint.X; // calculate to match possible delta sign
                    int   neardy     = nearConnectionPoint.Point.Y - sourceConnectionPoint.Y;
                    int   neardxsign = neardx.Sign();
                    int   neardysign = neardy.Sign();
                    int   deltaxsign = delta.X.Sign();
                    int   deltaysign = delta.Y.Sign();

                    // Are we attached already or moving toward the shape's connection point?
                    if ((neardxsign == 0 || deltaxsign == 0 || neardxsign == deltaxsign) &&
                        (neardysign == 0 || deltaysign == 0 || neardysign == deltaysign))
                    {
                        // If attached, are we moving away from the connection point to detach it?
                        // Keyboard overrides the velocity check so we immediately detach if moving away.
                        if (neardxsign == 0 && neardxsign == 0 && ((delta.X.Abs() >= SNAP_DETACH_VELOCITY || delta.Y.Abs() >= SNAP_DETACH_VELOCITY) ||
                                                                   (isByKeyPress && (neardxsign != deltaxsign || neardysign != deltaysign))))
                        {
                            // Detach:
                            action = new SnapAction(SnapAction.Action.Detach, selectedElement, type, si.NearElement, si.LineConnectionPoint, nearConnectionPoint, delta);
                            break;
                        }
                        else
                        {
                            // Not already connected?
                            if (neardxsign != 0 || neardysign != 0)
                            {
                                // Attach:
                                action = new SnapAction(SnapAction.Action.Attach, selectedElement, type, si.NearElement, si.LineConnectionPoint, nearConnectionPoint, new Point(neardx, neardy));
                            }
                            else
                            {
                                action = new SnapAction();
                                break;
                            }

                            // delta = new Point(neardx, neardy);
                            // snapped = true;
                            break;
                        }
                    }
                }
            }

            return(action);
        }