From fcd5fc2830d81bfbabfd5d16789cf6bd4050c85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=87=E9=9D=92?= Date: Sat, 9 Apr 2016 11:02:10 +0800 Subject: [PATCH] Support key navigation --- ImgButton.qml | 34 ++++++++++++++++++++------ LoginFrame.qml | 33 ++++++++++++++++++++----- Main.qml | 63 ++++++++++++++++++++++++++++++++++++++++++++---- PowerFrame.qml | 26 ++++++++++++++++---- SessionFrame.qml | 35 ++++++++++++++++++++++++--- UserFrame.qml | 48 +++++++++++++++++++++++++----------- 6 files changed, 198 insertions(+), 41 deletions(-) diff --git a/ImgButton.qml b/ImgButton.qml index 696d946..2dc70eb 100644 --- a/ImgButton.qml +++ b/ImgButton.qml @@ -1,23 +1,43 @@ import QtQuick 2.0 -Image { +Rectangle { id: button + radius: 5 + color: focus ? "#33000000" : "transparent" + width: 30 + height: 30 property url normalImg: "" property url hoverImg: normalImg property url pressImg: normalImg - source: normalImg signal clicked() + signal enterPressed() - onNormalImgChanged: button.source = normalImg + onNormalImgChanged: img.source = normalImg + + Image { + id: img + width: parent.width + height: parent.height + anchors.centerIn: parent + } MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: button.source = hoverImg - onPressed: button.source = pressImg - onExited: button.source = normalImg - onReleased: button.source = normalImg + onEntered: img.source = hoverImg + onPressed: img.source = pressImg + onExited: img.source = normalImg + onReleased: img.source = normalImg onClicked: button.clicked() } + Component.onCompleted: { + img.source = normalImg + } + Keys.onPressed: { + if (event.key == Qt.Key_Return || event.key == Qt.Key_Enter) { + button.clicked() + button.enterPressed() + } + } } diff --git a/LoginFrame.qml b/LoginFrame.qml index dadca2b..771bd5a 100644 --- a/LoginFrame.qml +++ b/LoginFrame.qml @@ -7,10 +7,8 @@ Item { property int sessionIndex: sessionModel.lastIndex property string userName: userModel.lastUser property bool isProcessing: glowAnimation.running - - function captureFocus() { - passwdInput.focus = true - } + property alias input: passwdInput + property alias button: loginButton Connections { target: sddm @@ -47,6 +45,10 @@ Item { width: 130 height: 130 source: userFrame.currentIconPath + onClicked: { + root.state = "stateUser" + userFrame.focus = true + } } Glow { @@ -117,11 +119,28 @@ Item { glowAnimation.running = true sddm.login(userNameText.text, passwdInput.text, sessionIndex) } - - KeyNavigation.backtab: userButton; KeyNavigation.tab: shutdownButton + KeyNavigation.backtab: { + if (sessionButton.visible) { + return sessionButton + } + else if (userButton.visible) { + return userButton + } + else { + return shutdownButton + } + } + KeyNavigation.tab: loginButton + Timer { + interval: 200 + running: true + onTriggered: passwdInput.forceActiveFocus() + } } ImgButton { id: loginButton + height: passwdInput.height + width: height anchors { right: parent.right verticalCenter: parent.verticalCenter @@ -134,6 +153,8 @@ Item { glowAnimation.running = true sddm.login(userNameText.text, passwdInput.text, sessionIndex) } + KeyNavigation.tab: shutdownButton + KeyNavigation.backtab: passwdInput } } } diff --git a/Main.qml b/Main.qml index f384dc8..5d7bda9 100644 --- a/Main.qml +++ b/Main.qml @@ -101,7 +101,10 @@ Rectangle { id: powerFrame anchors.fill: parent enabled: root.state == "statePower" - onNeedClose: root.state = "stateLogin" + onNeedClose: { + root.state = "stateLogin" + loginFrame.input.forceActiveFocus() + } onNeedShutdown: sddm.powerOff() onNeedRestart: sddm.reboot() onNeedSuspend: sddm.suspend() @@ -115,8 +118,12 @@ Rectangle { console.log("Selected session:", index) root.state = "stateLogin" loginFrame.sessionIndex = index + loginFrame.input.forceActiveFocus() + } + onNeedClose: { + root.state = "stateLogin" + loginFrame.input.forceActiveFocus() } - onNeedClose: root.state = "stateLogin" } UserFrame { @@ -127,8 +134,12 @@ Rectangle { console.log("Select user:", userName) root.state = "stateLogin" loginFrame.userName = userName + loginFrame.input.forceActiveFocus() + } + onNeedClose: { + root.state = "stateLogin" + loginFrame.input.forceActiveFocus() } - onNeedClose: root.state = "stateLogin" } LoginFrame { @@ -222,7 +233,21 @@ Rectangle { height: m_powerButtonSize visible: sessionFrame.isMultipleSessions() normalImg: sessionFrame.getCurrentSessionIconIndicator() - onClicked: root.state = "stateSession" + onClicked: { + root.state = "stateSession" + sessionFrame.focus = true + } + onEnterPressed: sessionFrame.currentItem.forceActiveFocus() + + KeyNavigation.tab: loginFrame.input + KeyNavigation.backtab: { + if (userButton.visible) { + return userButton + } + else { + return shutdownButton + } + } } ImgButton { @@ -237,6 +262,17 @@ Rectangle { onClicked: { console.log("Switch User...") root.state = "stateUser" + userFrame.focus = true + } + onEnterPressed: userFrame.currentItem.forceActiveFocus() + KeyNavigation.backtab: shutdownButton + KeyNavigation.tab: { + if (sessionButton.visible) { + return sessionButton + } + else { + return loginFrame.input + } } } @@ -250,6 +286,20 @@ Rectangle { onClicked: { console.log("Show shutdown menu") root.state = "statePower" + powerFrame.focus = true + } + onEnterPressed: powerFrame.shutdown.focus = true + KeyNavigation.backtab: loginFrame.button + KeyNavigation.tab: { + if (userButton.visible) { + return userButton + } + else if (sessionButton.visible) { + return sessionButton + } + else { + return loginFrame.input + } } } } @@ -258,7 +308,10 @@ Rectangle { MouseArea { z: -1 anchors.fill: parent - onClicked: root.state = "stateLogin" + onClicked: { + root.state = "stateLogin" + loginFrame.input.forceActiveFocus() + } } } } diff --git a/PowerFrame.qml b/PowerFrame.qml index 395e65a..abcc875 100644 --- a/PowerFrame.qml +++ b/PowerFrame.qml @@ -7,6 +7,8 @@ Item { signal needRestart() signal needSuspend() + property alias shutdown: shutdownButton + Row { spacing: 70 @@ -18,12 +20,18 @@ Item { height: 150 ImgButton { + id: shutdownButton + width: 75 + height: 75 anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top normalImg: "icons/powerframe/shutdown_normal.png" hoverImg: "icons/powerframe/shutdown_hover.png" pressImg: "icons/powerframe/shutdown_press.png" onClicked: needShutdown() + KeyNavigation.right: restartButton + KeyNavigation.left: suspendButton + Keys.onEscapePressed: needClose() } Text { @@ -42,12 +50,18 @@ Item { height: 150 ImgButton { + id: restartButton + width: 75 + height: 75 anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top normalImg: "icons/powerframe/restart_normal.png" hoverImg: "icons/powerframe/restart_hover.png" pressImg: "icons/powerframe/restart_press.png" onClicked: needRestart() + KeyNavigation.right: suspendButton + KeyNavigation.left: shutdownButton + Keys.onEscapePressed: needClose() } Text { @@ -66,12 +80,18 @@ Item { height: 150 ImgButton { + id: suspendButton + width: 75 + height: 75 anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top normalImg: "icons/powerframe/suspend_normal.png" hoverImg: "icons/powerframe/suspend_hover.png" pressImg: "icons/powerframe/suspend_press.png" onClicked: needSuspend() + KeyNavigation.right: shutdownButton + KeyNavigation.left: restartButton + Keys.onEscapePressed: needClose() } Text { @@ -92,9 +112,5 @@ Item { onClicked: needClose() } - Keys.onPressed: { - if (event.key === Qt.Key_Escape) { - needClose() - } - } + Keys.onEscapePressed: needClose() } diff --git a/SessionFrame.qml b/SessionFrame.qml index a157ae9..4d2dbe1 100644 --- a/SessionFrame.qml +++ b/SessionFrame.qml @@ -9,6 +9,8 @@ Item { readonly property int m_viewMaxWidth: frame.width - prevSession.width - nextSession.width - 230; property bool shouldShowBG: false property var sessionTypeList: ["deepin", "enlightenment", "fluxbox", "gnome", "kde", "lxde", "ubuntu"] + property alias currentItem: sessionList.currentItem + function getIconName(sessionName) { for (var item in sessionTypeList) { var str = sessionTypeList[item] @@ -33,6 +35,13 @@ Item { shouldShowBG = false } + onFocusChanged: { + // Active by mouse click + if (focus) { + sessionList.currentItem.focus = false + } + } + ImgButton { id: prevSession visible: sessionList.childrenRect.width > m_viewMaxWidth @@ -44,7 +53,6 @@ Item { sessionList.decrementCurrentIndex() shouldShowBG = true } -// KeyNavigation.backtab: btnShutdown; KeyNavigation.tab: listView } ListView { @@ -62,9 +70,9 @@ Item { property bool activeBG: sessionList.currentIndex === index && shouldShowBG border.width: 3 - border.color: activeBG ? "#33ffffff" : "transparent" + border.color: activeBG || focus ? "#33ffffff" : "transparent" radius: 8 - color: activeBG ? "#55000000" : "transparent" + color: activeBG || focus ? "#55000000" : "transparent" width: 230 height: 150 @@ -98,6 +106,24 @@ Item { color: "white" wrapMode: Text.WordWrap } + + Keys.onLeftPressed: { + sessionList.decrementCurrentIndex() + sessionList.currentItem.forceActiveFocus() + } + Keys.onRightPressed: { + sessionList.incrementCurrentIndex() + sessionList.currentItem.forceActiveFocus() + } + Keys.onEscapePressed: needClose() + Keys.onEnterPressed: { + selected(index) + sessionList.currentIndex = index + } + Keys.onReturnPressed: { + selected(index) + sessionList.currentIndex = index + } } } @@ -112,7 +138,6 @@ Item { sessionList.incrementCurrentIndex() shouldShowBG = true } -// KeyNavigation.backtab: listView; KeyNavigation.tab: session } MouseArea { @@ -120,4 +145,6 @@ Item { anchors.fill: parent onClicked: needClose() } + + Keys.onEscapePressed: needClose() } diff --git a/UserFrame.qml b/UserFrame.qml index ecdf41d..5b0e2cb 100644 --- a/UserFrame.qml +++ b/UserFrame.qml @@ -10,6 +10,7 @@ Item { property string currentIconPath: usersList.currentItem.iconPath property string currentUserName: usersList.currentItem.userName property bool shouldShowBG: false + property alias currentItem: usersList.currentItem function isMultipleUsers() { return usersList.count > 1 @@ -19,6 +20,13 @@ Item { shouldShowBG = false } + onFocusChanged: { + // Active by mouse click + if (focus) { + usersList.currentItem.focus = false + } + } + ImgButton { id: prevUser visible: usersList.childrenRect.width > m_viewMaxWidth @@ -30,7 +38,6 @@ Item { usersList.decrementCurrentIndex() shouldShowBG = true } -// KeyNavigation.backtab: btnShutdown; KeyNavigation.tab: listView } ListView { @@ -44,18 +51,26 @@ Item { orientation: ListView.Horizontal delegate: Rectangle { + id: item property string iconPath: icon property string userName: nameText.text property bool activeBG: usersList.currentIndex === index && shouldShowBG border.width: 3 - border.color: activeBG ? "#33ffffff" : "transparent" + border.color: activeBG || focus ? "#33ffffff" : "transparent" radius: 8 - color: activeBG ? "#55000000" : "transparent" + color: activeBG || focus? "#55000000" : "transparent" width: 130 height: 150 + function select() { + selected(name) + usersList.currentIndex = index + currentIconPath = icon + currentUserName = name + } + UserAvatar { id: iconButton anchors.top: parent.top @@ -63,13 +78,7 @@ Item { width: 100 height: 100 source: icon - onClicked: { - selected(name) - usersList.currentIndex = index - currentIconPath = icon - currentUserName = name - selected(name) - } + onClicked: item.select() } Text { @@ -84,11 +93,21 @@ Item { wrapMode: Text.WordWrap } + Keys.onLeftPressed: { + usersList.decrementCurrentIndex() + usersList.currentItem.forceActiveFocus() + } + Keys.onRightPressed: { + usersList.incrementCurrentIndex() + usersList.currentItem.forceActiveFocus() + } + Keys.onEscapePressed: needClose() + Keys.onEnterPressed: item.select() + Keys.onReturnPressed: item.select() + Component.onCompleted: { if (name === userModel.lastUser) { - usersList.currentIndex = index - currentIconPath = icon - currentUserName = name + item.select() } } } @@ -105,7 +124,6 @@ Item { usersList.incrementCurrentIndex() shouldShowBG = true } -// KeyNavigation.backtab: listView; KeyNavigation.tab: session } MouseArea { @@ -113,4 +131,6 @@ Item { anchors.fill: parent onClicked: needClose() } + + Keys.onEscapePressed: needClose() }