mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-03-27 01:03:09 +00:00
Fix console UI regressions: icons, hint bar, category rail, dialog
- ConsoleCategoryRail: port from CouchSidebar using Kirigami.Icon + IconWithResourceFallback, radius: smallSpacing (not pill), Hidden source, Import+Settings buttons with tooltips, App.gameModel.gameAt() - Main.qml: use BottomHintBar component, wire sourceSelected/ settingsRequested/importRequested signals, flat ToolButton for search, declare GameEditDialog as proper child, remove Maui.ContextualMenu - GameCard: Maui.Icon -> Kirigami.Icon, Maui.Theme -> Kirigami.Theme - ConsoleGameDetail: Maui.Icon -> Kirigami.Icon, Maui.Theme -> Kirigami.Theme, replace broken inline hint rows with BottomHintBar
This commit is contained in:
parent
84c6795fd6
commit
cb69f801bf
4 changed files with 204 additions and 264 deletions
|
|
@ -4,73 +4,96 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import org.mauikit.controls as Maui
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
|
import "components"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string currentCategory: "all"
|
property string currentSource: "all"
|
||||||
|
|
||||||
signal categorySelected(string categoryId)
|
signal sourceSelected(string source)
|
||||||
|
signal settingsRequested()
|
||||||
|
signal importRequested()
|
||||||
|
|
||||||
function selectNext() {
|
function selectNext() {
|
||||||
if (rail.currentIndex < categoryModel.count - 1) {
|
if (sourceModel.count <= 0) return
|
||||||
rail.currentIndex++
|
let i = (tabList.currentIndex + 1) % sourceModel.count
|
||||||
categorySelected(categoryModel.get(rail.currentIndex).categoryId)
|
_applyIndex(i)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPrevious() {
|
function selectPrevious() {
|
||||||
if (rail.currentIndex > 0) {
|
if (sourceModel.count <= 0) return
|
||||||
rail.currentIndex--
|
let i = tabList.currentIndex - 1
|
||||||
categorySelected(categoryModel.get(rail.currentIndex).categoryId)
|
if (i < 0) i = sourceModel.count - 1
|
||||||
|
_applyIndex(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
function _applyIndex(i) {
|
||||||
|
tabList.currentIndex = i
|
||||||
|
let item = sourceModel.get(i)
|
||||||
|
if (item) {
|
||||||
|
root.currentSource = item.sourceId
|
||||||
|
root.sourceSelected(item.sourceId)
|
||||||
|
tabList.positionViewAtIndex(i, ListView.Contain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _platformIcon(name) {
|
function iconInfoForPlatform(platformName) {
|
||||||
let p = (name || "").toLowerCase()
|
let p = (platformName || "").toLowerCase()
|
||||||
if (p.includes("steam")) return ":/icons/brand/steam-symbolic.svg"
|
if (p.includes("steam")) return { source: "com.valvesoftware.Steam", fallback: "steam", resourceFallback: Qt.resolvedUrl("icons/brand/steam-symbolic.svg") }
|
||||||
if (p.includes("itch")) return ":/icons/brand/itchdotio-symbolic.svg"
|
if (p.includes("itch")) return { source: "io.itch.itch", fallback: "applications-games", resourceFallback: Qt.resolvedUrl("icons/brand/itchdotio-symbolic.svg") }
|
||||||
if (p.includes("retroarch")) return ":/icons/brand/retroarch-symbolic.svg"
|
if (p.includes("retroarch")) return { source: "org.libretro.RetroArch", fallback: "applications-games", resourceFallback: Qt.resolvedUrl("icons/brand/retroarch-symbolic.svg") }
|
||||||
if (p.includes("lutris")) return "applications-games"
|
if (p.includes("lutris")) return { source: "lutris", fallback: "applications-games", resourceFallback: "" }
|
||||||
if (p.includes("heroic")) return "applications-games"
|
if (p.includes("heroic")) return { source: "com.heroicgameslauncher.hgl", fallback: "applications-games", resourceFallback: "" }
|
||||||
if (p.includes("bottles")) return "application-x-executable"
|
if (p.includes("bottles")) return { source: "com.usebottles.bottles", fallback: "application-x-executable", resourceFallback: "" }
|
||||||
if (p.includes("flatpak")) return "applications-games"
|
if (p.includes("flatpak")) return { source: "flatpak-discover", fallback: "applications-games", resourceFallback: "" }
|
||||||
if (p.includes("desktop")) return "computer"
|
if (p.includes("desktop")) return { source: "user-desktop", fallback: "computer", resourceFallback: "" }
|
||||||
return "applications-games"
|
if (p.includes("legendary")) return { source: "legendary", fallback: "applications-games", resourceFallback: "" }
|
||||||
|
return { source: "applications-games", fallback: "applications-games", resourceFallback: "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
GameSortFilterModel {
|
onCurrentSourceChanged: {
|
||||||
id: allGames
|
for (let i = 0; i < sourceModel.count; ++i) {
|
||||||
sourceModel: App.gameModel
|
if (sourceModel.get(i).sourceId === currentSource) {
|
||||||
showHidden: false
|
tabList.currentIndex = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: categoryModel
|
id: sourceModel
|
||||||
|
Component.onCompleted: refresh()
|
||||||
|
|
||||||
Component.onCompleted: rebuild()
|
function refresh() {
|
||||||
|
|
||||||
function rebuild() {
|
|
||||||
clear()
|
clear()
|
||||||
append({ label: i18n("All"), categoryId: "all", iconSource: "view-list-icons" })
|
let allCount = 0, favCount = 0, hiddenCount = 0
|
||||||
append({ label: i18n("Favorites"), categoryId: "favorites", iconSource: "starred-symbolic" })
|
let sources = {}
|
||||||
|
|
||||||
let seen = {}
|
for (let i = 0; i < App.gameModel.rowCount(); i++) {
|
||||||
for (let i = 0; i < allGames.count; ++i) {
|
let game = App.gameModel.gameAt(i)
|
||||||
let g = allGames.get(i)
|
if (!game) continue
|
||||||
if (!g) continue
|
if (game.hidden) { hiddenCount++; continue }
|
||||||
let p = g.platform || ""
|
allCount++
|
||||||
if (p && !seen[p]) {
|
if (game.favorite) favCount++
|
||||||
seen[p] = true
|
let p = game.platform
|
||||||
append({ label: p, categoryId: p, iconSource: root._platformIcon(p) })
|
sources[p] = (sources[p] || 0) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
append({ name: i18n("All"), sourceId: "all", icon: "view-list-icons", fallback: "applications-games", resourceFallback: "", count: allCount })
|
||||||
|
append({ name: i18n("Favorites"), sourceId: "favorites", icon: "bookmark-new", fallback: "bookmark-new", resourceFallback: "", count: favCount })
|
||||||
|
append({ name: i18n("Hidden"), sourceId: "hidden", icon: "view-hidden", fallback: "view-hidden", resourceFallback: "", count: hiddenCount })
|
||||||
|
|
||||||
|
for (let platform in sources) {
|
||||||
|
let info = root.iconInfoForPlatform(platform)
|
||||||
|
append({ name: platform, sourceId: platform, icon: info.source, fallback: info.fallback, resourceFallback: info.resourceFallback, count: sources[platform] })
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let j = 0; j < count; ++j) {
|
for (let j = 0; j < count; ++j) {
|
||||||
if (get(j).categoryId === root.currentCategory) {
|
if (get(j).sourceId === root.currentSource) {
|
||||||
rail.currentIndex = j
|
tabList.currentIndex = j
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,83 +102,112 @@ Item {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: App.gameModel
|
target: App.gameModel
|
||||||
function onCountChanged() { categoryModel.rebuild() }
|
function onCountChanged() { sourceModel.refresh() }
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: App
|
||||||
|
function onImportCompleted() { sourceModel.refresh() }
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentCategoryChanged: {
|
RowLayout {
|
||||||
for (let j = 0; j < categoryModel.count; ++j) {
|
anchors.fill: parent
|
||||||
if (categoryModel.get(j).categoryId === currentCategory) {
|
spacing: 0
|
||||||
rail.currentIndex = j
|
|
||||||
return
|
QQC2.ScrollView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||||
|
QQC2.ScrollBar.vertical.policy: QQC2.ScrollBar.AlwaysOff
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: tabList
|
||||||
|
model: sourceModel
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
leftMargin: Kirigami.Units.largeSpacing
|
||||||
|
rightMargin: Kirigami.Units.largeSpacing
|
||||||
|
topMargin: Kirigami.Units.smallSpacing
|
||||||
|
bottomMargin: Kirigami.Units.smallSpacing
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: QQC2.ItemDelegate {
|
||||||
|
id: tabDelegate
|
||||||
|
width: implicitWidth
|
||||||
|
height: tabList.height - tabList.topMargin - tabList.bottomMargin
|
||||||
|
|
||||||
|
readonly property bool isActive: model.sourceId === root.currentSource
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: Kirigami.Units.smallSpacing
|
||||||
|
color: tabDelegate.isActive ? Kirigami.Theme.highlightColor
|
||||||
|
: (tabDelegate.hovered ? Kirigami.Theme.alternateBackgroundColor : "transparent")
|
||||||
|
opacity: tabDelegate.isActive ? 0.22 : (tabDelegate.hovered ? 0.12 : 0.0)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: 2
|
||||||
|
radius: 1
|
||||||
|
color: Kirigami.Theme.highlightColor
|
||||||
|
visible: tabDelegate.isActive
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
|
||||||
|
}
|
||||||
|
|
||||||
|
leftPadding: Kirigami.Units.mediumSpacing
|
||||||
|
rightPadding: Kirigami.Units.mediumSpacing
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
IconWithResourceFallback {
|
||||||
|
primary: model.icon
|
||||||
|
secondary: model.fallback
|
||||||
|
resourceFallback: model.resourceFallback ? Qt.resolvedUrl(model.resourceFallback) : ""
|
||||||
|
Layout.preferredWidth: Kirigami.Units.iconSizes.small
|
||||||
|
Layout.preferredHeight: Kirigami.Units.iconSizes.small
|
||||||
|
color: tabDelegate.isActive ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Label {
|
||||||
|
text: model.name
|
||||||
|
color: tabDelegate.isActive ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
|
||||||
|
font.bold: tabDelegate.isActive
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.currentSource = model.sourceId
|
||||||
|
root.sourceSelected(model.sourceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Kirigami.Separator { Layout.fillHeight: true }
|
||||||
anchors.fill: parent
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.55)
|
|
||||||
|
|
||||||
ListView {
|
QQC2.ToolButton {
|
||||||
id: rail
|
icon.name: "document-import"
|
||||||
anchors {
|
onClicked: root.importRequested()
|
||||||
fill: parent
|
Layout.fillHeight: true
|
||||||
leftMargin: 24
|
flat: true
|
||||||
rightMargin: 24
|
QQC2.ToolTip.text: i18n("Import Games")
|
||||||
}
|
QQC2.ToolTip.visible: hovered
|
||||||
orientation: ListView.Horizontal
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
spacing: 8
|
}
|
||||||
clip: true
|
|
||||||
model: categoryModel
|
|
||||||
keyNavigationEnabled: true
|
|
||||||
highlightMoveDuration: 200
|
|
||||||
|
|
||||||
delegate: QQC2.ItemDelegate {
|
QQC2.ToolButton {
|
||||||
id: pill
|
icon.name: "configure"
|
||||||
width: implicitContentWidth + 32
|
onClicked: root.settingsRequested()
|
||||||
height: rail.height
|
Layout.fillHeight: true
|
||||||
topPadding: 0
|
flat: true
|
||||||
bottomPadding: 0
|
QQC2.ToolTip.text: i18n("Settings")
|
||||||
leftPadding: 16
|
QQC2.ToolTip.visible: hovered
|
||||||
rightPadding: 16
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
|
|
||||||
readonly property bool isCurrent: ListView.isCurrentItem
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
radius: height / 2
|
|
||||||
color: pill.isCurrent
|
|
||||||
? Maui.Theme.highlightColor
|
|
||||||
: (pill.hovered ? Qt.rgba(1, 1, 1, 0.12) : Qt.rgba(1, 1, 1, 0.06))
|
|
||||||
border.color: pill.isCurrent ? Maui.Theme.highlightColor : Qt.rgba(1, 1, 1, 0.18)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Behavior on color { ColorAnimation { duration: 120 } }
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
spacing: 6
|
|
||||||
|
|
||||||
Maui.Icon {
|
|
||||||
source: model.iconSource
|
|
||||||
Layout.preferredWidth: 16
|
|
||||||
Layout.preferredHeight: 16
|
|
||||||
color: "white"
|
|
||||||
opacity: pill.isCurrent ? 1.0 : 0.75
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: model.label
|
|
||||||
color: "white"
|
|
||||||
opacity: pill.isCurrent ? 1.0 : 0.75
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.weight: pill.isCurrent ? Font.DemiBold : Font.Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
rail.currentIndex = index
|
|
||||||
root.categorySelected(model.categoryId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
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.kde.kirigami as Kirigami
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
|
import "components"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: detailRoot
|
id: detailRoot
|
||||||
|
|
@ -202,7 +203,7 @@ Item {
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
Maui.Icon {
|
Kirigami.Icon {
|
||||||
source: "media-playback-start"
|
source: "media-playback-start"
|
||||||
width: 22; height: 22
|
width: 22; height: 22
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
@ -218,9 +219,9 @@ Item {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: 8
|
radius: 8
|
||||||
color: playBtn.activeFocus
|
color: playBtn.activeFocus
|
||||||
? Maui.Theme.highlightColor
|
? Kirigami.Theme.highlightColor
|
||||||
: (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 ? Maui.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: 100 } }
|
||||||
}
|
}
|
||||||
|
|
@ -239,7 +240,7 @@ Item {
|
||||||
KeyNavigation.left: playBtn
|
KeyNavigation.left: playBtn
|
||||||
KeyNavigation.right: editBtn
|
KeyNavigation.right: editBtn
|
||||||
|
|
||||||
contentItem: Maui.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
|
||||||
color: detailRoot.game && detailRoot.game.favorite ? "#f5c518" : "white"
|
color: detailRoot.game && detailRoot.game.favorite ? "#f5c518" : "white"
|
||||||
|
|
@ -271,7 +272,7 @@ Item {
|
||||||
KeyNavigation.left: favoriteBtn
|
KeyNavigation.left: favoriteBtn
|
||||||
KeyNavigation.right: closeBtn
|
KeyNavigation.right: closeBtn
|
||||||
|
|
||||||
contentItem: Maui.Icon {
|
contentItem: Kirigami.Icon {
|
||||||
source: "document-edit"
|
source: "document-edit"
|
||||||
width: 20; height: 20
|
width: 20; height: 20
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
@ -301,7 +302,7 @@ Item {
|
||||||
icon.name: "window-close"
|
icon.name: "window-close"
|
||||||
KeyNavigation.left: editBtn
|
KeyNavigation.left: editBtn
|
||||||
|
|
||||||
contentItem: Maui.Icon {
|
contentItem: Kirigami.Icon {
|
||||||
source: "window-close"
|
source: "window-close"
|
||||||
width: 20; height: 20
|
width: 20; height: 20
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
@ -327,36 +328,11 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { Layout.preferredHeight: 32 }
|
Item { Layout.preferredHeight: 16 }
|
||||||
|
|
||||||
RowLayout {
|
BottomHintBar {
|
||||||
spacing: 28
|
uiMode: Config.Couch
|
||||||
|
context: "details"
|
||||||
Repeater {
|
|
||||||
model: [
|
|
||||||
{ icon: ":/icons/gamepad/generic/south.svg", label: i18n("Play") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/east.svg", label: i18n("Back") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/north.svg", label: i18n("Edit") }
|
|
||||||
]
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
spacing: 6
|
|
||||||
visible: GamepadManager.connected
|
|
||||||
|
|
||||||
Image {
|
|
||||||
source: modelData.icon
|
|
||||||
width: 22; height: 22
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
smooth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: modelData.label
|
|
||||||
color: Qt.rgba(1, 1, 1, 0.65)
|
|
||||||
font.pixelSize: 13
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { Layout.fillHeight: true; Layout.preferredHeight: 1 }
|
Item { Layout.fillHeight: true; Layout.preferredHeight: 1 }
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
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.kde.kirigami as Kirigami
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -41,9 +41,9 @@ Item {
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: true
|
||||||
shadowColor: Qt.rgba(
|
shadowColor: Qt.rgba(
|
||||||
Maui.Theme.highlightColor.r,
|
Kirigami.Theme.highlightColor.r,
|
||||||
Maui.Theme.highlightColor.g,
|
Kirigami.Theme.highlightColor.g,
|
||||||
Maui.Theme.highlightColor.b, 0.55)
|
Kirigami.Theme.highlightColor.b, 0.55)
|
||||||
shadowBlur: 0.8
|
shadowBlur: 0.8
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 6
|
shadowVerticalOffset: 6
|
||||||
|
|
@ -78,7 +78,7 @@ Item {
|
||||||
smooth: true
|
smooth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Maui.Icon {
|
Kirigami.Icon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: "applications-games"
|
source: "applications-games"
|
||||||
width: parent.width * 0.38
|
width: parent.width * 0.38
|
||||||
|
|
@ -133,7 +133,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Maui.Icon {
|
Kirigami.Icon {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: 8
|
anchors.margins: 8
|
||||||
|
|
@ -149,7 +149,7 @@ Item {
|
||||||
anchors.fill: coverFrame
|
anchors.fill: coverFrame
|
||||||
radius: 8
|
radius: 8
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: Maui.Theme.highlightColor
|
border.color: Kirigami.Theme.highlightColor
|
||||||
border.width: gameCard.isCurrent ? 3 : 0
|
border.width: gameCard.isCurrent ? 3 : 0
|
||||||
opacity: gameCard.isCurrent ? 1.0 : 0.0
|
opacity: gameCard.isCurrent ? 1.0 : 0.0
|
||||||
Behavior on opacity { NumberAnimation { duration: 120 } }
|
Behavior on opacity { NumberAnimation { duration: 120 } }
|
||||||
|
|
|
||||||
130
src/qml/Main.qml
130
src/qml/Main.qml
|
|
@ -7,6 +7,7 @@ import QtQuick.Layouts
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import org.mauikit.controls as Maui
|
import org.mauikit.controls as Maui
|
||||||
import org.kde.alakarte
|
import org.kde.alakarte
|
||||||
|
import "components"
|
||||||
|
|
||||||
Maui.ApplicationWindow {
|
Maui.ApplicationWindow {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -21,7 +22,6 @@ Maui.ApplicationWindow {
|
||||||
property bool detailVisible: false
|
property bool detailVisible: false
|
||||||
property bool searchVisible: false
|
property bool searchVisible: false
|
||||||
property bool settingsVisible: false
|
property bool settingsVisible: false
|
||||||
property bool importVisible: false
|
|
||||||
property string searchText: ""
|
property string searchText: ""
|
||||||
|
|
||||||
color: "#0d0d14"
|
color: "#0d0d14"
|
||||||
|
|
@ -99,8 +99,8 @@ Maui.ApplicationWindow {
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 12
|
||||||
anchors.rightMargin: 12
|
anchors.rightMargin: 0
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: "qrc:/icons/sc-apps-org.kde.alakarte.svg"
|
source: "qrc:/icons/sc-apps-org.kde.alakarte.svg"
|
||||||
|
|
@ -110,55 +110,26 @@ Maui.ApplicationWindow {
|
||||||
smooth: true
|
smooth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { Layout.preferredWidth: 8 }
|
Item { Layout.preferredWidth: 4 }
|
||||||
|
|
||||||
ConsoleCategoryRail {
|
ConsoleCategoryRail {
|
||||||
id: categoryRail
|
id: categoryRail
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
currentCategory: root.currentCategory
|
currentSource: root.currentCategory
|
||||||
onCategorySelected: function(cat) {
|
onSourceSelected: function(src) { root.currentCategory = src }
|
||||||
root.currentCategory = cat
|
onSettingsRequested: root.settingsVisible = true
|
||||||
}
|
onImportRequested: App.importAllGames()
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.ToolButton {
|
QQC2.ToolButton {
|
||||||
id: searchBtn
|
|
||||||
icon.name: "edit-find"
|
icon.name: "edit-find"
|
||||||
icon.color: "white"
|
flat: true
|
||||||
Layout.preferredWidth: 40
|
Layout.preferredWidth: 40
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
onClicked: root.searchVisible = !root.searchVisible
|
onClicked: root.searchVisible = !root.searchVisible
|
||||||
background: Rectangle {
|
QQC2.ToolTip.text: i18n("Search")
|
||||||
radius: 6
|
QQC2.ToolTip.visible: hovered
|
||||||
color: searchBtn.pressed ? Qt.rgba(1,1,1,0.18) : (searchBtn.hovered ? Qt.rgba(1,1,1,0.12) : "transparent")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.ToolButton {
|
|
||||||
id: settingsBtn
|
|
||||||
icon.name: "configure"
|
|
||||||
icon.color: "white"
|
|
||||||
Layout.preferredWidth: 40
|
|
||||||
Layout.preferredHeight: 40
|
|
||||||
onClicked: root.settingsVisible = true
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 6
|
|
||||||
color: settingsBtn.pressed ? Qt.rgba(1,1,1,0.18) : (settingsBtn.hovered ? Qt.rgba(1,1,1,0.12) : "transparent")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.ToolButton {
|
|
||||||
id: importBtn
|
|
||||||
icon.name: "document-import"
|
|
||||||
icon.color: "white"
|
|
||||||
Layout.preferredWidth: 40
|
|
||||||
Layout.preferredHeight: 40
|
|
||||||
onClicked: root.importVisible = true
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 6
|
|
||||||
color: importBtn.pressed ? Qt.rgba(1,1,1,0.18) : (importBtn.hovered ? Qt.rgba(1,1,1,0.12) : "transparent")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,14 +143,6 @@ Maui.ApplicationWindow {
|
||||||
Layout.topMargin: 4
|
Layout.topMargin: 4
|
||||||
visible: root.searchVisible
|
visible: root.searchVisible
|
||||||
placeholderText: i18n("Search games…")
|
placeholderText: i18n("Search games…")
|
||||||
color: "white"
|
|
||||||
font.pixelSize: 15
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 8
|
|
||||||
color: Qt.rgba(1, 1, 1, 0.10)
|
|
||||||
border.color: Qt.rgba(1, 1, 1, 0.22)
|
|
||||||
border.width: 1
|
|
||||||
}
|
|
||||||
onTextChanged: root.searchText = text
|
onTextChanged: root.searchText = text
|
||||||
Keys.onEscapePressed: {
|
Keys.onEscapePressed: {
|
||||||
root.searchVisible = false
|
root.searchVisible = false
|
||||||
|
|
@ -196,54 +159,24 @@ Maui.ApplicationWindow {
|
||||||
filterSource: root.currentCategory
|
filterSource: root.currentCategory
|
||||||
filterText: root.searchText
|
filterText: root.searchText
|
||||||
|
|
||||||
onGameFocused: function(game) {
|
onGameFocused: function(game) { root.focusedGame = game }
|
||||||
root.focusedGame = game
|
|
||||||
}
|
|
||||||
onGameSelected: function(game) {
|
onGameSelected: function(game) {
|
||||||
root.selectedGame = game
|
root.selectedGame = game
|
||||||
root.detailVisible = true
|
root.detailVisible = true
|
||||||
}
|
}
|
||||||
onGameLaunched: function(game) {
|
onGameLaunched: function(game) { App.launcher.launchGame(game) }
|
||||||
App.launcher.launchGame(game)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 38
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.55)
|
color: Qt.rgba(0, 0, 0, 0.55)
|
||||||
visible: GamepadManager.connected
|
implicitHeight: hintBar.implicitHeight + 12
|
||||||
|
|
||||||
RowLayout {
|
BottomHintBar {
|
||||||
|
id: hintBar
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: 32
|
uiMode: Config.Couch
|
||||||
|
context: root.detailVisible ? "details" : "library"
|
||||||
Repeater {
|
|
||||||
model: [
|
|
||||||
{ icon: ":/icons/gamepad/generic/south.svg", label: i18n("Select / Details") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/east.svg", label: i18n("Back") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/lb.svg", label: i18n("Prev Category") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/rb.svg", label: i18n("Next Category") },
|
|
||||||
{ icon: ":/icons/gamepad/generic/menu.svg", label: i18n("Settings") }
|
|
||||||
]
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
spacing: 5
|
|
||||||
|
|
||||||
Image {
|
|
||||||
source: modelData.icon
|
|
||||||
width: 18; height: 18
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
smooth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: modelData.label
|
|
||||||
color: Qt.rgba(1, 1, 1, 0.6)
|
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -299,20 +232,8 @@ Maui.ApplicationWindow {
|
||||||
onLoaded: item.forceActiveFocus()
|
onLoaded: item.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
GameEditDialog {
|
||||||
id: importLoader
|
|
||||||
anchors.fill: parent
|
|
||||||
z: 20
|
|
||||||
active: root.importVisible
|
|
||||||
sourceComponent: DiagnosticsSheet {
|
|
||||||
onClosed: root.importVisible = false
|
|
||||||
}
|
|
||||||
onLoaded: item.forceActiveFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
Maui.ContextualMenu {
|
|
||||||
id: gameEditDialog
|
id: gameEditDialog
|
||||||
property var game: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
@ -320,13 +241,11 @@ Maui.ApplicationWindow {
|
||||||
|
|
||||||
function onBackPressed() {
|
function onBackPressed() {
|
||||||
if (root.settingsVisible) { root.settingsVisible = false; return }
|
if (root.settingsVisible) { root.settingsVisible = false; return }
|
||||||
if (root.importVisible) { root.importVisible = false; return }
|
if (root.searchVisible) {
|
||||||
if (root.searchVisible) {
|
|
||||||
root.searchVisible = false
|
root.searchVisible = false
|
||||||
root.searchText = ""
|
root.searchText = ""
|
||||||
searchField.text = ""
|
searchField.text = ""
|
||||||
libraryView.restoreFocus()
|
libraryView.restoreFocus()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -336,9 +255,7 @@ Maui.ApplicationWindow {
|
||||||
|
|
||||||
function onSearchPressed() {
|
function onSearchPressed() {
|
||||||
root.searchVisible = !root.searchVisible
|
root.searchVisible = !root.searchVisible
|
||||||
if (root.searchVisible) {
|
if (root.searchVisible) Qt.callLater(function() { searchField.forceActiveFocus() })
|
||||||
Qt.callLater(function() { searchField.forceActiveFocus() })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLeftBumperPressed() {
|
function onLeftBumperPressed() {
|
||||||
|
|
@ -349,9 +266,4 @@ Maui.ApplicationWindow {
|
||||||
if (!root.detailVisible) categoryRail.selectNext()
|
if (!root.detailVisible) categoryRail.selectNext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: App
|
|
||||||
function onImportingChanged() {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue