pragma ComponentBehavior: Bound import QtQuick import QtQuick.Shapes import qs.HyprChrome.Theme // Panel chrome for the authentication dialog. // // Deliberately NOT BarPanel. The rail's panel exists to carry two renderings of // the same data and cross-fade between them as the rail changes density, and // almost all of its size is that machinery: the summary slot, the animated // height, the state pair, the transitions. A modal has exactly one density and // never collapses, so inheriting all of that would mean carrying dead weight // and, worse, tying the dialog's look to a component whose real job is the rail // — every restyle here would have to be justified against the panels up there. // // What it does keep is the silhouette, because that is the shell's visual // signature rather than the rail's: two cut corners (top-right, bottom-left) // with detached accent caps outside them, an accent rule under the header slug, // its mirror at the lower right, and a header strip of slug / title / meta. // // This is the file to edit to restyle the prompt. Nothing else reads it. Item { id: panel property string panelId: "" property string title: "" property string meta: "" property int chamfer: 16 property int padding: 14 property int outlineWidth: 1 property int accentLineThickness: 3 readonly property int headerHeight: 30 // Gap between the header rule and the body. property int headerGap: 10 readonly property int headerPadding: 10 // Detached corner caps: the corner each chamfer removed, put back outside // the panel as an accent triangle whose hypotenuse faces the cut. capGap is // the perpendicular distance from the cut, so the per-axis shift is it over // root 2 — the cap moves along the cut's normal, not along an axis. property real capGap: 4 readonly property real capOffset: panel.capGap / Math.SQRT2 // Never let the two cuts cross, which would turn the outline inside out on // a panel shorter than twice the chamfer. readonly property real activeChamfer: Math.max(2, Math.min(panel.chamfer, panel.height / 2 - 1)) // The accent rule under the slug is sized to the slug, not to the panel. readonly property real accentLineWidth: Math.min(panel.width, slugChip.width + panel.headerPadding * 2) default property alias content: body.data implicitHeight: Math.round(body.y + body.height + panel.padding) Shape { id: panelShape anchors.fill: parent preferredRendererType: Shape.CurveRenderer // Outline: square except for the two cut corners. ShapePath { fillColor: Theme.surface strokeColor: Theme.hair strokeWidth: panel.outlineWidth startX: 0; startY: 0 PathLine { x: panelShape.width - panel.activeChamfer; y: 0 } PathLine { x: panelShape.width; y: panel.activeChamfer } PathLine { x: panelShape.width; y: panelShape.height } PathLine { x: panel.activeChamfer; y: panelShape.height } PathLine { x: 0; y: panelShape.height - panel.activeChamfer } PathLine { x: 0; y: 0 } } // Cap on the top-right cut. ShapePath { fillColor: Theme.accent strokeWidth: 0 startX: panelShape.width - panel.activeChamfer + panel.capOffset startY: -panel.capOffset PathLine { x: panelShape.width + panel.capOffset; y: panel.activeChamfer - panel.capOffset } PathLine { x: panelShape.width + panel.capOffset; y: -panel.capOffset } PathLine { x: panelShape.width - panel.activeChamfer + panel.capOffset; y: -panel.capOffset } } // Cap on the bottom-left cut, the same triangle mirrored. ShapePath { fillColor: Theme.accent strokeWidth: 0 startX: panel.activeChamfer - panel.capOffset startY: panelShape.height + panel.capOffset PathLine { x: -panel.capOffset; y: panelShape.height - panel.activeChamfer + panel.capOffset } PathLine { x: -panel.capOffset; y: panelShape.height + panel.capOffset } PathLine { x: panel.activeChamfer - panel.capOffset; y: panelShape.height + panel.capOffset } } // Accent rule under the slug. ShapePath { fillColor: Theme.accent strokeWidth: 0 startX: 0; startY: 0 PathLine { x: panel.accentLineWidth; y: 0 } PathLine { x: panel.accentLineWidth; y: panel.accentLineThickness } PathLine { x: 0; y: panel.accentLineThickness } PathLine { x: 0; y: 0 } } // Its mirror at the lower right. ShapePath { fillColor: Theme.accent strokeWidth: 0 startX: panelShape.width; startY: panelShape.height PathLine { x: panelShape.width - panel.accentLineWidth; y: panelShape.height } PathLine { x: panelShape.width - panel.accentLineWidth; y: panelShape.height - panel.accentLineThickness } PathLine { x: panelShape.width; y: panelShape.height - panel.accentLineThickness } PathLine { x: panelShape.width; y: panelShape.height } } } // Header: slug chip, title, and the meta text pinned right. Row { id: headerRow x: panel.headerPadding y: Math.round((panel.headerHeight - height) / 2) spacing: panel.headerPadding + 6 Rectangle { id: slugChip width: slugText.implicitWidth + 8 height: slugText.implicitHeight + 4 color: Theme.accent Text { id: slugText anchors.centerIn: parent text: panel.panelId color: Theme.surface font.family: Theme.microFont font.pixelSize: 11 font.bold: true } } Text { anchors.verticalCenter: slugChip.verticalCenter text: panel.title color: Theme.text font.family: Theme.displayFont font.pixelSize: 12 font.bold: true font.letterSpacing: 1.1 elide: Text.ElideRight } } Text { anchors.right: parent.right anchors.rightMargin: panel.headerPadding + 2 y: Math.round((panel.headerHeight - implicitHeight) / 2) visible: panel.meta.length > 0 text: panel.meta color: Theme.muted font.family: Theme.microFont font.pixelSize: 8 font.letterSpacing: 0.7 horizontalAlignment: Text.AlignRight elide: Text.ElideRight } // Header rule. Rectangle { x: 1 y: panel.headerHeight width: parent.width - 2 height: 1 color: Theme.text opacity: 0.12 } // Body. Measured by childrenRect, so a child must carry its own size and // must NOT anchor to this slot. Item { id: body x: panel.padding y: panel.headerHeight + panel.headerGap width: Math.max(0, panel.width - panel.padding * 2) height: childrenRect.height } }