// edge id: 0 = left; 1 = right; 2 = bottom; 3 = top void Rectangles::createLines(unsigned rectangleIndex, Edge edgeID) { // line's center glm::vec2 linePosition = glm::vec2(0.0f, 0.0f); if (edgeID == Edge::LEFT || edgeID == Edge::RIGHT) { // vertical edge if (edgeID == Edge::LEFT) { // left edge linePosition.x = rectangles[rectangleIndex].getLeft(); } else { // right edge linePosition.x = rectangles[rectangleIndex].getRight(); } createVerticalLine(rectangleIndex, linePosition); } else { // horizontal edge if (edgeID == Edge::BOTTOM) { // bottom edge linePosition.y = rectangles[rectangleIndex].getBottom(); } else { // top edge linePosition.y = rectangles[rectangleIndex].getTop(); } createHorizontalLine(rectangleIndex, linePosition); } }
/*! Check if the bottom edge of moving rect is snappable to the incative rect's top or bottom edge. The inactive rect's edge is only chosen if it is a better fit for vertical snapping. */ void HsSnapToLines::compareBottomOfMovingRectForSnapping() { //Check if the inactive rect lies to the left or right of the moving rect checkInactiveRectLieLeftOrRightOfMovingRect(); //calculate the distance of the moving rect's bottom edge to the inactive rect's top and bottom edges checkInactiveRectHorizontalEdgesInRange(mMovingRect.bottom()); //calculate the distance of inactive rect's top edge and container rect's top edge qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top(); //calculate the distance of inactive rect's bottom edge and container rect's bottom edge qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom(); qreal ySnapGapAdjustment = 0.0; mDistanceHorizontalEdges = 0.0; mMinDistancePosition = 0.0; //If only one edge of inactive rect is in snappable range, save that position if ((mTopInRange && !mBottomInRange) || !mTopInRange && mBottomInRange) { if (mTopInRange) { mMinDistancePosition = mInactiveRectToCompare.top(); mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; ySnapGapAdjustment = mSnapGap; } else { mMinDistancePosition = mInactiveRectToCompare.bottom(); mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; ySnapGapAdjustment = 0.0; } } //else both edges of inactive rect are in range, check which is a better fit else if (mTopInRange && mBottomInRange) { //if bottom edge of moving rect to the bottom of inactive rect is closer than the bottom edge of moving rect to the top of the inactive rect if (mHorizontalEdgeToBottomOfInactiveRect < mHorizontalEdgeToTopOfInactiveRect ) { mMinDistancePosition = mInactiveRectToCompare.bottom(); mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; ySnapGapAdjustment = 0.0; mTopInRange = false; } //if bottom edge of moving rect to the bottom of inactive rect is at the same distance as the bottom edge of moving rect to the top of inactive rect else if (mHorizontalEdgeToBottomOfInactiveRect == mHorizontalEdgeToTopOfInactiveRect) { //if inactive rect lies towards the bottom of container rect, then the bottom edge is priortized as the selected edge for snapping //This is done for outside snapping if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) { mMinDistancePosition = mInactiveRectToCompare.bottom(); mDistanceHorizontalEdges = mHorizontalEdgeToBottomOfInactiveRect; ySnapGapAdjustment = 0.0; mTopInRange = false; } //else top of the inactive rect lies more close to the top of the container rect or at the same distance, and hence prioritize it else { mMinDistancePosition = mInactiveRectToCompare.top(); mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; ySnapGapAdjustment = mSnapGap; mBottomInRange = false; } } //else bottom edge of moving rect to the top of inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect else{ mMinDistancePosition = mInactiveRectToCompare.top(); mDistanceHorizontalEdges = mHorizontalEdgeToTopOfInactiveRect; ySnapGapAdjustment = mSnapGap; mBottomInRange = false; } } //Check if this inactive rect is better fit than the previous selected rect checkInactiveRectBetterFitForVerticalSnapping(differenceContainerBottomEdgeToInactiveRectBottomEdge, differenceContainerTopEdgeToInactiveRectTopEdge); if (mIsBetterFitVerticalSnap) { qreal proposedTopOfActiveRect = mMinDistancePosition - mActiveRectHeight - ySnapGapAdjustment; if (qBound(mContainerRect.top(), proposedTopOfActiveRect, mContainerRect.bottom()) == proposedTopOfActiveRect) { mVerticalSnapFound = true; mVerticalSnapPosition = proposedTopOfActiveRect; mMinHorizontalEdgesDistance = mDistanceHorizontalEdges; mHorizontalDistanceFromSelectedRect = mHorizontalDistance; //Save the new distance of the Selected Rectangle's bottom edge from Container's bottom edge mContainerHorizontalEdgeDistance = differenceContainerBottomEdgeToInactiveRectBottomEdge; createHorizontalLine(); } } }