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