Files

112 lines
3.4 KiB
QML

// The scaffold every settings page shares: a scrolling column with a title, a
// one-line lede, and consistent margins.
//
// This existed eleven times as copy-pasted Flickable/Column/x:34/y:30 blocks,
// which is a large part of why several pages settled for read-only text instead
// of real controls -- adding a page was expensive enough that the cheap thing
// won. Pages are now just their content:
//
// SettingsPage {
// title: "Appearance"
// lede: "Tokyo Night Moon, tuned for clarity and quiet motion."
//
// SettingsCard { title: "Windows"; ToggleRow { setting: "blurEnabled" } }
// }
import QtQuick
import qs.config
Item {
id: root
default property alias content: column.data
property string title: ""
property string lede: ""
// Anything that should sit above the title and stay put while the rest
// scrolls -- the Appearance page pins its live preview here.
property Component header: null
// A view that replaces the page entirely while it is up. Containers' log
// reader is the case: logs need their own scrollback, and a scrolling view
// nested inside a scrolling page makes the wheel ambiguous over exactly the
// region where somebody wants to use it. A page that owns one stays a
// SettingsPage rather than becoming a bare Item wrapping two of them.
property Component drillIn: null
property bool drilledIn: false
Loader {
id: pinnedHeader
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.leftMargin: 34
anchors.rightMargin: 34
anchors.topMargin: 30
visible: !root.drilledIn
active: root.header !== null
sourceComponent: root.header
z: 1
}
Loader {
anchors.fill: parent
active: root.drillIn !== null && root.drilledIn
sourceComponent: root.drillIn
z: 2
}
Flickable {
id: pageScroll
anchors.left: parent.left
anchors.right: parent.right
anchors.top: pinnedHeader.implicitHeight > 0 ? pinnedHeader.bottom : parent.top
anchors.bottom: parent.bottom
anchors.topMargin: pinnedHeader.implicitHeight > 0 ? 16 : 0
visible: !root.drilledIn
clip: true
contentWidth: width
contentHeight: layout.implicitHeight + (pinnedHeader.implicitHeight > 0 ? 34 : 64)
boundsBehavior: Flickable.StopAtBounds
Column {
id: layout
width: parent.width - 68
x: 34
y: pinnedHeader.implicitHeight > 0 ? 0 : 30
spacing: 16
Text {
width: parent.width
visible: root.title !== ""
text: root.title
color: Theme.fg
font.family: Theme.fontFamily
font.pixelSize: 27
font.weight: Font.DemiBold
}
Text {
width: parent.width
visible: root.lede !== ""
text: root.lede
color: Theme.fgDim
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSize
wrapMode: Text.WordWrap
bottomPadding: 6
}
Column {
id: column
width: parent.width
spacing: 16
}
}
}
}