Fix layout rendering, text wrapping, and scrollbar issues
- LinuxViewRenderer: Remove redundant child rendering that caused "View already has a parent" errors - SkiaLabel: Consider LineBreakMode.WordWrap for multi-line measurement and rendering - SkiaScrollView: Update ContentSize in OnDraw with properly constrained measurement - SkiaShell: Account for padding in MeasureOverride (consistent with ArrangeOverride) - Version bump to 1.0.0-preview.4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -429,9 +429,10 @@ public class SkiaLabel : SkiaView
|
||||
bounds.Bottom - Padding.Bottom);
|
||||
|
||||
// Handle single line vs multiline
|
||||
// Use DrawSingleLine for normal labels (MaxLines <= 1 or unlimited) without newlines
|
||||
// Use DrawMultiLineWithWrapping only when MaxLines > 1 (word wrap needed) or text has newlines
|
||||
bool needsMultiLine = MaxLines > 1 || Text.Contains('\n');
|
||||
// Use DrawMultiLineWithWrapping when: MaxLines > 1, text has newlines, OR WordWrap is enabled
|
||||
bool needsMultiLine = MaxLines > 1 || Text.Contains('\n') ||
|
||||
LineBreakMode == LineBreakMode.WordWrap ||
|
||||
LineBreakMode == LineBreakMode.CharacterWrap;
|
||||
if (needsMultiLine)
|
||||
{
|
||||
DrawMultiLineWithWrapping(canvas, paint, font, contentBounds);
|
||||
@@ -771,8 +772,10 @@ public class SkiaLabel : SkiaView
|
||||
using var font = new SKFont(typeface, FontSize);
|
||||
using var paint = new SKPaint(font);
|
||||
|
||||
// Use same logic as OnDraw: multiline only when MaxLines > 1 or text has newlines
|
||||
bool needsMultiLine = MaxLines > 1 || Text.Contains('\n');
|
||||
// Use multiline when: MaxLines > 1, text has newlines, OR WordWrap is enabled
|
||||
bool needsMultiLine = MaxLines > 1 || Text.Contains('\n') ||
|
||||
LineBreakMode == LineBreakMode.WordWrap ||
|
||||
LineBreakMode == LineBreakMode.CharacterWrap;
|
||||
if (!needsMultiLine)
|
||||
{
|
||||
var textBounds = new SKRect();
|
||||
|
||||
@@ -268,8 +268,16 @@ public class SkiaScrollView : SkiaView
|
||||
if (_content != null)
|
||||
{
|
||||
// Ensure content is measured and arranged
|
||||
var availableSize = new SKSize(bounds.Width, float.PositiveInfinity);
|
||||
_content.Measure(availableSize);
|
||||
// Account for vertical scrollbar width to prevent horizontal scrollbar from appearing
|
||||
var effectiveWidth = bounds.Width;
|
||||
if (Orientation != ScrollOrientation.Horizontal && VerticalScrollBarVisibility != ScrollBarVisibility.Never)
|
||||
{
|
||||
// Reserve space for vertical scrollbar if content might be taller than viewport
|
||||
effectiveWidth -= ScrollBarWidth;
|
||||
}
|
||||
var availableSize = new SKSize(effectiveWidth, float.PositiveInfinity);
|
||||
// Update ContentSize with the properly constrained measurement
|
||||
ContentSize = _content.Measure(availableSize);
|
||||
|
||||
// Apply content's margin
|
||||
var margin = _content.Margin;
|
||||
@@ -669,12 +677,18 @@ public class SkiaScrollView : SkiaView
|
||||
case ScrollOrientation.Both:
|
||||
// For Both: first measure with viewport width to get responsive layout
|
||||
// Content can still exceed viewport if it has minimum width constraints
|
||||
// Reserve space for vertical scrollbar to prevent horizontal scrollbar
|
||||
contentWidth = float.IsInfinity(availableSize.Width) ? 800f : availableSize.Width;
|
||||
if (VerticalScrollBarVisibility != ScrollBarVisibility.Never)
|
||||
contentWidth -= ScrollBarWidth;
|
||||
contentHeight = float.PositiveInfinity;
|
||||
break;
|
||||
case ScrollOrientation.Vertical:
|
||||
default:
|
||||
// Reserve space for vertical scrollbar to prevent horizontal scrollbar
|
||||
contentWidth = float.IsInfinity(availableSize.Width) ? 800f : availableSize.Width;
|
||||
if (VerticalScrollBarVisibility != ScrollBarVisibility.Never)
|
||||
contentWidth -= ScrollBarWidth;
|
||||
contentHeight = float.PositiveInfinity;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -287,14 +287,14 @@ public class SkiaShell : SkiaLayoutView
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
{
|
||||
// Measure current content
|
||||
// Measure current content with padding accounted for (consistent with ArrangeOverride)
|
||||
if (_currentContent != null)
|
||||
{
|
||||
float contentTop = NavBarIsVisible ? NavBarHeight : 0;
|
||||
float contentBottom = TabBarIsVisible ? TabBarHeight : 0;
|
||||
var contentSize = new SKSize(
|
||||
availableSize.Width,
|
||||
availableSize.Height - contentTop - contentBottom);
|
||||
availableSize.Width - (float)Padding.Left - (float)Padding.Right,
|
||||
availableSize.Height - contentTop - contentBottom - (float)Padding.Top - (float)Padding.Bottom);
|
||||
_currentContent.Measure(contentSize);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user