/// <inheritdoc />
        protected override void BuildPartUI(VisualElement parent)
        {
            if (m_Model is IVariableDeclarationModel variableDeclarationModel)
            {
                m_Field = GraphElementFactory.CreateUI <GraphElement>(m_OwnerElement.View, m_OwnerElement.CommandDispatcher,
                                                                      variableDeclarationModel, blackboardVariablePartCreationContext);

                if (m_Field == null)
                {
                    return;
                }

                m_Field.AddToClassList(ussClassName);
                m_Field.AddToClassList(m_ParentClassName.WithUssElement(PartName));
                m_Field.viewDataKey = m_Model.Guid + "__" + Blackboard.persistenceKey;

                m_Field.AddToView(m_OwnerElement.View);

                if (m_Field is BlackboardField blackboardField)
                {
                    blackboardField.NameLabel.RegisterCallback <ChangeEvent <string> >(OnFieldRenamed);
                }

                if (parent is BlackboardRow row)
                {
                    row.FieldSlot.Add(m_Field);
                }
                else
                {
                    parent.Add(m_Field);
                }
            }
        }
        static bool WasSelectableDescendantHitByMouse(GraphElement currentTarget, MouseDownEvent evt)
        {
            VisualElement targetElement = evt.target as VisualElement;

            if (targetElement == null || currentTarget == targetElement)
            {
                return(false);
            }

            VisualElement descendant = targetElement;

            while (descendant != null && currentTarget != descendant)
            {
                GraphElement selectableDescendant = descendant as GraphElement;

                if (selectableDescendant != null && selectableDescendant.enabledInHierarchy && selectableDescendant.pickingMode != PickingMode.Ignore && selectableDescendant.Model.IsSelectable())
                {
                    Vector2 localMousePosition = currentTarget.ChangeCoordinatesTo(descendant, evt.localMousePosition);

                    if (selectableDescendant.ContainsPoint(localMousePosition))
                    {
                        return(true);
                    }
                }
                descendant = descendant.parent;
            }
            return(false);
        }
 internal void BeginSnap(GraphElement selectedElement)
 {
     UpdateSnappingStrategies();
     foreach (var snapStrategy in m_SnappingStrategies.Where(snapStrategy => snapStrategy.Enabled))
     {
         snapStrategy.BeginSnap(selectedElement);
     }
 }
        static void OffsetDependency(GraphElement element, IDependency model, Vector2 delta, INodeModel _)
        {
            Vector2 prevPos = model.DependentNode.Position;
            Rect    posRect = element.GetPosition();

            posRect.position = prevPos + delta;
            element.SetPosition(posRect);
        }
示例#5
0
 void UpdateSpacingPositions(GraphElement selectedElement, Rect sourceRect)
 {
     ClearRectsToConsider();
     GetRectsToConsiderInView(selectedElement);
     SortReferenceRects();
     ComputeSpacingPositions(m_VerticalReferenceRects, sourceRect);
     ComputeSpacingPositions(m_HorizontalReferenceRects, sourceRect);
 }
        static void AdjustSnappedRect(ref Rect snappedRect, Rect sourceRect, GraphElement selectedElement, float scale, SnapStrategy snapStrategy, Vector2 mousePanningDelta = default)
        {
            // Retrieve the snapping strategy's suggested snapped rect and its snapping offset
            Vector2 snappingOffset       = new Vector2(float.MaxValue, float.MaxValue);
            Rect    suggestedSnappedRect = snapStrategy.GetSnappedRect(ref snappingOffset, sourceRect, selectedElement, scale, mousePanningDelta);

            // Set snapped rect coordinates using the suggested rect's relevant coordinates
            SetSnappedRect(ref snappedRect, suggestedSnappedRect, snappingOffset);
        }
        /// <summary>
        /// Callback for the MouseDown event.
        /// </summary>
        /// <param name="e">The event.</param>
        protected void OnMouseDown(MouseDownEvent e)
        {
            if (m_Active)
            {
                e.StopImmediatePropagation();
                return;
            }

            m_Active           = false;
            m_Dragging         = false;
            m_AddedByMouseDown = false;

            if (target == null)
            {
                return;
            }

            m_SelectionContainer = target.GetFirstAncestorOfType <IDragSource>();

            if (m_SelectionContainer == null)
            {
                // Keep for potential later use in OnMouseUp (where e.target might be different then)
                m_SelectionContainer = target.GetFirstOfType <IDragSource>();
                m_SelectedElement    = e.target as GraphElement;
                return;
            }

            m_SelectedElement = target.GetFirstOfType <GraphElement>();

            if (m_SelectedElement == null)
            {
                return;
            }

            // Since we didn't drag after all, update selection with current element only
            if (!m_SelectedElement.IsSelected())
            {
                var selectionMode = e.actionKey ? SelectElementsCommand.SelectionMode.Add : SelectElementsCommand.SelectionMode.Replace;
                m_SelectedElement.CommandDispatcher.Dispatch(new SelectElementsCommand(selectionMode, m_SelectedElement.Model));
                m_AddedByMouseDown = true;
            }

            if (e.button == (int)m_ActivateButton)
            {
                // avoid starting a manipulation on a non movable object

                if (!m_SelectedElement.Model.IsDroppable())
                {
                    return;
                }

                m_MouseDownPosition = e.localMousePosition;
                m_Active            = true;
                target.CaptureMouse();
                e.StopPropagation();
            }
        }
        internal Rect GetSnappedRect(Rect sourceRect, GraphElement selectedElement, float scale, Vector2 mousePanningDelta = default)
        {
            Rect snappedRect = sourceRect;

            foreach (var snapStrategy in m_SnappingStrategies.Where(snapStrategy => snapStrategy.Enabled))
            {
                AdjustSnappedRect(ref snappedRect, sourceRect, selectedElement, scale, snapStrategy, mousePanningDelta);
            }

            return(snappedRect);
        }
        internal static BorderWidth GetBorderWidth(GraphElement element)
        {
            var borderWidth = new BorderWidth
            {
                Top    = element.contentContainer.resolvedStyle.borderTopWidth,
                Bottom = element.contentContainer.resolvedStyle.borderBottomWidth,
                Left   = element.contentContainer.resolvedStyle.borderLeftWidth,
                Right  = element.contentContainer.resolvedStyle.borderRightWidth
            };

            return(borderWidth);
        }
示例#10
0
        bool IsIgnoredElement(GraphElement selectedElement, GraphElement element, Rect rectToFit)
        {
            if (selectedElement is Placemat placemat && element.layout.Overlaps(placemat.layout) || element is Edge || !element.visible ||
                element.IsSelected() || element.layout.Overlaps(selectedElement.layout))
            {
                return(true);
            }

            Rect localSelRect = m_GraphView.ChangeCoordinatesTo(element, rectToFit);

            return(!element.Overlaps(localSelRect));
        }
示例#11
0
 void AddReferenceRects(GraphElement selectedElement, GraphElement element, Rect rectToAdd)
 {
     // Check if element is within selectedElement's vertical boundaries before adding
     if (AreElementsSuperposed(selectedElement.layout, element.layout, PortOrientation.Horizontal))
     {
         m_VerticalReferenceRects.Rects.Add(rectToAdd);
     }
     // Check if element is within selectedElement's horizontal boundaries before adding
     if (AreElementsSuperposed(selectedElement.layout, element.layout, PortOrientation.Vertical))
     {
         m_HorizontalReferenceRects.Rects.Add(rectToAdd);
     }
 }
 void GetLeftOversBoundingRects(ref List <Tuple <Rect, List <IGraphElementModel> > > boundingRects)
 {
     foreach (IGraphElementModel element in m_LeftOverElementModels)
     {
         GraphElement elementUI = element.GetUI <GraphElement>(m_GraphView);
         if (elementUI != null)
         {
             boundingRects.Add(new Tuple <Rect, List <IGraphElementModel> >(elementUI.GetPosition(), new List <IGraphElementModel> {
                 element
             }));
         }
     }
 }
        public override void BeginSnap(GraphElement selectedElement)
        {
            if (IsActive)
            {
                Debug.LogError("SnapService.BeginSnap: Snap to grid already active. Call EndSnap() first.");
            }
            IsActive = true;

            m_BorderWidth = GetBorderWidth(selectedElement); // Needed to snap element on its content container's border

            m_GraphView = selectedElement.GraphView;

            m_GridSpacing = m_GraphView.SafeQ <GridBackground>().Spacing;
        }
示例#14
0
        void SnapOrMoveElement(GraphElement element, Rect originalPos, Rect selectedElementGeom)
        {
            if (m_Snapper.IsActive)
            {
                Vector2 geomDiff = selectedElementGeom.position - m_OriginalPos[m_SelectedElement].pos.position;
                Vector2 position = new Vector2(originalPos.x + geomDiff.x, originalPos.y + geomDiff.y);

                element.SetPosition(new Rect(position, element.layout.size));
            }
            else
            {
                MoveElement(element, originalPos);
            }
        }
示例#15
0
        void GetRectsToConsiderInView(GraphElement selectedElement)
        {
            // Consider only the visible nodes.
            Rect rectToFit = m_GraphView.layout;

            foreach (GraphElement element in m_GraphView.GraphElements.ToList())
            {
                if (!IsIgnoredElement(selectedElement, element, rectToFit))
                {
                    Rect geometryInContentViewContainerSpace = (element).parent.ChangeCoordinatesTo(m_GraphView.ContentViewContainer, (element).GetPosition());
                    AddReferenceRects(selectedElement, element, geometryInContentViewContainerSpace);
                }
            }
        }
示例#16
0
        List <Rect> GetNotSelectedElementRectsInView(GraphElement selectedElement)
        {
            var notSelectedElementRects = new List <Rect>();
            var ignoredModels           = m_GraphView.GetSelection().ToList();

            // Consider only the visible nodes.
            Rect rectToFit = m_GraphView.layout;

            foreach (GraphElement element in m_GraphView.GraphElements.ToList())
            {
                if (selectedElement is Placemat placemat && element.layout.Overlaps(placemat.layout))
                {
                    // If the selected element is a placemat, we do not consider the elements under it
                    ignoredModels.Add(element.Model);
                }
示例#17
0
        public override void BeginSnap(GraphElement selectedElement)
        {
            if (IsActive)
            {
                throw new InvalidOperationException("SnapStrategy.BeginSnap: Snap to spacing already active. Call EndSnap() first.");
            }
            IsActive = true;

            m_GraphView = selectedElement.GraphView;
            if (m_LineView == null)
            {
                m_LineView = new LineView(m_GraphView);
            }
            m_GraphView.Add(m_LineView);
        }
示例#18
0
        void MoveElement(GraphElement element, Rect originalPos)
        {
            Matrix4x4 g     = element.worldTransform;
            var       scale = new Vector3(g.m00, g.m11, g.m22);

            Rect newPos = new Rect(0, 0, originalPos.width, originalPos.height);

            // Compute the new position of the selected element using the mouse delta position and panning info
            newPos.x = originalPos.x - (m_MouseDiff.x - m_ItemPanDiff.x) * m_PanSpeed.x / scale.x * element.transform.scale.x;
            newPos.y = originalPos.y - (m_MouseDiff.y - m_ItemPanDiff.y) * m_PanSpeed.y / scale.y * element.transform.scale.y;

            newPos = m_GraphView.ContentViewContainer.ChangeCoordinatesTo(element.hierarchy.parent, newPos);

            element.SetPosition(newPos);
        }
示例#19
0
        public override void BeginSnap(GraphElement selectedElement)
        {
            if (IsActive)
            {
                throw new InvalidOperationException("SnapStrategy.BeginSnap: Snap to port already active. Call EndSnap() first.");
            }
            IsActive = true;

            if (selectedElement is Node selectedNode)
            {
                m_GraphView = selectedElement.GraphView;

                m_ConnectedEdges    = GetConnectedEdges(selectedNode);
                m_ConnectedPortsPos = GetConnectedPortPositions(m_ConnectedEdges);
            }
        }
示例#20
0
        void ComputeSnappedRect(ref Rect selectedElementProposedGeom, GraphElement element)
        {
            // Check if snapping is paused first: if yes, the snapper will return the original dragging position
            if (Event.current != null)
            {
                m_Snapper.PauseSnap(Event.current.shift);
            }

            // Let the snapper compute a snapped position
            Rect geometryInContentViewContainerSpace = element.parent.ChangeCoordinatesTo(m_GraphView.ContentViewContainer, selectedElementProposedGeom);

            Vector2 mousePanningDelta = new Vector2((m_MouseDiff.x - m_ItemPanDiff.x) * m_PanSpeed.x / m_Scale, (m_MouseDiff.y - m_ItemPanDiff.y) * m_PanSpeed.y / m_Scale);

            geometryInContentViewContainerSpace = m_Snapper.GetSnappedRect(geometryInContentViewContainerSpace, element, m_Scale, mousePanningDelta);

            // Once the snapped position is computed in the GraphView.contentViewContainer's space then
            // translate it into the local space of the parent of the selected element.
            selectedElementProposedGeom = m_GraphView.ContentViewContainer.ChangeCoordinatesTo(element.parent, geometryInContentViewContainerSpace);
        }
示例#21
0
        protected void OnMouseUp(MouseUpEvent e)
        {
            GraphElement ce = e.target as GraphElement;

            if (ce != null && !ce.IsMovable())
            {
                return;
            }

            if (m_Active)
            {
                if (CanStopManipulation(e))
                {
                    m_Active = false;
                    target.ReleaseMouse();
                    e.StopPropagation();
                }
            }
        }
示例#22
0
        /// <summary>
        /// Callback for the MouseCaptureOut event.
        /// </summary>
        /// <param name="e">The event.</param>
        protected void OnMouseCaptureOutEvent(MouseCaptureOutEvent e)
        {
            if (m_Active)
            {
                if (m_CurrentDropTarget != null && m_GraphView != null)
                {
                    using (DragExitedEvent eExit = DragExitedEvent.GetPooled())
                    {
                        eExit.target = m_CurrentDropTarget;
                        m_GraphView.SendEvent(eExit);
                    }
                }

                // Stop processing the event sequence if the target has lost focus, then.
                m_SelectedElement   = null;
                m_CurrentDropTarget = null;
                m_Active            = false;

                if (m_GraphView?.GetSelection().Any() ?? false)
                {
                    m_Snapper.EndSnap();
                }
            }
        }
 public abstract void BeginSnap(GraphElement selectedElement);
示例#24
0
        /// <summary>
        /// Callback for the MouseUp event.
        /// </summary>
        /// <param name="evt">The event.</param>
        protected void OnMouseUp(MouseUpEvent evt)
        {
            if (m_GraphView == null)
            {
                if (m_Active)
                {
                    target.ReleaseMouse();
                    m_SelectedElement   = null;
                    m_Active            = false;
                    m_Dragging          = false;
                    m_CurrentDropTarget = null;
                }

                return;
            }

            var selectedModels = m_GraphView.GetSelection();

            if (CanStopManipulation(evt))
            {
                if (m_Active)
                {
                    if (m_Dragging || m_SelectedElement == null)
                    {
                        if (target is GraphView graphView)
                        {
                            graphView.StopSelectionDragger();
                            graphView.PositionDependenciesManager.StopNotifyMove();
                        }

                        // if we stop dragging on something else than a DropTarget, just move elements
                        if (m_GraphView != null && (m_CurrentDropTarget == null || !m_CurrentDropTarget.CanAcceptDrop(selectedModels)))
                        {
                            var movedElements = new HashSet <GraphElement>(m_OriginalPos.Keys);
                            movedElements.AddRangeInternal(m_EdgesToUpdate);

                            KeyValuePair <GraphElement, OriginalPos> firstPos = m_OriginalPos.First();
                            var delta  = firstPos.Key.GetPosition().position - firstPos.Value.pos.position;
                            var models = movedElements
                                         // PF remove this Where clause. It comes from VseGraphView.OnGraphViewChanged.
                                         .Where(e => !(e.Model is INodeModel) || e.IsMovable())
                                         .Select(e => e.Model)
                                         .OfType <IMovable>();
                            m_GraphView.CommandDispatcher.Dispatch(
                                new MoveElementsCommand(delta, models.ToList()));
                        }
                    }

                    foreach (var edge in m_EdgesToUpdate)
                    {
                        edge.EdgeControl.ControlPointOffset = Vector2.zero;
                    }
                    m_EdgesToUpdate.Clear();

                    m_PanSchedule.Pause();

                    if (m_ItemPanDiff != Vector3.zero)
                    {
                        Vector3 p = m_GraphView.ContentViewContainer.transform.position;
                        Vector3 s = m_GraphView.ContentViewContainer.transform.scale;
                        m_GraphView.CommandDispatcher.Dispatch(new ReframeGraphViewCommand(p, s));
                    }

                    if (selectedModels.Count > 0 && m_CurrentDropTarget != null)
                    {
                        if (m_CurrentDropTarget.CanAcceptDrop(selectedModels))
                        {
                            using (DragPerformEvent ePerform = DragPerformEvent.GetPooled(evt))
                            {
                                ePerform.target = m_CurrentDropTarget;
                                m_GraphView.SendEvent(ePerform);
                            }
                        }
                        else
                        {
                            using (DragExitedEvent eExit = DragExitedEvent.GetPooled(evt))
                            {
                                eExit.target = m_CurrentDropTarget;
                                m_GraphView.SendEvent(eExit);
                            }
                        }
                    }

                    if (selectedModels.Any())
                    {
                        m_Snapper.EndSnap();
                    }

                    target.ReleaseMouse();
                    evt.StopPropagation();
                }
                m_SelectedElement   = null;
                m_Active            = false;
                m_CurrentDropTarget = null;
                m_Dragging          = false;
                m_CurrentDropTarget = null;
            }
        }
 static bool IsOnPlacemats(GraphElement element, List <Placemat> placemats)
 {
     return(placemats.Any(placemat => !element.Equals(placemat) && element.layout.Overlaps(placemat.layout)));
 }
示例#26
0
        public override Rect GetSnappedRect(ref Vector2 snappingOffset, Rect sourceRect, GraphElement selectedElement, float scale, Vector2 mousePanningDelta = default)
        {
            if (!IsActive)
            {
                throw new InvalidOperationException("SnapStrategy.GetSnappedRect: Snap to spacing not active. Call BeginSnap() first.");
            }
            if (IsPaused)
            {
                // Snapping was paused, we do not return a snapped rect and we clear the snap lines
                ClearSnapLines();
                return(sourceRect);
            }

            Rect selectedElementRect = (selectedElement).parent.ChangeCoordinatesTo(m_GraphView.ContentViewContainer, (selectedElement).GetPosition());

            UpdateSpacingPositions(selectedElement, selectedElementRect);

            Rect snappedRect = sourceRect;

            m_CurrentScale = scale;

            m_LineView.lines.Clear();

            List <SnapToSpacingResult> results = GetClosestSpacingPositions(sourceRect);

            foreach (var result in results.Where(result => result != null))
            {
                ApplySnapToSpacingResult(ref snappingOffset, sourceRect, ref snappedRect, result);

                // Make sure the element is snapped before drawing the lines
                if (IsSnapped(snappedRect, sourceRect, result.ReferenceRects.Orientation))
                {
                    foreach (SpacingLine spacingLine in GetSpacingLines(result.ReferenceRects.Rects, result.ReferenceRects.Orientation))
                    {
                        m_LineView.lines.AddRange(spacingLine.Lines);
                    }
                }
            }
            m_LineView.MarkDirtyRepaint();

            return(snappedRect);
        }
示例#27
0
        /// <summary>
        /// Callback for the MouseMove event.
        /// </summary>
        /// <param name="e">The event.</param>
        protected void OnMouseMove(MouseMoveEvent e)
        {
            if (!m_Active)
            {
                return;
            }

            if (m_GraphView == null)
            {
                return;
            }

            var     ve         = (VisualElement)e.target;
            Vector2 gvMousePos = ve.ChangeCoordinatesTo(m_GraphView.contentContainer, e.localMousePosition);

            m_PanDiff = GetEffectivePanSpeed(gvMousePos);

            if (m_PanDiff != Vector3.zero)
            {
                m_PanSchedule.Resume();
            }
            else
            {
                m_PanSchedule.Pause();
            }

            // We need to monitor the mouse diff "by hand" because we stop positioning the graph elements once the
            // mouse has gone out.
            m_MouseDiff = m_OriginalMouse - e.mousePosition;

            if (m_SelectedElement.parent != null)
            {
                // Handle the selected element
                Rect selectedElementGeom = GetSelectedElementGeom();

                ComputeSnappedRect(ref selectedElementGeom, m_SelectedElement);

                foreach (KeyValuePair <GraphElement, OriginalPos> v in m_OriginalPos)
                {
                    GraphElement ce = v.Key;

                    // Protect against stale visual elements that have been deparented since the start of the manipulation
                    if (ce.hierarchy.parent == null)
                    {
                        continue;
                    }

                    if (!v.Value.dragStarted)
                    {
                        v.Value.dragStarted = true;
                    }

                    SnapOrMoveElement(v.Key, v.Value.pos, selectedElementGeom);
                }

                foreach (var edge in m_EdgesToUpdate)
                {
                    SnapOrMoveEdge(edge, selectedElementGeom);
                }
            }

            var selection  = m_GraphView.GetSelection();
            var selectedUI = selection.Select(m => m.GetUI(m_GraphView));

            // TODO: Replace with a temp drawing or something...maybe manipulator could fake position
            // all this to let operation know which element sits under cursor...or is there another way to draw stuff that is being dragged?

            var previousDropTarget = m_CurrentDropTarget;

            m_CurrentDropTarget = GetDropTargetAt(e.mousePosition, selectedUI.OfType <VisualElement>().ToList());

            if (m_CurrentDropTarget != previousDropTarget)
            {
                if (previousDropTarget != null)
                {
                    using (DragLeaveEvent eLeave = DragLeaveEvent.GetPooled(e))
                    {
                        eLeave.target = previousDropTarget;
                        m_GraphView.SendEvent(eLeave);
                    }
                }

                if (m_CurrentDropTarget != null)
                {
                    using (DragEnterEvent eEnter = DragEnterEvent.GetPooled(e))
                    {
                        eEnter.target = m_CurrentDropTarget;
                        m_GraphView.SendEvent(eEnter);
                    }
                }
            }

            if (m_CurrentDropTarget != null)
            {
                using (DragUpdatedEvent eUpdated = DragUpdatedEvent.GetPooled(e))
                {
                    eUpdated.target = m_CurrentDropTarget;
                    m_GraphView.SendEvent(eUpdated);
                }
            }

            m_Dragging = true;
            e.StopPropagation();
        }
示例#28
0
        public override Rect GetSnappedRect(ref Vector2 snappingOffset, Rect sourceRect, GraphElement selectedElement, float scale, Vector2 mousePanningDelta = default)
        {
            if (!IsActive)
            {
                throw new InvalidOperationException("SnapStrategy.GetSnappedRect: Snap to borders not active. Call BeginSnap() first.");
            }

            if (IsPaused)
            {
                // Snapping was paused, we do not return a snapped rect and we clear the snap lines
                ClearSnapLines();
                return(sourceRect);
            }

            Rect snappedRect = sourceRect;

            m_CurrentScale = scale;

            List <SnapToBordersResult> results = GetClosestSnapElements(sourceRect);

            m_LineView.lines.Clear();

            foreach (SnapToBordersResult result in results)
            {
                ApplySnapToBordersResult(ref snappingOffset, sourceRect, ref snappedRect, result);
                result.IndicatorLine = GetSnapLine(snappedRect, result.SourceReference, result.SnappableRect, result.SnappableReference);
                m_LineView.lines.Add(result.IndicatorLine);
            }
            m_LineView.MarkDirtyRepaint();

            m_SnappableRects = GetNotSelectedElementRectsInView(selectedElement);

            return(snappedRect);
        }
 public abstract Rect GetSnappedRect(ref Vector2 snappingOffset, Rect sourceRect, GraphElement selectedElement, float scale, Vector2 mousePanningDelta = default);
示例#30
0
        public override Rect GetSnappedRect(ref Vector2 snappingOffset, Rect sourceRect, GraphElement selectedElement, float scale, Vector2 mousePanningDelta = default)
        {
            if (!IsActive)
            {
                throw new InvalidOperationException("SnapStrategy.GetSnappedRect: Snap to port not active. Call BeginSnap() first.");
            }

            if (IsPaused)
            {
                // Snapping was paused, we do not return a snapped rect
                return(sourceRect);
            }

            Rect snappedRect = sourceRect;

            if (selectedElement is Node selectedNode)
            {
                m_CurrentScale = scale;
                SnapToPortResult chosenResult = GetClosestSnapToPortResult(selectedNode, mousePanningDelta);

                if (chosenResult != null)
                {
                    var adjustedSourceRect = GetAdjustedSourceRect(chosenResult, sourceRect, mousePanningDelta);
                    snappedRect = adjustedSourceRect;
                    ApplySnapToPortResult(ref snappingOffset, adjustedSourceRect, ref snappedRect, chosenResult);
                }
            }

            return(snappedRect);
        }