diff --git a/qml.qrc b/qml.qrc index 297d67ee81ec985f93fcdfe5a9166b286c284e4c..c6396fa303b51b2c6740cf9f6ec876a2a3d2c327 100644 --- a/qml.qrc +++ b/qml.qrc @@ -159,5 +159,6 @@ <file>src/constant/JamiResources.qml</file> <file>src/commoncomponents/BubbleLabel.qml</file> <file>src/commoncomponents/BackButton.qml</file> + <file>src/commoncomponents/JamiSwitch.qml</file> </qresource> </RCC> diff --git a/src/commoncomponents/BackButton.qml b/src/commoncomponents/BackButton.qml index 9f523b009d5edb6de95cde8662d5a12e5af0b95f..71eea2764d1b759ac15310a4a6ef3d8f9a50904e 100644 --- a/src/commoncomponents/BackButton.qml +++ b/src/commoncomponents/BackButton.qml @@ -29,4 +29,11 @@ PushButton { source: JamiResources.ic_arrow_back_24dp_svg toolTipText: JamiStrings.back + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + clicked() + keyEvent.accepted = true + } + } } diff --git a/src/commoncomponents/JamiSwitch.qml b/src/commoncomponents/JamiSwitch.qml new file mode 100644 index 0000000000000000000000000000000000000000..055919efd965ab34f990aba439f9ef2434a3208e --- /dev/null +++ b/src/commoncomponents/JamiSwitch.qml @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 by Savoir-faire Linux + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +import net.jami.Constants 1.0 + +Switch { + id: root + + indicator: Rectangle { + implicitWidth: JamiTheme.switchPreferredWidth + implicitHeight: JamiTheme.switchPreferredHeight + + x: root.leftPadding + y: parent.height / 2 - height / 2 + + radius: JamiTheme.switchIndicatorRadius + + color: root.checked ? JamiTheme.switchBackgroundCheckedColor : JamiTheme.whiteColor + border.color: root.checked ? JamiTheme.switchBackgroundCheckedColor : + JamiTheme.switchBackgroundBorderColor + + Rectangle { + x: root.checked ? parent.width - width : 0 + y: parent.height / 2 - height / 2 + + width: JamiTheme.switchIndicatorPreferredWidth + height: JamiTheme.switchIndicatorPreferredHeight + + radius: JamiTheme.switchIndicatorRadius + + color: (root.down || root.focus) ? Qt.darker(JamiTheme.switchBackgroundBorderColor, 1.2) : + JamiTheme.whiteColor + border.color: root.checked ? JamiTheme.switchBackgroundCheckedColor : + JamiTheme.switchIndicatorBorderColor + } + } + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + checked = !checked + keyEvent.accepted = true + } + } +} diff --git a/src/commoncomponents/MaterialButton.qml b/src/commoncomponents/MaterialButton.qml index 578c9922b65d782b099b179f8947fff6cda0add6..2a83d8b64dbc12bad2e8e7ccc320f1caa2632a73 100644 --- a/src/commoncomponents/MaterialButton.qml +++ b/src/commoncomponents/MaterialButton.qml @@ -32,6 +32,7 @@ Button { property var color: "transparent" property var hoveredColor: undefined property var pressedColor: undefined + property var keysNavigationFocusColor: Qt.darker(hoveredColor, 2) property var outlined: false property string animatedImageSource: "" @@ -149,7 +150,7 @@ Button { return root.hoveredColor if (checked && root.pressedColor) return root.pressedColor - return root.color + return root.focus ? root.keysNavigationFocusColor : root.color } border.color: { if (!outlined) @@ -158,8 +159,15 @@ Button { return root.hoveredColor if (checked && root.pressedColor) return root.pressedColor - return root.color + return root.focus ? root.keysNavigationFocusColor : root.color } radius: 4 } + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + clicked() + keyEvent.accepted = true + } + } } diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml index 7f1b33412c94c32ffd4b8a22a3a825f17570f864..4593c808fcc7743d5987cd2bf90c2ba1479e57c6 100644 --- a/src/commoncomponents/PhotoboothView.qml +++ b/src/commoncomponents/PhotoboothView.qml @@ -33,6 +33,9 @@ Item { property alias imageId: avatar.imageId required property real avatarSize + signal focusOnPreviousItem + signal focusOnNextItem + width: avatarSize height: boothLayout.height @@ -48,6 +51,14 @@ Item { isPreviewing = false } + function focusOnNextPhotoBoothItem () { + takePhotoButton.forceActiveFocus() + } + + function focusOnPreviousPhotoBoothItem () { + importButton.forceActiveFocus() + } + onVisibleChanged: { if (!visible) { stopBooth() @@ -66,10 +77,28 @@ Item { qsTr("All files") + " (*)" ] + onVisibleChanged: { + if (!visible) { + rejected() + } + } + onAccepted: { + if (importButton.focusAfterFileDialogClosed) { + importButton.focusAfterFileDialogClosed = false + importButton.forceActiveFocus() + } + var filePath = UtilsAdapter.getAbsPath(file) AccountAdapter.setCurrentAccountAvatarFile(filePath) } + + onRejected: { + if (importButton.focusAfterFileDialogClosed) { + importButton.focusAfterFileDialogClosed = false + importButton.forceActiveFocus() + } + } } ColumnLayout { @@ -153,6 +182,7 @@ Item { id: takePhotoButton Layout.alignment: Qt.AlignHCenter + radius: JamiTheme.primaryRadius imageColor: JamiTheme.textColor toolTipText: JamiStrings.takePhoto @@ -160,6 +190,23 @@ Item { JamiResources.round_add_a_photo_24dp_svg : JamiResources.baseline_camera_alt_24dp_svg + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + clicked() + keyEvent.accepted = true + } else if (keyEvent.matches(StandardKey.MoveToPreviousLine)) { + root.focusOnPreviousItem() + keyEvent.accepted = true + } + } + + KeyNavigation.tab: { + if (clearButton.visible) + return clearButton + return importButton + } + KeyNavigation.down: KeyNavigation.tab + onClicked: { if (isPreviewing) { flashAnimation.start() @@ -176,13 +223,27 @@ Item { PushButton { id: clearButton - visible: LRCInstance.currentAccountAvatarSet Layout.alignment: Qt.AlignHCenter + + visible: LRCInstance.currentAccountAvatarSet + radius: JamiTheme.primaryRadius source: JamiResources.round_close_24dp_svg toolTipText: JamiStrings.clearAvatar imageColor: JamiTheme.textColor + KeyNavigation.tab: importButton + KeyNavigation.up: takePhotoButton + KeyNavigation.down: KeyNavigation.tab + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + clicked() + takePhotoButton.forceActiveFocus() + keyEvent.accepted = true + } + } + onClicked: { stopBooth() AccountAdapter.setCurrentAccountAvatarBase64() @@ -192,12 +253,33 @@ Item { PushButton { id: importButton + property bool focusAfterFileDialogClosed: false + Layout.alignment: Qt.AlignHCenter + radius: JamiTheme.primaryRadius source: JamiResources.round_folder_24dp_svg toolTipText: JamiStrings.importFromFile imageColor: JamiTheme.textColor + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { + focusAfterFileDialogClosed = true + clicked() + keyEvent.accepted = true + } else if (keyEvent.matches(StandardKey.MoveToNextLine) || + keyEvent.key === Qt.Key_Tab) { + root.focusOnNextItem() + keyEvent.accepted = true + } + } + + KeyNavigation.up: { + if (clearButton.visible) + return clearButton + return takePhotoButton + } + onClicked: { stopBooth() importFromFileDialog.open() diff --git a/src/commoncomponents/PushButton.qml b/src/commoncomponents/PushButton.qml index ef9bbb01151570bed5502b7636897393c4ba04f6..8706e4338187f982248ce1c693e8b97da79a02ca 100644 --- a/src/commoncomponents/PushButton.qml +++ b/src/commoncomponents/PushButton.qml @@ -153,7 +153,7 @@ AbstractButton { PropertyChanges { target: background; color: pressedColor } }, State { - name: "hovered"; when: hovered + name: "hovered"; when: hovered || root.focus PropertyChanges { target: background; color: hoveredColor } }, State { diff --git a/src/constant/JamiTheme.qml b/src/constant/JamiTheme.qml index 9958f963d40c1f34aeea8c9711d7c8dd729111e7..381a8728b82c0536cf9e2822c7e0143e3e9ab6b6 100644 --- a/src/constant/JamiTheme.qml +++ b/src/constant/JamiTheme.qml @@ -97,6 +97,11 @@ Item { property color closeButtonLighterBlack: "#4c4c4c" + // Jami switch + property color switchBackgroundBorderColor: "#cccccc" + property color switchBackgroundCheckedColor: primaryBackgroundColor + property color switchIndicatorBorderColor: "#999999" + // Call buttons property color acceptButtonGreen: "#4caf50" property color acceptButtonHoverGreen: "#5db761" @@ -254,6 +259,13 @@ Item { property real lineEditContextMenuItemsWidth: 100 property real lineEditContextMenuSeparatorsHeight: 2 + // Jami switch + property real switchIndicatorRadius: 13 + property real switchPreferredHeight: 18 + property real switchPreferredWidth: 48 + property real switchIndicatorPreferredHeight: 26 + property real switchIndicatorPreferredWidth: 26 + // Modal Popup property real modalPopupRadius: 4 property real modalPopupDropShadowSamples: 16 diff --git a/src/mainview/components/ContactSearchBar.qml b/src/mainview/components/ContactSearchBar.qml index 7eccf510aaa6ed65450913b32a68281de0f0d8d0..c67912cbe662c975de6fc3eea97c0bf026e78b09 100644 --- a/src/mainview/components/ContactSearchBar.qml +++ b/src/mainview/components/ContactSearchBar.qml @@ -133,12 +133,11 @@ Rectangle { onActivated: contactSearchBar.forceActiveFocus() } - Shortcut { - sequence: "Return" - context: Qt.ApplicationShortcut - onActivated: { + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.InsertParagraphSeparator)) { if (contactSearchBar.text !== "") { returnPressedWhileSearching() + keyEvent.accepted = true } } } diff --git a/src/wizardview/components/BackupKeyPage.qml b/src/wizardview/components/BackupKeyPage.qml index 49fde169502b5404fba79b7ed67b33af79d75db0..af1455110df328c6f342ce234efe952dde03204c 100644 --- a/src/wizardview/components/BackupKeyPage.qml +++ b/src/wizardview/components/BackupKeyPage.qml @@ -95,6 +95,10 @@ Rectangle { rejected() } } + + onRejected: { + backupBtn.forceActiveFocus() + } } color: JamiTheme.backgroundColor @@ -157,10 +161,17 @@ Rectangle { font.pointSize: JamiTheme.textFontSize } - Switch { + JamiSwitch { id: passwordSwitch + Layout.alignment: Qt.AlignRight + focus: visible + + KeyNavigation.tab: backupBtn + KeyNavigation.up: skipBackupBtn + KeyNavigation.down: KeyNavigation.tab + onToggled: AppSettingsManager.setValue(Settings.NeverShowMeAgain, checked) } } @@ -177,10 +188,16 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedGreyHovered pressedColor: JamiTheme.buttonTintedGreyPressed + KeyNavigation.tab: skipBackupBtn + KeyNavigation.up: passwordSwitch + KeyNavigation.down: KeyNavigation.tab + onClicked: exportDialog.open() } MaterialButton { + id: skipBackupBtn + Layout.alignment: Qt.AlignCenter Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth @@ -192,6 +209,10 @@ Rectangle { pressedColor: JamiTheme.buttonTintedGreyPressed outlined: true + KeyNavigation.tab: passwordSwitch + KeyNavigation.up: backupBtn + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.nextStep() } } diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml index 2eda7a3afe423d0feec1d222913a2927bacd51a8..7645c6c7c5a761f4ce800a2c813686fdd4d01e4e 100644 --- a/src/wizardview/components/ConnectToAccountManagerPage.qml +++ b/src/wizardview/components/ConnectToAccountManagerPage.qml @@ -62,11 +62,6 @@ Rectangle { color: JamiTheme.backgroundColor - onVisibleChanged: { - if (visible) - accountManagerEdit.focus = true - } - ColumnLayout { id: connectToAccountManagerPageColumnLayout @@ -104,6 +99,8 @@ Rectangle { Layout.preferredWidth: connectBtn.width Layout.alignment: Qt.AlignCenter + focus: visible + selectByMouse: true placeholderText: JamiStrings.jamiManagementServerURL font.pointSize: JamiTheme.textFontSize @@ -111,6 +108,16 @@ Rectangle { borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: usernameManagerEdit + KeyNavigation.up: { + if (backButton.visible) + return backButton + else if (connectBtn.enabled) + return connectBtn + return passwordManagerEdit + } + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -140,6 +147,10 @@ Rectangle { borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: passwordManagerEdit + KeyNavigation.up: accountManagerEdit + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -158,6 +169,16 @@ Rectangle { echoMode: TextInput.Password borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: { + if (connectBtn.enabled) + return connectBtn + else if (backButton.visible) + return backButton + return accountManagerEdit + } + KeyNavigation.up: usernameManagerEdit + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -177,7 +198,17 @@ Rectangle { && passwordManagerEdit.text.length !== 0 && !spinnerTriggered + KeyNavigation.tab: { + if (backButton.visible) + return backButton + return accountManagerEdit + } + KeyNavigation.up: passwordManagerEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: { + if (connectBtn.focus) + accountManagerEdit.forceActiveFocus() spinnerTriggered = true WizardViewStepModel.accountCreationInfo = @@ -216,6 +247,14 @@ Rectangle { preferredSize: JamiTheme.wizardViewPageBackButtonSize + KeyNavigation.tab: accountManagerEdit + KeyNavigation.up: { + if (connectBtn.enabled) + return connectBtn + return passwordManagerEdit + } + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml index 843f430d2a05a65dadac20755aa13c55d589147e..2788bfa2a1cdd04f4a8bcd466eeba1caf41e5ca3 100644 --- a/src/wizardview/components/CreateAccountPage.qml +++ b/src/wizardview/components/CreateAccountPage.qml @@ -131,6 +131,11 @@ Rectangle { focus: visible + KeyNavigation.tab: chooseUsernameButton.enabled ? chooseUsernameButton : + skipButton + KeyNavigation.up: backButton + KeyNavigation.down: KeyNavigation.tab + placeholderText: isRendezVous ? JamiStrings.chooseAName : JamiStrings.chooseYourUserName } @@ -174,6 +179,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: skipButton + KeyNavigation.up: usernameEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.nextStep() } @@ -190,6 +199,11 @@ Rectangle { pressedColor: JamiTheme.buttonTintedGreyPressed outlined: true + KeyNavigation.tab: backButton + KeyNavigation.up: chooseUsernameButton.enabled ? chooseUsernameButton : + usernameEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: { usernameEdit.clear() WizardViewStepModel.nextStep() @@ -215,8 +229,14 @@ Rectangle { property int stackIndex: 1 + focus: visible + color: JamiTheme.backgroundColor + KeyNavigation.tab: passwordSwitch + KeyNavigation.up: passwordSwitch + KeyNavigation.down: passwordSwitch + ColumnLayout { id: passwordColumnLayout @@ -239,7 +259,7 @@ Rectangle { font.pointSize: JamiTheme.textFontSize + 3 } - Switch { + JamiSwitch { id: passwordSwitch objectName: "passwordSwitch" @@ -247,6 +267,10 @@ Rectangle { Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter Layout.leftMargin: -JamiTheme.wizardViewPageLayoutSpacing Layout.topMargin: 5 + + KeyNavigation.tab: checked ? passwordEdit : createAccountButton + KeyNavigation.up: backButton + KeyNavigation.down: KeyNavigation.tab } BubbleLabel { @@ -274,6 +298,10 @@ Rectangle { placeholderText: JamiStrings.password font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: passwordConfirmEdit + KeyNavigation.up: passwordSwitch + KeyNavigation.down: KeyNavigation.tab } MaterialLineEdit { @@ -292,6 +320,11 @@ Rectangle { placeholderText: JamiStrings.confirmPassword font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: createAccountButton.enabled ? createAccountButton : + backButton + KeyNavigation.up: passwordEdit + KeyNavigation.down: KeyNavigation.tab } Label { @@ -328,6 +361,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: backButton + KeyNavigation.up: passwordSwitch.checked ? passwordConfirmEdit : passwordSwitch + KeyNavigation.down: KeyNavigation.tab + onClicked: { WizardViewStepModel.accountCreationInfo = JamiQmlUtils.setUpAccountCreationInputPara( @@ -361,6 +398,20 @@ Rectangle { preferredSize: JamiTheme.wizardViewPageBackButtonSize + KeyNavigation.tab: { + if (createAccountStack.currentIndex === nameRegistrationPage.stackIndex) + return usernameEdit + else + return passwordSwitch + } + KeyNavigation.up: { + if (createAccountStack.currentIndex === nameRegistrationPage.stackIndex) + return skipButton + else + return createAccountButton.enabled ? createAccountButton : passwordConfirmEdit + } + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml index d60b0bf0ff59e7676eecc45980604f5466dd5e26..4c2346cc89acc938797796782451513c73bed0e6 100644 --- a/src/wizardview/components/CreateSIPAccountPage.qml +++ b/src/wizardview/components/CreateSIPAccountPage.qml @@ -98,6 +98,10 @@ Rectangle { placeholderText: JamiStrings.server font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: sipProxyEdit + KeyNavigation.up: backButton + KeyNavigation.down: KeyNavigation.tab } MaterialLineEdit { @@ -113,6 +117,10 @@ Rectangle { placeholderText: JamiStrings.proxy font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: sipUsernameEdit + KeyNavigation.up: sipServernameEdit + KeyNavigation.down: KeyNavigation.tab } MaterialLineEdit { @@ -128,6 +136,10 @@ Rectangle { placeholderText: JamiStrings.username font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: sipPasswordEdit + KeyNavigation.up: sipProxyEdit + KeyNavigation.down: KeyNavigation.tab } MaterialLineEdit { @@ -144,6 +156,10 @@ Rectangle { placeholderText: JamiStrings.password font.pointSize: JamiTheme.textFontSize font.kerning: true + + KeyNavigation.tab: createAccountButton + KeyNavigation.up: sipUsernameEdit + KeyNavigation.down: KeyNavigation.tab } MaterialButton { @@ -161,6 +177,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: backButton + KeyNavigation.up: sipPasswordEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: { WizardViewStepModel.accountCreationInfo = JamiQmlUtils.setUpAccountCreationInputPara( @@ -182,6 +202,10 @@ Rectangle { preferredSize: JamiTheme.wizardViewPageBackButtonSize + KeyNavigation.tab: sipServernameEdit + KeyNavigation.up: createAccountButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml index 7ffffb038901799a80aa5ba219093a87f5279f50..f6fdf0f7972d2d7c2aded025783dec56d3df7dbe 100644 --- a/src/wizardview/components/ImportFromBackupPage.qml +++ b/src/wizardview/components/ImportFromBackupPage.qml @@ -42,6 +42,7 @@ Rectangle { function clearAllTextFields() { connectBtn.spinnerTriggered = false passwordFromBackupEdit.clear() + filePath = "" errorText = "" fileImportBtnText = JamiStrings.archive } @@ -75,6 +76,16 @@ Rectangle { nameFilters: [JamiStrings.jamiArchiveFiles + " (*.gz)", JamiStrings.allFiles + " (*)"] + onVisibleChanged: { + if (!visible) { + rejected() + } + } + + onRejected: { + fileImportBtn.forceActiveFocus() + } + onAccepted: { filePath = file if (file.length !== "") { @@ -116,6 +127,16 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedGreyHovered pressedColor: JamiTheme.buttonTintedGreyPressed + KeyNavigation.tab: passwordFromBackupEdit + KeyNavigation.up: { + if (backButton.visible) + return backButton + else if (connectBtn.enabled) + return connectBtn + return passwordFromBackupEdit + } + KeyNavigation.down: KeyNavigation.tab + onClicked: { errorText = "" importFromFileDialog.open() @@ -161,6 +182,16 @@ Rectangle { echoMode: TextInput.Password borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: { + if (connectBtn.enabled) + return connectBtn + else if (backButton.visible) + return backButton + return fileImportBtn + } + KeyNavigation.up: fileImportBtn + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -185,7 +216,17 @@ Rectangle { return false } + KeyNavigation.tab: { + if (backButton.visible) + return backButton + return fileImportBtn + } + KeyNavigation.up: passwordFromBackupEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: { + if (connectBtn.focus) + fileImportBtn.forceActiveFocus() spinnerTriggered = true WizardViewStepModel.accountCreationInfo = @@ -225,6 +266,14 @@ Rectangle { preferredSize: JamiTheme.wizardViewPageBackButtonSize + KeyNavigation.tab: fileImportBtn + KeyNavigation.up: { + if (connectBtn.enabled) + return connectBtn + return passwordFromBackupEdit + } + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml index b343aa3e9ed65cd02b3c726b5cb67aa9a690406f..049934bcd961f563448afdd47543a167601d07d9 100644 --- a/src/wizardview/components/ImportFromDevicePage.qml +++ b/src/wizardview/components/ImportFromDevicePage.qml @@ -95,6 +95,14 @@ Rectangle { echoMode: TextInput.Password borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: pinFromDevice + KeyNavigation.up: { + if (backButton.visible) + return backButton + return pinFromDevice + } + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -133,6 +141,16 @@ Rectangle { borderColorMode: MaterialLineEdit.NORMAL + KeyNavigation.tab: { + if (connectBtn.enabled) + return connectBtn + else if (connectBtn.spinnerTriggered) + return passwordFromDevice + return backButton + } + KeyNavigation.up: passwordFromDevice + KeyNavigation.down: KeyNavigation.tab + onTextChanged: errorText = "" } @@ -149,6 +167,10 @@ Rectangle { enabled: pinFromDevice.text.length !== 0 && !spinnerTriggered + KeyNavigation.tab: backButton + KeyNavigation.up: pinFromDevice + KeyNavigation.down: KeyNavigation.tab + onClicked: { spinnerTriggered = true @@ -186,6 +208,10 @@ Rectangle { visible: !connectBtn.spinnerTriggered + KeyNavigation.tab: passwordFromDevice + KeyNavigation.up: connectBtn + KeyNavigation.down: KeyNavigation.tab + preferredSize: JamiTheme.wizardViewPageBackButtonSize onClicked: WizardViewStepModel.previousStep() diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml index 7d9e061512cdae2fe4db1612007d8d26ce3d4ef2..1292916d76ae77b5510a2eb8f38da738eb487ae4 100644 --- a/src/wizardview/components/ProfilePage.qml +++ b/src/wizardview/components/ProfilePage.qml @@ -104,6 +104,14 @@ Rectangle { imageId: createdAccountId avatarSize: 200 + onFocusOnPreviousItem: { + skipProfileSavingButton.forceActiveFocus() + } + + onFocusOnNextItem: { + aliasEdit.forceActiveFocus() + } + onVisibleChanged: { if (visible) LRCInstance.currentAccountAvatarSet = false @@ -138,6 +146,16 @@ Rectangle { fieldLayoutWidth: saveProfileBtn.width + KeyNavigation.tab: saveProfileBtn + KeyNavigation.down: KeyNavigation.tab + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.MoveToPreviousLine)) { + setAvatarWidget.focusOnPreviousPhotoBoothItem() + keyEvent.accepted = true + } + } + onTextEdited: { if (LRCInstance.currentAccountAvatarSet) return @@ -170,6 +188,10 @@ Rectangle { return JamiStrings.creatingAccount } + KeyNavigation.tab: skipProfileSavingButton + KeyNavigation.up: aliasEdit + KeyNavigation.down: KeyNavigation.tab + onClicked: { AccountAdapter.setCurrAccDisplayName(aliasEdit.text) WizardViewStepModel.nextStep() @@ -177,6 +199,10 @@ Rectangle { } MaterialButton { + id: skipProfileSavingButton + + objectName: "skipProfileSavingButton" + Layout.alignment: Qt.AlignCenter Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight @@ -188,6 +214,16 @@ Rectangle { pressedColor: JamiTheme.buttonTintedGreyPressed outlined: true + KeyNavigation.up: saveProfileBtn + + Keys.onPressed: function (keyEvent) { + if (keyEvent.matches(StandardKey.MoveToNextLine) || + keyEvent.key === Qt.Key_Tab) { + setAvatarWidget.focusOnNextPhotoBoothItem() + keyEvent.accepted = true + } + } + onClicked: { AccountAdapter.setCurrentAccountAvatarBase64() aliasEdit.clear() diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml index 4557e6ae50b69253ce7e26028bcf90d2102efad3..0d86072a68202861f71dfbdeb3f296b772166f90 100644 --- a/src/wizardview/components/WelcomePage.qml +++ b/src/wizardview/components/WelcomePage.qml @@ -48,6 +48,16 @@ Rectangle { } } + // Make sure that welcomePage grab activeFocus initially (when there is no account) + onVisibleChanged: { + if (visible) + forceActiveFocus() + } + + KeyNavigation.tab: newAccountButton + KeyNavigation.up: newAccountButton + KeyNavigation.down: KeyNavigation.tab + ColumnLayout { id: welcomePageColumnLayout @@ -98,6 +108,13 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: newRdvButton + KeyNavigation.up: backButton.visible ? backButton : + (showAdvancedButton.showAdvanced ? + newSIPAccountButton : + showAdvancedButton) + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.CreateJamiAccount) } @@ -117,6 +134,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: fromDeviceButton + KeyNavigation.up: newAccountButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.CreateRendezVous) } @@ -136,6 +157,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: fromBackupButton + KeyNavigation.up: newRdvButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.ImportFromDevice) } @@ -155,6 +180,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: showAdvancedButton + KeyNavigation.up: fromDeviceButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.ImportFromBackup) } @@ -181,8 +210,13 @@ Rectangle { hoverEnabled: true + KeyNavigation.tab: showAdvanced ? connectAccountManagerButton : + (backButton.visible ? backButton : newAccountButton) + KeyNavigation.up: fromBackupButton + KeyNavigation.down: KeyNavigation.tab + onClicked: { - showAdvanced = !showAdvanced + showAdvanced = !showAdvanced connectAccountManagerButton.visible = showAdvanced newSIPAccountButton.visible = showAdvanced } @@ -205,6 +239,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: newSIPAccountButton + KeyNavigation.up: showAdvancedButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.ConnectToAccountManager) } @@ -227,6 +265,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed + KeyNavigation.tab: backButton.visible ? backButton : newAccountButton + KeyNavigation.up: connectAccountManagerButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.startAccountCreationFlow( WizardViewStepModel.AccountCreationOption.CreateSipAccount) } @@ -253,6 +295,10 @@ Rectangle { visible: UtilsAdapter.getAccountListSize() + KeyNavigation.tab: newAccountButton + KeyNavigation.up: newSIPAccountButton + KeyNavigation.down: KeyNavigation.tab + onClicked: WizardViewStepModel.previousStep() } }