Align bar icons on a shared baseline
This commit is contained in:
@@ -343,6 +343,7 @@ QtObject {
|
|||||||
readonly property int sizeVertical: root.barToken("size-vertical", 28)
|
readonly property int sizeVertical: root.barToken("size-vertical", 28)
|
||||||
readonly property int iconSlot: root.barToken("icon-slot", 27)
|
readonly property int iconSlot: root.barToken("icon-slot", 27)
|
||||||
readonly property int iconCanvas: root.barToken("icon-canvas", 16)
|
readonly property int iconCanvas: root.barToken("icon-canvas", 16)
|
||||||
|
readonly property int iconFont: root.barToken("icon-font", 13)
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ WidgetButton {
|
|||||||
property real opticalSize: Style.bar.iconCanvas
|
property real opticalSize: Style.bar.iconCanvas
|
||||||
property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
|
property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
|
||||||
readonly property real opticalCenterErrorX: glyph.visible ? glyph.paintedCenterX - opticalCanvas.width / 2 : 0
|
readonly property real opticalCenterErrorX: glyph.visible ? glyph.paintedCenterX - opticalCanvas.width / 2 : 0
|
||||||
readonly property real opticalCenterErrorY: glyph.visible ? glyph.paintedCenterY - opticalCanvas.height / 2 : 0
|
readonly property real glyphBaselineY: glyph.visible ? glyph.baselineY : 0
|
||||||
|
readonly property int glyphFontSize: glyph.visible ? glyph.renderedFontSize : 0
|
||||||
|
|
||||||
labelVisible: false
|
labelVisible: false
|
||||||
hasVisualContent: text !== "" || iconComponent !== null
|
hasVisualContent: text !== "" || iconComponent !== null
|
||||||
fontSize: Style.font.body
|
fontSize: Style.bar.iconFont
|
||||||
fixedWidth: vertical ? -1 : Style.bar.iconSlot
|
fixedWidth: vertical ? -1 : Style.bar.iconSlot
|
||||||
fixedHeight: vertical ? Style.bar.iconSlot : -1
|
fixedHeight: vertical ? Style.bar.iconSlot : -1
|
||||||
|
|
||||||
|
|||||||
+15
-18
@@ -8,43 +8,31 @@ Item {
|
|||||||
property string fontFamily: Style.font.family
|
property string fontFamily: Style.font.family
|
||||||
property real fontSize: Style.font.body
|
property real fontSize: Style.font.body
|
||||||
property color color: Color.foreground
|
property color color: Color.foreground
|
||||||
property real targetExtent: Math.min(width, height) * 0.82
|
|
||||||
property bool debugBounds: false
|
property bool debugBounds: false
|
||||||
|
|
||||||
readonly property real baseTightWidth: Math.max(1, baseMetrics.tightBoundingRect.width)
|
readonly property int renderedFontSize: Math.max(1, Math.round(fontSize))
|
||||||
readonly property real baseTightHeight: Math.max(1, baseMetrics.tightBoundingRect.height)
|
|
||||||
readonly property real normalizedScale: Math.min(1.5, targetExtent / Math.max(baseTightWidth, baseTightHeight))
|
|
||||||
readonly property int normalizedFontSize: Math.max(1, Math.round(fontSize * normalizedScale))
|
|
||||||
readonly property real tightWidth: Math.max(1, glyphMetrics.tightBoundingRect.width)
|
readonly property real tightWidth: Math.max(1, glyphMetrics.tightBoundingRect.width)
|
||||||
readonly property real tightHeight: Math.max(1, glyphMetrics.tightBoundingRect.height)
|
|
||||||
readonly property real horizontalCorrection: glyph.implicitWidth / 2 - (glyphMetrics.tightBoundingRect.x + tightWidth / 2)
|
readonly property real horizontalCorrection: glyph.implicitWidth / 2 - (glyphMetrics.tightBoundingRect.x + tightWidth / 2)
|
||||||
readonly property real verticalCorrection: glyph.implicitHeight / 2 - (glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2)
|
|
||||||
readonly property real paintedCenterX: glyph.x + glyphMetrics.tightBoundingRect.x + tightWidth / 2
|
readonly property real paintedCenterX: glyph.x + glyphMetrics.tightBoundingRect.x + tightWidth / 2
|
||||||
readonly property real paintedCenterY: glyph.y + glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2
|
readonly property real baselineY: glyph.y + glyph.baselineOffset
|
||||||
|
|
||||||
TextMetrics {
|
|
||||||
id: baseMetrics
|
|
||||||
font.family: root.fontFamily
|
|
||||||
font.pixelSize: root.fontSize
|
|
||||||
text: root.text
|
|
||||||
}
|
|
||||||
|
|
||||||
TextMetrics {
|
TextMetrics {
|
||||||
id: glyphMetrics
|
id: glyphMetrics
|
||||||
font.family: root.fontFamily
|
font.family: root.fontFamily
|
||||||
font.pixelSize: root.normalizedFontSize
|
font.pixelSize: root.renderedFontSize
|
||||||
text: root.text
|
text: root.text
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: glyph
|
id: glyph
|
||||||
|
// Keep the shared line box and baseline intact. Correcting only the
|
||||||
|
// horizontal painted bounds avoids per-glyph vertical drift.
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.horizontalCenterOffset: root.horizontalCorrection
|
anchors.horizontalCenterOffset: root.horizontalCorrection
|
||||||
anchors.verticalCenterOffset: root.verticalCorrection
|
|
||||||
text: root.text
|
text: root.text
|
||||||
color: root.color
|
color: root.color
|
||||||
font.family: root.fontFamily
|
font.family: root.fontFamily
|
||||||
font.pixelSize: root.normalizedFontSize
|
font.pixelSize: root.renderedFontSize
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,4 +43,13 @@ Item {
|
|||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: "#4488ff"
|
border.color: "#4488ff"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: root.debugBounds
|
||||||
|
x: 0
|
||||||
|
y: Math.round(root.baselineY)
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: "#44ff88"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,12 @@ ShellRoot {
|
|||||||
fail(name + " optical canvas is " + icon.opticalSize)
|
fail(name + " optical canvas is " + icon.opticalSize)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (Math.abs(icon.opticalCenterErrorX) > 0.5 || Math.abs(icon.opticalCenterErrorY) > 0.5) {
|
if (Math.abs(icon.opticalCenterErrorX) > 0.5) {
|
||||||
fail(name + " painted bounds are over half a pixel off center by " + icon.opticalCenterErrorX + "," + icon.opticalCenterErrorY)
|
fail(name + " painted bounds are over half a pixel off center by " + icon.opticalCenterErrorX)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (icon.glyphFontSize !== Style.bar.iconFont) {
|
||||||
|
fail(name + " font size is " + icon.glyphFontSize)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -51,6 +55,12 @@ ShellRoot {
|
|||||||
if (!checkIcon(audio, "audio")) return
|
if (!checkIcon(audio, "audio")) return
|
||||||
if (!checkIcon(monitor, "monitor")) return
|
if (!checkIcon(monitor, "monitor")) return
|
||||||
if (!checkIcon(power, "power")) return
|
if (!checkIcon(power, "power")) return
|
||||||
|
var baseline = bluetooth.glyphBaselineY
|
||||||
|
if (network.glyphBaselineY !== baseline || audio.glyphBaselineY !== baseline
|
||||||
|
|| monitor.glyphBaselineY !== baseline || power.glyphBaselineY !== baseline) {
|
||||||
|
fail("glyph baselines do not match")
|
||||||
|
return
|
||||||
|
}
|
||||||
if (vector.implicitWidth !== Style.bar.iconSlot || vector.opticalSize !== Style.bar.iconCanvas) {
|
if (vector.implicitWidth !== Style.bar.iconSlot || vector.opticalSize !== Style.bar.iconCanvas) {
|
||||||
fail("vector icon does not share glyph geometry")
|
fail("vector icon does not share glyph geometry")
|
||||||
return
|
return
|
||||||
@@ -96,7 +106,7 @@ output=$(timeout 15 env \
|
|||||||
|
|
||||||
if ! grep -q 'RESULT pass' <<<"$output"; then
|
if ! grep -q 'RESULT pass' <<<"$output"; then
|
||||||
printf '%s\n' "$output" >&2
|
printf '%s\n' "$output" >&2
|
||||||
fail "bar icons share centered optical geometry"
|
fail "bar icons share slot and baseline geometry"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pass "bar icons share centered optical geometry"
|
pass "bar icons share slot and baseline geometry"
|
||||||
|
|||||||
Reference in New Issue
Block a user