示例#1
0
// 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();
        }
    }
}