--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/vkbhosts/private/hbvkbgeometrylogic_p.cpp Fri Sep 17 08:32:10 2010 +0300
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbvkbgeometrylogic_p.h"
+
+#include <QtGlobal>
+#include <hbglobal.h>
+
+const qreal HbCursorLineMargin = 15.0;
+const qreal HbContainerBorderMargin = 20.0;
+const qreal HbEditorExtraMargin = 17.0;
+
+/*!
+ \class HbVkbGeometryLogicPrivate
+ \brief Calculates screen movement in cases the keyboard would overlap with editor
+
+ This class contains calculations and logic to move screen in cases, when upcoming
+ keyboard would overlap the editor so, that text written could not be seen. Idea is
+ to minimize the movement as much as possible.
+
+*/
+
+/*!
+ \internal
+ \brief Construct current state object screen status.
+
+ Constructor to create status object based on given parameters. These parameters
+ are used to calculate possible movement vector for container.
+
+ \param screenSize Size of screen.
+ \param keybadSize Size of keyboard.
+ \param sceneArea Size of view area, to which container belongs.
+ \param isVkbOpen Information about current status of VKB.
+ \param hideTitlebar Should titlebar hiding be calculated?
+ \param hideStatusbar Should statusbar hiding be calculated?
+ \param containerArea Area of editor's top item.
+ \param editorArea Area of editor itself.
+ \param cursorArea Area of cursor inside editor.
+*/
+HbVkbGeometryLogicPrivate::HbVkbGeometryLogicPrivate(
+ const QSizeF& screenSize,
+ const QSizeF& keypadSize,
+ const QRectF& sceneArea,
+ bool isVkbOpen,
+ bool hideTitlebar,
+ bool hideStatusbar,
+ const QRectF& containerArea,
+ const QRectF& editorArea,
+ const QRectF& cursorArea)
+{
+ // We need to consider situation, when keyboard is already on the screen, in
+ // which case, titlebar and statusbar are already hidden, thus bigger visible area
+ // is already in use, so no adjustments needed.
+ if ( isVkbOpen ) {
+ mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), screenSize.height() - keypadSize.height());
+ mAdjust = 0.0;
+ } else if ( hideTitlebar || hideStatusbar ) {
+ // Without titlebar and statusbar, the visible area is from the top of the screen
+ // to the top of the keyboard. Also, container needs to move slightly, when
+ // bars are going to be closed.
+ mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), screenSize.height() - keypadSize.height());
+ mAdjust = mVisibleArea.top() - sceneArea.top();
+ } else {
+ // When titlebar and statusbar are visible, visible area is going to be from
+ // bottom of the titlebar to top of the keyboard. No container movement needed.
+ mVisibleArea = QRectF(0.0, 0.0, screenSize.width(), sceneArea.height() - keypadSize.height());
+ mAdjust = 0.0;
+ }
+
+ // Find out the container area.
+ mContainerArea = containerArea;
+ mContainerArea.adjust(0.0, -HbContainerBorderMargin, 0.0, HbContainerBorderMargin);
+ mContainerArea.translate(QPointF(0, mAdjust));
+
+ // Find out the editor bounding box and add a small margin to height.
+ mEditorArea = editorArea;
+ mEditorArea.adjust(0.0, -HbCursorLineMargin, 0.0, HbCursorLineMargin);
+ mEditorArea.translate(QPointF(0, mAdjust));
+
+ // Finally, get cursor size and adjust it little bit
+ mCursorArea = cursorArea;
+ mCursorArea.adjust(0.0, -HbEditorExtraMargin, 0.0, HbEditorExtraMargin);
+ mCursorArea.translate(QPointF(0, mAdjust));
+}
+
+/*!
+ \internal
+ \brief Check the source area fits inside target area.
+*/
+bool HbVkbGeometryLogicPrivate::fitsArea(const QRectF& target, const QRectF& source) const
+{
+ return source.width() <= target.width() && source.height() <= target.height();
+}
+
+/*!
+ \internal
+ \brief Checks, whether the container fits into the visible area.
+
+ When keyboard opens, the screen will contain visible area and the keyboard area.
+ This method checks, whether container will fit the visible area.
+
+ \return True, when fits. Otherwise false.
+*/
+bool HbVkbGeometryLogicPrivate::containerFitsVisibleArea() const
+{
+ return fitsArea(mVisibleArea, mContainerArea);
+}
+
+/*!
+ \internal
+ \brief Checks, whether the editor fits into the visible area.
+
+ When keyboard opens, the screen will contain visible area and the keyboard area.
+ This method check, whether editor itself can be fitted to screen. This is needed
+ when the container cannot fit the screen, so the editor needs to be positioned.
+
+ \return
+*/
+bool HbVkbGeometryLogicPrivate::editorFitsVisibleArea() const
+{
+ return fitsArea(mVisibleArea, mEditorArea);
+}
+
+/*!
+ \internal
+ \brief Check if container is fully visible.
+
+ \return True, when fully inside visible area, otherwise false.
+*/
+bool HbVkbGeometryLogicPrivate::isContainerVisible() const
+{
+ return mVisibleArea.contains(mContainerArea);
+}
+
+/*!
+ \internal
+ \return True, when editor inside visible area
+*/
+bool HbVkbGeometryLogicPrivate::isEditorVisible() const
+{
+ return mVisibleArea.contains(mEditorArea);
+}
+
+/*!
+ \internal
+ \return True, when cursor inside visible area
+*/
+bool HbVkbGeometryLogicPrivate::isCursorVisible() const
+{
+ // Check wheter cursor inside the visible area.
+ return mVisibleArea.contains(mCursorArea);
+}
+
+/*!
+ \internal
+ \brief Calculates movement vector for viewport.
+
+ \return True, when container needs to be moved.
+*/
+bool HbVkbGeometryLogicPrivate::calculateContainerMovement(QPointF& vector) const
+{
+ // In case editor or cursor inside visible area, no extra movement needed.
+ if ( isCursorVisible() ) {
+ vector.rx() = 0.0;
+ vector.ry() = mAdjust;
+ return false;
+ }
+
+ // At this point we know, that cursor is not inside of visible area,
+ // after VKB has been shown. To make it bit prettier, let's check, if we can
+ // move and fit the whole editor into the screen at once.
+ if ( !isEditorVisible() && editorFitsVisibleArea() ) {
+ // Editor is not in screen but fits there, so simply move the whole editor
+ // to screen. Only thing yet to check is, which direction the editor needs
+ // to be moved.
+ if ( mEditorArea.top() <= mVisibleArea.top() ) {
+ vector = QPointF(0.0, -mEditorArea.top());
+ } else {
+ // In case editor is not inside visible area, move editor until it is.
+ vector = QPointF(0.0, mVisibleArea.bottom() - mEditorArea.bottom());
+ }
+
+ vector.ry() += mAdjust;
+
+ // Vector has been calculated, so finish the story and return.
+ return true;
+ }
+
+ // At this point we know, that cursor is not visible and the editor does not fit
+ // into the visible area. Here we need to move editor, so that the cursor can be
+ // seen in the visible area. There are two ways to do this.
+ // 1) Move container, until bottom of editor is reached OR
+ // 2) Move container, until cursor hits top of the screen
+ int cursorMove = (int)(mVisibleArea.top() - mCursorArea.top());
+ int editorMove = (int)(mVisibleArea.bottom() - mEditorArea.bottom());
+
+ // Choose smaller movement (notice usage of negative values)
+ vector = QPointF(0.0, cursorMove >= editorMove ? cursorMove : editorMove);
+
+ vector.ry() += mAdjust;
+ return true;
+}