homescreenapp/hsutils/src/hswidgetpositioningonwidgetmove.cpp
author hgs
Fri, 09 Jul 2010 14:36:01 +0300
changeset 63 52b0f64eeb51
parent 62 341166945d65
child 69 87476091b3f5
permissions -rw-r--r--
201027
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include <QVector2D>
hgs
parents:
diff changeset
    19
#include "hswidgetpositioningonwidgetmove.h"
hgs
parents:
diff changeset
    20
#include "hsapp_defs.h"
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
hgs
parents:
diff changeset
    23
/*!
hgs
parents:
diff changeset
    24
    The distance by which the line is extended on each side of reference points
hgs
parents:
diff changeset
    25
*/
hgs
parents:
diff changeset
    26
#define SNAP_LINE_EXTEND_VALUE 10.0
hgs
parents:
diff changeset
    27
hgs
parents:
diff changeset
    28
/*!
hgs
parents:
diff changeset
    29
    Sets the snap method instance. The existing instance
hgs
parents:
diff changeset
    30
    will be deleted.
hgs
parents:
diff changeset
    31
*/
hgs
parents:
diff changeset
    32
void HsWidgetPositioningOnWidgetMove::setInstance(HsWidgetPositioningOnWidgetMove *instance)
hgs
parents:
diff changeset
    33
{
hgs
parents:
diff changeset
    34
    if (mInstance)
hgs
parents:
diff changeset
    35
        delete mInstance;
hgs
parents:
diff changeset
    36
    mInstance = instance;
hgs
parents:
diff changeset
    37
}
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
/*!
hgs
parents:
diff changeset
    40
    Returns the snap method instance.
hgs
parents:
diff changeset
    41
*/
hgs
parents:
diff changeset
    42
HsWidgetPositioningOnWidgetMove *HsWidgetPositioningOnWidgetMove::instance()
hgs
parents:
diff changeset
    43
{
hgs
parents:
diff changeset
    44
    return mInstance;
hgs
parents:
diff changeset
    45
}
hgs
parents:
diff changeset
    46
hgs
parents:
diff changeset
    47
/*!
hgs
parents:
diff changeset
    48
    Points to the snap method instance.
hgs
parents:
diff changeset
    49
*/
hgs
parents:
diff changeset
    50
HsWidgetPositioningOnWidgetMove *HsWidgetPositioningOnWidgetMove::mInstance = 0;
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
/*!
hgs
parents:
diff changeset
    53
    Constructor.
hgs
parents:
diff changeset
    54
*/
hgs
parents:
diff changeset
    55
HsSnapToLines::HsSnapToLines() :
hgs
parents:
diff changeset
    56
    mActiveRectWidth(0.0), mActiveRectHeight(0.0),
hgs
parents:
diff changeset
    57
    mHorizontalSnapPosition(0.0), mVerticalSnapPosition(0.0),
hgs
parents:
diff changeset
    58
    mHorizontalSnapFound(false),
hgs
parents:
diff changeset
    59
    mVerticalSnapFound(false),
hgs
parents:
diff changeset
    60
    mRectLieAbove(false), mLeftInRange(false), mRightInRange(false),
hgs
parents:
diff changeset
    61
    mMinVerticalEdgesDistance(0.0), mVerticalDistance(0.0),
hgs
parents:
diff changeset
    62
    mVerticalDistanceFromSelectedRect(0.0), mContainerVerticalEdgeDistance(0.0),
hgs
parents:
diff changeset
    63
    mRectLieLeft(false), mTopInRange(false), mBottomInRange(false),
hgs
parents:
diff changeset
    64
    mMinHorizontalEdgesDistance(0.0), mHorizontalDistance(0.0),
hgs
parents:
diff changeset
    65
    mHorizontalDistanceFromSelectedRect(0.0), mContainerHorizontalEdgeDistance(0.0),
63
hgs
parents: 62
diff changeset
    66
    mSnapEnabled(false), mSnapForce(0.0), mSnapGap(0.0),
62
hgs
parents:
diff changeset
    67
    mRectVerticalEdgeLiesInLineWithVerticalLine(false), mRectLieAboveVerticalLine(false), mRectLieBelowVerticalLine(false),
hgs
parents:
diff changeset
    68
    mRectHorizontalEdgeLiesInLineWithHorizontalLine(false), mRectLieLeftOfHorizontalLine(false), mRectLiesRightOfHorizontalLine(false)
hgs
parents:
diff changeset
    69
{
hgs
parents:
diff changeset
    70
hgs
parents:
diff changeset
    71
}
hgs
parents:
diff changeset
    72
hgs
parents:
diff changeset
    73
/*!
hgs
parents:
diff changeset
    74
    Configures the snap-to-lines algorithm.
hgs
parents:
diff changeset
    75
*/
hgs
parents:
diff changeset
    76
void HsSnapToLines::setConfiguration(const QVariantHash &configuration)
hgs
parents:
diff changeset
    77
{
hgs
parents:
diff changeset
    78
    bool canConvert = false;
hgs
parents:
diff changeset
    79
    mSnapEnabled = configuration[SNAPENABLED].toBool();
hgs
parents:
diff changeset
    80
    //The following values should be in qreal, so the status received in canConvert is ignored
hgs
parents:
diff changeset
    81
    mSnapForce = configuration[SNAPFORCE].toDouble(&canConvert);
hgs
parents:
diff changeset
    82
    mSnapGap = configuration[SNAPGAP].toDouble(&canConvert);
hgs
parents:
diff changeset
    83
}
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
/*!
hgs
parents:
diff changeset
    86
    Set the dimensions of container rect, active rect and position of Inactive Rects
hgs
parents:
diff changeset
    87
    on the page.
hgs
parents:
diff changeset
    88
*/
hgs
parents:
diff changeset
    89
void HsSnapToLines::setPagePresentation(const QRectF &containerRect, 
hgs
parents:
diff changeset
    90
                                        const QList<QRectF> &inactiveRects,
hgs
parents:
diff changeset
    91
                                        const QRectF &activeRect)
hgs
parents:
diff changeset
    92
{
63
hgs
parents: 62
diff changeset
    93
    mContainerRect = containerRect;
62
hgs
parents:
diff changeset
    94
    mActiveRectWidth = activeRect.width();
hgs
parents:
diff changeset
    95
    mActiveRectHeight = activeRect.height();
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
    createSnappableRectangles(inactiveRects);
hgs
parents:
diff changeset
    98
}
hgs
parents:
diff changeset
    99
hgs
parents:
diff changeset
   100
/*!
hgs
parents:
diff changeset
   101
    Create the list of rects and flag if their sides are snappable from top or bottom or left or right,
hgs
parents:
diff changeset
   102
    depending on other rects overlapping with the rect.
hgs
parents:
diff changeset
   103
*/
hgs
parents:
diff changeset
   104
void HsSnapToLines::createSnappableRectangles(const QList<QRectF> &inactiveRects)
hgs
parents:
diff changeset
   105
{
hgs
parents:
diff changeset
   106
    mInactiveSnapRects.clear();
hgs
parents:
diff changeset
   107
hgs
parents:
diff changeset
   108
    int i;
hgs
parents:
diff changeset
   109
    for (i = 0; i<inactiveRects.count(); ++i) {
hgs
parents:
diff changeset
   110
        QRectF rect = inactiveRects[i];
hgs
parents:
diff changeset
   111
        HsSnapRectangle snapRectangle(rect);
hgs
parents:
diff changeset
   112
hgs
parents:
diff changeset
   113
        int j;
hgs
parents:
diff changeset
   114
        for (j = 0; j<inactiveRects.count(); ++j) {
hgs
parents:
diff changeset
   115
            QRectF rectToCompare = inactiveRects[j];
hgs
parents:
diff changeset
   116
            if (rect != rectToCompare) {
hgs
parents:
diff changeset
   117
                //Check if the rectangles being compared intersect each other
hgs
parents:
diff changeset
   118
                if (rectToCompare.intersects(rect)) {
hgs
parents:
diff changeset
   119
                    //As the widgets intersect, check which corner is contained,
hgs
parents:
diff changeset
   120
                    //The corner that is contained is not snappable, when the moving widget is in the same position
hgs
parents:
diff changeset
   121
                    if (rectToCompare.contains(rect.topLeft())) {
hgs
parents:
diff changeset
   122
                        snapRectangle.isLeftSnapableForAbove = false;
hgs
parents:
diff changeset
   123
                        snapRectangle.isTopSnapableForLeft = false;
hgs
parents:
diff changeset
   124
                    }
hgs
parents:
diff changeset
   125
hgs
parents:
diff changeset
   126
                    if (rectToCompare.contains(rect.topRight())) {
hgs
parents:
diff changeset
   127
                        snapRectangle.isRightSnapableForAbove = false;
hgs
parents:
diff changeset
   128
                        snapRectangle.isTopSnapableForRight = false;
hgs
parents:
diff changeset
   129
                    }
hgs
parents:
diff changeset
   130
hgs
parents:
diff changeset
   131
                    if (rectToCompare.contains(rect.bottomRight())) {
hgs
parents:
diff changeset
   132
                        snapRectangle.isRightSnapableForBelow = false;
hgs
parents:
diff changeset
   133
                        snapRectangle.isBottomSnapableForRight = false;
hgs
parents:
diff changeset
   134
                    }
hgs
parents:
diff changeset
   135
hgs
parents:
diff changeset
   136
                    if (rectToCompare.contains(rect.bottomLeft())) {
hgs
parents:
diff changeset
   137
                        snapRectangle.isLeftSnapableForBelow = false;
hgs
parents:
diff changeset
   138
                        snapRectangle.isBottomSnapableForLeft = false;
hgs
parents:
diff changeset
   139
                    }
hgs
parents:
diff changeset
   140
                }
hgs
parents:
diff changeset
   141
            }
hgs
parents:
diff changeset
   142
        }
hgs
parents:
diff changeset
   143
        if (snapRectangle.isLeftSnapableForAbove || snapRectangle.isLeftSnapableForBelow ||
hgs
parents:
diff changeset
   144
            snapRectangle.isRightSnapableForAbove || snapRectangle.isRightSnapableForBelow ||
hgs
parents:
diff changeset
   145
            snapRectangle.isTopSnapableForLeft || snapRectangle.isTopSnapableForRight ||
hgs
parents:
diff changeset
   146
            snapRectangle.isBottomSnapableForLeft || snapRectangle.isBottomSnapableForRight) {
hgs
parents:
diff changeset
   147
                mInactiveSnapRects.append(snapRectangle);
hgs
parents:
diff changeset
   148
        }
hgs
parents:
diff changeset
   149
    }
hgs
parents:
diff changeset
   150
}
hgs
parents:
diff changeset
   151
hgs
parents:
diff changeset
   152
/*!
hgs
parents:
diff changeset
   153
    Run the snap algorithm to with the position of moving rect, to get a snap result.
hgs
parents:
diff changeset
   154
*/
hgs
parents:
diff changeset
   155
HsWidgetPositioningOnWidgetMove::Result HsSnapToLines::run(const QRectF &movingRect)
hgs
parents:
diff changeset
   156
{
hgs
parents:
diff changeset
   157
    HsWidgetPositioningOnWidgetMove::Result result;
hgs
parents:
diff changeset
   158
hgs
parents:
diff changeset
   159
    if (mSnapEnabled) {
hgs
parents:
diff changeset
   160
        mMovingRect = movingRect;
hgs
parents:
diff changeset
   161
        mHorizontalSnapPosition = 0.0;
hgs
parents:
diff changeset
   162
        mVerticalSnapPosition = 0.0;
hgs
parents:
diff changeset
   163
hgs
parents:
diff changeset
   164
        mVerticalLine = QLineF();
hgs
parents:
diff changeset
   165
        mMinVerticalEdgesDistance = mSnapForce;
hgs
parents:
diff changeset
   166
        mVerticalDistanceFromSelectedRect = 0.0;
hgs
parents:
diff changeset
   167
        mContainerVerticalEdgeDistance = 0.0;
hgs
parents:
diff changeset
   168
        mHorizontalSnapFound = false;
hgs
parents:
diff changeset
   169
hgs
parents:
diff changeset
   170
        mHorizontalLine = QLineF();
hgs
parents:
diff changeset
   171
        mMinHorizontalEdgesDistance = mSnapForce;
hgs
parents:
diff changeset
   172
        mHorizontalDistanceFromSelectedRect = 0.0;
hgs
parents:
diff changeset
   173
        mContainerHorizontalEdgeDistance = 0.0;
hgs
parents:
diff changeset
   174
        mVerticalSnapFound = false;
hgs
parents:
diff changeset
   175
hgs
parents:
diff changeset
   176
        checkForCenterSnapping();
hgs
parents:
diff changeset
   177
        for (int i = 0; i < mInactiveSnapRects.count(); ++i) {
hgs
parents:
diff changeset
   178
            mInactiveSnapRectToCompare = mInactiveSnapRects[i];
hgs
parents:
diff changeset
   179
            mInactiveRectToCompare = mInactiveSnapRectToCompare.rectangle;
hgs
parents:
diff changeset
   180
            if (!movingRect.intersects(mInactiveRectToCompare)) { //Only compare if Inactive Rect and moving rect do not overlap.
hgs
parents:
diff changeset
   181
                //TODO: Move the above check to another function...
hgs
parents:
diff changeset
   182
                // X - Direction Snapping
hgs
parents:
diff changeset
   183
                compareLeftSideOfMovingRectForSnapping();
hgs
parents:
diff changeset
   184
                compareRightSideOfMovingRectForSnapping();
hgs
parents:
diff changeset
   185
                // Y - Direction Snapping
hgs
parents:
diff changeset
   186
                compareTopOfMovingRectForSnapping();
hgs
parents:
diff changeset
   187
                compareBottomOfMovingRectForSnapping();
hgs
parents:
diff changeset
   188
            }
hgs
parents:
diff changeset
   189
        }
hgs
parents:
diff changeset
   190
hgs
parents:
diff changeset
   191
        if (mHorizontalSnapFound) {
hgs
parents:
diff changeset
   192
            result.hasHorizontalSnap = true;
hgs
parents:
diff changeset
   193
            result.horizontalSnapPosition = mHorizontalSnapPosition;
hgs
parents:
diff changeset
   194
            extendVerticalLine();
hgs
parents:
diff changeset
   195
            result.verticalSnapLine = mVerticalLine;
hgs
parents:
diff changeset
   196
        }
hgs
parents:
diff changeset
   197
hgs
parents:
diff changeset
   198
        if (mVerticalSnapFound) {
hgs
parents:
diff changeset
   199
            result.hasVerticalSnap = true;
hgs
parents:
diff changeset
   200
            result.verticalSnapPosition = mVerticalSnapPosition;
hgs
parents:
diff changeset
   201
            extendHorizontalLine();
hgs
parents:
diff changeset
   202
            result.horizontalSnapLine = mHorizontalLine;
hgs
parents:
diff changeset
   203
        }
hgs
parents:
diff changeset
   204
    }
hgs
parents:
diff changeset
   205
hgs
parents:
diff changeset
   206
    return result;
hgs
parents:
diff changeset
   207
}
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
/*!
hgs
parents:
diff changeset
   210
    Check if the center of moving rect is in the snap force in the middle of continer rect.
hgs
parents:
diff changeset
   211
*/
hgs
parents:
diff changeset
   212
void HsSnapToLines::checkForCenterSnapping()
hgs
parents:
diff changeset
   213
{
hgs
parents:
diff changeset
   214
    QPointF centerOfContainerRect = mContainerRect.center();
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
    QRectF verticalSnapField = QRectF(QPointF(centerOfContainerRect.x() - (mSnapForce/2), mContainerRect.top()),
hgs
parents:
diff changeset
   217
         QPointF(centerOfContainerRect.x() + (mSnapForce/2), mContainerRect.bottom()));
hgs
parents:
diff changeset
   218
hgs
parents:
diff changeset
   219
    //Check that the widget lies in the container rect, if the snapping position is proposed... is not required,
hgs
parents:
diff changeset
   220
    //unless some widget is bigger than the page width
hgs
parents:
diff changeset
   221
    QPointF centerOfMovingRect = mMovingRect.center();
hgs
parents:
diff changeset
   222
    if (verticalSnapField.contains(centerOfMovingRect)) {
hgs
parents:
diff changeset
   223
        mHorizontalSnapFound = true;
hgs
parents:
diff changeset
   224
        mHorizontalSnapPosition = centerOfContainerRect.x() - mActiveRectWidth/2;
hgs
parents:
diff changeset
   225
        mMinVerticalEdgesDistance = qAbs(centerOfContainerRect.x() - centerOfMovingRect.x());
hgs
parents:
diff changeset
   226
        //save the points for the Vertical line
hgs
parents:
diff changeset
   227
        mVerticalLine.setP1(QPointF(centerOfContainerRect.x(), mMovingRect.top()));
hgs
parents:
diff changeset
   228
        mVerticalLine.setP2(QPointF(centerOfContainerRect.x(), mMovingRect.bottom()));
hgs
parents:
diff changeset
   229
    }
hgs
parents:
diff changeset
   230
}
hgs
parents:
diff changeset
   231
hgs
parents:
diff changeset
   232
/*!
hgs
parents:
diff changeset
   233
    Check if the inactive rect being compared with moving rect lies above or below of moving rect.
hgs
parents:
diff changeset
   234
*/
hgs
parents:
diff changeset
   235
void HsSnapToLines::checkInactiveRectLieAboveOrBelowOfMovingRect()
hgs
parents:
diff changeset
   236
{
hgs
parents:
diff changeset
   237
    //Check if the inactive rect lies below or above of the moving rect
hgs
parents:
diff changeset
   238
    mRectLieAbove = false;
hgs
parents:
diff changeset
   239
    mVerticalDistance = 0.0;
hgs
parents:
diff changeset
   240
    //Inactive Rect lies above or at the save Y position as the Moving Rect
hgs
parents:
diff changeset
   241
    if (mInactiveRectToCompare.top() <= mMovingRect.top()) {
hgs
parents:
diff changeset
   242
        mRectLieAbove = true;
hgs
parents:
diff changeset
   243
        if (mInactiveRectToCompare.bottom() <= mMovingRect.top()) {
hgs
parents:
diff changeset
   244
            mVerticalDistance = mMovingRect.top() - mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   245
        }
hgs
parents:
diff changeset
   246
        else {
hgs
parents:
diff changeset
   247
            mVerticalDistance = mMovingRect.top() - mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   248
        }
hgs
parents:
diff changeset
   249
    }
hgs
parents:
diff changeset
   250
    //Inactive Rect lies below the Moving Rect
hgs
parents:
diff changeset
   251
    else {
hgs
parents:
diff changeset
   252
        mRectLieAbove = false;
hgs
parents:
diff changeset
   253
        if (mMovingRect.bottom() <= mInactiveRectToCompare.top()) {
hgs
parents:
diff changeset
   254
            mVerticalDistance = mInactiveRectToCompare.top() - mMovingRect.bottom();
hgs
parents:
diff changeset
   255
        }
hgs
parents:
diff changeset
   256
        else {
hgs
parents:
diff changeset
   257
            mVerticalDistance = mInactiveRectToCompare.bottom() - mMovingRect.bottom();
hgs
parents:
diff changeset
   258
        }
hgs
parents:
diff changeset
   259
    }
hgs
parents:
diff changeset
   260
}
hgs
parents:
diff changeset
   261
hgs
parents:
diff changeset
   262
hgs
parents:
diff changeset
   263
/*!
hgs
parents:
diff changeset
   264
    Check if the left edge of moving rect is snappable to the incative rect's left or right edge.
hgs
parents:
diff changeset
   265
    The inactive rect's edge is only chosen if it is a better fit for horizontal snapping.
hgs
parents:
diff changeset
   266
*/
hgs
parents:
diff changeset
   267
void HsSnapToLines::compareLeftSideOfMovingRectForSnapping()
hgs
parents:
diff changeset
   268
{
hgs
parents:
diff changeset
   269
    checkInactiveRectLieAboveOrBelowOfMovingRect();
hgs
parents:
diff changeset
   270
hgs
parents:
diff changeset
   271
    //calculate the distance of the moving rect's left edge to the inactive rect's left and right edges
hgs
parents:
diff changeset
   272
    qreal leftToLeftOfInactiveRect = qAbs(mInactiveRectToCompare.left() - mMovingRect.left());
hgs
parents:
diff changeset
   273
    qreal leftToRightOfInactiveRect = qAbs(mInactiveRectToCompare.right() - mMovingRect.left());
hgs
parents:
diff changeset
   274
    mLeftInRange = false;
hgs
parents:
diff changeset
   275
    mRightInRange = false;
hgs
parents:
diff changeset
   276
hgs
parents:
diff changeset
   277
    if (leftToLeftOfInactiveRect <= mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   278
        if (mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForBelow
hgs
parents:
diff changeset
   279
         || !mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForAbove) { 
hgs
parents:
diff changeset
   280
            mLeftInRange = true;
hgs
parents:
diff changeset
   281
        }
hgs
parents:
diff changeset
   282
    }
hgs
parents:
diff changeset
   283
    if (leftToRightOfInactiveRect <= mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   284
        if (mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForBelow
hgs
parents:
diff changeset
   285
         || !mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForAbove) {
hgs
parents:
diff changeset
   286
            mRightInRange = true;
hgs
parents:
diff changeset
   287
        }
hgs
parents:
diff changeset
   288
    }
hgs
parents:
diff changeset
   289
hgs
parents:
diff changeset
   290
    //calculate the distance of inactive rect's left edge and container rect's left edge
hgs
parents:
diff changeset
   291
    qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left();
hgs
parents:
diff changeset
   292
    //calculate the distance of inactive rect's right edge and container rect's right edge
hgs
parents:
diff changeset
   293
    qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   294
hgs
parents:
diff changeset
   295
    qreal minDistancePosition = 0.0;
hgs
parents:
diff changeset
   296
    qreal distanceVerticalEdges = 0.0;
hgs
parents:
diff changeset
   297
    qreal xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   298
hgs
parents:
diff changeset
   299
    //If only one edge of inactive rect is in snappable range, save that position
hgs
parents:
diff changeset
   300
    if ((mLeftInRange && !mRightInRange)
hgs
parents:
diff changeset
   301
        || !mLeftInRange && mRightInRange) {
hgs
parents:
diff changeset
   302
        if (mLeftInRange) {
hgs
parents:
diff changeset
   303
            minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   304
            distanceVerticalEdges = leftToLeftOfInactiveRect;
hgs
parents:
diff changeset
   305
            xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   306
        }
hgs
parents:
diff changeset
   307
        else {
hgs
parents:
diff changeset
   308
            minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   309
            distanceVerticalEdges = leftToRightOfInactiveRect;
hgs
parents:
diff changeset
   310
            xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   311
        }
hgs
parents:
diff changeset
   312
    }
hgs
parents:
diff changeset
   313
    //else both edges of inactive rect are in range, check which is a better fit
hgs
parents:
diff changeset
   314
    else if (mLeftInRange && mRightInRange) {
hgs
parents:
diff changeset
   315
        //if left edge of moving rect to the left of the inactive rect is closer than the left edge of moving rect to the right of the inactive rect
hgs
parents:
diff changeset
   316
        if (leftToLeftOfInactiveRect < leftToRightOfInactiveRect) {
hgs
parents:
diff changeset
   317
            minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   318
            distanceVerticalEdges = leftToLeftOfInactiveRect;
hgs
parents:
diff changeset
   319
            xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   320
            mRightInRange = false;
hgs
parents:
diff changeset
   321
        }
hgs
parents:
diff changeset
   322
        //if the left edge of inactive rect to left of moving rect is at the same distance as the right edge of inactive rect to the right of moving rect
hgs
parents:
diff changeset
   323
        else if (leftToLeftOfInactiveRect == leftToRightOfInactiveRect) {
hgs
parents:
diff changeset
   324
            //if inactive rect lies towards the left or middle of container rect, then the left edge is priortized as the selected edge for outside snapping 
hgs
parents:
diff changeset
   325
            if (differenceContainerLeftEdgeToInactiveRectLeftEdge <= differenceContainerRightEdgeToInactiveRectRightEdge) { 
hgs
parents:
diff changeset
   326
                minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   327
                distanceVerticalEdges = leftToLeftOfInactiveRect;
hgs
parents:
diff changeset
   328
                xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   329
                mRightInRange = false;
hgs
parents:
diff changeset
   330
            }
hgs
parents:
diff changeset
   331
            //else right of the inactive rect lies more close to the right of the container rect, and hence prioritize it for snapping.
hgs
parents:
diff changeset
   332
            else {
hgs
parents:
diff changeset
   333
                minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   334
                distanceVerticalEdges = leftToRightOfInactiveRect;
hgs
parents:
diff changeset
   335
                xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   336
                mLeftInRange = false;
hgs
parents:
diff changeset
   337
            }
hgs
parents:
diff changeset
   338
        }
hgs
parents:
diff changeset
   339
        //else right edge of inactive rect to the left of the moving rect is closer than the left edge of inactive rect to the left of the moving rect
hgs
parents:
diff changeset
   340
        else{
hgs
parents:
diff changeset
   341
            minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   342
            distanceVerticalEdges = leftToRightOfInactiveRect;
hgs
parents:
diff changeset
   343
            xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   344
            mLeftInRange = false;
hgs
parents:
diff changeset
   345
        }
hgs
parents:
diff changeset
   346
    }
hgs
parents:
diff changeset
   347
hgs
parents:
diff changeset
   348
    //Check if this inactive rect is better fit than the previous selected rect for X - snapping
hgs
parents:
diff changeset
   349
    bool horizontalSnappingBetterFit = false;
hgs
parents:
diff changeset
   350
    if (mLeftInRange || mRightInRange) {
hgs
parents:
diff changeset
   351
        if (distanceVerticalEdges < mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   352
            horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   353
        }
hgs
parents:
diff changeset
   354
        else if (distanceVerticalEdges == mMinVerticalEdgesDistance) { //the distance in the vertical edges is same as from the selected rectangle
hgs
parents:
diff changeset
   355
            //check the position of rect with respect to Vertical line
hgs
parents:
diff changeset
   356
            checkInactiveRectPositionToVerticalLine();
hgs
parents:
diff changeset
   357
            //if horizontal snap position was previously found the rect's edges are in line with Vertical line
hgs
parents:
diff changeset
   358
            if (mHorizontalSnapFound && mRectVerticalEdgeLiesInLineWithVerticalLine) {
hgs
parents:
diff changeset
   359
                if (mRectLieAboveVerticalLine || mRectLieBelowVerticalLine) {
hgs
parents:
diff changeset
   360
                    extendVerticalLineToIncludeInactiveRect();
hgs
parents:
diff changeset
   361
                }
hgs
parents:
diff changeset
   362
            }
hgs
parents:
diff changeset
   363
            //here the case is that moving rect lies exactly in middle of two same sides of two inactive widgets.
hgs
parents:
diff changeset
   364
            else {
hgs
parents:
diff changeset
   365
                //Prioritize first on the fact if the inactive rect is closer to the moving rect in Y - direction.
hgs
parents:
diff changeset
   366
                if (mVerticalDistance < mVerticalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   367
                    horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   368
                }
hgs
parents:
diff changeset
   369
                else if (mVerticalDistance == mVerticalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   370
                    //Prioritize next if this Inactive rect is closer to the left edge of the container rect, then the previously selected rect
hgs
parents:
diff changeset
   371
                    if (differenceContainerLeftEdgeToInactiveRectLeftEdge < mContainerVerticalEdgeDistance) {
hgs
parents:
diff changeset
   372
                        horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   373
                    }
hgs
parents:
diff changeset
   374
                    //Prioritize next if the Inactive widget's left edge lies near to left edge of the container rect
hgs
parents:
diff changeset
   375
                    else if (differenceContainerLeftEdgeToInactiveRectLeftEdge < differenceContainerRightEdgeToInactiveRectRightEdge) {
hgs
parents:
diff changeset
   376
                        horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   377
                    }
hgs
parents:
diff changeset
   378
                    else {
hgs
parents:
diff changeset
   379
                        //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping.
hgs
parents:
diff changeset
   380
                        //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit.
hgs
parents:
diff changeset
   381
                    }
hgs
parents:
diff changeset
   382
                }
hgs
parents:
diff changeset
   383
            }
hgs
parents:
diff changeset
   384
        }
hgs
parents:
diff changeset
   385
    }
hgs
parents:
diff changeset
   386
hgs
parents:
diff changeset
   387
    if (horizontalSnappingBetterFit) {
hgs
parents:
diff changeset
   388
        qreal proposedRightOfActiveRect = minDistancePosition + xSnapGapAdjustment + mActiveRectWidth;
hgs
parents:
diff changeset
   389
        if (qBound(mContainerRect.left(), proposedRightOfActiveRect, mContainerRect.right())
hgs
parents:
diff changeset
   390
            == proposedRightOfActiveRect) {
hgs
parents:
diff changeset
   391
            mHorizontalSnapFound = true;
hgs
parents:
diff changeset
   392
            mHorizontalSnapPosition = minDistancePosition + xSnapGapAdjustment;
hgs
parents:
diff changeset
   393
            mMinVerticalEdgesDistance = distanceVerticalEdges;
hgs
parents:
diff changeset
   394
            mVerticalDistanceFromSelectedRect = mVerticalDistance;
hgs
parents:
diff changeset
   395
            //Save the new distance of the Chosen Rectangle's left edge from Container's left edge
hgs
parents:
diff changeset
   396
            mContainerVerticalEdgeDistance = differenceContainerLeftEdgeToInactiveRectLeftEdge;
hgs
parents:
diff changeset
   397
hgs
parents:
diff changeset
   398
            if (mRectLieAbove) {
hgs
parents:
diff changeset
   399
                mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.top()));
hgs
parents:
diff changeset
   400
                mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.bottom()));
hgs
parents:
diff changeset
   401
            }
hgs
parents:
diff changeset
   402
            else {
hgs
parents:
diff changeset
   403
                mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.bottom()));
hgs
parents:
diff changeset
   404
                mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.top()));
hgs
parents:
diff changeset
   405
            }
hgs
parents:
diff changeset
   406
        }
hgs
parents:
diff changeset
   407
    }
hgs
parents:
diff changeset
   408
}
hgs
parents:
diff changeset
   409
hgs
parents:
diff changeset
   410
/*!
hgs
parents:
diff changeset
   411
    Check if the right edge of moving rect is snappable to the incative rect's left or right edge.
hgs
parents:
diff changeset
   412
    The inactive rect's edge is only chosen if it is a better fit for horizontal snapping.
hgs
parents:
diff changeset
   413
*/
hgs
parents:
diff changeset
   414
void HsSnapToLines::compareRightSideOfMovingRectForSnapping()
hgs
parents:
diff changeset
   415
{
hgs
parents:
diff changeset
   416
    checkInactiveRectLieAboveOrBelowOfMovingRect();
hgs
parents:
diff changeset
   417
hgs
parents:
diff changeset
   418
    //calculate the distance of the moving rect's right edge to the inactive rect's left and right edges
hgs
parents:
diff changeset
   419
    qreal rightToLeftOfInactiveRect = qAbs(mInactiveRectToCompare.left() - mMovingRect.right());
hgs
parents:
diff changeset
   420
    qreal rightToRightOfInactiveRect = qAbs(mInactiveRectToCompare.right() - mMovingRect.right());
hgs
parents:
diff changeset
   421
    mLeftInRange = false;
hgs
parents:
diff changeset
   422
    mRightInRange = false;
hgs
parents:
diff changeset
   423
hgs
parents:
diff changeset
   424
    if (rightToLeftOfInactiveRect <= mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   425
        if (mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForBelow
hgs
parents:
diff changeset
   426
         || !mRectLieAbove && mInactiveSnapRectToCompare.isLeftSnapableForAbove) {
hgs
parents:
diff changeset
   427
            mLeftInRange = true;
hgs
parents:
diff changeset
   428
        }
hgs
parents:
diff changeset
   429
    }
hgs
parents:
diff changeset
   430
    if (rightToRightOfInactiveRect <= mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   431
        if (mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForBelow
hgs
parents:
diff changeset
   432
         || !mRectLieAbove && mInactiveSnapRectToCompare.isRightSnapableForAbove) {
hgs
parents:
diff changeset
   433
            mRightInRange = true;
hgs
parents:
diff changeset
   434
        }
hgs
parents:
diff changeset
   435
    }
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
    //calculate the distance of inactive rect's left edge and container rect's left edge
hgs
parents:
diff changeset
   438
    qreal differenceContainerLeftEdgeToInactiveRectLeftEdge = mInactiveRectToCompare.left() - mContainerRect.left();
hgs
parents:
diff changeset
   439
    //calculate the distance of inactive rect's right edge and container rect's right edge
hgs
parents:
diff changeset
   440
    qreal differenceContainerRightEdgeToInactiveRectRightEdge = mContainerRect.right() - mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   441
    qreal minDistancePosition = 0.0;
hgs
parents:
diff changeset
   442
    qreal distanceVerticalEdges = 0.0;
hgs
parents:
diff changeset
   443
    qreal xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   444
hgs
parents:
diff changeset
   445
    //If only one edge of inactive rect is in snappable range, save that position
hgs
parents:
diff changeset
   446
    if ((mLeftInRange && !mRightInRange)
hgs
parents:
diff changeset
   447
        || !mLeftInRange && mRightInRange) {
hgs
parents:
diff changeset
   448
        if (mLeftInRange) {
hgs
parents:
diff changeset
   449
            minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   450
            distanceVerticalEdges = rightToLeftOfInactiveRect;
hgs
parents:
diff changeset
   451
            xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   452
        }
hgs
parents:
diff changeset
   453
        else {
hgs
parents:
diff changeset
   454
            minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   455
            distanceVerticalEdges = rightToRightOfInactiveRect;
hgs
parents:
diff changeset
   456
            xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   457
        }
hgs
parents:
diff changeset
   458
    }
hgs
parents:
diff changeset
   459
    //else both edges of inactive rect are in range, check which is a better fit
hgs
parents:
diff changeset
   460
    else if (mLeftInRange && mRightInRange) {
hgs
parents:
diff changeset
   461
        //if right edge of moving rect to the right of the inactive rect is closer than the right edge of moving rect to the left of inactive rect
hgs
parents:
diff changeset
   462
        if (rightToRightOfInactiveRect < rightToLeftOfInactiveRect) {
hgs
parents:
diff changeset
   463
            minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   464
            distanceVerticalEdges = rightToRightOfInactiveRect;
hgs
parents:
diff changeset
   465
            xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   466
            mLeftInRange = false;
hgs
parents:
diff changeset
   467
        }
hgs
parents:
diff changeset
   468
        //if the right edge of moving rect to right of inactive rect is at the same distance as the right edge of moving rect to the left of inactive rect
hgs
parents:
diff changeset
   469
        else if (rightToRightOfInactiveRect == rightToLeftOfInactiveRect) {
hgs
parents:
diff changeset
   470
            //if inactive rect lies towards the right of container rect, then the right edge is priortized as the selected edge for outside snapping
hgs
parents:
diff changeset
   471
            if (differenceContainerRightEdgeToInactiveRectRightEdge < differenceContainerLeftEdgeToInactiveRectLeftEdge ) { 
hgs
parents:
diff changeset
   472
                minDistancePosition = mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   473
                distanceVerticalEdges = rightToRightOfInactiveRect;
hgs
parents:
diff changeset
   474
                xSnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   475
                mLeftInRange = false;
hgs
parents:
diff changeset
   476
            }
hgs
parents:
diff changeset
   477
            //else left of the inactive rect lies more close to the left or middle of the container rect, and hence prioritize it
hgs
parents:
diff changeset
   478
            else {
hgs
parents:
diff changeset
   479
                minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   480
                distanceVerticalEdges = rightToLeftOfInactiveRect;
hgs
parents:
diff changeset
   481
                xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   482
                mRightInRange = false;
hgs
parents:
diff changeset
   483
            }
hgs
parents:
diff changeset
   484
        }
hgs
parents:
diff changeset
   485
        //else right edge of moving rect to the left of the inactive rect is closer than the right edge of moving rect to the right of the incoming rect
hgs
parents:
diff changeset
   486
        else{
hgs
parents:
diff changeset
   487
            minDistancePosition = mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   488
            distanceVerticalEdges = rightToLeftOfInactiveRect;
hgs
parents:
diff changeset
   489
            xSnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   490
            mRightInRange = false;
hgs
parents:
diff changeset
   491
        }
hgs
parents:
diff changeset
   492
    }
hgs
parents:
diff changeset
   493
hgs
parents:
diff changeset
   494
    //Check if this inactive rect is better fit than the previous selected rect 
hgs
parents:
diff changeset
   495
    bool horizontalSnappingBetterFit = false;
hgs
parents:
diff changeset
   496
    if (mLeftInRange || mRightInRange) {
hgs
parents:
diff changeset
   497
        if (distanceVerticalEdges < mMinVerticalEdgesDistance) {
hgs
parents:
diff changeset
   498
            horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   499
        }
hgs
parents:
diff changeset
   500
        else if (distanceVerticalEdges == mMinVerticalEdgesDistance) { //the distance in the vertical edge is same as from the selected rectangle
hgs
parents:
diff changeset
   501
            //check the position of rect with respect to Vertical line
hgs
parents:
diff changeset
   502
            checkInactiveRectPositionToVerticalLine();
hgs
parents:
diff changeset
   503
            //if horizontal snap position was previously found and the rect's edge is in line with Vertical line
hgs
parents:
diff changeset
   504
            if (mHorizontalSnapFound && mRectVerticalEdgeLiesInLineWithVerticalLine) {
hgs
parents:
diff changeset
   505
                if (mRectLieAboveVerticalLine || mRectLieBelowVerticalLine) {
hgs
parents:
diff changeset
   506
                    extendVerticalLineToIncludeInactiveRect();
hgs
parents:
diff changeset
   507
                }
hgs
parents:
diff changeset
   508
            }
hgs
parents:
diff changeset
   509
            //here the case is that moving rect lies exactly in middle of two same sides of two inactive widgets.
hgs
parents:
diff changeset
   510
            else {
hgs
parents:
diff changeset
   511
                //Prioritize first on the fact if the inactive rect is closer to the moving rect in Y - direction.
hgs
parents:
diff changeset
   512
                if (mVerticalDistance < mVerticalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   513
                    horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   514
                }
hgs
parents:
diff changeset
   515
                else if (mVerticalDistance == mVerticalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   516
                    //Prioritize next if this Inactive rect is closer to the right edge of the container rect, then the previously selected rect
hgs
parents:
diff changeset
   517
                    if (differenceContainerRightEdgeToInactiveRectRightEdge < mContainerVerticalEdgeDistance) {
hgs
parents:
diff changeset
   518
                        horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   519
                    }
hgs
parents:
diff changeset
   520
                    //Prioritize next if the Inactive rect's right edge lies near to right edge of the container rect
hgs
parents:
diff changeset
   521
                    else if (differenceContainerRightEdgeToInactiveRectRightEdge < differenceContainerLeftEdgeToInactiveRectLeftEdge) {
hgs
parents:
diff changeset
   522
                        horizontalSnappingBetterFit = true;
hgs
parents:
diff changeset
   523
                    }
hgs
parents:
diff changeset
   524
                    else {
hgs
parents:
diff changeset
   525
                        //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, but in opposite Y direction.
hgs
parents:
diff changeset
   526
                        //In that case it does not matter which is the selected rectangle. Hece we leave the already selected rectangle as the better fit.
hgs
parents:
diff changeset
   527
                    }
hgs
parents:
diff changeset
   528
                }
hgs
parents:
diff changeset
   529
            }
hgs
parents:
diff changeset
   530
        }
hgs
parents:
diff changeset
   531
    }
hgs
parents:
diff changeset
   532
hgs
parents:
diff changeset
   533
    if (horizontalSnappingBetterFit) {
hgs
parents:
diff changeset
   534
        qreal proposedLeftOfActiveRect = minDistancePosition - mActiveRectWidth - xSnapGapAdjustment;
hgs
parents:
diff changeset
   535
        if (qBound(mContainerRect.left(), proposedLeftOfActiveRect, mContainerRect.right())
hgs
parents:
diff changeset
   536
            == proposedLeftOfActiveRect) {
hgs
parents:
diff changeset
   537
            mHorizontalSnapFound = true;
hgs
parents:
diff changeset
   538
            mHorizontalSnapPosition = proposedLeftOfActiveRect;
hgs
parents:
diff changeset
   539
            mMinVerticalEdgesDistance = distanceVerticalEdges;
hgs
parents:
diff changeset
   540
            mVerticalDistanceFromSelectedRect = mVerticalDistance;
hgs
parents:
diff changeset
   541
            //Save the new distance of the Chosen Rectangle's right edge from Container's right edge
hgs
parents:
diff changeset
   542
            mContainerVerticalEdgeDistance = differenceContainerRightEdgeToInactiveRectRightEdge;
hgs
parents:
diff changeset
   543
hgs
parents:
diff changeset
   544
            if (mRectLieAbove) {
hgs
parents:
diff changeset
   545
                //save the points for the Vertical line
hgs
parents:
diff changeset
   546
                mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.top()));
hgs
parents:
diff changeset
   547
                mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.bottom()));
hgs
parents:
diff changeset
   548
            }
hgs
parents:
diff changeset
   549
            else {
hgs
parents:
diff changeset
   550
                //save the points for the Vertical line
hgs
parents:
diff changeset
   551
                mVerticalLine.setP1(QPointF(minDistancePosition, mInactiveRectToCompare.bottom()));
hgs
parents:
diff changeset
   552
                mVerticalLine.setP2(QPointF(minDistancePosition, mMovingRect.top()));
hgs
parents:
diff changeset
   553
            }
hgs
parents:
diff changeset
   554
        }
hgs
parents:
diff changeset
   555
    }
hgs
parents:
diff changeset
   556
}
hgs
parents:
diff changeset
   557
hgs
parents:
diff changeset
   558
/*!
hgs
parents:
diff changeset
   559
    Check if the inactive rect being compared with moving rect lies on left or right of moving rect.
hgs
parents:
diff changeset
   560
*/
hgs
parents:
diff changeset
   561
void HsSnapToLines::checkInactiveRectLieLeftOrRightOfMovingRect()
hgs
parents:
diff changeset
   562
{
hgs
parents:
diff changeset
   563
    mRectLieLeft = false;
hgs
parents:
diff changeset
   564
    mHorizontalDistance = 0.0;
hgs
parents:
diff changeset
   565
    //Inactive Rect lies left of the Moving Rect
hgs
parents:
diff changeset
   566
    if (mInactiveRectToCompare.left() < mMovingRect.left()) {
hgs
parents:
diff changeset
   567
        mRectLieLeft = true;
hgs
parents:
diff changeset
   568
        if (mInactiveRectToCompare.right() <= mMovingRect.left()) {
hgs
parents:
diff changeset
   569
            mHorizontalDistance = mMovingRect.left() - mInactiveRectToCompare.right();
hgs
parents:
diff changeset
   570
        }
hgs
parents:
diff changeset
   571
        else {
hgs
parents:
diff changeset
   572
            mHorizontalDistance = mMovingRect.left() - mInactiveRectToCompare.left();
hgs
parents:
diff changeset
   573
        }
hgs
parents:
diff changeset
   574
    }
hgs
parents:
diff changeset
   575
    //Inactive Rect lies right of the Moving Rect
hgs
parents:
diff changeset
   576
    else {
hgs
parents:
diff changeset
   577
        mRectLieLeft = false;
hgs
parents:
diff changeset
   578
        if (mMovingRect.right() <= mInactiveRectToCompare.left()) {
hgs
parents:
diff changeset
   579
            mHorizontalDistance = mInactiveRectToCompare.left() - mMovingRect.right();
hgs
parents:
diff changeset
   580
        }
hgs
parents:
diff changeset
   581
        else {
hgs
parents:
diff changeset
   582
            mHorizontalDistance = mInactiveRectToCompare.right() - mMovingRect.right();
hgs
parents:
diff changeset
   583
        }
hgs
parents:
diff changeset
   584
    }
hgs
parents:
diff changeset
   585
}
hgs
parents:
diff changeset
   586
hgs
parents:
diff changeset
   587
/*!
hgs
parents:
diff changeset
   588
    Check if the top edge of moving rect is snappable to the incative rect's top or bottom edge.
hgs
parents:
diff changeset
   589
    The inactive rect's edge is only chosen if it is a better fit for vertical snapping.
hgs
parents:
diff changeset
   590
*/
hgs
parents:
diff changeset
   591
void HsSnapToLines::compareTopOfMovingRectForSnapping()
hgs
parents:
diff changeset
   592
{
hgs
parents:
diff changeset
   593
    //Check if the inactive rect lies to the left or right of the moving rect
hgs
parents:
diff changeset
   594
    checkInactiveRectLieLeftOrRightOfMovingRect();
hgs
parents:
diff changeset
   595
hgs
parents:
diff changeset
   596
    //calculate the distance of the moving rect's top edge to the inactive rect's top and bottom edges
hgs
parents:
diff changeset
   597
    qreal topToTopOfInactiveRect = qAbs(mInactiveRectToCompare.top() - mMovingRect.top());
hgs
parents:
diff changeset
   598
    qreal topToBottomOfInactiveRect = qAbs(mInactiveRectToCompare.bottom() - mMovingRect.top());
hgs
parents:
diff changeset
   599
    mTopInRange = false;
hgs
parents:
diff changeset
   600
    mBottomInRange = false;
hgs
parents:
diff changeset
   601
hgs
parents:
diff changeset
   602
    if (topToTopOfInactiveRect <= mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   603
        if (mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForRight
hgs
parents:
diff changeset
   604
         || !mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForLeft) {
hgs
parents:
diff changeset
   605
            mTopInRange = true;
hgs
parents:
diff changeset
   606
        }
hgs
parents:
diff changeset
   607
    }
hgs
parents:
diff changeset
   608
    if (topToBottomOfInactiveRect <= mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   609
        if (mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForRight
hgs
parents:
diff changeset
   610
         || !mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForLeft) {
hgs
parents:
diff changeset
   611
            mBottomInRange = true;
hgs
parents:
diff changeset
   612
        }
hgs
parents:
diff changeset
   613
    }
hgs
parents:
diff changeset
   614
hgs
parents:
diff changeset
   615
    //calculate the distance of inactive rect's top edge and container rect's top edge
hgs
parents:
diff changeset
   616
    qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top();
hgs
parents:
diff changeset
   617
    //calculate the distance of inactive rect's bottom edge and container rect's bottom edge
hgs
parents:
diff changeset
   618
    qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   619
    qreal minDistancePosition = 0.0;
hgs
parents:
diff changeset
   620
    qreal distanceHorizontalEdges = 0.0;
hgs
parents:
diff changeset
   621
    qreal ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   622
hgs
parents:
diff changeset
   623
    //If only one edge of inactive rect is in snappable range, save that position
hgs
parents:
diff changeset
   624
    if ((mTopInRange && !mBottomInRange)
hgs
parents:
diff changeset
   625
        || !mTopInRange && mBottomInRange) {
hgs
parents:
diff changeset
   626
        if (mTopInRange) {
hgs
parents:
diff changeset
   627
            minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   628
            distanceHorizontalEdges = topToTopOfInactiveRect;
hgs
parents:
diff changeset
   629
            ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   630
        }
hgs
parents:
diff changeset
   631
        else {
hgs
parents:
diff changeset
   632
            minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   633
            distanceHorizontalEdges = topToBottomOfInactiveRect;
hgs
parents:
diff changeset
   634
            ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   635
        }
hgs
parents:
diff changeset
   636
    }
hgs
parents:
diff changeset
   637
    //else both edges of inactive rect are in range, check which is a better fit
hgs
parents:
diff changeset
   638
    else if (mTopInRange && mBottomInRange) {
hgs
parents:
diff changeset
   639
        //if top edge of moving rect to the top of the inactive rect is closer than the bottom edge of moving rect to the bottom of the inactive rect
hgs
parents:
diff changeset
   640
        if (topToTopOfInactiveRect < topToBottomOfInactiveRect) {
hgs
parents:
diff changeset
   641
            minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   642
            distanceHorizontalEdges = topToTopOfInactiveRect;
hgs
parents:
diff changeset
   643
            ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   644
            mBottomInRange = false;
hgs
parents:
diff changeset
   645
        }
hgs
parents:
diff changeset
   646
        //if the top edge of moving rect to top of inactive rect is at the same distance as the top edge of moving rect to the bottom of inactive rect
hgs
parents:
diff changeset
   647
        else if (topToTopOfInactiveRect == topToBottomOfInactiveRect) {
hgs
parents:
diff changeset
   648
            //if inactive rect lies towards the top or middle of container rect, then the top edge is priortized as the selected edge for outside snapping
hgs
parents:
diff changeset
   649
            if (differenceContainerTopEdgeToInactiveRectTopEdge <= differenceContainerBottomEdgeToInactiveRectBottomEdge) { 
hgs
parents:
diff changeset
   650
                minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   651
                distanceHorizontalEdges = topToTopOfInactiveRect;
hgs
parents:
diff changeset
   652
                ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   653
                mBottomInRange = false;
hgs
parents:
diff changeset
   654
            }
hgs
parents:
diff changeset
   655
            //else bottom of the inactive rect lies more close to the bottom of the container rect, and hence prioritize it for snapping.
hgs
parents:
diff changeset
   656
            else {
hgs
parents:
diff changeset
   657
                minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   658
                distanceHorizontalEdges = topToBottomOfInactiveRect;
hgs
parents:
diff changeset
   659
                ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   660
                mTopInRange = false;
hgs
parents:
diff changeset
   661
            }
hgs
parents:
diff changeset
   662
        }
hgs
parents:
diff changeset
   663
        //else top edge of moving rect to the bottom of the inactive rect is closer than the top edge of moving rect to the top of the inactive rect
hgs
parents:
diff changeset
   664
        else{
hgs
parents:
diff changeset
   665
            minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   666
            distanceHorizontalEdges = topToBottomOfInactiveRect;
hgs
parents:
diff changeset
   667
            ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   668
            mTopInRange = false;
hgs
parents:
diff changeset
   669
        }
hgs
parents:
diff changeset
   670
    }
hgs
parents:
diff changeset
   671
hgs
parents:
diff changeset
   672
    //Check if this inactive rect is better fit than the previous selected rect 
hgs
parents:
diff changeset
   673
    bool verticalSnappingBetterFit = false;
hgs
parents:
diff changeset
   674
    if (mTopInRange || mBottomInRange) {
hgs
parents:
diff changeset
   675
        if (distanceHorizontalEdges < mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   676
            verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   677
        }
hgs
parents:
diff changeset
   678
        else if (distanceHorizontalEdges == mMinHorizontalEdgesDistance) { //the distance in the horizontal edge is same as from the selected rectangle
hgs
parents:
diff changeset
   679
            //check the position of rect with respect to horizontal line
hgs
parents:
diff changeset
   680
            checkInactiveRectPositionToHorizontalLine();
hgs
parents:
diff changeset
   681
            //if vertical snap position was already found and this rect's horizontal edges lies in line with Horizontal snap line
hgs
parents:
diff changeset
   682
            if (mVerticalSnapFound && mRectHorizontalEdgeLiesInLineWithHorizontalLine) {
hgs
parents:
diff changeset
   683
                if (mRectLieLeftOfHorizontalLine || mRectLiesRightOfHorizontalLine) {
hgs
parents:
diff changeset
   684
                    extendHorizontalLineToIncludeInactiveRect();
hgs
parents:
diff changeset
   685
                }
hgs
parents:
diff changeset
   686
            }
hgs
parents:
diff changeset
   687
            else {
hgs
parents:
diff changeset
   688
                //Prioritize first on the fact if the inactive rect is closer to the moving rect in X - direction.
hgs
parents:
diff changeset
   689
                if (mHorizontalDistance < mHorizontalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   690
                    verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   691
                }
hgs
parents:
diff changeset
   692
                else if (mHorizontalDistance == mHorizontalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   693
                    //Prioritize next if this Inactive rect is closer to the top edge of the container rect, then the previously selected rect
hgs
parents:
diff changeset
   694
                    if (differenceContainerTopEdgeToInactiveRectTopEdge < mContainerHorizontalEdgeDistance) {
hgs
parents:
diff changeset
   695
                        verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   696
                    }
hgs
parents:
diff changeset
   697
                    //Prioritize next if the Inactive widget's top edge lies near to top edge of the container rect
hgs
parents:
diff changeset
   698
                    else if (differenceContainerTopEdgeToInactiveRectTopEdge < differenceContainerBottomEdgeToInactiveRectBottomEdge) {
hgs
parents:
diff changeset
   699
                        verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   700
                    }
hgs
parents:
diff changeset
   701
                    else {
hgs
parents:
diff changeset
   702
                        //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, or in opposite X direction.
hgs
parents:
diff changeset
   703
                        //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit.
hgs
parents:
diff changeset
   704
                    }
hgs
parents:
diff changeset
   705
                }
hgs
parents:
diff changeset
   706
            }
hgs
parents:
diff changeset
   707
        }
hgs
parents:
diff changeset
   708
    }
hgs
parents:
diff changeset
   709
hgs
parents:
diff changeset
   710
    if (verticalSnappingBetterFit) {
hgs
parents:
diff changeset
   711
        qreal proposedBottomOfActiveRect = minDistancePosition + mActiveRectHeight + ySnapGapAdjustment;
hgs
parents:
diff changeset
   712
        if (qBound(mContainerRect.top(), proposedBottomOfActiveRect, mContainerRect.bottom())
hgs
parents:
diff changeset
   713
            == proposedBottomOfActiveRect) {
hgs
parents:
diff changeset
   714
            mVerticalSnapFound = true;
hgs
parents:
diff changeset
   715
            mVerticalSnapPosition = minDistancePosition + ySnapGapAdjustment;
hgs
parents:
diff changeset
   716
            mMinHorizontalEdgesDistance = distanceHorizontalEdges;
hgs
parents:
diff changeset
   717
            mHorizontalDistanceFromSelectedRect = mHorizontalDistance;
hgs
parents:
diff changeset
   718
            //Save the new distance of the Chosen Rectangle's top edge from Container's top edge
hgs
parents:
diff changeset
   719
            mContainerHorizontalEdgeDistance = differenceContainerTopEdgeToInactiveRectTopEdge;
hgs
parents:
diff changeset
   720
hgs
parents:
diff changeset
   721
            if (mRectLieLeft) {
hgs
parents:
diff changeset
   722
                //save the points for the Horizontal line
hgs
parents:
diff changeset
   723
                mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), minDistancePosition));
hgs
parents:
diff changeset
   724
                mHorizontalLine.setP2(QPointF(mMovingRect.right(), minDistancePosition));
hgs
parents:
diff changeset
   725
            }
hgs
parents:
diff changeset
   726
            else {
hgs
parents:
diff changeset
   727
                //save the points for the Horizontal line
hgs
parents:
diff changeset
   728
                mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), minDistancePosition));
hgs
parents:
diff changeset
   729
                mHorizontalLine.setP2(QPointF(mMovingRect.left(), minDistancePosition));
hgs
parents:
diff changeset
   730
            }
hgs
parents:
diff changeset
   731
        }
hgs
parents:
diff changeset
   732
    }
hgs
parents:
diff changeset
   733
}
hgs
parents:
diff changeset
   734
hgs
parents:
diff changeset
   735
/*!
hgs
parents:
diff changeset
   736
    Check if the bottom edge of moving rect is snappable to the incative rect's top or bottom edge.
hgs
parents:
diff changeset
   737
    The inactive rect's edge is only chosen if it is a better fit for vertical snapping.
hgs
parents:
diff changeset
   738
*/
hgs
parents:
diff changeset
   739
void HsSnapToLines::compareBottomOfMovingRectForSnapping()
hgs
parents:
diff changeset
   740
{
hgs
parents:
diff changeset
   741
    //Check if the inactive rect lies to the left or right of the moving rect
hgs
parents:
diff changeset
   742
    checkInactiveRectLieLeftOrRightOfMovingRect();
hgs
parents:
diff changeset
   743
hgs
parents:
diff changeset
   744
    //calculate the distance of the moving rect's bottom edge to the inactive rect's top and bottom edges
hgs
parents:
diff changeset
   745
    qreal bottomToTopOfInactiveRect = qAbs(mInactiveRectToCompare.top() - mMovingRect.bottom());
hgs
parents:
diff changeset
   746
    qreal bottomToBottomOfInactiveRect = qAbs(mInactiveRectToCompare.bottom() - mMovingRect.bottom());
hgs
parents:
diff changeset
   747
    mTopInRange = false;
hgs
parents:
diff changeset
   748
    mBottomInRange = false;
hgs
parents:
diff changeset
   749
hgs
parents:
diff changeset
   750
    if (bottomToTopOfInactiveRect <= mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   751
        if (mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForRight
hgs
parents:
diff changeset
   752
         || !mRectLieLeft && mInactiveSnapRectToCompare.isTopSnapableForLeft) {
hgs
parents:
diff changeset
   753
            mTopInRange = true;
hgs
parents:
diff changeset
   754
        }
hgs
parents:
diff changeset
   755
    }
hgs
parents:
diff changeset
   756
    if (bottomToBottomOfInactiveRect <= mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   757
        if (mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForRight
hgs
parents:
diff changeset
   758
         || !mRectLieLeft && mInactiveSnapRectToCompare.isBottomSnapableForLeft) {
hgs
parents:
diff changeset
   759
            mBottomInRange = true;
hgs
parents:
diff changeset
   760
        }
hgs
parents:
diff changeset
   761
    }
hgs
parents:
diff changeset
   762
hgs
parents:
diff changeset
   763
    //calculate the distance of inactive rect's top edge and container rect's top edge
hgs
parents:
diff changeset
   764
    qreal differenceContainerTopEdgeToInactiveRectTopEdge = mInactiveRectToCompare.top() - mContainerRect.top();
hgs
parents:
diff changeset
   765
    //calculate the distance of inactive rect's bottom edge and container rect's bottom edge
hgs
parents:
diff changeset
   766
    qreal differenceContainerBottomEdgeToInactiveRectBottomEdge = mContainerRect.bottom() - mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   767
    qreal minDistancePosition = 0.0;
hgs
parents:
diff changeset
   768
    qreal distanceHorizontalEdges = 0.0;
hgs
parents:
diff changeset
   769
    qreal ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   770
hgs
parents:
diff changeset
   771
    //If only one edge of inactive rect is in snappable range, save that position
hgs
parents:
diff changeset
   772
    if ((mTopInRange && !mBottomInRange)
hgs
parents:
diff changeset
   773
        || !mTopInRange && mBottomInRange) {
hgs
parents:
diff changeset
   774
        if (mTopInRange) {
hgs
parents:
diff changeset
   775
            minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   776
            distanceHorizontalEdges = bottomToTopOfInactiveRect;
hgs
parents:
diff changeset
   777
            ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   778
        }
hgs
parents:
diff changeset
   779
        else {
hgs
parents:
diff changeset
   780
            minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   781
            distanceHorizontalEdges = bottomToBottomOfInactiveRect;
hgs
parents:
diff changeset
   782
            ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   783
        }
hgs
parents:
diff changeset
   784
    }
hgs
parents:
diff changeset
   785
    //else both edges of inactive rect are in range, check which is a better fit
hgs
parents:
diff changeset
   786
    else if (mTopInRange && mBottomInRange) {
hgs
parents:
diff changeset
   787
        //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
hgs
parents:
diff changeset
   788
        if (bottomToBottomOfInactiveRect < bottomToTopOfInactiveRect ) {
hgs
parents:
diff changeset
   789
            minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   790
            distanceHorizontalEdges = bottomToBottomOfInactiveRect;
hgs
parents:
diff changeset
   791
            ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   792
            mTopInRange = false;
hgs
parents:
diff changeset
   793
        }
hgs
parents:
diff changeset
   794
        //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
hgs
parents:
diff changeset
   795
        else if (bottomToBottomOfInactiveRect == bottomToTopOfInactiveRect) {
hgs
parents:
diff changeset
   796
            //if inactive rect lies towards the bottom of container rect, then the bottom edge is priortized as the selected edge for snapping
hgs
parents:
diff changeset
   797
            //This is done for outside snapping
hgs
parents:
diff changeset
   798
            if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) {
hgs
parents:
diff changeset
   799
                minDistancePosition = mInactiveRectToCompare.bottom();
hgs
parents:
diff changeset
   800
                distanceHorizontalEdges = bottomToBottomOfInactiveRect;
hgs
parents:
diff changeset
   801
                ySnapGapAdjustment = 0.0;
hgs
parents:
diff changeset
   802
                mTopInRange = false;
hgs
parents:
diff changeset
   803
            }
hgs
parents:
diff changeset
   804
            //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
hgs
parents:
diff changeset
   805
            else {
hgs
parents:
diff changeset
   806
                minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   807
                distanceHorizontalEdges = bottomToTopOfInactiveRect;
hgs
parents:
diff changeset
   808
                ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   809
                mBottomInRange = false;
hgs
parents:
diff changeset
   810
            }
hgs
parents:
diff changeset
   811
        }
hgs
parents:
diff changeset
   812
        //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
hgs
parents:
diff changeset
   813
        else{
hgs
parents:
diff changeset
   814
            minDistancePosition = mInactiveRectToCompare.top();
hgs
parents:
diff changeset
   815
            distanceHorizontalEdges = bottomToTopOfInactiveRect;
hgs
parents:
diff changeset
   816
            ySnapGapAdjustment = mSnapGap;
hgs
parents:
diff changeset
   817
            mBottomInRange = false;
hgs
parents:
diff changeset
   818
        }
hgs
parents:
diff changeset
   819
    }
hgs
parents:
diff changeset
   820
hgs
parents:
diff changeset
   821
    //Check if this inactive rect is better fit than the previous selected rect 
hgs
parents:
diff changeset
   822
    bool verticalSnappingBetterFit = false;
hgs
parents:
diff changeset
   823
    if (mTopInRange || mBottomInRange) {
hgs
parents:
diff changeset
   824
        if (distanceHorizontalEdges < mMinHorizontalEdgesDistance) {
hgs
parents:
diff changeset
   825
            verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   826
        }
hgs
parents:
diff changeset
   827
        else if (distanceHorizontalEdges == mMinHorizontalEdgesDistance) { //the distance in the horizontal edge is same as from the selected rectangle
hgs
parents:
diff changeset
   828
            //check the position of rect with respect to horizontal line
hgs
parents:
diff changeset
   829
            checkInactiveRectPositionToHorizontalLine();
hgs
parents:
diff changeset
   830
            //if vertical snap was already found and the horizontal line of rect is in line with horizontal snap line
hgs
parents:
diff changeset
   831
            if (mVerticalSnapFound && mRectHorizontalEdgeLiesInLineWithHorizontalLine) {
hgs
parents:
diff changeset
   832
                if (mRectLieLeftOfHorizontalLine || mRectLiesRightOfHorizontalLine) {
hgs
parents:
diff changeset
   833
                    extendHorizontalLineToIncludeInactiveRect();
hgs
parents:
diff changeset
   834
                }
hgs
parents:
diff changeset
   835
            }
hgs
parents:
diff changeset
   836
            else {
hgs
parents:
diff changeset
   837
                //Prioritize first on the fact if the inactive rect is closer to the moving rect in X - direction.
hgs
parents:
diff changeset
   838
                if (mHorizontalDistance < mHorizontalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   839
                    verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   840
                }
hgs
parents:
diff changeset
   841
                else if (mHorizontalDistance == mHorizontalDistanceFromSelectedRect) {
hgs
parents:
diff changeset
   842
                    //Prioritize next if this Inactive rect is closer to the bottom edge of the container rect, then the previously selected rect
hgs
parents:
diff changeset
   843
                    if (differenceContainerBottomEdgeToInactiveRectBottomEdge < mContainerHorizontalEdgeDistance) {
hgs
parents:
diff changeset
   844
                        verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   845
                    }
hgs
parents:
diff changeset
   846
                    //Prioritize next if the Inactive widget's bottom edge lies near to bottom edge of the container rect
hgs
parents:
diff changeset
   847
                    else if (differenceContainerBottomEdgeToInactiveRectBottomEdge < differenceContainerTopEdgeToInactiveRectTopEdge) {
hgs
parents:
diff changeset
   848
                        verticalSnappingBetterFit = true;
hgs
parents:
diff changeset
   849
                    }
hgs
parents:
diff changeset
   850
                    else {
hgs
parents:
diff changeset
   851
                        //This else will happen if this rectangle being compared is exactly the same as the selected rectangle for snapping, or in opposite X direction.
hgs
parents:
diff changeset
   852
                        //In that case it does not matter which is the selected rectangle. Hence we leave the already selected rectangle as the better fit.
hgs
parents:
diff changeset
   853
                    }
hgs
parents:
diff changeset
   854
                }
hgs
parents:
diff changeset
   855
            }
hgs
parents:
diff changeset
   856
        }
hgs
parents:
diff changeset
   857
    }
hgs
parents:
diff changeset
   858
hgs
parents:
diff changeset
   859
    if (verticalSnappingBetterFit) {
hgs
parents:
diff changeset
   860
        qreal proposedTopOfActiveRect = minDistancePosition - mActiveRectHeight - ySnapGapAdjustment;
hgs
parents:
diff changeset
   861
        if (qBound(mContainerRect.top(), proposedTopOfActiveRect, mContainerRect.bottom())
hgs
parents:
diff changeset
   862
            == proposedTopOfActiveRect) {
hgs
parents:
diff changeset
   863
            mVerticalSnapFound = true;
hgs
parents:
diff changeset
   864
            mVerticalSnapPosition = proposedTopOfActiveRect;
hgs
parents:
diff changeset
   865
            mMinHorizontalEdgesDistance = distanceHorizontalEdges;
hgs
parents:
diff changeset
   866
            mHorizontalDistanceFromSelectedRect = mHorizontalDistance;
hgs
parents:
diff changeset
   867
            //Save the new distance of the Selected Rectangle's bottom edge from Container's bottom edge
hgs
parents:
diff changeset
   868
            mContainerHorizontalEdgeDistance = differenceContainerBottomEdgeToInactiveRectBottomEdge;
hgs
parents:
diff changeset
   869
hgs
parents:
diff changeset
   870
            if (mRectLieLeft) {
hgs
parents:
diff changeset
   871
                //save the points for the Horizontal line
hgs
parents:
diff changeset
   872
                mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), minDistancePosition));
hgs
parents:
diff changeset
   873
                mHorizontalLine.setP2(QPointF(mMovingRect.right(), minDistancePosition));
hgs
parents:
diff changeset
   874
            }
hgs
parents:
diff changeset
   875
            else {
hgs
parents:
diff changeset
   876
                //save the points for the Horizontal line
hgs
parents:
diff changeset
   877
                mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), minDistancePosition));
hgs
parents:
diff changeset
   878
                mHorizontalLine.setP2(QPointF(mMovingRect.left(), minDistancePosition));
hgs
parents:
diff changeset
   879
            }
hgs
parents:
diff changeset
   880
        }
hgs
parents:
diff changeset
   881
    }
hgs
parents:
diff changeset
   882
}
hgs
parents:
diff changeset
   883
hgs
parents:
diff changeset
   884
/*!
hgs
parents:
diff changeset
   885
    Extend the Vertical line on both side of reference(snapping) rectancles.
hgs
parents:
diff changeset
   886
*/
hgs
parents:
diff changeset
   887
void HsSnapToLines::extendVerticalLine()
hgs
parents:
diff changeset
   888
{
hgs
parents:
diff changeset
   889
    if (mVerticalLine.y1() <= mVerticalLine.y2()) {
hgs
parents:
diff changeset
   890
        mVerticalLine.setP1(QPointF(mVerticalLine.x1(), mVerticalLine.y1() - SNAP_LINE_EXTEND_VALUE));
hgs
parents:
diff changeset
   891
        mVerticalLine.setP2(QPointF(mVerticalLine.x2(), mVerticalLine.y2() + SNAP_LINE_EXTEND_VALUE));
hgs
parents:
diff changeset
   892
    }
hgs
parents:
diff changeset
   893
    else {
hgs
parents:
diff changeset
   894
        mVerticalLine.setP1(QPointF(mVerticalLine.x1(), mVerticalLine.y1() + SNAP_LINE_EXTEND_VALUE));
hgs
parents:
diff changeset
   895
        mVerticalLine.setP2(QPointF(mVerticalLine.x2(), mVerticalLine.y2() - SNAP_LINE_EXTEND_VALUE));
hgs
parents:
diff changeset
   896
    }
hgs
parents:
diff changeset
   897
}
hgs
parents:
diff changeset
   898
hgs
parents:
diff changeset
   899
/*!
hgs
parents:
diff changeset
   900
    Extend the Horizontal line on both side of reference(snapping) rectancles.
hgs
parents:
diff changeset
   901
*/
hgs
parents:
diff changeset
   902
void HsSnapToLines::extendHorizontalLine()
hgs
parents:
diff changeset
   903
{
hgs
parents:
diff changeset
   904
    if (mHorizontalLine.x1() <= mHorizontalLine.x2()) {
hgs
parents:
diff changeset
   905
        mHorizontalLine.setP1(QPointF(mHorizontalLine.x1() - SNAP_LINE_EXTEND_VALUE, mHorizontalLine.y1()));
hgs
parents:
diff changeset
   906
        mHorizontalLine.setP2(QPointF(mHorizontalLine.x2() + SNAP_LINE_EXTEND_VALUE, mHorizontalLine.y2()));
hgs
parents:
diff changeset
   907
    }
hgs
parents:
diff changeset
   908
    else {
hgs
parents:
diff changeset
   909
        mHorizontalLine.setP1(QPointF(mHorizontalLine.x1() + SNAP_LINE_EXTEND_VALUE, mHorizontalLine.y1()));
hgs
parents:
diff changeset
   910
        mHorizontalLine.setP2(QPointF(mHorizontalLine.x2() - SNAP_LINE_EXTEND_VALUE, mHorizontalLine.y2()));
hgs
parents:
diff changeset
   911
    }
hgs
parents:
diff changeset
   912
}
hgs
parents:
diff changeset
   913
hgs
parents:
diff changeset
   914
/*!
hgs
parents:
diff changeset
   915
    Check if the Vertical edge of the Rectangle lies out of the Vertical line.
hgs
parents:
diff changeset
   916
    Also check if the rectangle's edge lies out of the line.
hgs
parents:
diff changeset
   917
*/
hgs
parents:
diff changeset
   918
void HsSnapToLines::checkInactiveRectPositionToVerticalLine()
hgs
parents:
diff changeset
   919
{
hgs
parents:
diff changeset
   920
    mRectVerticalEdgeLiesInLineWithVerticalLine = false;
hgs
parents:
diff changeset
   921
    mRectLieAboveVerticalLine = false;
hgs
parents:
diff changeset
   922
    mRectLieBelowVerticalLine = false;
hgs
parents:
diff changeset
   923
hgs
parents:
diff changeset
   924
    //if rectangle vertical edge lies inline with Vertical line.
hgs
parents:
diff changeset
   925
    if ((mLeftInRange && mInactiveRectToCompare.left() == mVerticalLine.x1())
hgs
parents:
diff changeset
   926
        || (mRightInRange && mInactiveRectToCompare.right() == mVerticalLine.x1())) {
hgs
parents:
diff changeset
   927
        mRectVerticalEdgeLiesInLineWithVerticalLine = true;
hgs
parents:
diff changeset
   928
        //if the rectangle lies below the vertical line
hgs
parents:
diff changeset
   929
        if (mInactiveRectToCompare.bottom() > mVerticalLine.y1() && mInactiveRectToCompare.bottom() > mVerticalLine.y2()) {
hgs
parents:
diff changeset
   930
            mRectLieBelowVerticalLine = true;
hgs
parents:
diff changeset
   931
        }
hgs
parents:
diff changeset
   932
        //if the rectangle lies above the vertical line
hgs
parents:
diff changeset
   933
        if (mInactiveRectToCompare.top() < mVerticalLine.y1() && mInactiveRectToCompare.top() < mVerticalLine.y2()) {
hgs
parents:
diff changeset
   934
            mRectLieAboveVerticalLine = true;
hgs
parents:
diff changeset
   935
        }
hgs
parents:
diff changeset
   936
    }
hgs
parents:
diff changeset
   937
}
hgs
parents:
diff changeset
   938
hgs
parents:
diff changeset
   939
/*!
hgs
parents:
diff changeset
   940
    Increase the Vertical line to include the inactive rect whose vertical edge is inline with vertical line
hgs
parents:
diff changeset
   941
*/
hgs
parents:
diff changeset
   942
void HsSnapToLines::extendVerticalLineToIncludeInactiveRect()
hgs
parents:
diff changeset
   943
{
hgs
parents:
diff changeset
   944
    if (mRectLieAboveVerticalLine) {
hgs
parents:
diff changeset
   945
        if (mVerticalLine.y1() < mVerticalLine.y2()) {
hgs
parents:
diff changeset
   946
            mVerticalLine.setP1(QPointF(mVerticalLine.x1(), mInactiveRectToCompare.top()));
hgs
parents:
diff changeset
   947
        }
hgs
parents:
diff changeset
   948
        else {
hgs
parents:
diff changeset
   949
            mVerticalLine.setP2(QPointF(mVerticalLine.x1(), mInactiveRectToCompare.top()));
hgs
parents:
diff changeset
   950
        }
hgs
parents:
diff changeset
   951
    }
hgs
parents:
diff changeset
   952
    if (mRectLieBelowVerticalLine) {
hgs
parents:
diff changeset
   953
        if (mVerticalLine.y1() < mVerticalLine.y2()) {
hgs
parents:
diff changeset
   954
            mVerticalLine.setP2(QPointF(mVerticalLine.x1(), mInactiveRectToCompare.bottom()));
hgs
parents:
diff changeset
   955
        }
hgs
parents:
diff changeset
   956
        else {
hgs
parents:
diff changeset
   957
            mVerticalLine.setP1(QPointF(mVerticalLine.x1(), mInactiveRectToCompare.bottom()));
hgs
parents:
diff changeset
   958
        }
hgs
parents:
diff changeset
   959
    }
hgs
parents:
diff changeset
   960
}
hgs
parents:
diff changeset
   961
hgs
parents:
diff changeset
   962
/*!
hgs
parents:
diff changeset
   963
    Check if the Horizontal edge of the Rectangle lies inline with the Horizontal line.
hgs
parents:
diff changeset
   964
    Also check if the rectangle's edge lies out of the line.
hgs
parents:
diff changeset
   965
*/
hgs
parents:
diff changeset
   966
void HsSnapToLines::checkInactiveRectPositionToHorizontalLine()
hgs
parents:
diff changeset
   967
{
hgs
parents:
diff changeset
   968
    mRectHorizontalEdgeLiesInLineWithHorizontalLine = false;
hgs
parents:
diff changeset
   969
    mRectLieLeftOfHorizontalLine = false;
hgs
parents:
diff changeset
   970
    mRectLiesRightOfHorizontalLine = false;
hgs
parents:
diff changeset
   971
hgs
parents:
diff changeset
   972
    //if rectangle horizontal edge lies inline with Horizontal line.
hgs
parents:
diff changeset
   973
    if ((mTopInRange && mInactiveRectToCompare.top() == mHorizontalLine.y1())
hgs
parents:
diff changeset
   974
        || (mBottomInRange && mInactiveRectToCompare.bottom() == mHorizontalLine.y1())) {
hgs
parents:
diff changeset
   975
        mRectHorizontalEdgeLiesInLineWithHorizontalLine = true;
hgs
parents:
diff changeset
   976
        //if the rectangle lies left of the horizontal line
hgs
parents:
diff changeset
   977
        if (mInactiveRectToCompare.left() < mHorizontalLine.x1() && mInactiveRectToCompare.left() < mHorizontalLine.x2()) {
hgs
parents:
diff changeset
   978
            mRectLieLeftOfHorizontalLine = true;
hgs
parents:
diff changeset
   979
        }
hgs
parents:
diff changeset
   980
        //if the rectangle lies right of the horizontal line
hgs
parents:
diff changeset
   981
        if (mInactiveRectToCompare.right() > mHorizontalLine.x1() && mInactiveRectToCompare.right() > mHorizontalLine.x2()) {
hgs
parents:
diff changeset
   982
            mRectLiesRightOfHorizontalLine = true;
hgs
parents:
diff changeset
   983
        }
hgs
parents:
diff changeset
   984
    }
hgs
parents:
diff changeset
   985
}
hgs
parents:
diff changeset
   986
hgs
parents:
diff changeset
   987
/*!
hgs
parents:
diff changeset
   988
    Increase the Horizontal line to include the inactive rect whose horizontal edge is inline with horizontal line
hgs
parents:
diff changeset
   989
*/
hgs
parents:
diff changeset
   990
void HsSnapToLines::extendHorizontalLineToIncludeInactiveRect()
hgs
parents:
diff changeset
   991
{
hgs
parents:
diff changeset
   992
    if (mRectLieLeftOfHorizontalLine) {
hgs
parents:
diff changeset
   993
        if (mHorizontalLine.x1() < mHorizontalLine.x2()) {
hgs
parents:
diff changeset
   994
            mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.left(), mHorizontalLine.y1()));
hgs
parents:
diff changeset
   995
        }
hgs
parents:
diff changeset
   996
        else {
hgs
parents:
diff changeset
   997
            mHorizontalLine.setP2(QPointF(mInactiveRectToCompare.left(), mHorizontalLine.y1()));
hgs
parents:
diff changeset
   998
        }
hgs
parents:
diff changeset
   999
    }
hgs
parents:
diff changeset
  1000
    if (mRectLiesRightOfHorizontalLine) {
hgs
parents:
diff changeset
  1001
        if (mHorizontalLine.x1() < mHorizontalLine.x2()) {
hgs
parents:
diff changeset
  1002
            mHorizontalLine.setP2(QPointF(mInactiveRectToCompare.right(), mHorizontalLine.y1()));
hgs
parents:
diff changeset
  1003
        }
hgs
parents:
diff changeset
  1004
        else {
hgs
parents:
diff changeset
  1005
            mHorizontalLine.setP1(QPointF(mInactiveRectToCompare.right(), mHorizontalLine.y1()));
hgs
parents:
diff changeset
  1006
        }
hgs
parents:
diff changeset
  1007
    }
hgs
parents:
diff changeset
  1008
}