1
0

FreeVirtualKeyboardInputContext.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //============================================================================
  2. // INCLUDES
  3. //============================================================================
  4. #include "FreeVirtualKeyboardInputContext.h"
  5. #include <QDebug>
  6. #include <QPointer>
  7. #include <QEvent>
  8. #include <QGuiApplication>
  9. #include <QQmlEngine>
  10. #include <QQmlContext>
  11. #include <QVariant>
  12. #include <QQmlEngine>
  13. #include <QJSEngine>
  14. #include <QPropertyAnimation>
  15. #include <private/qquickflickable_p.h>
  16. #include "DeclarativeInputEngine.h"
  17. /**
  18. * Private data class for FreeVirtualKeyboardInputContext
  19. */
  20. class FreeVirtualKeyboardInputContextPrivate
  21. {
  22. public:
  23. FreeVirtualKeyboardInputContextPrivate();
  24. QQuickFlickable* Flickable;
  25. QQuickItem* FocusItem;
  26. bool Visible;
  27. DeclarativeInputEngine* InputEngine;
  28. QPropertyAnimation* FlickableContentScrollAnimation;//< for smooth scrolling of flickable content item
  29. };
  30. //==============================================================================
  31. FreeVirtualKeyboardInputContextPrivate::FreeVirtualKeyboardInputContextPrivate()
  32. : Flickable(0),
  33. FocusItem(0),
  34. Visible(false),
  35. InputEngine(new DeclarativeInputEngine())
  36. {
  37. qDebug() << "FreeVirtualKeyboardInputContextPrivate :: CONSTRUCTOR";
  38. }
  39. //==============================================================================
  40. FreeVirtualKeyboardInputContext::FreeVirtualKeyboardInputContext() :
  41. QPlatformInputContext(), d(new FreeVirtualKeyboardInputContextPrivate)
  42. {
  43. d->FlickableContentScrollAnimation = new QPropertyAnimation(this);
  44. d->FlickableContentScrollAnimation->setPropertyName("contentY");
  45. d->FlickableContentScrollAnimation->setDuration(400);
  46. d->FlickableContentScrollAnimation->setEasingCurve(QEasingCurve(QEasingCurve::OutBack));
  47. qmlRegisterSingletonType<DeclarativeInputEngine>("FreeVirtualKeyboard", 1, 0,
  48. "InputEngine", inputEngineProvider);
  49. connect(d->InputEngine, SIGNAL(animatingChanged()), this, SLOT(ensureFocusedObjectVisible()));
  50. connect(d->InputEngine, SIGNAL(reset()), this, SLOT(resetInputEngine()));
  51. }
  52. //==============================================================================
  53. FreeVirtualKeyboardInputContext::~FreeVirtualKeyboardInputContext()
  54. {
  55. qDebug( "FreeVirtualKeyboardInputContext DESTRUCTOR !!!");
  56. }
  57. //==============================================================================
  58. FreeVirtualKeyboardInputContext* FreeVirtualKeyboardInputContext::instance()
  59. {
  60. static FreeVirtualKeyboardInputContext* InputContextInstance = new FreeVirtualKeyboardInputContext;
  61. return InputContextInstance;
  62. }
  63. //==============================================================================
  64. bool FreeVirtualKeyboardInputContext::isValid() const
  65. {
  66. qDebug("IS VALID called");
  67. return true;
  68. }
  69. //==============================================================================
  70. QRectF FreeVirtualKeyboardInputContext::keyboardRect() const
  71. {
  72. qDebug("QRect called");
  73. return QRectF();
  74. }
  75. //==============================================================================
  76. void FreeVirtualKeyboardInputContext::showInputPanel()
  77. {
  78. qDebug( "showInputPanel");
  79. d->Visible = true;
  80. QPlatformInputContext::showInputPanel();
  81. emitInputPanelVisibleChanged();
  82. }
  83. //==============================================================================
  84. void FreeVirtualKeyboardInputContext::hideInputPanel()
  85. {
  86. qDebug( "hideInputPanel");
  87. d->Visible = false;
  88. QPlatformInputContext::hideInputPanel();
  89. emitInputPanelVisibleChanged();
  90. }
  91. //==============================================================================
  92. bool FreeVirtualKeyboardInputContext::isInputPanelVisible() const
  93. {
  94. return d->Visible;
  95. }
  96. //==============================================================================
  97. bool FreeVirtualKeyboardInputContext::isAnimating() const
  98. {
  99. return false;
  100. }
  101. //==============================================================================
  102. void FreeVirtualKeyboardInputContext::setFocusObject(QObject *object)
  103. {
  104. static const int NumericInputHints = Qt::ImhPreferNumbers | Qt::ImhDate
  105. | Qt::ImhTime | Qt::ImhDigitsOnly | Qt::ImhFormattedNumbersOnly;
  106. static const int DialableInputHints = Qt::ImhDialableCharactersOnly;
  107. d->Flickable = 0;
  108. qDebug() << "FreeVirtualKeyboardInputContext::setFocusObject";
  109. if (!object)
  110. {
  111. return;
  112. }
  113. // we only support QML at the moment - so if this is not a QML item, then
  114. // we leave immediatelly
  115. d->FocusItem = dynamic_cast<QQuickItem*>(object);
  116. if (!d->FocusItem)
  117. {
  118. return;
  119. }
  120. // Check if an input control has focus that accepts text input - if not,
  121. // then we can leave immediatelly
  122. bool AcceptsInput = d->FocusItem->inputMethodQuery(Qt::ImEnabled).toBool();
  123. if (!AcceptsInput)
  124. {
  125. return;
  126. }
  127. // Set input mode depending on input method hints queried from focused
  128. // object / item
  129. Qt::InputMethodHints InputMethodHints(d->FocusItem->inputMethodQuery(Qt::ImHints).toInt());
  130. qDebug() << QString("InputMethodHints: %1").arg(InputMethodHints, 0, 16);
  131. if (InputMethodHints & DialableInputHints)
  132. {
  133. d->InputEngine->setInputMode(DeclarativeInputEngine::Dialable);
  134. }
  135. else if (InputMethodHints & NumericInputHints)
  136. {
  137. d->InputEngine->setInputMode(DeclarativeInputEngine::Numeric);
  138. }
  139. else
  140. {
  141. d->InputEngine->setInputMode(DeclarativeInputEngine::Latin);
  142. }
  143. // Search for the top most flickable so that we can scroll the control
  144. // into the visible area, if the keyboard hides the control
  145. // QQuickItem* i = d->FocusItem;
  146. // while (i)
  147. // {
  148. // QQuickFlickable* Flickable = dynamic_cast<QQuickFlickable*>(i);
  149. // if (Flickable)
  150. // {
  151. // d->Flickable = Flickable;
  152. // qDebug() << "is QQuickFlickable";
  153. // }
  154. // i = i->parentItem();
  155. // }
  156. ensureFocusedObjectVisible();
  157. }
  158. //==============================================================================
  159. void resetInputEngine(){
  160. qDebug() << "RESET INPUT ENGINE !!!!!";
  161. return;
  162. }
  163. //==============================================================================
  164. void FreeVirtualKeyboardInputContext::ensureFocusedObjectVisible()
  165. {
  166. if (d->Visible && !d->InputEngine->isAnimating() )
  167. {
  168. QQuickItem* i = d->FocusItem;
  169. while (i)
  170. {
  171. QQuickFlickable* Flickable = dynamic_cast<QQuickFlickable*>(i);
  172. if (Flickable)
  173. {
  174. d->Flickable = Flickable;
  175. qDebug() << "is QQuickFlickable";
  176. }
  177. i = i->parentItem();
  178. }
  179. }
  180. // If the keyboard is hidden, no scrollable element exists or the keyboard
  181. // is just animating, then we leave here
  182. if (!d->Visible || !d->Flickable || d->InputEngine->isAnimating() )
  183. {
  184. return;
  185. }
  186. qDebug() << "FreeVirtualKeyboardInputContext::ensureFocusedObjectVisible";
  187. QRectF FocusItemRect(0, 0, d->FocusItem->width(), d->FocusItem->height());
  188. FocusItemRect = d->Flickable->mapRectFromItem(d->FocusItem, FocusItemRect);
  189. qDebug() << "FocusItemRect: " << FocusItemRect;
  190. qDebug() << "Content origin: " << QPointF(d->Flickable->contentX(), d->Flickable->contentY());
  191. qDebug() << "Flickable size: " << QSize(d->Flickable->width(), d->Flickable->height());
  192. d->FlickableContentScrollAnimation->setTargetObject(d->Flickable);
  193. qreal ContentY = d->Flickable->contentY();
  194. if (FocusItemRect.bottom() >= d->Flickable->height())
  195. {
  196. qDebug() << "Item outside!!! FocusItemRect.bottom() >= d->Flickable->height()";
  197. ContentY = d->Flickable->contentY() + (FocusItemRect.bottom() - d->Flickable->height()) + 20;
  198. d->FlickableContentScrollAnimation->setEndValue(ContentY);
  199. d->FlickableContentScrollAnimation->start();
  200. }
  201. else if (FocusItemRect.top() < 0)
  202. {
  203. qDebug() << "Item outside!!! d->FocusItem->position().x < 0";
  204. ContentY = d->Flickable->contentY() + FocusItemRect.top() - 20;
  205. d->FlickableContentScrollAnimation->setEndValue(ContentY);
  206. d->FlickableContentScrollAnimation->start();
  207. }
  208. }
  209. //==============================================================================
  210. QObject* FreeVirtualKeyboardInputContext::inputEngineProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
  211. {
  212. Q_UNUSED(engine)
  213. Q_UNUSED(scriptEngine)
  214. return FreeVirtualKeyboardInputContext::instance()->d->InputEngine;
  215. }
  216. //------------------------------------------------------------------------------
  217. // EOF FreeVirtualKeyboardInpitContext.cpp