Fix overlapping text in OutlineView

- Replace manual Item+anchoring with ColumnLayout for proper height calc
- Remove redundant bodyMeasure Text and bodyWidth property
- Add proper top/bottom margins using rowPad constant
- Body row now uses RowLayout with Layout.fillWidth
This commit is contained in:
Levi Neely 2026-10-01 08:50:52 +02:00
parent 71a89943ae
commit e129f9ee94
1 changed files with 30 additions and 59 deletions

View File

@ -40,48 +40,20 @@ TreeView {
readonly property string sectionBody: (model.body ?? "").trim()
readonly property int bodyIndent: 12
// The horizontal space available to the body text. The base delegate
// reserves (depth+1)*indentation on the left for the tree structure;
// the content region occupies the rest, minus our body indent and a
// right margin. Computing this explicitly (rather than via anchors)
// gives the body Text a concrete width, so contentHeight resolves
// deterministically and the row height below is correct.
readonly property real bodyWidth:
Math.max(1, tree.width - (depth + 1) * indentation
- bodyIndent - 12)
implicitWidth: tree.width
// Row height = headline + body (if any) + padding. bodyMeasure is a
// non-visible Text with the same font/width as the body, used purely
// to measure wrapped height without depending on the laid-out item.
implicitHeight: headlineRow.implicitHeight
+ (sectionBody !== "" ? bodyMeasure.implicitHeight + 4 : 0)
+ tree.rowPad * 2
background: Rectangle {
color: del.current ? "#2f3540" : "transparent"
radius: 4
}
// Off-screen measurement of the wrapped body height.
Text {
id: bodyMeasure
visible: false
width: del.bodyWidth
text: del.sectionBody
font.pixelSize: 12
lineHeight: 1.15
wrapMode: Text.WordWrap
textFormat: Text.PlainText
}
contentItem: ColumnLayout {
spacing: 4
contentItem: Item {
RowLayout {
id: headlineRow
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
Layout.fillWidth: true
Layout.topMargin: tree.rowPad
spacing: 8
// TODO keyword pill.
@ -156,34 +128,33 @@ TreeView {
}
}
// Left rule marking the body region.
Rectangle {
visible: bodyLabel.visible
width: 2
color: "#3b4252"
anchors.top: bodyLabel.top
anchors.bottom: bodyLabel.bottom
anchors.left: parent.left
anchors.leftMargin: 2
}
// Section body, always visible inline beneath the headline.
// Given an explicit width (matching bodyMeasure) so wrapping and
// height are consistent with the reserved row height.
Text {
id: bodyLabel
anchors.top: headlineRow.bottom
anchors.topMargin: 4
anchors.left: parent.left
anchors.leftMargin: del.bodyIndent
width: del.bodyWidth
// Body row with left rule.
RowLayout {
visible: del.sectionBody !== ""
text: del.sectionBody
color: tree.dimColor
font.pixelSize: 12
lineHeight: 1.15
wrapMode: Text.WordWrap
textFormat: Text.PlainText
Layout.fillWidth: true
Layout.bottomMargin: tree.rowPad
spacing: 8
// Left rule marking the body region.
Rectangle {
width: 2
Layout.fillHeight: true
Layout.leftMargin: 2
color: "#3b4252"
}
// Section body text.
Text {
id: bodyLabel
Layout.fillWidth: true
Layout.leftMargin: del.bodyIndent - 10
text: del.sectionBody
color: tree.dimColor
font.pixelSize: 12
lineHeight: 1.15
wrapMode: Text.WordWrap
textFormat: Text.PlainText
}
}
}
}