bar/goth: fix inverse radius override

This commit is contained in:
bbedward
2026-09-21 22:51:49 -04:00
parent e9498716f9
commit 2d1b4f905d
4 changed files with 52 additions and 31 deletions
+14 -8
View File
@@ -41,6 +41,7 @@ function frame(g, start, end, thickness, attachedStart, attachedEnd, farStart, f
thickness,
inset,
wing: Math.max(0, g.wing),
wingCross: Math.max(0, g.wingCross ?? g.wing),
attachedStart: shrink(attachedStart),
attachedEnd: shrink(attachedEnd),
farStart: shrink(farStart),
@@ -136,9 +137,10 @@ function alongOps(f) {
const p = pen();
const i = f.inset;
const r = f.wing;
const rc = f.wingCross;
const T = f.thickness;
// the offset of a wing arc meets the offset attached edge 2*sqrt(r*i) short of the wing tip
const reach = 2 * Math.sqrt(r * i);
// the offset of a wing arc meets the offset attached edge 2*sqrt(rc*i) short of the tip, stretched by the along/cross ratio
const reach = rc + i > 0 ? (r + i) * 2 * Math.sqrt(rc * i) / (rc + i) : 0;
const startTip = f.start - r;
const endTip = f.end + r;
if (r > 0) {
@@ -146,7 +148,7 @@ function alongOps(f) {
p.at(startTip + reach, i).at(endTip - reach, i);
else
p.at(endTip, -i);
p.arc(r + i, 0, f.end - i, r);
p.arc(r + i, 0, f.end - i, rc, rc + i);
} else {
if (f.attachedVisible)
p.at(f.start + i + f.attachedStart, i);
@@ -155,11 +157,11 @@ function alongOps(f) {
p.at(f.end - i, T - i - f.farEnd).corner(f.farEnd, f.end - i - f.farEnd, T - i);
p.at(f.start + i + f.farStart, T - i).corner(f.farStart, f.start + i, T - i - f.farStart);
if (r > 0) {
p.at(f.start + i, r);
p.at(f.start + i, rc);
if (f.attachedVisible)
p.arc(r + i, 0, startTip + reach, i);
p.arc(r + i, 0, startTip + reach, i, rc + i);
else
p.arc(r + i, 0, startTip, -i);
p.arc(r + i, 0, startTip, -i, rc + i);
} else {
p.at(f.start + i, i + f.attachedStart).corner(f.attachedStart, f.start + i + f.attachedStart, i);
}
@@ -182,10 +184,11 @@ function pen() {
self.down = true;
return self;
},
arc(radius, sweep, a, c) {
arc(radius, sweep, a, c, crossRadius) {
self.ops.push({
op: "A",
radius,
crossRadius: crossRadius ?? radius,
sweep,
a,
c
@@ -215,6 +218,7 @@ function pen() {
function serialize(ops, position, width, height) {
const map = mapper(position, width, height);
const flipSweep = position === "bottom" || position === "left";
const vertical = position === "left" || position === "right";
return ops.map(op => {
if (op.op === "Z")
return "Z";
@@ -223,7 +227,9 @@ function serialize(ops, position, width, height) {
if (op.op !== "A")
return `${op.op} ${target}`;
const sweep = flipSweep ? 1 - op.sweep : op.sweep;
return `A ${num(op.radius)} ${num(op.radius)} 0 0 ${sweep} ${target}`;
const rx = vertical ? op.crossRadius : op.radius;
const ry = vertical ? op.radius : op.crossRadius;
return `A ${num(rx)} ${num(ry)} 0 0 ${sweep} ${target}`;
}).join(" ");
}
+15 -6
View File
@@ -22,7 +22,11 @@ Item {
readonly property bool farEdge: isBottom || isRight
readonly property bool edgeAttached: (barConfig?.attachToScreenEdge ?? false) && !frameShapesBar
readonly property bool alongWings: !(barWindow.spansEdge ?? true)
readonly property real crossSize: axis.isVertical ? (parent?.width ?? 0) : (parent?.height ?? 0)
readonly property real wingCrossCap: Math.max(0, crossSize - Math.min(rt, crossSize / 2))
readonly property real wing: gothEnabled ? barWindow._wingR : 0
readonly property real wingAlong: Math.max(0, motion.currentOffsetAlong)
readonly property real wingCross: alongWings ? Math.min(wingAlong, wingCrossCap) : wingAlong
readonly property real windowLength: axis.isVertical ? barWindow.height : barWindow.width
readonly property string startSide: axis.isVertical ? "top" : "left"
readonly property string endSide: axis.isVertical ? "bottom" : "right"
@@ -216,21 +220,25 @@ Item {
GothCorner {
id: leadingWing
radius: Math.max(0, motion.currentOffsetAlong)
radius: root.wingAlong
radiusX: root.axis.isVertical ? root.wingCross : radius
radiusY: root.axis.isVertical ? radius : root.wingCross
color: root.barWindow._bgColor
visible: root.gothEnabled && radius > 0 && root.startCover <= 0
x: root.alongWings ? (root.axis.isVertical && root.isRight ? root.width - radius : 0) : (root.isLeft ? body.width : 0)
y: root.alongWings ? (!root.axis.isVertical && root.isBottom ? root.height - radius : 0) : (root.isTop ? body.height : 0)
x: root.alongWings ? (root.axis.isVertical && root.isRight ? root.width - width : 0) : (root.isLeft ? body.width : 0)
y: root.alongWings ? (!root.axis.isVertical && root.isBottom ? root.height - height : 0) : (root.isTop ? body.height : 0)
corner: root.alongWings ? root.alongWingCorner(true) : root.isTop ? "bottomRight" : root.isBottom ? "topRight" : root.isLeft ? "bottomRight" : "bottomLeft"
}
GothCorner {
id: trailingWing
radius: Math.max(0, motion.currentOffsetAlong)
radius: root.wingAlong
radiusX: root.axis.isVertical ? root.wingCross : radius
radiusY: root.axis.isVertical ? radius : root.wingCross
color: root.barWindow._bgColor
visible: root.gothEnabled && radius > 0 && root.endCover <= 0
x: root.axis.isVertical ? (root.alongWings ? (root.isRight ? root.width - radius : 0) : (root.isLeft ? body.width : 0)) : root.width - radius
y: root.axis.isVertical ? root.height - radius : (root.alongWings ? (root.isBottom ? root.height - radius : 0) : (root.isTop ? body.height : 0))
x: root.axis.isVertical ? (root.alongWings ? (root.isRight ? root.width - width : 0) : (root.isLeft ? body.width : 0)) : root.width - width
y: root.axis.isVertical ? root.height - height : (root.alongWings ? (root.isBottom ? root.height - height : 0) : (root.isTop ? body.height : 0))
corner: root.alongWings ? root.alongWingCorner(false) : root.isTop ? "bottomLeft" : root.isBottom ? "topLeft" : root.isLeft ? "topRight" : "topLeft"
}
@@ -257,6 +265,7 @@ Item {
bottomRight: body.bottomRightRadius
},
wing: root.gothEnabled ? leadingWing.radius : 0,
wingCross: root.gothEnabled ? root.wingCross : 0,
alongWings: root.alongWings,
inset: thickness / 2,
open: !showFullBorder,
+1 -1
View File
@@ -225,7 +225,7 @@ Item {
Region {
intersection: Intersection.Subtract
radius: wingRegion.wing.radius
shape: RegionShape.Ellipse
x: wingRegion.x + wingRegion.wing.discRect.x
y: wingRegion.y + wingRegion.wing.discRect.y
width: wingRegion.wing.discRect.width
@@ -5,42 +5,48 @@ Item {
id: root
property real radius: 0
property real radiusX: radius
property real radiusY: radius
property color color: "transparent"
property string corner: "topLeft"
readonly property real rotationAngle: {
readonly property rect discRect: {
const rx = radiusX;
const ry = radiusY;
switch (corner) {
case "topRight":
return 90;
return Qt.rect(0, -ry, rx * 2, ry * 2);
case "bottomRight":
return 180;
return Qt.rect(0, 0, rx * 2, ry * 2);
case "bottomLeft":
return 270;
return Qt.rect(-rx, 0, rx * 2, ry * 2);
default:
return 0;
return Qt.rect(-rx, -ry, rx * 2, ry * 2);
}
}
readonly property rect discRect: {
const r = radius;
readonly property string path: {
const rx = radiusX;
const ry = radiusY;
if (rx <= 0 || ry <= 0)
return "";
switch (corner) {
case "topRight":
return Qt.rect(0, -r, r * 2, r * 2);
return `M 0 0 L 0 ${ry} L ${rx} ${ry} A ${rx} ${ry} 0 0 1 0 0 Z`;
case "bottomRight":
return Qt.rect(0, 0, r * 2, r * 2);
return `M 0 ${ry} L 0 0 L ${rx} 0 A ${rx} ${ry} 0 0 0 0 ${ry} Z`;
case "bottomLeft":
return Qt.rect(-r, 0, r * 2, r * 2);
return `M ${rx} ${ry} L ${rx} 0 L 0 0 A ${rx} ${ry} 0 0 1 ${rx} ${ry} Z`;
default:
return Qt.rect(-r, -r, r * 2, r * 2);
return `M ${rx} 0 L ${rx} ${ry} L 0 ${ry} A ${rx} ${ry} 0 0 0 ${rx} 0 Z`;
}
}
width: Math.max(0, radius)
height: Math.max(0, radius)
visible: radius > 0
width: Math.max(0, radiusX)
height: Math.max(0, radiusY)
visible: radiusX > 0 && radiusY > 0
Shape {
anchors.fill: parent
rotation: root.rotationAngle
preferredRendererType: Shape.CurveRenderer
ShapePath {
@@ -49,7 +55,7 @@ Item {
strokeWidth: 0
PathSvg {
path: root.radius > 0 ? `M ${root.radius} 0 L ${root.radius} ${root.radius} L 0 ${root.radius} A ${root.radius} ${root.radius} 0 0 0 ${root.radius} 0 Z` : ""
path: root.path
}
}
}