I decided to implement this myself in a native solution. This gives me more control over what’s displayed and will work on any platform. Here’s my files:
Main.qml
import Felgo 3.0
import QtQuick 2.5
App {
property var accents: {"a": ["à"], "e": ["é", "è", "ê"], "i": ["î"], "u": ["û"], "c": ["ç"]}
property var accentList: ["a", "e", "i", "u", "c"]
property var accentKeys: {"a": Qt.Key_A, "e": Qt.Key_E, "i": Qt.Key_I, "u": Qt.Key_U, "c": Qt.Key_C}
property string currentAccent: ""
property bool showAccents: false
// insert the character at the given cursor index
function insertAtCursor(cursorIdx, text, chr) {
var keepIdx = cursorIdx-1
return text.slice(0, keepIdx) + chr + text.slice(cursorIdx)
}
function forEachAccent(fn) {
for(var i=0; i<accentList.length; i++) {
fn(accentList[i], accentKeys[accentList[i]], accents[accentList[i]])
}
}
ShortcutHandler {}
AppTextEdit {
id: textEdit
placeholderText: "type here"
focus: true
anchors.verticalCenter: parent.verticalCenter
x: parent.width / 3
Keys.onPressed: {
// ignore repeats of accent keys: 'a', 'e', etc
if(event.isAutoRepeat) {
var accept = false
forEachAccent(function(chr, key, list) {
if(event.key == key) {
accept = true
}
})
event.accepted = accept
return
}
// if the accent pop up is showing, then intercept the number keys and replace the text with the accent
if(showAccents) {
if(event.key >= Qt.Key_1 && event.key <= Qt.Key_1 + accents[currentAccent].length) {
console.log(accents[currentAccent][event.key-Qt.Key_1])
var cursorIdx = textEdit.cursorPosition
textEdit.text = insertAtCursor(cursorIdx, textEdit.text, accents[currentAccent][event.key-Qt.Key_1])
textEdit.cursorPosition = cursorIdx
showAccents = false
currentAccent = ""
event.accepted = true
return
}
}
// check if the key press was an accent character and if so,
// start a timer to count how long it's held down for
currentAccent = ""
showAccents = false
forEachAccent(function(chr, key, list) {
if(key == event.key) {
currentAccent = chr
autoRepeatThreshold.start()
}
})
}
Keys.onReleased: {
autoRepeatThreshold.stop()
}
AccentsPopup {
id: accentsBox
x: -width/2 + textEdit.cursorRectangle.x
anchors.bottom: parent.top
}
}
Timer {
id: autoRepeatThreshold
running: false
repeat: false
interval: 300
onTriggered: {
showAccents = true
}
}
}
ShortcutHandler.qml
import Felgo 3.0
import QtQuick 2.5
Item {
id: shortcutHandler
Shortcut {
sequence: 'Escape'
context: Qt.ApplicationShortcut
onActivated: {
showAccents = false
currentAccent = ""
}
}
}
AccentsPopup.qml
import Felgo 3.0
import QtQuick 2.5
Rectangle {
visible: showAccents
width: accentText.width + dp(20)
height: dp(40)
radius: dp(2)
Grid {
id: accentText
columns: currentAccent === "" ? 0 : accents[currentAccent].length
anchors.horizontalCenter: parent.horizontalCenter
columnSpacing: dp(10)
Repeater {
model: currentAccent === "" ? [] : accents[currentAccent]
AppText {
text: currentAccent === "" ? [] : accents[currentAccent][index]
font.pointSize: dp(15)
}
}
Repeater {
model: currentAccent === "" ? [] : accents[currentAccent]
AppText {
text: index + 1
color: "#777777"
font.pointSize: dp(15)
}
}
}
PolygonItem {
id: triangle
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
color: parent.color
fill: true
vertices: [
Qt.point(0, 0),
Qt.point(20, 0),
Qt.point(10, 10)
]
}
}
My only issue now is when trying to override the Escape shortcut to cancel the input, I get the message QQuickAction::event: Ambiguous shortcut overload: ?
. Is this a Qt issue or a Felgo issue?
Thanks,
Phil