// The resolution list for one display. // // Grouped by resolution with refresh rates beside it, rather than a flat list // of "3840x2160@60.00Hz" strings: this panel reports 35 modes, many of which // differ only in refresh-rate rounding, and a flat list of those is a wall of // near-identical text rather than a choice. import QtQuick import qs.config import qs.services Column { id: root property var monitor: null property bool enabled: true // Emitted once a mode has been asked for, so a container can put the list // away. Applying is still this component's job; closing is not. signal picked spacing: 0 readonly property var grouped: { if (!root.monitor) return []; const buckets = {}; const order = []; for (const mode of root.monitor.modes) { const key = mode.label; if (!buckets[key]) { buckets[key] = { label: key, width: mode.width, height: mode.height, rates: [] }; order.push(key); } buckets[key].rates.push(mode); } return order.map(key => buckets[key]); } Repeater { model: root.grouped SettingRow { id: resolution required property var modelData required property int index readonly property bool isCurrent: root.monitor && root.monitor.width === resolution.modelData.width && root.monitor.height === resolution.modelData.height label: resolution.modelData.label detail: resolution.isCurrent ? "Current resolution" : "" controlWidth: Math.max(120, resolution.modelData.rates.length * 84) divider: resolution.index < root.grouped.length - 1 Row { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: 6 Repeater { model: resolution.modelData.rates Rectangle { id: rate required property var modelData readonly property bool selected: resolution.isCurrent && Displays.modeIsCurrent(root.monitor, rate.modelData) implicitWidth: Math.max(74, rateCaption.implicitWidth + 22) implicitHeight: 30 radius: 9 opacity: root.enabled ? 1 : 0.45 color: rate.selected ? "transparent" : Theme.alpha(Theme.fg, rateHover.hovered && root.enabled ? 0.11 : 0.06) border.width: rate.selected ? 1 : 0 border.color: Theme.alpha(Theme.accent, 0.5) Rectangle { anchors.fill: parent radius: parent.radius visible: rate.selected border.width: 0 gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0; color: Theme.alpha(Theme.accent, 0.28) } GradientStop { position: 1.0; color: Theme.alpha(Theme.accentSecondary, 0.28) } } } Text { id: rateCaption anchors.centerIn: parent text: rate.modelData.refreshLabel color: rate.selected ? Theme.fg : Theme.fgDim font.family: Theme.fontFamily font.features: Theme.tabularFigures font.pixelSize: Theme.fontSizeSmall font.weight: rate.selected ? Font.DemiBold : Font.Normal } HoverHandler { id: rateHover enabled: root.enabled cursorShape: Qt.PointingHandCursor } TapHandler { enabled: root.enabled && !rate.selected onTapped: { Displays.apply( root.monitor.name, rate.modelData.mode, Displays.nearestCleanScale(rate.modelData.mode, root.monitor.scale), root.monitor.transform); root.picked(); } } } } } } } }