125 lines
3.6 KiB
QML
125 lines
3.6 KiB
QML
import QtQuick
|
|
import QtQuick.Effects
|
|
import "." as M
|
|
|
|
Item {
|
|
id: root
|
|
|
|
default property alias content: layout.children
|
|
property color borderColor: M.Theme.base02
|
|
|
|
visible: layout.visibleChildren.length > 0
|
|
|
|
implicitWidth: layout.implicitWidth + _pad * 2
|
|
implicitHeight: layout.implicitHeight + _pad * 2
|
|
|
|
readonly property int _pad: 6
|
|
readonly property int _spacing: M.Theme.moduleSpacing + 2
|
|
readonly property int _sepWidth: 1
|
|
|
|
// Shadow source — rendered offscreen, only its glow is visible
|
|
Rectangle {
|
|
id: shadowSource
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
border.color: root.borderColor
|
|
border.width: 1
|
|
radius: M.Theme.radius
|
|
visible: false
|
|
}
|
|
|
|
MultiEffect {
|
|
source: shadowSource
|
|
anchors.fill: shadowSource
|
|
shadowEnabled: true
|
|
shadowColor: root.borderColor
|
|
shadowBlur: 1.0
|
|
shadowVerticalOffset: 0
|
|
shadowHorizontalOffset: 0
|
|
}
|
|
|
|
// Background gradient
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: M.Theme.radius
|
|
gradient: Gradient {
|
|
GradientStop { position: 0; color: Qt.rgba(root.borderColor.r, root.borderColor.g, root.borderColor.b, 0.15) }
|
|
GradientStop { position: 1; color: "transparent" }
|
|
}
|
|
}
|
|
|
|
// Visible border
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
border.color: root.borderColor
|
|
border.width: 1
|
|
radius: M.Theme.radius
|
|
}
|
|
|
|
// Separator container — thin lines drawn between visible modules
|
|
Item {
|
|
id: sepContainer
|
|
anchors.fill: layout
|
|
}
|
|
|
|
// Layout container — children are positioned horizontally with separators between them
|
|
Item {
|
|
id: layout
|
|
anchors.centerIn: parent
|
|
|
|
onChildrenChanged: Qt.callLater(root._relayout)
|
|
onVisibleChildrenChanged: Qt.callLater(root._relayout)
|
|
|
|
// Also watch individual child width changes
|
|
Component.onCompleted: Qt.callLater(root._relayout)
|
|
}
|
|
|
|
function _relayout() {
|
|
// Remove old separators
|
|
for (let i = sepContainer.children.length - 1; i >= 0; i--)
|
|
sepContainer.children[i].destroy();
|
|
|
|
// Position visible children horizontally, insert separators
|
|
let x = 0;
|
|
let first = true;
|
|
const visible = [];
|
|
for (let i = 0; i < layout.children.length; i++) {
|
|
const child = layout.children[i];
|
|
if (!child.visible || child.width <= 0) continue;
|
|
visible.push(child);
|
|
}
|
|
|
|
for (let i = 0; i < visible.length; i++) {
|
|
const child = visible[i];
|
|
if (!first) {
|
|
// Add separator
|
|
const sep = _sepComp.createObject(sepContainer, {
|
|
x: x + _spacing / 2 - _sepWidth / 2,
|
|
height: Qt.binding(() => layout.implicitHeight * 0.6),
|
|
y: Qt.binding(() => layout.implicitHeight * 0.2)
|
|
});
|
|
x += _spacing;
|
|
}
|
|
child.x = x;
|
|
child.y = Qt.binding(function() { return (layout.implicitHeight - child.height) / 2; });
|
|
x += child.width;
|
|
first = false;
|
|
}
|
|
|
|
layout.implicitWidth = x;
|
|
layout.implicitHeight = 0;
|
|
for (let i = 0; i < visible.length; i++) {
|
|
if (visible[i].height > layout.implicitHeight)
|
|
layout.implicitHeight = visible[i].height;
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: _sepComp
|
|
Rectangle {
|
|
width: root._sepWidth
|
|
color: Qt.rgba(root.borderColor.r, root.borderColor.g, root.borderColor.b, 0.4)
|
|
}
|
|
}
|
|
}
|