Implement keyboard navigation and focus rectangles

Fixes #102
This commit is contained in:
Martin Bříza 2017-08-30 17:09:48 +02:00
parent ffbecb613e
commit c909ac9679
13 changed files with 217 additions and 93 deletions

View File

@ -27,6 +27,7 @@ Item {
id: root
width: parent.width
height: $(84)
activeFocusOnTab: true
readonly property bool isTop: !releases.get(index-1) || (release.category !== releases.get(index-1).category)
readonly property bool isBottom:
@ -156,14 +157,20 @@ Item {
}
}
}
FocusRectangle {
visible: root.activeFocus
anchors.fill: parent
anchors.margins: $(3)
}
}
Keys.onSpacePressed: delegateMouse.action()
MouseArea {
id: delegateMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
function action() {
if (release.isLocal) {
releases.selectedIndex = index
fileDialog.visible = true
@ -173,5 +180,8 @@ Item {
imageList.stepForward(release.index)
}
}
onClicked: {
action()
}
}
}

View File

@ -19,13 +19,21 @@
import QtQuick 2.0
import QtQuick.Window 2.0
import "../simple"
IndicatedImage {
id: root
activeFocusOnTab: true
Keys.onSpacePressed: mouse.action()
MouseArea {
id: mouse
anchors.fill: parent
onClicked: fullscreenViewer.show(root.source)
function action() {
fullscreenViewer.show(root.source)
}
onClicked: action()
cursorShape: Qt.PointingHandCursor
}
@ -36,6 +44,12 @@ IndicatedImage {
Behavior on opacity { NumberAnimation { duration: 160 } }
}
FocusRectangle {
anchors.fill: parent
anchors.margins: $(-3)
visible: parent.activeFocus
}
Behavior on scale {
NumberAnimation {
easing.type: Easing.InOutElastic

View File

@ -272,6 +272,8 @@ Dialog {
anchors.fill: parent
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
flickableItem.flickableDirection: Flickable.VerticalFlick
activeFocusOnTab: false
contentItem: Item {
width: contentScrollView.width - $(18)
height: layout.height + $(18)
@ -441,6 +443,7 @@ Dialog {
}
AdwaitaComboBox {
z: pressed ? 1 : 0
enabled: visible
visible: releases.selected.version.variant.arch.id == Architecture.ARM || (releases.selected.isLocal && releases.variant.iso.indexOf(".iso", releases.variant.iso.length - ".iso".length) === -1)
width: driveCombo.implicitWidth * 2.5
model: ["Raspberry Pi 2 Model B", "Raspberry Pi 3 Model B"]

View File

@ -143,6 +143,7 @@ ApplicationWindow {
AdwaitaPopup {
id: newVersionPopup
enabled: open
open: versionChecker.newerVersion
title: qsTr("Fedora Media Writer %1 Released").arg(versionChecker.newerVersion)
text: qsTr("Update for great new features and bugfixes!")
@ -175,6 +176,7 @@ ApplicationWindow {
Rectangle {
id: fatalErrorOverlay
opacity: drives.isBroken ? 1.0 : 0.0
enabled: visible
visible: opacity > 0.1
Behavior on opacity { NumberAnimation { } }
anchors.fill: parent

View File

@ -26,5 +26,6 @@
<file>simple/Cross.qml</file>
<file>main.qml</file>
<file>complex/DeleteButton.qml</file>
<file>simple/FocusRectangle.qml</file>
</qresource>
</RCC>

View File

@ -38,6 +38,7 @@ AdwaitaRectangle {
property bool pressed: isOpen
property bool isOpen: false
activeFocusOnTab: true
signal activated(int index)
@ -76,12 +77,28 @@ AdwaitaRectangle {
font.pointSize: $(9)
}
Keys.onUpPressed: {
if (currentIndex > 0)
currentIndex--
}
Keys.onDownPressed: {
if (currentIndex < count - 1)
currentIndex++
}
Keys.onSpacePressed: mouse.action()
MouseArea {
id: mouse
hoverEnabled: true
enabled: !isOpen
anchors.fill: parent
onClicked: if (count > 0) isOpen = true
function action() {
if (count > 0) {
isOpen = true
options.focus = true
}
}
onClicked: action()
}
// area capturing clicks around the open dropdown... a bit hacky
@ -132,15 +149,20 @@ AdwaitaRectangle {
text: textRole ? model[textRole] : modelData
font.pointSize: $(9)
}
Keys.onSpacePressed: itemMouse.action()
MouseArea {
id: itemMouse
hoverEnabled: true
anchors.fill: parent
onClicked: {
function action() {
options.currentIndex = index
control.isOpen = false
activated(index)
}
onClicked: {
action()
}
onContainsMouseChanged: {
if (containsMouse)
options.itemContainsMouse = true

View File

@ -25,6 +25,7 @@ import QtQuick.Layouts 1.1
Rectangle {
id: root
clip: true
enabled: open
focus: open
color: "#729FCF"

View File

@ -23,10 +23,11 @@ import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
Item {
FocusScope {
id: root
property bool open: false
visible: opacity > 0.0
enabled: open
opacity: open ? 1.0 : 0.0
Behavior on opacity { NumberAnimation { duration: 120 } }

View File

@ -23,7 +23,7 @@ import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
Item {
FocusScope {
id: popover
property bool open: false
visible: opacity > 0.0

View File

@ -70,6 +70,12 @@ Item {
property color topColor: control.enabled ? !(control.pressed || control.checked) ? !control.hovered ? "#14ffffff" : "#14ffffff" : "#1e000000" : "transparent"
property color bottomColor: control.enabled ? !(control.pressed || control.checked) ? !control.hovered ? "#14000000" : "#05ffffff" : "#14000000" : "transparent"
}
FocusRectangle {
id: focusRect
visible: control.activeFocus
anchors.fill: parent
anchors.margins: $(2)
}
}
SystemPalette {

View File

@ -0,0 +1,11 @@
import QtQuick 2.0
// TODO use a BorderImage or something else to draw a dashed rectangle, this is ugly
Rectangle {
color: "transparent"
radius: $(2)
border {
width: $(1)
color: mixColors(palette.windowText, palette.button, 0.4)
}
}

View File

@ -34,6 +34,7 @@ Item {
anchors.fill: parent
property bool focused: contentList.currentIndex === 1
enabled: focused
onFocusedChanged: {
if (focused && !prereleaseNotification.wasOpen && releases.selected.prerelease.length > 0)
@ -66,6 +67,8 @@ Item {
}
ScrollView {
activeFocusOnTab: false
focus: true
anchors {
fill: parent
leftMargin: anchors.rightMargin
@ -189,13 +192,23 @@ Item {
Behavior on color { ColorAnimation { duration: 100 } }
MouseArea {
id: versionMouse
activeFocusOnTab: true
enabled: versionRepeater.count > 1
anchors.fill: parent
hoverEnabled: true
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
function action() {
versionPopover.open = !versionPopover.open
}
onClicked: {
action()
}
Keys.onSpacePressed: action()
FocusRectangle {
anchors.fill: parent
anchors.margins: $(-2)
visible: parent.activeFocus
}
}
BusyIndicator {
@ -314,14 +327,26 @@ Item {
Behavior on color { ColorAnimation { duration: 100 } }
MouseArea {
id: archMouse
activeFocusOnTab: parent.visible
anchors.fill: parent
hoverEnabled: true
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
if (versionPopover.open)
function action() {
if (versionPopover.open) {
versionPopover.open = false
else
}
else {
archPopover.open = !archPopover.open
}
}
Keys.onSpacePressed: action()
onClicked: {
action()
}
FocusRectangle {
anchors.fill: parent
anchors.margins: $(-2)
visible: parent.activeFocus
}
}

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.3
import QtQuick 2.4
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
@ -25,15 +25,17 @@ import QtQuick.Layouts 1.1
import "../simple"
import "../complex"
Item {
FocusScope {
id: imageList
property alias currentIndex: osListView.currentIndex
property real fadeDuration: 200
property int lastIndex: -1
property bool focused: contentList.currentIndex === 0
signal stepForward(int index)
onStepForward: lastIndex = index
enabled: focused
anchors.fill: parent
clip: true
@ -62,6 +64,7 @@ Item {
Rectangle {
enabled: !releases.frontPage
opacity: !releases.frontPage ? 1.0 : 0.0
visible: opacity > 0.0
id: searchBox
border {
color: searchInput.activeFocus ? "#4a90d9" : Qt.darker(palette.button, 1.3)
@ -117,6 +120,7 @@ Item {
}
TextInput {
id: searchInput
activeFocusOnTab: searchBox.visible
anchors {
left: magnifyingGlass.right
top: parent.top
@ -150,6 +154,8 @@ Item {
}
id: archSelect
activeFocusOnTab: visible
visible: opacity > 0.0
anchors {
right: parent.right
top: parent.top
@ -217,6 +223,7 @@ Item {
ListView {
id: osListView
clip: true
focus: true
anchors {
fill: parent
leftMargin: mainWindow.margin
@ -224,6 +231,26 @@ Item {
topMargin: whiteBackground.y
}
model: releases
delegate: DelegateImage {
width: parent.width
focus: true
}
remove: Transition {
NumberAnimation { properties: "x"; to: width; duration: 300 }
}
removeDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
}
add: Transition {
NumberAnimation { properties: releases.frontPage ? "y" : "x"; from: releases.frontPage ? 0 : -width; duration: 300 }
}
addDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
}
section {
property: "release.category"
criteria: ViewSection.FullString
@ -247,8 +274,10 @@ Item {
}
footer: Item {
id: footerRoot
height: !releases.frontPage ? aboutColumn.height + $(72) : $(36)
width: osListView.width
z: 0
Column {
id: aboutColumn
width: parent.width
@ -328,95 +357,94 @@ Item {
}
}
}
}
Rectangle {
id: threeDotWrapper
clip: true
visible: releases.frontPage
enabled: visible
activeFocusOnTab: true
radius: $(3)
color: palette.window
width: osListView.width - $(2)
height: $(32)
anchors.horizontalCenter: parent.horizontalCenter
y: $(84)*3 + 1
z: -1
Rectangle {
clip: true
visible: releases.frontPage
anchors.fill: parent
anchors.margins: 1
radius: $(3)
color: palette.window
Rectangle {
anchors.fill: parent
anchors.topMargin: $(-10)
color: threeDotMouse.containsPress ? Qt.darker(palette.window, 1.2) : threeDotMouse.containsMouse ? palette.window : palette.base
Behavior on color { ColorAnimation { duration: 120 } }
radius: $(5)
border {
color: Qt.darker(palette.base, 1.3)
width: 1
}
}
Column {
id: threeDotDots
property bool hidden: false
opacity: hidden ? 0.0 : 1.0
Behavior on opacity { NumberAnimation { duration: 60 } }
anchors.centerIn: parent
spacing: $(3)
Repeater {
model: 3
Rectangle { height: $(4); width: $(4); radius: $(1); color: mixColors(palette.windowText, palette.window, 0.75); antialiasing: true }
}
}
Text {
id: threeDotText
y: threeDotDots.hidden ? parent.height / 2 - height / 2 : -height
font.pointSize: $(9)
anchors.horizontalCenter: threeDotDots.horizontalCenter
Behavior on y { NumberAnimation { duration: 60 } }
clip: true
text: qsTr("Display additional Fedora flavors")
color: "gray"
}
Timer {
id: threeDotTimer
interval: 200
onTriggered: {
threeDotDots.hidden = true
}
}
MouseArea {
id: threeDotMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onHoveredChanged: {
if (containsMouse && !pressed) {
threeDotTimer.start()
}
if (!containsMouse) {
threeDotTimer.stop()
threeDotDots.hidden = false
}
}
onClicked: {
moveUp.enabled = true
releases.frontPage = false
}
anchors.topMargin: $(-10)
color: threeDotMouse.containsPress ? Qt.darker(palette.window, 1.2) : threeDotMouse.containsMouse ? palette.window : palette.base
Behavior on color { ColorAnimation { duration: 120 } }
radius: $(5)
border {
color: Qt.darker(palette.base, 1.3)
width: 1
}
}
}
model: releases
Column {
id: threeDotDots
property bool hidden: false
opacity: hidden ? 0.0 : 1.0
Behavior on opacity { NumberAnimation { duration: 60 } }
anchors.centerIn: parent
spacing: $(3)
Repeater {
model: 3
Rectangle { height: $(4); width: $(4); radius: $(1); color: mixColors(palette.windowText, palette.window, 0.75); antialiasing: true }
}
}
delegate: DelegateImage {
width: parent.width
}
Text {
id: threeDotText
y: threeDotDots.hidden ? parent.height / 2 - height / 2 : -height
font.pointSize: $(9)
anchors.horizontalCenter: threeDotDots.horizontalCenter
Behavior on y { NumberAnimation { duration: 60 } }
clip: true
text: qsTr("Display additional Fedora flavors")
color: "gray"
}
remove: Transition {
NumberAnimation { properties: "x"; to: width; duration: 300 }
}
removeDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
}
add: Transition {
NumberAnimation { properties: releases.frontPage ? "y" : "x"; from: releases.frontPage ? 0 : -width; duration: 300 }
}
addDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
FocusRectangle {
visible: threeDotWrapper.activeFocus
anchors.fill: parent
anchors.margins: $(2)
}
Timer {
id: threeDotTimer
interval: 200
onTriggered: {
threeDotDots.hidden = true
}
}
Keys.onSpacePressed: threeDotMouse.action()
MouseArea {
id: threeDotMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onHoveredChanged: {
if (containsMouse && !pressed) {
threeDotTimer.start()
}
if (!containsMouse) {
threeDotTimer.stop()
threeDotDots.hidden = false
}
}
function action() {
moveUp.enabled = true
releases.frontPage = false
}
onClicked: {
action()
}
}
}
}
style: ScrollViewStyle {