src/hbcore/vkbhosts/private/hbvkbgeometrylogic_p.cpp
changeset 28 b7da29130b0e
child 30 80e4d18b72f5
equal deleted inserted replaced
23:e6ad4ef83b23 28:b7da29130b0e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbvkbgeometrylogic_p.h"
       
    27 
       
    28 #include <QtGlobal>
       
    29 #include <hbglobal.h>
       
    30 
       
    31 const qreal HbCursorLineMargin = 15.0;
       
    32 const qreal HbContainerBorderMargin = 20.0;
       
    33 const qreal HbEditorExtraMargin = 17.0;
       
    34 
       
    35 /*!
       
    36     \class HbVkbGeometryLogicPrivate
       
    37     \brief Calculates screen movement in cases the keyboard would overlap with editor
       
    38 
       
    39     This class contains calculations and logic to move screen in cases, when upcoming
       
    40     keyboard would overlap the editor so, that text written could not be seen. Idea is
       
    41     to minimize the movement as much as possible.
       
    42 
       
    43 */
       
    44 
       
    45 /*!
       
    46     \internal
       
    47     \brief Construct current state object screen status.
       
    48 
       
    49     Constructor to create status object based on given parameters. These parameters
       
    50     are used to calculate possible movement vector for container.
       
    51 
       
    52     \param screenSize       Size of screen.
       
    53     \param keybadSize       Size of keyboard.
       
    54     \param sceneArea        Size of view area, to which container belongs.
       
    55     \param isVkbOpen        Information about current status of VKB.
       
    56     \param hideTitlebar     Should titlebar hiding be calculated?
       
    57     \param hideStatusbar    Should statusbar hiding be calculated?
       
    58     \param containerArea    Area of editor's top item.
       
    59     \param editorArea       Area of editor itself.
       
    60     \param cursorArea       Area of cursor inside editor.
       
    61 */
       
    62 HbVkbGeometryLogicPrivate::HbVkbGeometryLogicPrivate(
       
    63         const QSizeF& screenSize,
       
    64         const QSizeF& keypadSize,
       
    65         const QRectF& sceneArea,
       
    66         bool isVkbOpen,
       
    67         bool hideTitlebar,
       
    68         bool hideStatusbar,
       
    69         const QRectF& containerArea,
       
    70         const QRectF& editorArea,
       
    71         const QRectF& cursorArea)
       
    72 {
       
    73     // We need to consider situation, when keyboard is already on the screen, in
       
    74     // which case, titlebar and statusbar are already hidden, thus bigger visible area
       
    75     // is already in use, so no adjustments needed.
       
    76     if ( isVkbOpen ) {
       
    77         mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), screenSize.height() - keypadSize.height());
       
    78         mAdjust = 0.0;
       
    79     } else if ( hideTitlebar || hideStatusbar ) {
       
    80         // Without titlebar and statusbar, the visible area is from the top of the screen
       
    81         // to the top of the keyboard. Also, container needs to move slightly, when
       
    82         // bars are going to be closed.
       
    83         mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), screenSize.height() - keypadSize.height());
       
    84         mAdjust = mVisibleArea.top() - sceneArea.top();
       
    85     } else {
       
    86         // When titlebar and statusbar are visible, visible area is going to be from
       
    87         // bottom of the titlebar to top of the keyboard. No container movement needed.
       
    88         mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), sceneArea.height() - keypadSize.height());
       
    89         mAdjust = 0.0;
       
    90     }
       
    91 
       
    92     // Find out the container area.
       
    93     mContainerArea = containerArea;
       
    94     mContainerArea.adjust(0.0, -HbContainerBorderMargin, 0.0, HbContainerBorderMargin);
       
    95     mContainerArea.translate(QPointF(0, mAdjust));
       
    96 
       
    97     // Find out the editor bounding box and add a small margin to height.
       
    98     mEditorArea = editorArea;
       
    99     mEditorArea.adjust(0.0, -HbCursorLineMargin, 0.0, HbCursorLineMargin);
       
   100     mEditorArea.translate(QPointF(0, mAdjust));
       
   101 
       
   102     // Finally, get cursor size and adjust it little bit
       
   103     mCursorArea = cursorArea;
       
   104     mCursorArea.adjust(0.0, -HbEditorExtraMargin, 0.0, HbEditorExtraMargin);
       
   105     mCursorArea.translate(QPointF(0, mAdjust));
       
   106 }
       
   107 
       
   108 /*!
       
   109     \internal
       
   110     \brief Check the source area fits inside target area.
       
   111 */
       
   112 bool HbVkbGeometryLogicPrivate::fitsArea(const QRectF& target, const QRectF& source) const
       
   113 {
       
   114     return source.width() <= target.width() && source.height() <= target.height();
       
   115 }
       
   116 
       
   117 /*!
       
   118     \internal
       
   119     \brief Checks, whether the container fits into the visible area.
       
   120 
       
   121     When keyboard opens, the screen will contain visible area and the keyboard area.
       
   122     This method checks, whether container will fit the visible area.
       
   123 
       
   124     \return True, when fits. Otherwise false.
       
   125 */
       
   126 bool HbVkbGeometryLogicPrivate::containerFitsVisibleArea() const
       
   127 {
       
   128      return fitsArea(mVisibleArea, mContainerArea);
       
   129 }
       
   130 
       
   131 /*!
       
   132     \internal
       
   133     \brief Checks, whether the editor fits into the visible area.
       
   134 
       
   135     When keyboard opens, the screen will contain visible area and the keyboard area.
       
   136     This method check, whether editor itself can be fitted to screen. This is needed
       
   137     when the container cannot fit the screen, so the editor needs to be positioned.
       
   138 
       
   139     \return
       
   140 */
       
   141 bool HbVkbGeometryLogicPrivate::editorFitsVisibleArea() const
       
   142 {
       
   143     return fitsArea(mVisibleArea, mEditorArea);
       
   144 }
       
   145 
       
   146 /*!
       
   147     \internal
       
   148     \brief Check if container is fully visible.
       
   149 
       
   150     \return True, when fully inside visible area, otherwise false.
       
   151 */
       
   152 bool HbVkbGeometryLogicPrivate::isContainerVisible() const
       
   153 {
       
   154     return mVisibleArea.contains(mContainerArea);
       
   155 }
       
   156 
       
   157 /*!
       
   158     \internal
       
   159     \return True, when editor inside visible area
       
   160 */
       
   161 bool HbVkbGeometryLogicPrivate::isEditorVisible() const
       
   162 {
       
   163     return mVisibleArea.contains(mEditorArea);
       
   164 }
       
   165 
       
   166 /*!
       
   167     \internal
       
   168     \return True, when cursor inside visible area
       
   169 */
       
   170 bool HbVkbGeometryLogicPrivate::isCursorVisible() const
       
   171 {
       
   172     // Check wheter cursor inside the visible area.
       
   173     return mVisibleArea.contains(mCursorArea);
       
   174 }
       
   175 
       
   176 /*!
       
   177     \internal
       
   178     \brief Calculates movement vector for viewport.
       
   179 
       
   180     \return True, when container needs to be moved.
       
   181 */
       
   182 bool HbVkbGeometryLogicPrivate::calculateContainerMovement(QPointF& vector) const
       
   183 {
       
   184     // In case editor or cursor inside visible area, no extra movement needed.
       
   185     if ( isCursorVisible() ) {
       
   186         vector.rx() = 0.0;
       
   187         vector.ry() = mAdjust;
       
   188         return false;
       
   189     }
       
   190 
       
   191     // At this point we know, that cursor is not inside of visible area,
       
   192     // after VKB has been shown. To make it bit prettier, let's check, if we can
       
   193     // move and fit the whole editor into the screen at once.
       
   194     if ( !isEditorVisible() && editorFitsVisibleArea() ) {
       
   195         // Editor is not in screen but fits there, so simply move the whole editor
       
   196         // to screen. Only thing yet to check is, which direction the editor needs
       
   197         // to be moved.
       
   198         if ( mEditorArea.top() <= mVisibleArea.top() ) {
       
   199             vector = QPointF(0.0, -mEditorArea.top());
       
   200         } else {
       
   201             // In case editor is not inside visible area, move editor until it is.
       
   202             vector = QPointF(0.0, mVisibleArea.bottom() - mEditorArea.bottom());
       
   203         }
       
   204 
       
   205         vector.ry() += mAdjust;
       
   206 
       
   207         // Vector has been calculated, so finish the story and return.
       
   208         return true;
       
   209     }
       
   210 
       
   211     // At this point we know, that cursor is not visible and the editor does not fit
       
   212     // into the visible area. Here we need to move editor, so that the cursor can be
       
   213     // seen in the visible area. There are two ways to do this.
       
   214     // 1) Move container, until bottom of editor is reached OR
       
   215     // 2) Move container, until cursor hits top of the screen
       
   216     int cursorMove = (int)(mVisibleArea.top() - mCursorArea.top());
       
   217     int editorMove = (int)(mVisibleArea.bottom() - mEditorArea.bottom());
       
   218 
       
   219     // Choose smaller movement (notice usage of negative values)
       
   220     vector = QPointF(0.0, cursorMove >= editorMove ? cursorMove : editorMove);
       
   221 
       
   222     vector.ry() += mAdjust;
       
   223     return true;
       
   224 }