mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-03 20:32:07 -04:00
153 lines
4.5 KiB
QML
153 lines
4.5 KiB
QML
import QtQuick
|
|
import QtQuick.Shapes
|
|
import qs.Common
|
|
|
|
// ConnectedCorner — Seam-complement connector that fills the void between
|
|
// a bar's rounded corner and a popout's flush edge, creating a seamless junction.
|
|
//
|
|
// Usage: Place as a sibling to contentWrapper inside unrollCounteract (DankPopout)
|
|
// or as a sibling to dockBackground (Dock). Position using contentWrapper.x/y.
|
|
//
|
|
// barSide: "top" | "bottom" | "left" | "right" — which edge the bar is on
|
|
// placement: "left" | "right" — which lateral end of that edge
|
|
// spacing: gap between bar surface and popout surface (storedBarSpacing, ~4px)
|
|
// connectorRadius: bar corner radius to match (frameRounding or Theme.cornerRadius)
|
|
// color: fill color matching the popout surface
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property string barSide: "top"
|
|
property string placement: "left"
|
|
property real spacing: 4
|
|
property real connectorRadius: 12
|
|
property color color: "transparent"
|
|
|
|
readonly property bool isHorizontalBar: barSide === "top" || barSide === "bottom"
|
|
readonly property bool isPlacementLeft: placement === "left"
|
|
readonly property string arcCorner: {
|
|
if (barSide === "top")
|
|
return isPlacementLeft ? "bottomLeft" : "bottomRight";
|
|
if (barSide === "bottom")
|
|
return isPlacementLeft ? "topLeft" : "topRight";
|
|
if (barSide === "left")
|
|
return isPlacementLeft ? "topRight" : "bottomRight";
|
|
return isPlacementLeft ? "topLeft" : "bottomLeft";
|
|
}
|
|
readonly property real pathStartX: {
|
|
switch (arcCorner) {
|
|
case "topLeft":
|
|
return width;
|
|
case "topRight":
|
|
case "bottomLeft":
|
|
return 0;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real pathStartY: {
|
|
switch (arcCorner) {
|
|
case "bottomRight":
|
|
return height;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real firstLineX: {
|
|
switch (arcCorner) {
|
|
case "topLeft":
|
|
case "bottomLeft":
|
|
return width;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real firstLineY: {
|
|
switch (arcCorner) {
|
|
case "topLeft":
|
|
case "topRight":
|
|
return height;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real secondLineX: {
|
|
switch (arcCorner) {
|
|
case "topRight":
|
|
case "bottomLeft":
|
|
case "bottomRight":
|
|
return width;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real secondLineY: {
|
|
switch (arcCorner) {
|
|
case "topLeft":
|
|
case "topRight":
|
|
case "bottomLeft":
|
|
return height;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
readonly property real arcCenterX: arcCorner === "topRight" || arcCorner === "bottomRight" ? width : 0
|
|
readonly property real arcCenterY: arcCorner === "bottomLeft" || arcCorner === "bottomRight" ? height : 0
|
|
readonly property real arcStartAngle: {
|
|
switch (arcCorner) {
|
|
case "topLeft":
|
|
case "topRight":
|
|
return 90;
|
|
case "bottomLeft":
|
|
return 0;
|
|
default:
|
|
return -90;
|
|
}
|
|
}
|
|
readonly property real arcSweepAngle: {
|
|
switch (arcCorner) {
|
|
case "topRight":
|
|
return 90;
|
|
default:
|
|
return -90;
|
|
}
|
|
}
|
|
|
|
// Horizontal bar: connector is tall (bridges vertical gap), narrow (corner radius wide)
|
|
// Vertical bar: connector is wide (bridges horizontal gap), short (corner radius tall)
|
|
width: isHorizontalBar ? connectorRadius : (spacing + connectorRadius)
|
|
height: isHorizontalBar ? (spacing + connectorRadius) : connectorRadius
|
|
|
|
Shape {
|
|
anchors.fill: parent
|
|
preferredRendererType: Shape.CurveRenderer
|
|
|
|
ShapePath {
|
|
fillColor: root.color
|
|
strokeColor: "transparent"
|
|
strokeWidth: 0
|
|
startX: root.pathStartX
|
|
startY: root.pathStartY
|
|
|
|
PathLine {
|
|
x: root.firstLineX
|
|
y: root.firstLineY
|
|
}
|
|
|
|
PathLine {
|
|
x: root.secondLineX
|
|
y: root.secondLineY
|
|
}
|
|
|
|
PathAngleArc {
|
|
centerX: root.arcCenterX
|
|
centerY: root.arcCenterY
|
|
radiusX: root.width
|
|
radiusY: root.height
|
|
startAngle: root.arcStartAngle
|
|
sweepAngle: root.arcSweepAngle
|
|
}
|
|
}
|
|
}
|
|
}
|