--- a/src/hbcore/vkbhosts/hbabstractvkbhost.cpp Thu Sep 02 20:44:51 2010 +0300
+++ b/src/hbcore/vkbhosts/hbabstractvkbhost.cpp Fri Sep 17 08:32:10 2010 +0300
@@ -22,8 +22,10 @@
** Nokia at developer.feedback@nokia.com.
**
****************************************************************************/
+
#include "hbabstractvkbhost.h"
#include "hbabstractvkbhost_p.h"
+#include "private/hbvkbgeometrylogic_p.h"
#include "hbinputvirtualkeyboard.h"
#include "hbinputsettingproxy.h"
#include "hbinputvkbhostbridge.h"
@@ -38,14 +40,8 @@
#include <QTextEdit>
const int HbAnimationTime = 200;
-const qreal HbEditorExtraMargin = 17.0;
-const qreal HbCursorLineMargin = 5.0;
-const qreal HbContainerBorderMargin = 20.0;
const qreal HbHeightVerticalFactor = 0.5;
const qreal HbHeightHorizFactor = 0.7;
-//Marginal value of the keypad height
-const qreal HbHeightMarginFactor = 0.6;
-const qreal HbDeltaHeight = 3.0;
const QString KHandWritingName("Handwriting");
// see hbpopup.cpp for this
@@ -218,137 +214,64 @@
mScreenSize = screenSize();
}
-bool HbAbstractVkbHostPrivate::prepareContainerAnimation(HbVkbHost::HbVkbStatus status)
-{
- if (!mKeypad || !mContainerWidget->widgetObject() || !mInputMethod || !mInputMethod->focusObject()) {
+// TODO: could be in vkb geometry engine
+bool HbAbstractVkbHostPrivate::getViewAndFocusObjects(HbView*& currentView, HbInputFocusObject*& focusObject)
+{
+ if (!mKeypad || !mInputMethod || !mContainerWidget ) {
+ return false;
+ }
+
+ HbMainWindow* window = mainWindow();
+ if (!window) {
+ return false;
+ }
+
+ currentView = window->currentView();
+ if (!currentView) {
+ return false;
+ }
+
+ focusObject = mInputMethod->focusObject();
+ if (!focusObject) {
return false;
}
- if (status == HbVkbHost::HbVkbStatusOpened) {
- // Calculate the area that remains visible when the keypad is open.
- QRectF visibleArea = QRectF(0.0, 0.0, mScreenSize.width(), mScreenSize.height() - mKeypad->size().height());
- // adjust the container position such that the focused object is always visible. This is required in some cases
- // where the actual visible area is very less when the keypad is opened. The cotainer position is automatically adjusted when
- // the keypad height to screen height ratio exceeds the marginal height value HbHeightMarginFactor. By doing this, we can make
- // sure that some space available for displaying popups like exactword popup in some input methods
- bool adjustContainer = (q_ptr->confirmedKeyboardSize().height() >
- (mScreenSize.height() * HbHeightMarginFactor))? true : false;
- // Find out the container area.
- QRectF containerArea = mContainerWidget->sceneBoundingRect();
- containerArea.adjust(0.0, -HbContainerBorderMargin, 0.0, HbContainerBorderMargin);
-
- HbMainWindow *mainWin = mainWindow();
- HbView *currentView = mainWin ? mainWin->currentView() : 0;
-
- if (!currentView) {
- return false;
- }
- // check whether the title and status bars are hidden or not
- bool isTitleOrStatusBarVisible = currentView->isItemVisible(
- Hb::TitleBarItem) | currentView->isItemVisible(Hb::StatusBarItem);
+ return true;
+}
- // move the container up when hiding the title and status bars
- if (isTitleOrStatusBarVisible) {
- mContainerMovementVector.setY(visibleArea.top() - currentView->sceneBoundingRect().top());
- }
-
- if (visibleArea.contains(containerArea)) {
- // The whole container is already inside the visible area, nothing to do.
- return false;
- }
-
- // If it isn't in the visible area yet but fits there. Let's move it there.
- if (visibleArea.height() >= containerArea.height()) {
- // calculate the new container area after hiding the bars
- containerArea.translate(mContainerMovementVector);
-
- if (adjustContainer) {
- adjustContainerPosition();
- } else {
- mContainerMovementVector += QPointF(0.0, visibleArea.bottom() - containerArea.bottom());
- }
- return true;
- }
-
- // Find out the editor bounding box and add a small margin to height.
- QRectF editorGeometry = mInputMethod->focusObject()->editorGeometry();
- editorGeometry.adjust(0.0, -HbCursorLineMargin, 0.0, HbCursorLineMargin);
-
- // calculate the new editor position after hiding the title bars
- editorGeometry.translate(mContainerMovementVector);
+bool HbAbstractVkbHostPrivate::prepareContainerAnimation(HbVkbHost::HbVkbStatus status)
+{
+ // Init and check main objects
+ HbView* currentView = NULL;
+ HbInputFocusObject* focusObject = NULL;
+ if (!getViewAndFocusObjects(currentView, focusObject)) {
+ return false;
+ }
- // Then see if the editor is already inside the visible area.
- // If it isn't, see if it would fit there.
- if (!visibleArea.contains(editorGeometry)) {
- if (editorGeometry.width() <= visibleArea.width() &&
- editorGeometry.height() <= visibleArea.height()) {
- // first check whether the microfocus rectangle is inside the visible area. In case of
- // text or multiline editors, dont change the editor position if cursor is in visible area
- if (adjustContainer) {
- if (adjustContainerPosition()) {
- return true;
- }
- }
- // Yes, it fits into visible area, let's move it there so that
- // the whole editor area is in use right away.
- // First check if we want to move it to upper or lower
- // part of the visible area.
- if (editorGeometry.top() <= visibleArea.top()) {
- // It goes to the upper part of the visible area.
- mContainerMovementVector += QPointF(0.0, -editorGeometry.top());
- } else {
- mContainerMovementVector += QPointF(0.0, visibleArea.bottom() - editorGeometry.bottom());
- }
- return true;
- }
- }
-
- // The editor is either already inside the visible area or doesn't fit there.
- // Let's see if the cursor is visble.
- // First find out micro focus rectangle and increase the height by a small margin.
- QRectF microFocus = mInputMethod->focusObject()->microFocus();
- microFocus.setTop(microFocus.top() - HbEditorExtraMargin);
- microFocus.setBottom(microFocus.bottom() + HbEditorExtraMargin);
+ // Init parameters before calling...
+ QSizeF keypadSize = mKeypad->size();
+ QRectF viewRect = currentView->sceneBoundingRect();
+ bool vkbOpen = mKeypadStatus == HbVkbHost::HbVkbStatusOpened;
+ bool titlebarVisible = currentView->isItemVisible(Hb::TitleBarItem);
+ bool statusbarVisible = currentView->isItemVisible(Hb::StatusBarItem);
+ QRectF containerRect = mContainerWidget->sceneBoundingRect();
+ QRectF editorRect = focusObject->editorGeometry();
+ QRectF cursorRect = focusObject->microFocus();
- // calculate the new cursor position after hiding the title bars
- microFocus.translate(mContainerMovementVector);
-
- // Check whether the cursor rectangle is inside visible area.
- if (!visibleArea.contains(microFocus)) {
- QRectF realEditorGeometry = editorGeometry;
- realEditorGeometry.adjust(0.0, HbCursorLineMargin, 0.0, -HbCursorLineMargin);
- if (!realEditorGeometry.contains(microFocus)) {
- // A sanity check. If the microFocus rectangle is outside the editor
- // bounding rect, don't do anything. The situation in editor widget is not
- // up to date.
- return false;
- }
- // The cursor is outside the visible area. Figure out how much and
- // to which direction the container has to be moved.
- if (microFocus.bottom() <= visibleArea.top()) {
- // First see what would happen if we returned the container to original position.
- // Is the cursor visible then?
- // This is always preferred, use it if possible.
- QPointF toOriginalPos = mOriginalContainerPosition - mContainerWidget->pos();
- QRectF translatedMicroFocus = microFocus.translated(toOriginalPos);
- if (visibleArea.contains(translatedMicroFocus)) {
- mContainerMovementVector += toOriginalPos;
- } else {
- // It goes to the upper part of the visible area.
- mContainerMovementVector += QPointF(0.0, visibleArea.top() - microFocus.top());
- }
- } else {
- mContainerMovementVector += QPointF(0.0, visibleArea.bottom() - microFocus.bottom());
- }
- return true;
- }
- if (adjustContainer && adjustContainerPosition()) {
- return true;
- }
- } else {
- // It is going to be closed or minimized.
- mContainerMovementVector = mOriginalContainerPosition - mContainerMovementStartingPoint;
- return true;
+ if (status == HbVkbHost::HbVkbStatusOpened) {
+ // Initialize geometry calculation unit to handle all geometry calculations.
+ HbVkbGeometryLogicPrivate unit = HbVkbGeometryLogicPrivate(
+ mScreenSize,
+ keypadSize,
+ viewRect,
+ vkbOpen,
+ titlebarVisible,
+ statusbarVisible,
+ containerRect,
+ editorRect,
+ cursorRect);
+
+ return unit.calculateContainerMovement( mContainerMovementVector );
}
return false;
@@ -409,7 +332,7 @@
if (mainWindow) {
q_ptr->connect(mainWindow, SIGNAL(aboutToChangeOrientation()), q_ptr, SLOT(orientationAboutToChange()));
q_ptr->connect(mainWindow, SIGNAL(orientationChanged(Qt::Orientation)), q_ptr, SLOT(orientationChanged(Qt::Orientation)));
- q_ptr->connect(mainWindow, SIGNAL(currentViewChanged(HbView *)), q_ptr, SLOT(currentViewChanged(HbView *)));
+ q_ptr->connect(mainWindow, SIGNAL(aboutToChangeView(HbView *, HbView *)), q_ptr, SLOT(aboutToChangeView(HbView *, HbView *)));
}
}
@@ -422,7 +345,7 @@
if (mainWindow) {
q_ptr->disconnect(mainWindow, SIGNAL(aboutToChangeOrientation()), q_ptr, SLOT(orientationAboutToChange()));
q_ptr->disconnect(mainWindow, SIGNAL(orientationChanged(Qt::Orientation)), q_ptr, SLOT(orientationChanged(Qt::Orientation)));
- q_ptr->disconnect(mainWindow, SIGNAL(currentViewChanged(HbView *)), q_ptr, SLOT(currentViewChanged(HbView *)));
+ q_ptr->disconnect(mainWindow, SIGNAL(aboutToChangeView(HbView *, HbView *)), q_ptr, SLOT(aboutToChangeView(HbView *, HbView *)));
}
}
@@ -679,9 +602,12 @@
}
HbMainWindow *mainWin = mainWindow();
- HbView *currentView;
+ if (!mainWin) {
+ return;
+ }
- if (mainWin && (currentView = mainWin->currentView())) {
+ HbView *currentView = mainWin->currentView();
+ if (currentView) {
HbView::HbViewFlags flags = currentView->viewFlags();
HbView::HbViewFlags setFlags = HbView::ViewFlagNone;
@@ -716,34 +642,6 @@
}
}
-bool HbAbstractVkbHostPrivate::adjustContainerPosition()
-{
- bool result = false;
- if (!mInputMethod || !mInputMethod->focusObject()) {
- return result;
- }
- // Calculate the area that remains visible when the keypad is open.
- QRectF visibleArea = QRectF(0.0, 0.0, mScreenSize.width(), mScreenSize.height() - mKeypad->size().height());
- QRectF microFocus = mInputMethod->focusObject()->microFocus();
- microFocus.adjust(0.0, -HbEditorExtraMargin, 0.0, HbEditorExtraMargin);
-
- // calculate the new cursor position after moving it to the visible area
- QRectF newCursorRect = microFocus.translated(mContainerMovementVector);
- if (visibleArea.contains(newCursorRect)) {
- qreal topArea = newCursorRect.top() - visibleArea.top() - HbDeltaHeight;
- qreal bottomArea = visibleArea.bottom() - newCursorRect.bottom() - HbDeltaHeight;
- if (topArea > 0 && bottomArea > 0) {
- if (topArea >= bottomArea) {
- mContainerMovementVector += QPointF(0.0, bottomArea);
- } else {
- mContainerMovementVector += QPointF(0.0, -topArea);
- }
- }
- result = true;
- }
- return result;
-}
-
/// @endcond
@@ -753,6 +651,9 @@
setParent(containerWidget);
HbVkbHost::attachHost(this, containerWidget);
+ if (containerWidget) {
+ containerWidget->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ }
connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
@@ -775,6 +676,9 @@
setParent(containerWidget);
HbVkbHost::attachHost(this, containerWidget);
+ if (containerWidget) {
+ containerWidget->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ }
connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
@@ -786,6 +690,9 @@
setParent(containerWidget);
HbVkbHost::attachHost(this, containerWidget);
+ if (containerWidget) {
+ containerWidget->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ }
connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
@@ -966,7 +873,9 @@
// Make sure the keypad never steals focus.
d->mKeypad->setFlag(QGraphicsItem::ItemIsPanel, true);
- d->mKeypad->setActive(false);
+ if (d->mKeypad->isActive()) {
+ d->mKeypad->setActive(false);
+ }
emit keypadOpened();
} else if (d->mKeypadStatus == HbVkbHost::HbVkbStatusMinimized) {
d->mCallback->keyboardMinimized(this);
@@ -979,7 +888,11 @@
d->mContainerWidget->widgetObject()->setProperty(KPositionManagedByVKB, false );
d->mCallback->keyboardClosed(this);
emit keypadClosed();
- HbVkbHostBridge::instance()->connectHost(0);
+
+ // Keyboard might be opened again due to pending open call
+ if (d->mKeypadStatus == HbVkbHost::HbVkbStatusClosed) {
+ HbVkbHostBridge::instance()->connectHost(0);
+ }
}
}
}
@@ -1199,19 +1112,8 @@
*/
void HbAbstractVkbHost::currentViewChanged(HbView *view)
{
- Q_D(HbAbstractVkbHost);
+ Q_UNUSED(view);
- if (view != d->mContainerWidget->widgetObject()) {
- if (d->mTimeLine.state() == QTimeLine::Running) {
- d->cancelAnimationAndHideVkbWidget();
- if (d->mCallback) {
- d->mCallback->keyboardClosed(this);
- }
- } else if (d->mKeypadStatus != HbVkbStatusClosed) {
- d->closeKeypadWithoutAnimation();
- emit keypadClosed();
- }
- }
}
/*!
@@ -1257,5 +1159,23 @@
openKeypad(vkb, d->mInputMethod, d->mPendingCall.animationAllowed);
}
}
+/*!
+This slot is called when change in active HbView starts.
+*/
+void HbAbstractVkbHost::aboutToChangeView(HbView *oldView, HbView *newView)
+{
+ Q_D(HbAbstractVkbHost);
+ if (oldView != newView) {
+ if (d->mTimeLine.state() == QTimeLine::Running) {
+ d->cancelAnimationAndHideVkbWidget();
+ if (d->mCallback) {
+ d->mCallback->keyboardClosed(this);
+ }
+ } else if (d->mKeypadStatus != HbVkbStatusClosed) {
+ d->closeKeypadWithoutAnimation();
+ emit keypadClosed();
+ }
+ }
+}
// End of file