import QtQuick import QtQuick.Controls as QQC2 import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.alakarte RowLayout { id: root spacing: uiMode === Config.Couch ? Kirigami.Units.largeSpacing * 1.25 : Kirigami.Units.largeSpacing property int uiMode: Config.Auto property int activeInput: InputManager.KeyboardMouse readonly property bool useGamepadHints: { if (!GamepadManager.connected) return false if (uiMode === Config.Couch) { if (activeInput === InputManager.KeyboardMouse && InputManager.hasSeenKeyboardMouse) return false return true } return activeInput === InputManager.Gamepad } readonly property int style: GamepadManager.controllerStyle property string context: "library" function iconBasePath() { if (!useGamepadHints) return "" switch (style) { case GamepadManager.PlayStationController: return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/playstation/" case GamepadManager.XboxController: return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/xbox/" case GamepadManager.NintendoController: return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/nintendo/" default: return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/generic/" } } function iconForButton(buttonLabel) { if (!useGamepadHints) return "" const base = iconBasePath() if (style === GamepadManager.PlayStationController) { if (buttonLabel === "Cross") return base + "cross.svg" if (buttonLabel === "Circle") return base + "circle.svg" if (buttonLabel === "Square") return base + "square.svg" if (buttonLabel === "Triangle") return base + "triangle.svg" } if (style === GamepadManager.XboxController || style === GamepadManager.NintendoController) { return base + buttonLabel.toLowerCase() + ".svg" } if (buttonLabel === "A") return base + "south.svg" if (buttonLabel === "B") return base + "east.svg" if (buttonLabel === "X") return base + "west.svg" if (buttonLabel === "Y") return base + "north.svg" return base + "south.svg" } function iconForAux(action) { if (!useGamepadHints) return "" if (action === "dpad") { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/generic/dpad.svg" } if (action === "lb") { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/generic/lb.svg" } if (action === "rb") { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/generic/rb.svg" } if (action === "menu") { if (style === GamepadManager.PlayStationController) { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/playstation/options.svg" } if (style === GamepadManager.NintendoController) { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/nintendo/plus.svg" } if (style === GamepadManager.XboxController) { return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/xbox/menu.svg" } return "qrc:/qt/qml/org/kde/alakarte/qml/icons/gamepad/generic/menu.svg" } return "" } function keyboardLabel(action) { if (root.context === "confirm" || root.context === "confirm_remove") { switch (action) { case "navigate": return "Tab" case "confirm": return "Enter" case "back": return "Esc" case "menu": return "" default: return "" } } if (root.context === "library") { switch (action) { case "navigate": return i18n("Arrows") case "confirm": return "Space" case "back": return "" case "details": return "Enter" case "search": return "Ctrl+F" case "lb": return "Ctrl+PgUp" case "rb": return "Ctrl+PgDown" case "menu": return "Ctrl+," default: return "" } } if (root.context === "edit") { switch (action) { case "navigate": return "Tab" case "confirm": return "Enter" case "back": return "Esc" default: return "" } } if (root.context === "details") { switch (action) { case "navigate": return "Tab" case "confirm": return "Enter" case "back": return "Esc" case "details": return "F" case "search": return "E" case "menu": return "Ctrl+," default: return "" } } if (root.context === "sidebar") { switch (action) { case "navigate": return i18n("Arrows/Tab") case "confirm": return "Enter" case "back": return "Esc" case "lb": return "Ctrl+PgUp" case "rb": return "Ctrl+PgDown" case "menu": return "Ctrl+," default: return "" } } if (root.context === "settings") { switch (action) { case "navigate": return "Tab" case "confirm": return "Enter" case "back": return "Esc" case "menu": return "Ctrl+," default: return "" } } if (root.context === "settings" || root.context === "import" || root.context === "sidebar" || root.context === "about") { switch (action) { case "navigate": return "Tab" case "confirm": return "Enter" case "back": return "Esc" default: return "" } } return "" } function actionLabel(action) { if (root.context === "confirm" || root.context === "confirm_remove") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Cancel") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : "" default: return "" } } if (root.context === "library") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Play") case "back": return "" case "details": return i18n("Details") case "search": return i18n("Search") case "lb": return i18n("Prev Source") case "rb": return i18n("Next Source") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : i18n("Settings") default: return "" } } if (root.context === "settings") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : i18n("Close") default: return "" } } if (root.context === "edit") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : "" default: return "" } } if (root.context === "details") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "details": return i18n("Favorite") case "search": return i18n("Edit") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : i18n("Settings") default: return "" } } if (root.context === "sidebar") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "lb": return i18n("Prev Source") case "rb": return i18n("Next Source") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Close") : i18n("Settings") default: return "" } } if (root.context === "settings" || root.context === "import" || root.context === "sidebar") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : "" default: return "" } } if (root.context === "about") { switch (action) { case "navigate": return (useGamepadHints || keyboardLabel("navigate") !== "") ? i18n("Navigate") : "" case "confirm": return i18n("Select") case "back": return i18n("Back") case "menu": return (useGamepadHints && uiMode === Config.Couch) ? i18n("Menu") : "" default: return "" } } return "" } component HintItem: RowLayout { required property string action property string label: "" property string iconSource: "" property string keyLabel: "" visible: { if (root.useGamepadHints) return iconSource != "" && label.length > 0 return keyLabel.length > 0 && label.length > 0 } spacing: Kirigami.Units.smallSpacing Rectangle { id: buttonFrame radius: Kirigami.Units.smallSpacing color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.08) border.width: 1 border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2) Layout.preferredHeight: uiMode === Config.Couch ? Kirigami.Units.gridUnit * 1.8 : Kirigami.Units.gridUnit * 1.4 Layout.preferredWidth: useGamepadHints ? Layout.preferredHeight : Math.max(keyText.implicitWidth + Kirigami.Units.mediumSpacing * 2, Layout.preferredHeight) Image { id: buttonIcon anchors.centerIn: parent width: parent.height * 0.7 height: width source: parent.parent.iconSource visible: useGamepadHints && source != "" sourceSize: Qt.size(width * 2, height * 2) } QQC2.Label { id: keyText anchors.centerIn: parent text: parent.parent.keyLabel font.bold: true font.pointSize: uiMode === Config.Couch ? Kirigami.Theme.defaultFont.pointSize : Kirigami.Theme.smallFont.pointSize color: Kirigami.Theme.textColor visible: !useGamepadHints } } QQC2.Label { text: parent.label color: Kirigami.Theme.textColor font.pointSize: uiMode === Config.Couch ? Kirigami.Theme.defaultFont.pointSize : Kirigami.Theme.smallFont.pointSize Layout.alignment: Qt.AlignVCenter } } HintItem { action: "navigate" label: actionLabel("navigate") iconSource: iconForAux("dpad") keyLabel: keyboardLabel("navigate") } HintItem { action: "confirm" label: actionLabel("confirm") iconSource: iconForButton(GamepadManager.confirmButtonLabel) keyLabel: keyboardLabel("confirm") } HintItem { action: "back" label: actionLabel("back") iconSource: iconForButton(GamepadManager.backButtonLabel) keyLabel: keyboardLabel("back") } HintItem { action: "details" label: actionLabel("details") iconSource: iconForButton(GamepadManager.detailsButtonLabel) keyLabel: keyboardLabel("details") } HintItem { action: "search" label: actionLabel("search") iconSource: iconForButton(GamepadManager.searchButtonLabel) keyLabel: keyboardLabel("search") } HintItem { action: "lb" label: actionLabel("lb") iconSource: (root.context === "library" || root.context === "sidebar") ? iconForAux("lb") : "" keyLabel: keyboardLabel("lb") } HintItem { action: "rb" label: actionLabel("rb") iconSource: (root.context === "library" || root.context === "sidebar") ? iconForAux("rb") : "" keyLabel: keyboardLabel("rb") } HintItem { action: "menu" label: actionLabel("menu") iconSource: (useGamepadHints && uiMode === Config.Couch) ? iconForAux("menu") : ((root.context === "library" || root.context === "details" || root.context === "sidebar" || root.context === "settings") ? iconForAux("menu") : "") keyLabel: keyboardLabel("menu") } }