// The system power profiles as tiles rather than a stack of rows. // // Three rows with the word "Active" in the trailing column is a list you have // to read to find out what is set. Three tiles with one lit answers that // without reading anything -- and the profile is the one control on the Power // page a person changes on purpose rather than tunes once and forgets. // // Presentation only, the same shape ColorProfileTiles has: the page passes in // what the daemon says and decides what a pick means, so this cannot offer a // profile the daemon would refuse. Names and one-line descriptions still come // from PowerProfiles, which is where they live so the Control Center and // Settings cannot disagree about what "Balanced" means. import QtQuick import qs.config import qs.services import qs.widgets Flow { id: root // The daemon's own list, its current answer, and whether a change is still // in flight. property var profiles: [] property string current: "" property bool busy: false signal picked(string profile) width: parent ? parent.width : 620 spacing: 10 bottomPadding: 12 // The same freedesktop symbolic names the quick-settings panel uses, so a // themed icon set redresses both at once. function iconFor(profile: string): string { switch (profile) { case "power-saver": return "power-profile-power-saver-symbolic"; case "performance": return "power-profile-performance-symbolic"; default: return "power-profile-balanced-symbolic"; } } // Three across when they fit, one across when they do not. There is no // useful two-across arrangement of three tiles. readonly property int columns: root.width >= 460 ? 3 : 1 readonly property real tileWidth: (root.width - root.spacing * (root.columns - 1)) / root.columns Repeater { model: root.profiles Rectangle { id: tile required property var modelData readonly property string profile: String(tile.modelData) readonly property bool selected: tile.profile === root.current width: root.tileWidth implicitHeight: body.implicitHeight + 24 radius: Theme.cardRadius opacity: root.busy && !tile.selected ? 0.55 : 1 color: tile.selected ? Theme.alpha(Theme.accent, 0.09) : Theme.alpha(Theme.fg, tileHover.hovered ? 0.08 : 0.04) border.width: tile.selected || tile.activeFocus ? 2 : 1 border.color: tile.activeFocus ? Theme.accentSecondary : (tile.selected ? Theme.alpha(Theme.accent, 0.6) : Theme.alpha(Theme.fg, 0.08)) activeFocusOnTab: true Accessible.role: Accessible.RadioButton Accessible.name: PowerProfiles.label(tile.profile) Accessible.checked: tile.selected function choose(): void { if (!tile.selected && !root.busy) root.picked(tile.profile); } Keys.onReturnPressed: tile.choose() Keys.onSpacePressed: tile.choose() Column { id: body anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.margins: 12 spacing: 6 ThemedIcon { icon: root.iconFor(tile.profile) iconFallback: "preferences-system-power-symbolic" size: 20 tint: tile.selected ? Theme.accent : Theme.fgDim } Text { width: parent.width text: PowerProfiles.label(tile.profile) color: Theme.fg font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall font.weight: Font.DemiBold elide: Text.ElideRight } Text { width: parent.width text: PowerProfiles.detail(tile.profile) color: Theme.fgDim font.family: Theme.fontFamily font.pixelSize: Math.max(9, Theme.fontSizeSmall - 1) wrapMode: Text.WordWrap } } HoverHandler { id: tileHover cursorShape: Qt.PointingHandCursor } TapHandler { onTapped: { tile.choose(); tile.forceActiveFocus(); } } } } }