24 ****************************************************************************/ |
24 ****************************************************************************/ |
25 #include "hbabstractvkbhost.h" |
25 #include "hbabstractvkbhost.h" |
26 #include "hbabstractvkbhost_p.h" |
26 #include "hbabstractvkbhost_p.h" |
27 #include "hbinputvirtualkeyboard.h" |
27 #include "hbinputvirtualkeyboard.h" |
28 #include "hbinputsettingproxy.h" |
28 #include "hbinputsettingproxy.h" |
|
29 #include "hbinputvkbhostbridge.h" |
29 #include "hbinputmethod.h" |
30 #include "hbinputmethod.h" |
30 #include "hbdeviceprofile.h" |
31 #include "hbdeviceprofile.h" |
31 #include "hbmainwindow.h" |
32 #include "hbmainwindow.h" |
32 #include "hbpopup.h" |
33 #include "hbpopup.h" |
33 #include "hbview.h" |
34 #include "hbview.h" |
65 mKeypadMovementStartingPoint(QPointF(0, 0)), |
66 mKeypadMovementStartingPoint(QPointF(0, 0)), |
66 mKeypadMovementVector(QPointF(0, 0)), |
67 mKeypadMovementVector(QPointF(0, 0)), |
67 mInputMethod(0), |
68 mInputMethod(0), |
68 mKeypadStatusBeforeOrientationChange(HbVkbHost::HbVkbStatusClosed) |
69 mKeypadStatusBeforeOrientationChange(HbVkbHost::HbVkbStatusClosed) |
69 { |
70 { |
|
71 mTimeLine.setUpdateInterval(16); |
70 } |
72 } |
71 |
73 |
72 void HbAbstractVkbHostPrivate::prepareAnimationsCommon() |
74 void HbAbstractVkbHostPrivate::prepareAnimationsCommon() |
73 { |
75 { |
74 if (mContainerWidget && mKeypad) { |
76 if (mContainerWidget && mKeypad) { |
148 // Check whether the cursor rectangle is inside visible area. |
150 // Check whether the cursor rectangle is inside visible area. |
149 if (!visibleArea.contains(microFocus)) { |
151 if (!visibleArea.contains(microFocus)) { |
150 // The cursor is outside the visible area. Figure out how much and |
152 // The cursor is outside the visible area. Figure out how much and |
151 // to which direction the container has to be moved. |
153 // to which direction the container has to be moved. |
152 if (microFocus.bottom() <= visibleArea.top()) { |
154 if (microFocus.bottom() <= visibleArea.top()) { |
153 // It goes to the upper part of the visible area. |
155 // First see what would happen if we returned the container to original position. |
154 mContainerMovementVector = QPointF(0.0, HbCursorLineMargin - microFocus.top()); |
156 // Is the cursor visible then? |
|
157 // This is always preferred, use it if possible. |
|
158 QPointF toOriginalPos = mOriginalContainerPosition - mContainerWidget->pos(); |
|
159 QRectF translatedMicroFocus = microFocus.translated(toOriginalPos); |
|
160 if (visibleArea.contains(translatedMicroFocus)) { |
|
161 mContainerMovementVector = toOriginalPos; |
|
162 } else { |
|
163 // It goes to the upper part of the visible area. |
|
164 mContainerMovementVector = QPointF(0.0, HbCursorLineMargin - microFocus.top()); |
|
165 } |
155 } else { |
166 } else { |
156 mContainerMovementVector = QPointF(0.0, visibleArea.bottom() - HbCursorLineMargin - microFocus.bottom()); |
167 mContainerMovementVector = QPointF(0.0, visibleArea.bottom() - HbCursorLineMargin - microFocus.bottom()); |
157 } |
168 } |
158 |
169 |
159 return true; |
170 return true; |
196 |
207 |
197 bool HbAbstractVkbHostPrivate::prepareAnimations(HbVkbHost::HbVkbStatus status) |
208 bool HbAbstractVkbHostPrivate::prepareAnimations(HbVkbHost::HbVkbStatus status) |
198 { |
209 { |
199 prepareAnimationsCommon(); |
210 prepareAnimationsCommon(); |
200 |
211 |
201 return (prepareContainerAnimation(status) | |
212 bool containerResult = prepareContainerAnimation(status); |
202 prepareKeypadAnimation(status)); |
213 if (containerResult) { |
|
214 // A sanity check. Container should never be moved below it's original |
|
215 // position. Limit the movement in case editor's micro focus returned faulty value |
|
216 // or something else bad happened. |
|
217 if ((mContainerMovementStartingPoint + mContainerMovementVector).y() > mOriginalContainerPosition.y()) { |
|
218 mContainerMovementVector.setY(mOriginalContainerPosition.y() - mContainerMovementStartingPoint.y()); |
|
219 qWarning("Abstract VKB host: Invalid container position."); |
|
220 } |
|
221 } |
|
222 |
|
223 return (containerResult | prepareKeypadAnimation(status)); |
203 } |
224 } |
204 |
225 |
205 void HbAbstractVkbHostPrivate::connectSignals() |
226 void HbAbstractVkbHostPrivate::connectSignals() |
206 { |
227 { |
207 if (mContainerWidget) { |
228 if (mContainerWidget) { |
243 q_ptr->disconnect(popup, SIGNAL(aboutToHide()), q_ptr, SLOT(containerAboutToClose())); |
264 q_ptr->disconnect(popup, SIGNAL(aboutToHide()), q_ptr, SLOT(containerAboutToClose())); |
244 } |
265 } |
245 } |
266 } |
246 |
267 |
247 void HbAbstractVkbHostPrivate::openKeypad() |
268 void HbAbstractVkbHostPrivate::openKeypad() |
248 { |
269 { |
249 if (mContainerWidget) { |
270 if (mContainerWidget) { |
250 HbMainWindow* mainWin = mainWindow(); |
271 HbMainWindow* mainWin = mainWindow(); |
251 if (mainWin && mKeypad) { |
272 if (mainWin && mKeypad) { |
252 if (mKeypad->scene() != mainWin->scene()) { |
273 if (mKeypad->scene() != mainWin->scene()) { |
253 // Add keypad to scene if it is not already in there. |
274 // Add keypad to scene if it is not already in there. |
309 |
330 |
310 if (mKeypadStatus != HbVkbHost::HbVkbStatusOpened) { |
331 if (mKeypadStatus != HbVkbHost::HbVkbStatusOpened) { |
311 mCallback->aboutToOpen(q_ptr); |
332 mCallback->aboutToOpen(q_ptr); |
312 q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries. |
333 q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries. |
313 } |
334 } |
314 |
|
315 if (prepareAnimations(HbVkbHost::HbVkbStatusOpened)) { |
335 if (prepareAnimations(HbVkbHost::HbVkbStatusOpened)) { |
316 if (!disableCursorShift()) { |
336 if (!disableCursorShift()) { |
317 // Move the container widget to keep the focused line visible. |
337 // Move the container widget to keep the focused line visible. |
318 mContainerWidget->setPos(mContainerWidget->pos() + mContainerMovementVector); |
338 mContainerWidget->setPos(mContainerWidget->pos() + mContainerMovementVector); |
319 |
339 |
320 // Move the keypad |
340 // Move the keypad |
321 mKeypad->setPos(mKeypadMovementStartingPoint + mKeypadMovementVector); |
341 mKeypad->setPos(mKeypadMovementStartingPoint + mKeypadMovementVector); |
322 } |
342 } |
323 |
343 |
324 mKeypadStatus = HbVkbHost::HbVkbStatusOpened; |
344 mKeypadStatus = HbVkbHost::HbVkbStatusOpened; |
|
345 mCallback->keyboardOpened(q_ptr); |
325 q_ptr->openFinished(); |
346 q_ptr->openFinished(); |
326 } |
347 } |
327 } |
348 } |
328 } |
349 } |
329 |
350 |
337 // Add item to scene if it is not already in there. |
358 // Add item to scene if it is not already in there. |
338 mainWin->scene()->addItem(mKeypad); |
359 mainWin->scene()->addItem(mKeypad); |
339 } |
360 } |
340 |
361 |
341 if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized) { |
362 if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized) { |
342 mCallback->aboutToOpen(q_ptr); |
363 mCallback->aboutToOpen(q_ptr); |
343 q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries. |
364 q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries. |
344 } |
365 } |
345 |
366 |
346 if (prepareAnimations(HbVkbHost::HbVkbStatusMinimized)) { |
367 if (prepareAnimations(HbVkbHost::HbVkbStatusMinimized)) { |
347 if (!disableCursorShift()) { |
368 if (!disableCursorShift()) { |
365 mContainerWidget->setPos(mOriginalContainerPosition); |
386 mContainerWidget->setPos(mOriginalContainerPosition); |
366 } |
387 } |
367 |
388 |
368 // Hide the keypad |
389 // Hide the keypad |
369 mKeypad->hide(); |
390 mKeypad->hide(); |
|
391 mCallback->keyboardClosed(q_ptr); |
370 mCallback = 0; |
392 mCallback = 0; |
371 } |
393 } |
372 } |
394 } |
373 |
395 |
374 void HbAbstractVkbHostPrivate::minimizeKeypadWithoutAnimation() |
396 void HbAbstractVkbHostPrivate::minimizeKeypadWithoutAnimation() |
375 { |
397 { |
376 HbMainWindow *mainWin = mainWindow(); |
398 HbMainWindow *mainWin = mainWindow(); |
377 if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized && mKeypad && mainWin) { |
399 if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized && mKeypad && mainWin) { |
378 mCallback->aboutToClose(q_ptr); |
400 mCallback->aboutToClose(q_ptr); |
379 if (mKeypad->scene() != mainWin->scene()) { |
401 if (mKeypad->scene() != mainWin->scene()) { |
380 // Add item to scene if it is not already in there. |
402 // Add item to scene if it is not already in there. |
381 mainWin->scene()->addItem(mKeypad); |
403 mainWin->scene()->addItem(mKeypad); |
382 } |
404 } |
383 |
405 |
|
406 mKeypadStatus = HbVkbHost::HbVkbStatusMinimized; |
384 if (!disableCursorShift()) { |
407 if (!disableCursorShift()) { |
385 // Return the container widget to original position. |
408 // Return the container widget to original position. |
386 mContainerWidget->setPos(mOriginalContainerPosition); |
409 mContainerWidget->setPos(mOriginalContainerPosition); |
387 |
410 |
388 // Set the keypad to minimized position. |
411 // Set the keypad to minimized position. |
389 mKeypad->setPos(QPointF(0.0, mScreenSize.height() - mCallback->minimizedKeyboardSize().height())); |
412 mKeypad->setPos(QPointF(0.0, mScreenSize.height() - mCallback->minimizedKeyboardSize().height())); |
390 } |
413 } |
391 |
|
392 mKeypadStatus = HbVkbHost::HbVkbStatusMinimized; |
|
393 } |
414 } |
394 } |
415 } |
395 |
416 |
396 void HbAbstractVkbHostPrivate::cancelAnimationAndHideVkbWidget() |
417 void HbAbstractVkbHostPrivate::cancelAnimationAndHideVkbWidget() |
397 { |
418 { |
407 } |
428 } |
408 |
429 |
409 // Clear possible pending call. |
430 // Clear possible pending call. |
410 mPendingCall.vkb = 0; |
431 mPendingCall.vkb = 0; |
411 |
432 |
|
433 emit q_ptr->keypadClosed(); |
|
434 HbVkbHostBridge::instance()->connectHost(0); |
412 mKeypadStatus = HbVkbHost::HbVkbStatusClosed; |
435 mKeypadStatus = HbVkbHost::HbVkbStatusClosed; |
413 } |
436 } |
414 } |
437 } |
415 |
438 |
416 HbMainWindow *HbAbstractVkbHostPrivate::mainWindow() const |
439 HbMainWindow *HbAbstractVkbHostPrivate::mainWindow() const |
527 // all the needed parameters. Null parameters are ok only if minimized |
551 // all the needed parameters. Null parameters are ok only if minimized |
528 // keypad is reopened. |
552 // keypad is reopened. |
529 return; |
553 return; |
530 } |
554 } |
531 |
555 |
532 if (d->mTimeLine.state() == QTimeLine::Running) { |
556 if (!HbVkbHostBridge::instance()->connectHost(this)) { |
|
557 connect(HbVkbHostBridge::instance(), SIGNAL(stateTransitionCompleted()), this, SLOT(stateTransitionCompleted())); |
533 // The previous keyboard is still closing. Set the call pending and return. |
558 // The previous keyboard is still closing. Set the call pending and return. |
534 d->mPendingCall.vkb = vkb; |
559 d->mPendingCall.vkb = vkb; |
535 d->mPendingCall.animationAllowed = animationAllowed; |
560 d->mPendingCall.animationAllowed = animationAllowed; |
536 return; |
561 return; |
537 } |
562 } |
570 { |
598 { |
571 Q_D(HbAbstractVkbHost); |
599 Q_D(HbAbstractVkbHost); |
572 |
600 |
573 if (d->mKeypadStatus != HbVkbStatusClosed && !d->mKeypadOperationOngoing) { |
601 if (d->mKeypadStatus != HbVkbStatusClosed && !d->mKeypadOperationOngoing) { |
574 d->mKeypadOperationOngoing = true; |
602 d->mKeypadOperationOngoing = true; |
|
603 |
|
604 emit aboutToClose(); |
575 |
605 |
576 if (animationAllowed) { |
606 if (animationAllowed) { |
577 d->closeKeypad(); |
607 d->closeKeypad(); |
578 } else { |
608 } else { |
579 d->closeKeypadWithoutAnimation(); |
609 d->closeKeypadWithoutAnimation(); |
|
610 emit keypadClosed(); |
|
611 HbVkbHostBridge::instance()->connectHost(0); |
580 } |
612 } |
581 |
613 |
582 d->disconnectSignals(); |
614 d->disconnectSignals(); |
583 d->mKeypadOperationOngoing = false; |
615 d->mKeypadOperationOngoing = false; |
584 } |
616 } |
659 |
691 |
660 if (d->mContainerWidget && d->mKeypad && d->mCallback && d->mInputMethod) { |
692 if (d->mContainerWidget && d->mKeypad && d->mCallback && d->mInputMethod) { |
661 if (!d->disableCursorShift()) { |
693 if (!d->disableCursorShift()) { |
662 // Make sure the container reached target position. |
694 // Make sure the container reached target position. |
663 d->mContainerWidget->setPos(d->mContainerMovementStartingPoint + d->mContainerMovementVector); |
695 d->mContainerWidget->setPos(d->mContainerMovementStartingPoint + d->mContainerMovementVector); |
664 |
|
665 // Make sure the keypad reached target position. |
696 // Make sure the keypad reached target position. |
666 d->mKeypad->setPos(d->mKeypadMovementStartingPoint + d->mKeypadMovementVector); |
697 d->mKeypad->setPos(d->mKeypadMovementStartingPoint + d->mKeypadMovementVector); |
667 } |
698 } |
668 |
699 |
669 // Notify |
700 // Notify |
684 emit keypadOpened(); |
715 emit keypadOpened(); |
685 } else if (d->mKeypadStatus == HbVkbHost::HbVkbStatusMinimized) { |
716 } else if (d->mKeypadStatus == HbVkbHost::HbVkbStatusMinimized) { |
686 d->mCallback->keyboardMinimized(this); |
717 d->mCallback->keyboardMinimized(this); |
687 emit keypadClosed(); |
718 emit keypadClosed(); |
688 } else { |
719 } else { |
689 // It was closed. |
720 // It was closed. Hide the keyboard. |
690 d->mKeypad->hide(); |
721 d->mKeypad->hide(); |
|
722 // Return the container where it was. |
|
723 d->mContainerWidget->setPos(d->mOriginalContainerPosition); |
691 d->mCallback->keyboardClosed(this); |
724 d->mCallback->keyboardClosed(this); |
692 emit keypadClosed(); |
725 emit keypadClosed(); |
693 |
726 HbVkbHostBridge::instance()->connectHost(0); |
694 if (d->mPendingCall.vkb) { |
|
695 // There was an open call pending. Do it now. |
|
696 HbVirtualKeyboard *vkb = d->mPendingCall.vkb; |
|
697 d->mPendingCall.vkb = 0; |
|
698 openKeypad(vkb, d->mInputMethod, d->mPendingCall.animationAllowed); |
|
699 } |
|
700 } |
727 } |
701 } |
728 } |
702 } |
729 } |
703 |
730 |
704 /*! |
731 /*! |
919 void HbAbstractVkbHost::currentViewChanged(HbView *view) |
946 void HbAbstractVkbHost::currentViewChanged(HbView *view) |
920 { |
947 { |
921 Q_D(HbAbstractVkbHost); |
948 Q_D(HbAbstractVkbHost); |
922 |
949 |
923 if (view != d->mContainerWidget) { |
950 if (view != d->mContainerWidget) { |
924 if (d->mTimeLine.state() == QTimeLine::Running) { |
951 if (d->mTimeLine.state() == QTimeLine::Running) { |
925 d->cancelAnimationAndHideVkbWidget(); |
952 d->cancelAnimationAndHideVkbWidget(); |
926 if (d->mCallback) { |
953 if (d->mCallback) { |
927 d->mCallback->keyboardClosed(this); |
954 d->mCallback->keyboardClosed(this); |
928 } |
955 } |
929 emit keypadClosed(); |
|
930 } else if (d->mKeypadStatus != HbVkbStatusClosed) { |
956 } else if (d->mKeypadStatus != HbVkbStatusClosed) { |
931 d->closeKeypadWithoutAnimation(); |
957 d->closeKeypadWithoutAnimation(); |
932 } |
958 } |
933 } |
959 } |
934 } |
960 } |
948 d->mTimeLine.start(); |
974 d->mTimeLine.start(); |
949 } |
975 } |
950 } |
976 } |
951 } |
977 } |
952 |
978 |
|
979 /*! |
|
980 \reimp |
|
981 */ |
|
982 bool HbAbstractVkbHost::stateTransitionOngoing() const |
|
983 { |
|
984 Q_D(const HbAbstractVkbHost); |
|
985 return (d->mTimeLine.state() == QTimeLine::Running); |
|
986 } |
|
987 |
|
988 /*! |
|
989 Receives signal from HbVkbHostBridge when previous host completes its state |
|
990 transition and sens pending call if any. |
|
991 */ |
|
992 void HbAbstractVkbHost::stateTransitionCompleted() |
|
993 { |
|
994 Q_D(HbAbstractVkbHost); |
|
995 |
|
996 disconnect(HbVkbHostBridge::instance(), SIGNAL(stateTransitionCompleted()), this, SLOT(stateTransitionCompleted())); |
|
997 |
|
998 if (d->mPendingCall.vkb) { |
|
999 // There was an open call pending. Do it now. |
|
1000 HbVirtualKeyboard *vkb = d->mPendingCall.vkb; |
|
1001 d->mPendingCall.vkb = 0; |
|
1002 openKeypad(vkb, d->mInputMethod, d->mPendingCall.animationAllowed); |
|
1003 } |
|
1004 } |
|
1005 |
953 // End of file |
1006 // End of file |