mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-03-27 01:03:09 +00:00
fix: restore console UI icon visibility, selection highlight, focus transfer
- Force isMask on header Kirigami.Icon contentItems (Search/Import/Settings) so white color is applied regardless of icon theme - Remove MultiEffect shadow from GameCard (was bleeding far outside card bounds) - Add gridActive prop to GameCard so selection highlight depends on actual flickable focus, not wrapper focus - Two-tier selection: full highlight when grid focused, dim border when grid unfocused (card stays visible) - Focus transfer: gamepad Up from top row emits headerFocusRequested; Down from rail/buttons calls libraryView.restoreFocus() - Gate gamepad navigation guards on grid.flickable.activeFocus (Maui.GridBrowser internal GridView)
This commit is contained in:
parent
b5e03fe856
commit
2df35e9b81
5 changed files with 195 additions and 37 deletions
|
|
@ -16,6 +16,15 @@ Item {
|
||||||
signal sourceSelected(string source)
|
signal sourceSelected(string source)
|
||||||
signal settingsRequested()
|
signal settingsRequested()
|
||||||
signal importRequested()
|
signal importRequested()
|
||||||
|
signal focusDownRequested()
|
||||||
|
|
||||||
|
function focusCurrent() {
|
||||||
|
if (tabList.currentItem) {
|
||||||
|
tabList.currentItem.forceActiveFocus()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tabList.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
function selectNext() {
|
function selectNext() {
|
||||||
if (sourceModel.count <= 0) return
|
if (sourceModel.count <= 0) return
|
||||||
|
|
@ -136,12 +145,25 @@ Item {
|
||||||
height: tabList.height - tabList.topMargin - tabList.bottomMargin
|
height: tabList.height - tabList.topMargin - tabList.bottomMargin
|
||||||
|
|
||||||
readonly property bool isActive: model.sourceId === root.currentSource
|
readonly property bool isActive: model.sourceId === root.currentSource
|
||||||
|
readonly property bool isFocused: tabDelegate.activeFocus || tabDelegate.hovered
|
||||||
|
|
||||||
background: Rectangle {
|
hoverEnabled: true
|
||||||
|
scale: tabDelegate.isFocused ? 1.02 : (tabDelegate.isActive ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Kirigami.ShadowedRectangle {
|
||||||
radius: Kirigami.Units.smallSpacing
|
radius: Kirigami.Units.smallSpacing
|
||||||
color: tabDelegate.isActive ? Kirigami.Theme.highlightColor
|
color: tabDelegate.isActive ? Kirigami.Theme.highlightColor
|
||||||
: (tabDelegate.hovered ? Kirigami.Theme.alternateBackgroundColor : "transparent")
|
: Kirigami.Theme.alternateBackgroundColor
|
||||||
opacity: tabDelegate.isActive ? 0.22 : (tabDelegate.hovered ? 0.12 : 0.0)
|
opacity: tabDelegate.isActive ? 0.20 : (tabDelegate.isFocused ? 0.10 : 0.0)
|
||||||
|
|
||||||
|
border.width: tabDelegate.isFocused ? 2 : 0
|
||||||
|
border.color: Kirigami.Theme.highlightColor
|
||||||
|
|
||||||
|
shadow.size: tabDelegate.isFocused ? Kirigami.Units.mediumSpacing : 0
|
||||||
|
shadow.color: Qt.rgba(0, 0, 0, 0.28)
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
@ -153,7 +175,17 @@ Item {
|
||||||
visible: tabDelegate.isActive
|
visible: tabDelegate.isActive
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on shadow.size {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPadding: Kirigami.Units.mediumSpacing
|
leftPadding: Kirigami.Units.mediumSpacing
|
||||||
|
|
@ -184,6 +216,8 @@ Item {
|
||||||
root.currentSource = model.sourceId
|
root.currentSource = model.sourceId
|
||||||
root.sourceSelected(model.sourceId)
|
root.sourceSelected(model.sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onDownPressed: root.focusDownRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -191,23 +225,89 @@ Item {
|
||||||
Kirigami.Separator { Layout.fillHeight: true }
|
Kirigami.Separator { Layout.fillHeight: true }
|
||||||
|
|
||||||
QQC2.ToolButton {
|
QQC2.ToolButton {
|
||||||
|
id: importBtn
|
||||||
icon.name: "document-import"
|
icon.name: "document-import"
|
||||||
onClicked: root.importRequested()
|
onClicked: root.importRequested()
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
flat: true
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.02 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Kirigami.Icon {
|
||||||
|
source: "document-import"
|
||||||
|
isMask: true
|
||||||
|
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Kirigami.ShadowedRectangle {
|
||||||
|
radius: Kirigami.Units.smallSpacing
|
||||||
|
color: Kirigami.Theme.alternateBackgroundColor
|
||||||
|
opacity: parent.activeFocus ? 0.18 : (parent.hovered ? 0.10 : 0.0)
|
||||||
|
border.width: parent.activeFocus ? 2 : 0
|
||||||
|
border.color: Kirigami.Theme.highlightColor
|
||||||
|
shadow.size: parent.activeFocus ? Kirigami.Units.mediumSpacing : 0
|
||||||
|
shadow.color: Qt.rgba(0, 0, 0, 0.28)
|
||||||
|
|
||||||
|
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
Behavior on shadow.size { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
Behavior on border.width { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
}
|
||||||
|
|
||||||
QQC2.ToolTip.text: i18n("Import Games")
|
QQC2.ToolTip.text: i18n("Import Games")
|
||||||
QQC2.ToolTip.visible: hovered
|
QQC2.ToolTip.visible: hovered
|
||||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
|
|
||||||
|
Keys.onDownPressed: root.focusDownRequested()
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.ToolButton {
|
QQC2.ToolButton {
|
||||||
|
id: settingsBtn
|
||||||
icon.name: "configure"
|
icon.name: "configure"
|
||||||
onClicked: root.settingsRequested()
|
onClicked: root.settingsRequested()
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
flat: true
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.02 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Kirigami.Icon {
|
||||||
|
source: "configure"
|
||||||
|
isMask: true
|
||||||
|
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Kirigami.ShadowedRectangle {
|
||||||
|
radius: Kirigami.Units.smallSpacing
|
||||||
|
color: Kirigami.Theme.alternateBackgroundColor
|
||||||
|
opacity: parent.activeFocus ? 0.18 : (parent.hovered ? 0.10 : 0.0)
|
||||||
|
border.width: parent.activeFocus ? 2 : 0
|
||||||
|
border.color: Kirigami.Theme.highlightColor
|
||||||
|
shadow.size: parent.activeFocus ? Kirigami.Units.mediumSpacing : 0
|
||||||
|
shadow.color: Qt.rgba(0, 0, 0, 0.28)
|
||||||
|
|
||||||
|
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
Behavior on shadow.size { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
Behavior on border.width { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
}
|
||||||
|
|
||||||
QQC2.ToolTip.text: i18n("Settings")
|
QQC2.ToolTip.text: i18n("Settings")
|
||||||
QQC2.ToolTip.visible: hovered
|
QQC2.ToolTip.visible: hovered
|
||||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
|
|
||||||
|
Keys.onDownPressed: root.focusDownRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,12 @@ Item {
|
||||||
focus: true
|
focus: true
|
||||||
KeyNavigation.right: favoriteBtn
|
KeyNavigation.right: favoriteBtn
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.03 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
|
|
@ -223,7 +229,7 @@ Item {
|
||||||
: (playBtn.hovered ? Qt.rgba(1,1,1,0.22) : Qt.rgba(1,1,1,0.14))
|
: (playBtn.hovered ? Qt.rgba(1,1,1,0.22) : Qt.rgba(1,1,1,0.14))
|
||||||
border.color: playBtn.activeFocus ? Kirigami.Theme.highlightColor : Qt.rgba(1,1,1,0.28)
|
border.color: playBtn.activeFocus ? Kirigami.Theme.highlightColor : Qt.rgba(1,1,1,0.28)
|
||||||
border.width: playBtn.activeFocus ? 0 : 1
|
border.width: playBtn.activeFocus ? 0 : 1
|
||||||
Behavior on color { ColorAnimation { duration: 100 } }
|
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 160
|
implicitWidth: 160
|
||||||
|
|
@ -240,6 +246,12 @@ Item {
|
||||||
KeyNavigation.left: playBtn
|
KeyNavigation.left: playBtn
|
||||||
KeyNavigation.right: editBtn
|
KeyNavigation.right: editBtn
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.03 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Kirigami.Icon {
|
contentItem: Kirigami.Icon {
|
||||||
source: detailRoot.game && detailRoot.game.favorite ? "starred-symbolic" : "non-starred-symbolic"
|
source: detailRoot.game && detailRoot.game.favorite ? "starred-symbolic" : "non-starred-symbolic"
|
||||||
width: 22; height: 22
|
width: 22; height: 22
|
||||||
|
|
@ -253,7 +265,7 @@ Item {
|
||||||
: (favoriteBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
: (favoriteBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
||||||
border.color: favoriteBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
border.color: favoriteBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
Behavior on color { ColorAnimation { duration: 100 } }
|
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 52
|
implicitWidth: 52
|
||||||
|
|
@ -272,6 +284,12 @@ Item {
|
||||||
KeyNavigation.left: favoriteBtn
|
KeyNavigation.left: favoriteBtn
|
||||||
KeyNavigation.right: closeBtn
|
KeyNavigation.right: closeBtn
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.03 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Kirigami.Icon {
|
contentItem: Kirigami.Icon {
|
||||||
source: "document-edit"
|
source: "document-edit"
|
||||||
width: 20; height: 20
|
width: 20; height: 20
|
||||||
|
|
@ -285,7 +303,7 @@ Item {
|
||||||
: (editBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
: (editBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
||||||
border.color: editBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
border.color: editBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
Behavior on color { ColorAnimation { duration: 100 } }
|
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 52
|
implicitWidth: 52
|
||||||
|
|
@ -302,6 +320,12 @@ Item {
|
||||||
icon.name: "window-close"
|
icon.name: "window-close"
|
||||||
KeyNavigation.left: editBtn
|
KeyNavigation.left: editBtn
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.03 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Kirigami.Icon {
|
contentItem: Kirigami.Icon {
|
||||||
source: "window-close"
|
source: "window-close"
|
||||||
width: 20; height: 20
|
width: 20; height: 20
|
||||||
|
|
@ -315,7 +339,7 @@ Item {
|
||||||
: (closeBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
: (closeBtn.hovered ? Qt.rgba(1,1,1,0.18) : Qt.rgba(1,1,1,0.10))
|
||||||
border.color: closeBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
border.color: closeBtn.activeFocus ? "white" : Qt.rgba(1,1,1,0.25)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
Behavior on color { ColorAnimation { duration: 100 } }
|
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 52
|
implicitWidth: 52
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Effects
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
|
|
||||||
|
|
@ -12,10 +11,13 @@ Item {
|
||||||
id: gameCard
|
id: gameCard
|
||||||
|
|
||||||
property var game
|
property var game
|
||||||
|
property bool gridActive: false
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal playClicked()
|
signal playClicked()
|
||||||
|
|
||||||
readonly property bool isCurrent: GridView.isCurrentItem
|
readonly property bool isCurrent: GridView.isCurrentItem
|
||||||
|
readonly property bool isGridFocused: gridActive
|
||||||
|
readonly property bool isHighlighted: isCurrent && isGridFocused
|
||||||
|
|
||||||
readonly property bool useAnimatedCover: App.config.animatedCovers
|
readonly property bool useAnimatedCover: App.config.animatedCovers
|
||||||
&& game && game.coverUrl
|
&& game && game.coverUrl
|
||||||
|
|
@ -32,21 +34,9 @@ Item {
|
||||||
width: parent.width - 16
|
width: parent.width - 16
|
||||||
height: parent.height - 16
|
height: parent.height - 16
|
||||||
|
|
||||||
scale: gameCard.isCurrent ? 1.08 : (hoverHandler.hovered ? 1.03 : 1.0)
|
scale: gameCard.isHighlighted ? 1.08 : ((gameCard.isCurrent || hoverHandler.hovered) ? 1.03 : 1.0)
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation { duration: 140; easing.type: Easing.OutCubic }
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
}
|
|
||||||
|
|
||||||
layer.enabled: gameCard.isCurrent
|
|
||||||
layer.effect: MultiEffect {
|
|
||||||
shadowEnabled: true
|
|
||||||
shadowColor: Qt.rgba(
|
|
||||||
Kirigami.Theme.highlightColor.r,
|
|
||||||
Kirigami.Theme.highlightColor.g,
|
|
||||||
Kirigami.Theme.highlightColor.b, 0.55)
|
|
||||||
shadowBlur: 0.8
|
|
||||||
shadowHorizontalOffset: 0
|
|
||||||
shadowVerticalOffset: 6
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -73,7 +63,7 @@ Item {
|
||||||
source: game ? game.coverUrl : ""
|
source: game ? game.coverUrl : ""
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
playing: gameCard.isCurrent
|
playing: gameCard.isHighlighted
|
||||||
visible: gameCard.useAnimatedCover
|
visible: gameCard.useAnimatedCover
|
||||||
smooth: true
|
smooth: true
|
||||||
}
|
}
|
||||||
|
|
@ -150,10 +140,10 @@ Item {
|
||||||
radius: 8
|
radius: 8
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: Kirigami.Theme.highlightColor
|
border.color: Kirigami.Theme.highlightColor
|
||||||
border.width: gameCard.isCurrent ? 3 : 0
|
border.width: gameCard.isHighlighted ? 3 : (gameCard.isCurrent ? 2 : 0)
|
||||||
opacity: gameCard.isCurrent ? 1.0 : 0.0
|
opacity: gameCard.isHighlighted ? 1.0 : (gameCard.isCurrent ? 0.55 : 0.0)
|
||||||
Behavior on opacity { NumberAnimation { duration: 120 } }
|
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
Behavior on border.width { NumberAnimation { duration: 120 } }
|
Behavior on border.width { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
}
|
}
|
||||||
|
|
||||||
HoverHandler { id: hoverHandler }
|
HoverHandler { id: hoverHandler }
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,17 @@ FocusScope {
|
||||||
signal gameSelected(var game)
|
signal gameSelected(var game)
|
||||||
signal gameFocused(var game)
|
signal gameFocused(var game)
|
||||||
signal gameLaunched(var game)
|
signal gameLaunched(var game)
|
||||||
|
signal headerFocusRequested()
|
||||||
|
|
||||||
readonly property int gameCount: proxyModel.count
|
readonly property int gameCount: proxyModel.count
|
||||||
|
|
||||||
function restoreFocus() {
|
function restoreFocus() {
|
||||||
|
if (grid.flickable) {
|
||||||
|
grid.flickable.forceActiveFocus()
|
||||||
|
} else {
|
||||||
grid.forceActiveFocus()
|
grid.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function focusedGame() {
|
function focusedGame() {
|
||||||
if (grid.currentIndex < 0) return null
|
if (grid.currentIndex < 0) return null
|
||||||
|
|
@ -85,6 +90,7 @@ FocusScope {
|
||||||
|
|
||||||
delegate: GameCard {
|
delegate: GameCard {
|
||||||
game: model.gameObject
|
game: model.gameObject
|
||||||
|
gridActive: grid.flickable ? grid.flickable.activeFocus : grid.activeFocus
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
grid.currentIndex = index
|
grid.currentIndex = index
|
||||||
|
|
@ -109,26 +115,29 @@ FocusScope {
|
||||||
Connections {
|
Connections {
|
||||||
target: GamepadManager
|
target: GamepadManager
|
||||||
function onSelectPressed() {
|
function onSelectPressed() {
|
||||||
if (!grid.activeFocus) return
|
if (!grid.flickable || !grid.flickable.activeFocus) return
|
||||||
libraryRoot.selectFocused()
|
libraryRoot.selectFocused()
|
||||||
}
|
}
|
||||||
function onNavigateUp() {
|
function onNavigateUp() {
|
||||||
if (!grid.activeFocus) return
|
if (!grid.flickable || !grid.flickable.activeFocus) return
|
||||||
if (grid.currentIndex <= 0) return
|
|
||||||
let cols = Math.max(1, Math.floor(grid.width / grid.cellWidth))
|
let cols = Math.max(1, Math.floor(grid.width / grid.cellWidth))
|
||||||
|
if (grid.currentIndex < cols) {
|
||||||
|
libraryRoot.headerFocusRequested()
|
||||||
|
return
|
||||||
|
}
|
||||||
grid.currentIndex = Math.max(0, grid.currentIndex - cols)
|
grid.currentIndex = Math.max(0, grid.currentIndex - cols)
|
||||||
}
|
}
|
||||||
function onNavigateDown() {
|
function onNavigateDown() {
|
||||||
if (!grid.activeFocus) return
|
if (!grid.flickable || !grid.flickable.activeFocus) return
|
||||||
let cols = Math.max(1, Math.floor(grid.width / grid.cellWidth))
|
let cols = Math.max(1, Math.floor(grid.width / grid.cellWidth))
|
||||||
grid.currentIndex = Math.min(proxyModel.count - 1, grid.currentIndex + cols)
|
grid.currentIndex = Math.min(proxyModel.count - 1, grid.currentIndex + cols)
|
||||||
}
|
}
|
||||||
function onNavigateLeft() {
|
function onNavigateLeft() {
|
||||||
if (!grid.activeFocus) return
|
if (!grid.flickable || !grid.flickable.activeFocus) return
|
||||||
grid.currentIndex = Math.max(0, grid.currentIndex - 1)
|
grid.currentIndex = Math.max(0, grid.currentIndex - 1)
|
||||||
}
|
}
|
||||||
function onNavigateRight() {
|
function onNavigateRight() {
|
||||||
if (!grid.activeFocus) return
|
if (!grid.flickable || !grid.flickable.activeFocus) return
|
||||||
grid.currentIndex = Math.min(proxyModel.count - 1, grid.currentIndex + 1)
|
grid.currentIndex = Math.min(proxyModel.count - 1, grid.currentIndex + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import org.mauikit.controls as Maui
|
import org.mauikit.controls as Maui
|
||||||
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
import "components"
|
import "components"
|
||||||
|
|
||||||
|
|
@ -120,16 +121,48 @@ Maui.ApplicationWindow {
|
||||||
onSourceSelected: function(src) { root.currentCategory = src }
|
onSourceSelected: function(src) { root.currentCategory = src }
|
||||||
onSettingsRequested: root.settingsVisible = true
|
onSettingsRequested: root.settingsVisible = true
|
||||||
onImportRequested: App.importAllGames()
|
onImportRequested: App.importAllGames()
|
||||||
|
onFocusDownRequested: libraryView.restoreFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.ToolButton {
|
QQC2.ToolButton {
|
||||||
|
id: searchButton
|
||||||
icon.name: "edit-find"
|
icon.name: "edit-find"
|
||||||
flat: true
|
flat: true
|
||||||
Layout.preferredWidth: 40
|
Layout.preferredWidth: 40
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
|
hoverEnabled: true
|
||||||
|
scale: activeFocus ? 1.02 : (hovered ? 1.01 : 1.0)
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
onClicked: root.searchVisible = !root.searchVisible
|
onClicked: root.searchVisible = !root.searchVisible
|
||||||
QQC2.ToolTip.text: i18n("Search")
|
QQC2.ToolTip.text: i18n("Search")
|
||||||
QQC2.ToolTip.visible: hovered
|
QQC2.ToolTip.visible: hovered
|
||||||
|
|
||||||
|
contentItem: Kirigami.Icon {
|
||||||
|
source: "edit-find"
|
||||||
|
isMask: true
|
||||||
|
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onDownPressed: libraryView.restoreFocus()
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: 8
|
||||||
|
color: parent.activeFocus
|
||||||
|
? Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.18)
|
||||||
|
: (parent.hovered ? Qt.rgba(1, 1, 1, 0.10) : Qt.rgba(1, 1, 1, 0.0))
|
||||||
|
border.width: parent.activeFocus ? 2 : 0
|
||||||
|
border.color: Kirigami.Theme.highlightColor
|
||||||
|
|
||||||
|
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
Behavior on border.width { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +192,8 @@ Maui.ApplicationWindow {
|
||||||
filterSource: root.currentCategory
|
filterSource: root.currentCategory
|
||||||
filterText: root.searchText
|
filterText: root.searchText
|
||||||
|
|
||||||
|
onHeaderFocusRequested: categoryRail.focusCurrent()
|
||||||
|
|
||||||
onGameFocused: function(game) { root.focusedGame = game }
|
onGameFocused: function(game) { root.focusedGame = game }
|
||||||
onGameSelected: function(game) {
|
onGameSelected: function(game) {
|
||||||
root.selectedGame = game
|
root.selectedGame = game
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue