Fix one-sided menu row borders
This commit is contained in:
@@ -206,21 +206,33 @@ function ringPath(w, h, radius, widths) {
|
|||||||
blrx: radius, blry: radius,
|
blrx: radius, blry: radius,
|
||||||
})
|
})
|
||||||
|
|
||||||
var ix = widths.left || 0
|
// Shape's OddEven fill can collapse to the outer fill when the inner
|
||||||
var iy = widths.top || 0
|
// cutout touches the outer path on one or more zero-width sides. Keep the
|
||||||
var iw = w - ix - (widths.right || 0)
|
// cutout strictly inside the outer path with a subpixel inset so one-sided
|
||||||
var ih = h - iy - (widths.bottom || 0)
|
// borders (for example selected-border-width = "0 0 0 4") render as a
|
||||||
|
// strip instead of painting the whole row.
|
||||||
|
var epsilon = 0.001
|
||||||
|
var left = Math.max(0, widths.left || 0)
|
||||||
|
var top = Math.max(0, widths.top || 0)
|
||||||
|
var right = Math.max(0, widths.right || 0)
|
||||||
|
var bottom = Math.max(0, widths.bottom || 0)
|
||||||
|
var ix = Math.max(left, epsilon)
|
||||||
|
var iy = Math.max(top, epsilon)
|
||||||
|
var ir = Math.max(right, epsilon)
|
||||||
|
var ib = Math.max(bottom, epsilon)
|
||||||
|
var iw = w - ix - ir
|
||||||
|
var ih = h - iy - ib
|
||||||
if (iw <= 0 || ih <= 0) return outer
|
if (iw <= 0 || ih <= 0) return outer
|
||||||
|
|
||||||
var inner = roundedRectPath(ix, iy, iw, ih, {
|
var inner = roundedRectPath(ix, iy, iw, ih, {
|
||||||
tlrx: Math.max(0, radius - (widths.left || 0)),
|
tlrx: Math.max(0, radius - left),
|
||||||
tlry: Math.max(0, radius - (widths.top || 0)),
|
tlry: Math.max(0, radius - top),
|
||||||
trrx: Math.max(0, radius - (widths.right || 0)),
|
trrx: Math.max(0, radius - right),
|
||||||
trry: Math.max(0, radius - (widths.top || 0)),
|
trry: Math.max(0, radius - top),
|
||||||
brrx: Math.max(0, radius - (widths.right || 0)),
|
brrx: Math.max(0, radius - right),
|
||||||
brry: Math.max(0, radius - (widths.bottom || 0)),
|
brry: Math.max(0, radius - bottom),
|
||||||
blrx: Math.max(0, radius - (widths.left || 0)),
|
blrx: Math.max(0, radius - left),
|
||||||
blry: Math.max(0, radius - (widths.bottom || 0)),
|
blry: Math.max(0, radius - bottom),
|
||||||
})
|
})
|
||||||
|
|
||||||
return outer + " " + inner
|
return outer + " " + inner
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ Item {
|
|||||||
property color selectedText: Color.launcher.selectedText
|
property color selectedText: Color.launcher.selectedText
|
||||||
property color selectedBorder: Color.launcher.selectedBorder
|
property color selectedBorder: Color.launcher.selectedBorder
|
||||||
property var selectedBorderSpec: Border.surfaceSpec("launcher", "selected-border", selectedBorder, 0)
|
property var selectedBorderSpec: Border.surfaceSpec("launcher", "selected-border", selectedBorder, 0)
|
||||||
|
readonly property real rowReservedBorderLeft: Border.left(selectedBorderSpec)
|
||||||
|
readonly property real rowReservedBorderRight: Border.right(selectedBorderSpec)
|
||||||
property string fontFamily: Style.font.menuFamily
|
property string fontFamily: Style.font.menuFamily
|
||||||
|
|
||||||
property int cardWidth: 644
|
property int cardWidth: 644
|
||||||
@@ -495,7 +497,7 @@ Item {
|
|||||||
Item {
|
Item {
|
||||||
id: iconSlot
|
id: iconSlot
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: row.borderLeft + 14
|
anchors.leftMargin: root.rowReservedBorderLeft + 14
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: root.iconSlotWidth
|
width: root.iconSlotWidth
|
||||||
height: parent.height
|
height: parent.height
|
||||||
@@ -525,7 +527,7 @@ Item {
|
|||||||
anchors.left: iconSlot.right
|
anchors.left: iconSlot.right
|
||||||
anchors.leftMargin: 14
|
anchors.leftMargin: 14
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: row.borderRight + 14
|
anchors.rightMargin: root.rowReservedBorderRight + 14
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: row.name
|
text: row.name
|
||||||
color: row.hasCursor ? root.selectedText : root.foreground
|
color: row.hasCursor ? root.selectedText : root.foreground
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ Item {
|
|||||||
property color selectedText: Color.menu.selectedText
|
property color selectedText: Color.menu.selectedText
|
||||||
property color selectedBorder: Color.menu.selectedBorder
|
property color selectedBorder: Color.menu.selectedBorder
|
||||||
property var selectedBorderSpec: Border.surfaceSpec("menu", "selected-border", selectedBorder, 0)
|
property var selectedBorderSpec: Border.surfaceSpec("menu", "selected-border", selectedBorder, 0)
|
||||||
|
readonly property real rowReservedBorderLeft: Border.left(selectedBorderSpec)
|
||||||
|
readonly property real rowReservedBorderRight: Border.right(selectedBorderSpec)
|
||||||
readonly property int cornerRadius: Style.cornerRadius
|
readonly property int cornerRadius: Style.cornerRadius
|
||||||
property int contentMargin: Style.spacing.panelPadding
|
property int contentMargin: Style.spacing.panelPadding
|
||||||
property int headerHeight: Math.max(Style.space(34), Style.font.title + Style.spacing.controlPaddingY * 2)
|
property int headerHeight: Math.max(Style.space(34), Style.font.title + Style.spacing.controlPaddingY * 2)
|
||||||
@@ -933,7 +935,7 @@ Item {
|
|||||||
radius: Math.min(root.cornerRadius, Style.space(4))
|
radius: Math.min(root.cornerRadius, Style.space(4))
|
||||||
color: root.selectedBackground
|
color: root.selectedBackground
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: row.borderLeft + Style.space(8)
|
anchors.leftMargin: root.rowReservedBorderLeft + Style.space(8)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -948,14 +950,14 @@ Item {
|
|||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: row.borderLeft + Style.space(8)
|
anchors.leftMargin: root.rowReservedBorderLeft + Style.space(8)
|
||||||
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
anchors.left: row.hasIcon ? iconText.right : parent.left
|
anchors.left: row.hasIcon ? iconText.right : parent.left
|
||||||
anchors.leftMargin: row.hasIcon ? Style.space(6) : row.borderLeft + Style.space(18)
|
anchors.leftMargin: row.hasIcon ? Style.space(6) : root.rowReservedBorderLeft + Style.space(18)
|
||||||
anchors.right: trail.left
|
anchors.right: trail.left
|
||||||
anchors.rightMargin: Style.space(6)
|
anchors.rightMargin: Style.space(6)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -988,7 +990,7 @@ Item {
|
|||||||
id: trail
|
id: trail
|
||||||
width: Style.space(14)
|
width: Style.space(14)
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: row.borderRight + Style.space(8)
|
anchors.rightMargin: root.rowReservedBorderRight + Style.space(8)
|
||||||
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ const pathData = geometry.ringPath(100, 50, 10, { top: 4, right: 2, bottom: 8, l
|
|||||||
assert(pathData.includes('M 10 0'), 'border geometry emits outer rounded path')
|
assert(pathData.includes('M 10 0'), 'border geometry emits outer rounded path')
|
||||||
assert(pathData.includes('M 10 4'), 'border geometry emits inset inner rounded path')
|
assert(pathData.includes('M 10 4'), 'border geometry emits inset inner rounded path')
|
||||||
|
|
||||||
|
const oneSidedPath = geometry.ringPath(100, 50, 10, { top: 0, right: 0, bottom: 0, left: 4 })
|
||||||
|
assert(oneSidedPath.includes('M 10 0.001'), 'border geometry keeps zero-width top inside outer path')
|
||||||
|
assert(oneSidedPath.includes('99.999 10.001'), 'border geometry keeps zero-width right inside outer path')
|
||||||
|
|
||||||
const endpoints = geometry.gradientEndpoints(100, 50, 0)
|
const endpoints = geometry.gradientEndpoints(100, 50, 0)
|
||||||
assertEqual(Math.round(endpoints.x1), 0, 'border geometry 0deg starts at left edge')
|
assertEqual(Math.round(endpoints.x1), 0, 'border geometry 0deg starts at left edge')
|
||||||
assertEqual(Math.round(endpoints.x2), 100, 'border geometry 0deg ends at right edge')
|
assertEqual(Math.round(endpoints.x2), 100, 'border geometry 0deg ends at right edge')
|
||||||
|
|||||||
Executable
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
source "$(dirname "$0")/base-test.sh"
|
||||||
|
|
||||||
|
run_node_test <<'JS'
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const menuQml = fs.readFileSync(path.join(root, 'shell/plugins/menu/Menu.qml'), 'utf8')
|
||||||
|
const launcherQml = fs.readFileSync(path.join(root, 'shell/plugins/launcher/Launcher.qml'), 'utf8')
|
||||||
|
|
||||||
|
assert(
|
||||||
|
/rowReservedBorderLeft:\s*Border\.left\(selectedBorderSpec\)/.test(menuQml)
|
||||||
|
&& /rowReservedBorderRight:\s*Border\.right\(selectedBorderSpec\)/.test(menuQml),
|
||||||
|
'Menu rows reserve selected border insets'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!/anchors\.(left|right)Margin:[^\n]*\brow\.border(Left|Right)\b/.test(menuQml),
|
||||||
|
'Menu row content does not depend on current selected border state'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
/rowReservedBorderLeft:\s*Border\.left\(selectedBorderSpec\)/.test(launcherQml)
|
||||||
|
&& /rowReservedBorderRight:\s*Border\.right\(selectedBorderSpec\)/.test(launcherQml),
|
||||||
|
'Launcher rows reserve selected border insets'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!/anchors\.(left|right)Margin:[^\n]*\brow\.border(Left|Right)\b/.test(launcherQml),
|
||||||
|
'Launcher row content does not depend on current selected border state'
|
||||||
|
)
|
||||||
|
JS
|
||||||
Reference in New Issue
Block a user