Set alphabetic/numeric keyboard per field entered

This commit is contained in:
David Rowe 2016-09-30 11:54:32 +13:00
parent e3be34528f
commit 5e842843c6
6 changed files with 64 additions and 36 deletions

View file

@ -12,10 +12,11 @@
var MAX_WARNINGS = 3;
var numWarnings = 0;
var isKeyboardRaised = false;
var isNumericKeyboard = false;
var KEYBOARD_HEIGHT = 200;
function shouldRaiseKeyboard() {
if (document.activeElement.nodeName == "INPUT" || document.activeElement.nodeName == "TEXTAREA") {
if (document.activeElement.nodeName === "INPUT" || document.activeElement.nodeName === "TEXTAREA") {
return true;
} else {
// check for contenteditable attribute
@ -29,26 +30,39 @@
}
};
function shouldSetNumeric() {
return document.activeElement.type === "number";
};
setInterval(function () {
if (isKeyboardRaised !== shouldRaiseKeyboard()) {
isKeyboardRaised = !isKeyboardRaised;
var keyboardRaised = shouldRaiseKeyboard();
var numericKeyboard = shouldSetNumeric();
if (isKeyboardRaised) {
var delta = document.activeElement.getBoundingClientRect().bottom + 10
- (document.body.clientHeight - KEYBOARD_HEIGHT);
if (delta > 0) {
document.body.scrollTop += delta;
}
}
if (keyboardRaised !== isKeyboardRaised || numericKeyboard !== isNumericKeyboard) {
if (typeof EventBridge != "undefined") {
EventBridge.emitWebEvent(isKeyboardRaised ? "_RAISE_KEYBOARD" : "_LOWER_KEYBOARD");
if (typeof EventBridge !== "undefined") {
EventBridge.emitWebEvent(
keyboardRaised ? ("_RAISE_KEYBOARD" + (numericKeyboard ? "_NUMERIC" : "")) : "_LOWER_KEYBOARD"
);
} else {
if (numWarnings < MAX_WARNINGS) {
console.log("WARNING: no global EventBridge object found");
numWarnings++;
}
}
if (!isKeyboardRaised) {
var delta = document.activeElement.getBoundingClientRect().bottom + 10
- (document.body.clientHeight - KEYBOARD_HEIGHT);
if (delta > 0) {
setTimeout(function () {
document.body.scrollTop += delta;
}, 500); // Allow time for keyboard to be raised in QML.
}
}
isKeyboardRaised = keyboardRaised;
isNumericKeyboard = numericKeyboard;
}
}, POLL_FREQUENCY);
})();

View file

@ -857,7 +857,7 @@ void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
}
// Handle QML text fields' focus and unfocus - testing READ_ONLY_PROPERTY prevents action for HTML files.
// HTML text fields are handled via emitWebEvent().
// HTML text fields are handled in emitWebEvent() methods.
const char* READ_ONLY_PROPERTY = "readOnly";
setKeyboardRaised(item, item->hasActiveFocus() && item->property(READ_ONLY_PROPERTY) == false);
_currentFocusItem = item;
@ -919,14 +919,20 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key) {
QCoreApplication::postEvent(getEventHandler(), releaseEvent);
}
void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised) {
void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric) {
if (!object) {
return;
}
QQuickItem* item = dynamic_cast<QQuickItem*>(object);
while (item) {
// Numeric value may be set in parameter from HTML UI; for QML UI, detect numeric fields here.
numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox";
if (item->property("keyboardRaised").isValid()) {
if (item->property("punctuationMode").isValid()) {
item->setProperty("punctuationMode", QVariant(numeric));
}
item->setProperty("keyboardRaised", QVariant(raised));
return;
}
@ -946,10 +952,14 @@ void OffscreenQmlSurface::emitWebEvent(const QVariant& message) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "emitWebEvent", Qt::QueuedConnection, Q_ARG(QVariant, message));
} else {
// special case to handle raising and lowering the virtual keyboard
if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD") {
setKeyboardRaised(_currentFocusItem, true);
} else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD") {
// Special case to handle raising and lowering the virtual keyboard.
const QString RAISE_KEYBOARD = "_RAISE_KEYBOARD";
const QString RAISE_KEYBOARD_NUMERIC = "_RAISE_KEYBOARD_NUMERIC";
const QString LOWER_KEYBOARD = "_LOWER_KEYBOARD";
QString messageString = message.type() == QVariant::String ? message.toString() : "";
if (messageString.left(RAISE_KEYBOARD.length()) == RAISE_KEYBOARD) {
setKeyboardRaised(_currentFocusItem, true, messageString == RAISE_KEYBOARD_NUMERIC);
} else if (messageString == LOWER_KEYBOARD) {
setKeyboardRaised(_currentFocusItem, false);
} else {
emit webEventReceived(message);

View file

@ -70,7 +70,7 @@ public:
QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget);
bool eventFilter(QObject* originalDestination, QEvent* event) override;
void setKeyboardRaised(QObject* object, bool raised);
void setKeyboardRaised(QObject* object, bool raised, bool numeric = false);
Q_INVOKABLE void synthesizeKeyPress(QString key);

View file

@ -43,10 +43,14 @@ void QmlWebWindowClass::emitWebEvent(const QVariant& webMessage) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "emitWebEvent", Qt::QueuedConnection, Q_ARG(QVariant, webMessage));
} else {
// Special cases for raising and lowering the virtual keyboard.
if (webMessage.type() == QVariant::String && webMessage.toString() == "_RAISE_KEYBOARD") {
setKeyboardRaised(asQuickItem(), true);
} else if (webMessage.type() == QVariant::String && webMessage.toString() == "_LOWER_KEYBOARD") {
// Special case to handle raising and lowering the virtual keyboard.
const QString RAISE_KEYBOARD = "_RAISE_KEYBOARD";
const QString RAISE_KEYBOARD_NUMERIC = "_RAISE_KEYBOARD_NUMERIC";
const QString LOWER_KEYBOARD = "_LOWER_KEYBOARD";
QString messageString = webMessage.type() == QVariant::String ? webMessage.toString() : "";
if (messageString.left(RAISE_KEYBOARD.length()) == RAISE_KEYBOARD) {
setKeyboardRaised(asQuickItem(), true, messageString == RAISE_KEYBOARD_NUMERIC);
} else if (messageString == LOWER_KEYBOARD) {
setKeyboardRaised(asQuickItem(), false);
} else {
emit webEventReceived(webMessage);
@ -54,7 +58,7 @@ void QmlWebWindowClass::emitWebEvent(const QVariant& webMessage) {
}
}
void QmlWebWindowClass::setKeyboardRaised(QObject* object, bool raised) {
void QmlWebWindowClass::setKeyboardRaised(QObject* object, bool raised, bool numeric) {
if (!object) {
return;
}
@ -62,6 +66,9 @@ void QmlWebWindowClass::setKeyboardRaised(QObject* object, bool raised) {
QQuickItem* item = dynamic_cast<QQuickItem*>(object);
while (item) {
if (item->property("keyboardRaised").isValid()) {
if (item->property("punctuationMode").isValid()) {
item->setProperty("punctuationMode", QVariant(numeric));
}
item->setProperty("keyboardRaised", QVariant(raised));
return;
}

View file

@ -35,7 +35,7 @@ protected:
QString qmlSource() const override { return "QmlWebWindow.qml"; }
private:
void setKeyboardRaised(QObject* object, bool raised);
void setKeyboardRaised(QObject* object, bool raised, bool numeric = false);
};
#endif

View file

@ -20,18 +20,15 @@ function setUpKeyboardControl() {
lowerTimer = null;
}
if (isRaised) {
return;
}
EventBridge.emitWebEvent("_RAISE_KEYBOARD" + (this.type === "number" ? "_NUMERIC" : ""));
var delta = this.getBoundingClientRect().bottom + 10 - (document.body.clientHeight - KEYBOARD_HEIGHT);
EventBridge.emitWebEvent("_RAISE_KEYBOARD");
if (delta > 0) {
setTimeout(function () {
document.body.scrollTop += delta;
}, 500); // Allow time for keyboard to be raised in QML.
if (!isRaised) {
var delta = this.getBoundingClientRect().bottom + 10 - (document.body.clientHeight - KEYBOARD_HEIGHT);
if (delta > 0) {
setTimeout(function () {
document.body.scrollTop += delta;
}, 500); // Allow time for keyboard to be raised in QML.
}
}
isRaised = true;