mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-11 00:47:22 +00:00
Rework Game Center into console-style capsule rails
Restructure the overlay around landscape 16:9 media capsules, clearer focus borders, tighter search/filter rails, and stronger handheld vs big-screen spacing hierarchy.
This commit is contained in:
parent
434f46403c
commit
75a0f7a21e
1 changed files with 145 additions and 135 deletions
|
|
@ -41,6 +41,15 @@ Window {
|
|||
readonly property int shortAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsFast)
|
||||
readonly property int longAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsDefault)
|
||||
readonly property int launchFadeDuration: MobileShell.Motion.duration(MobileShell.Motion.StandardAccel)
|
||||
readonly property int shortestSide: Math.min(width, height)
|
||||
readonly property bool compactMode: !ShellSettings.Settings.convergenceModeEnabled && shortestSide <= Kirigami.Units.gridUnit * 50
|
||||
readonly property bool bigScreenMode: !compactMode
|
||||
readonly property int horizontalPadding: compactMode ? Kirigami.Units.largeSpacing : Kirigami.Units.largeSpacing * 2
|
||||
readonly property int verticalPadding: compactMode ? Kirigami.Units.largeSpacing : Kirigami.Units.largeSpacing * 2
|
||||
readonly property real gridMinCellSize: compactMode ? Kirigami.Units.gridUnit * 6.8 : Kirigami.Units.gridUnit * 8.8
|
||||
// Steam library assets heavily favor wide capsules and 16:9 media surfaces.
|
||||
// Keep game tiles landscape-first to avoid mobile-style portrait cards.
|
||||
readonly property real capsuleArtAspect: 16 / 9
|
||||
|
||||
function controlLegendText() {
|
||||
if (GamingShell.GamepadManager.hasGamepad) {
|
||||
|
|
@ -508,7 +517,7 @@ Window {
|
|||
anchors.fill: parent
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
color: MobileShell.SurfaceColors.withAlpha(MobileShell.SurfaceColors.accentSurface(Kirigami.Theme.backgroundColor, 0.24, 0.12), 0.92)
|
||||
color: MobileShell.SurfaceColors.withAlpha(MobileShell.SurfaceColors.accentSurface(Kirigami.Theme.backgroundColor, 0.24, 0.12), root.bigScreenMode ? 0.94 : 0.9)
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
|
|
@ -521,8 +530,11 @@ Window {
|
|||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.largeSpacing * 2
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
anchors.leftMargin: root.horizontalPadding
|
||||
anchors.rightMargin: root.horizontalPadding
|
||||
anchors.topMargin: root.verticalPadding
|
||||
anchors.bottomMargin: root.verticalPadding
|
||||
spacing: root.compactMode ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing
|
||||
|
||||
// ---- header ----
|
||||
RowLayout {
|
||||
|
|
@ -531,7 +543,7 @@ Window {
|
|||
|
||||
Kirigami.Heading {
|
||||
text: i18n("Game Center")
|
||||
level: 1
|
||||
level: root.compactMode ? 2 : 1
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
|
@ -586,7 +598,7 @@ Window {
|
|||
|
||||
QQC2.ToolButton {
|
||||
icon.name: "window-close"
|
||||
text: i18n("Exit Gaming Mode")
|
||||
text: root.compactMode ? i18n("Exit") : i18n("Exit Gaming Mode")
|
||||
display: QQC2.AbstractButton.TextBesideIcon
|
||||
Keys.onReturnPressed: clicked()
|
||||
Keys.onEnterPressed: clicked()
|
||||
|
|
@ -598,6 +610,7 @@ Window {
|
|||
RunningGamesView {
|
||||
id: runningGames
|
||||
Layout.fillWidth: true
|
||||
compactMode: root.compactMode
|
||||
onTaskActivated: {
|
||||
GamingShell.GameLauncherProvider.clearPendingLaunch()
|
||||
root.gameStarted()
|
||||
|
|
@ -652,7 +665,9 @@ Window {
|
|||
ListView {
|
||||
id: recentList
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 5
|
||||
readonly property int cardWidth: root.compactMode ? Kirigami.Units.gridUnit * 8 : Kirigami.Units.gridUnit * 10
|
||||
readonly property int artHeight: Math.round(cardWidth / root.capsuleArtAspect)
|
||||
Layout.preferredHeight: artHeight + Kirigami.Units.gridUnit * 1.7
|
||||
orientation: ListView.Horizontal
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
clip: true
|
||||
|
|
@ -690,7 +705,7 @@ Window {
|
|||
Keys.onDownPressed: grid.forceActiveFocus()
|
||||
|
||||
delegate: QQC2.ItemDelegate {
|
||||
width: Kirigami.Units.gridUnit * 7
|
||||
width: recentList.cardWidth
|
||||
height: recentList.height
|
||||
|
||||
required property var modelData
|
||||
|
|
@ -704,16 +719,26 @@ Window {
|
|||
background: Rectangle {
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
color: parent.isCurrent
|
||||
? Kirigami.Theme.highlightColor
|
||||
: (parent.hovered ? Kirigami.Theme.hoverColor : "transparent")
|
||||
? Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.22)
|
||||
: (parent.hovered
|
||||
? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.08)
|
||||
: "transparent")
|
||||
border.color: parent.isCurrent ? Kirigami.Theme.highlightColor : "transparent"
|
||||
border.width: parent.isCurrent ? 2 : 0
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Image {
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: recentList.artHeight
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
clip: true
|
||||
color: Qt.rgba(Kirigami.Theme.alternateBackgroundColor.r, Kirigami.Theme.alternateBackgroundColor.g, Kirigami.Theme.alternateBackgroundColor.b, 0.8)
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: hasArt ? "file://" + modelData.artwork : ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
visible: hasArt
|
||||
|
|
@ -721,19 +746,20 @@ Window {
|
|||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: Kirigami.Units.iconSizes.large
|
||||
implicitHeight: Kirigami.Units.iconSizes.large
|
||||
source: modelData.icon
|
||||
visible: !hasArt
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData.name
|
||||
maximumLineCount: 1
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.85
|
||||
color: parent.parent.isCurrent
|
||||
? Kirigami.Theme.highlightedTextColor
|
||||
|
|
@ -761,9 +787,14 @@ Window {
|
|||
}
|
||||
|
||||
// ---- search + filter ----
|
||||
RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
implicitHeight: searchFilterStack.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: searchFilterStack
|
||||
anchors.fill: parent
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Kirigami.SearchField {
|
||||
id: searchField
|
||||
|
|
@ -783,6 +814,7 @@ Window {
|
|||
|
||||
QQC2.TabBar {
|
||||
id: sourceFilterBar
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Repeater {
|
||||
|
|
@ -808,6 +840,7 @@ Window {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- game grid ----
|
||||
|
||||
|
|
@ -819,11 +852,12 @@ Window {
|
|||
|
||||
model: GamingShell.GameLauncherProvider
|
||||
|
||||
readonly property real minCellSize: Kirigami.Units.gridUnit * 8
|
||||
readonly property real minCellSize: root.gridMinCellSize
|
||||
readonly property int columns: Math.max(2, Math.floor(width / minCellSize))
|
||||
|
||||
cellWidth: Math.floor(width / columns)
|
||||
cellHeight: Math.floor(cellWidth * 1.5) + Kirigami.Units.gridUnit * 2
|
||||
readonly property int artHeight: Math.round(cellWidth / root.capsuleArtAspect)
|
||||
cellHeight: artHeight + (root.compactMode ? Kirigami.Units.gridUnit * 1.9 : Kirigami.Units.gridUnit * 2.2)
|
||||
|
||||
keyNavigationEnabled: true
|
||||
highlightMoveDuration: 0
|
||||
|
|
@ -898,7 +932,7 @@ Window {
|
|||
|
||||
QQC2.ItemDelegate {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.smallSpacing
|
||||
anchors.margins: root.compactMode ? 0 : Kirigami.Units.smallSpacing
|
||||
padding: 0
|
||||
|
||||
readonly property bool isCurrent: GridView.isCurrentItem && grid.activeFocus
|
||||
|
|
@ -906,24 +940,30 @@ Window {
|
|||
background: Rectangle {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
color: parent.isCurrent
|
||||
? Kirigami.Theme.highlightColor
|
||||
: (parent.hovered ? Kirigami.Theme.hoverColor : "transparent")
|
||||
? Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g,
|
||||
Kirigami.Theme.highlightColor.b, 0.22)
|
||||
: (parent.hovered
|
||||
? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g,
|
||||
Kirigami.Theme.textColor.b, 0.08)
|
||||
: "transparent")
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
border.color: parent.isCurrent ? Kirigami.Theme.highlightColor : "transparent"
|
||||
border.width: parent.isCurrent ? 2 : 0
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
// ---- cover art tile ----
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
visible: hasArt
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: grid.artHeight
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
clip: true
|
||||
color: "transparent"
|
||||
color: Qt.rgba(Kirigami.Theme.alternateBackgroundColor.r,
|
||||
Kirigami.Theme.alternateBackgroundColor.g,
|
||||
Kirigami.Theme.alternateBackgroundColor.b, 0.85)
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
|
|
@ -931,6 +971,15 @@ Window {
|
|||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
visible: hasArt
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: root.compactMode ? Kirigami.Units.iconSizes.large : Kirigami.Units.iconSizes.huge
|
||||
implicitHeight: implicitWidth
|
||||
source: icon
|
||||
visible: !hasArt
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
@ -954,76 +1003,35 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
// Title beneath artwork
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
PC3.Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 2
|
||||
text: name
|
||||
maximumLineCount: 1
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
leftPadding: Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
color: parent.parent.parent.isCurrent
|
||||
? Kirigami.Theme.highlightedTextColor
|
||||
: Kirigami.Theme.textColor
|
||||
}
|
||||
}
|
||||
|
||||
// ---- fallback icon tile ----
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.smallSpacing
|
||||
visible: !hasArt
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: Kirigami.Units.iconSizes.huge
|
||||
implicitHeight: Kirigami.Units.iconSizes.huge
|
||||
source: icon
|
||||
|
||||
scale: parent.parent.parent.isCurrent ? 1.08 : 1.0
|
||||
Behavior on scale {
|
||||
MobileShell.MotionNumberAnimation { type: MobileShell.Motion.EffectsFast; duration: root.shortAnimationDuration }
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
text: name
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: lastPlayedText.length > 0
|
||||
text: lastPlayedText
|
||||
maximumLineCount: 1
|
||||
elide: Text.ElideRight
|
||||
color: parent.parent.parent.isCurrent
|
||||
? Kirigami.Theme.highlightedTextColor
|
||||
: Kirigami.Theme.textColor
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: source !== "desktop"
|
||||
radius: height / 2
|
||||
color: root.sourceChipColor(source)
|
||||
implicitHeight: sourceChipLabel.implicitHeight + Kirigami.Units.smallSpacing
|
||||
implicitWidth: sourceChipLabel.implicitWidth + Kirigami.Units.largeSpacing
|
||||
|
||||
PC3.Label {
|
||||
id: sourceChipLabel
|
||||
anchors.centerIn: parent
|
||||
text: root.sourceLabel(source)
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.72
|
||||
font.weight: Font.DemiBold
|
||||
color: "white"
|
||||
leftPadding: Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
opacity: 0.65
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.78
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1074,6 +1082,7 @@ Window {
|
|||
|
||||
Repeater {
|
||||
model: GamingShell.GamepadManager
|
||||
visible: root.bigScreenMode
|
||||
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
|
@ -1113,7 +1122,7 @@ Window {
|
|||
PC3.Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.controlLegendText()
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * (root.compactMode ? 0.7 : 0.75)
|
||||
opacity: 0.5
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignRight
|
||||
|
|
@ -1126,6 +1135,7 @@ Window {
|
|||
GamingQuickSettings {
|
||||
id: quickSettings
|
||||
z: 50
|
||||
compactMode: root.compactMode
|
||||
}
|
||||
|
||||
// Launch transition: brief fade to black, then dismiss
|
||||
|
|
|
|||
Loading…
Reference in a new issue