Martin Smith
Martin Smith

Reputation: 63

How change QT Virtual Keyboard Shift Logic

I have defined a custom style and layout for a QT Virtual Keyboard using QT 5.11.

The default implementation for the QT virtual keyboard shift key enables Caps Lock when you double click the Shift key.

How could I change the implementation to work on a cycle based procedure?

For example:

Upvotes: 0

Views: 1665

Answers (2)

malek.khlif
malek.khlif

Reputation: 85

Maybe this code give you an idea

import QtQuick 2.0
import QtQuick.Controls 2.3
import QtQuick.VirtualKeyboard 2.1
import QtQuick.Window 2.0

Window {
    id: window
    width: 800
    height: 480
    color: "#F6F6F6"
    visible: true

    MouseArea  {
        id: content
        width: window.width

        Column {
            id: textEditors
            spacing: 15
            x: 12
            y: 12
            width: parent.width - 26

            Label {
                color: "#565758"
                text: "Tap fields to enter text"
                anchors.horizontalCenter: parent.horizontalCenter
            }
            TextField {
                width: parent.width
                placeholderText: "One line field"
                inputMethodHints: Qt.ImhPreferLowercase
            }
            TextField {
                id: passwordField
                width: parent.width
                echoMode: TextField.Password
                placeholderText: "Password field"
                // changes do not work
                inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText

                onTextChanged: console.log(text)
            }
        }
    }

    InputPanel {
        id: inputPanel
        z: 2
        y: window.height
        width: window.width

        property bool shiftActive: (InputContext == null) ? null : InputContext.shiftActive
        property variant shiftKey: null

        function findKey(parent) {
            if (parent === null) {
                return null
            }

            var children = parent.children
            if (children === undefined || children === null) {
                return null
            }

            var obj = null

            for (var i = 0; i < children.length; i++) {
                obj = children[i]

                if (obj instanceof ShiftKey) {
                    return obj
                }

                obj = findKey(obj)

                if (obj === null) {
                    continue
                }

                if (obj instanceof ShiftKey) {
                    return obj
                }
            }

            return null
        }

        Timer {
            id: timer
            interval: 0
            repeat: false
            running: false
            onTriggered: {
                inputPanel.shiftKey.clicked()
            }
        }

        Connections {
            target: (InputContext.inputItem != null && InputContext.inputItem.echoMode === TextField.Password) ? InputContext.inputItem : null
            onTextChanged: {
                if (inputPanel.shiftActive) {
                    if (inputPanel.shiftKey == null) {
                        inputPanel.shiftKey = inputPanel.findKey(inputPanel.keyboard)
                    }

                    timer.start()
                }
            }
        }


        states: State {
            name: "visible"
            when: inputPanel.active
            PropertyChanges {
                target: inputPanel
                y: window.height - inputPanel.height
            }
        }
        transitions: Transition {
            from: ""
            to: "visible"
            reversible: true
            ParallelAnimation {
                NumberAnimation {
                    properties: "y"
                    duration: 250
                    easing.type: Easing.InOutQuad
                }
            }
        }
    }
}

Upvotes: 1

Jakub Motyczko
Jakub Motyczko

Reputation: 11

Unfortunately handling of the Shift behavior is implemented inside ShiftHandler::toggleShift where it checks for mouseDoubleClickInterval and other stuff, so the easiest way to accomplish feature you mentioned is to do it in a bit 'hacky' way by overlaying shift button with a MouseArea.

Things to do:

Here's an example on how to make it work to have:

  • shift toggle on singular click

  • capsLock toggle on longPress

Code:

shiftKeyPanel: KeyPanel {
    Rectangle {
        id: shiftKeyBackground
        radius: 5
        color: "#1e1b18"
        anchors.fill: parent
        anchors.margins: keyBackgroundMargin
        Image {
            id: shiftKeyIcon
            anchors.centerIn: parent
            sourceSize.width: 144 * keyIconScale
            sourceSize.height: 134 * keyIconScale
            smooth: false
            source: resourcePrefix + "images/shift-868482.svg"
        }
        states: [
            State {
                name: "capslock"
                when: InputContext.capsLock
                PropertyChanges {
                    target: shiftKeyBackground
                    color: "#5a892e"
                }
                PropertyChanges {
                    target: shiftKeyIcon
                    source: resourcePrefix + "images/shift-c5d6b6.svg"
                }
            },
            State {
                name: "shift"
                when: InputContext.shift
                PropertyChanges {
                    target: shiftKeyIcon
                    source: resourcePrefix + "images/shift-80c342.svg"
                }
            }
        ]

        MouseArea { ////////////////////here's the magic MouseArea
            anchors.fill: parent

            onClicked: {
                InputContext.capsLock = false
                InputContext.shiftHandler.toggleShift()
            }
            onPressAndHold: InputContext.capsLock = !InputContext.capsLock
        }
    }
    states: [
        State {
            name: "pressed"
            when: control.pressed
            PropertyChanges {
                target: shiftKeyBackground
                opacity: 0.80
            }
            PropertyChanges {
                target: shiftKeyIcon
                opacity: 0.6
            }
        },
        State {
            name: "disabled"
            when: !control.enabled
            PropertyChanges {
                target: shiftKeyBackground
                opacity: 0.8
            }
            PropertyChanges {
                target: shiftKeyIcon
                opacity: 0.2
            }
        }

Upvotes: 1

Related Questions