More fixes

This commit is contained in:
2026-01-17 08:06:22 +00:00
parent f1a368a6c2
commit dc52f7f2bc
18 changed files with 1022 additions and 65 deletions

View File

@@ -407,7 +407,9 @@ public class SkiaBorder : SkiaLayoutView
canvas.DrawPath(shapePath, borderPaint);
}
// Draw children
// Clip to shape and draw children
canvas.Save();
canvas.ClipPath(shapePath);
foreach (var child in Children)
{
if (child.IsVisible)
@@ -415,6 +417,7 @@ public class SkiaBorder : SkiaLayoutView
child.Draw(canvas);
}
}
canvas.Restore();
}
#endregion

View File

@@ -74,7 +74,7 @@ public class SkiaEntry : SkiaView, IInputContext
nameof(EntryBackgroundColor),
typeof(Color),
typeof(SkiaEntry),
Colors.White,
Colors.Transparent,
propertyChanged: (b, o, n) => ((SkiaEntry)b).Invalidate());
/// <summary>
@@ -837,31 +837,52 @@ public class SkiaEntry : SkiaView, IInputContext
Invalidate();
}
protected override void DrawBackground(SKCanvas canvas, SKRect bounds)
{
// Skip base background drawing if Entry is transparent
// (transparent Entry is likely inside a Border that handles appearance)
var bgColor = ToSKColor(EntryBackgroundColor);
var baseBgColor = GetEffectiveBackgroundColor();
if (bgColor.Alpha < 10 && baseBgColor.Alpha < 10)
return;
// Otherwise let base class draw
base.DrawBackground(canvas, bounds);
}
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
{
// Draw background
using var bgPaint = new SKPaint
var bgColor = ToSKColor(EntryBackgroundColor);
var isTransparent = bgColor.Alpha < 10; // Consider nearly transparent as transparent
// Only draw background and border if not transparent
// (transparent means the Entry is likely inside a Border that handles appearance)
if (!isTransparent)
{
Color = ToSKColor(EntryBackgroundColor),
IsAntialias = true,
Style = SKPaintStyle.Fill
};
// Draw background
using var bgPaint = new SKPaint
{
Color = bgColor,
IsAntialias = true,
Style = SKPaintStyle.Fill
};
var rect = new SKRoundRect(bounds, (float)CornerRadius);
canvas.DrawRoundRect(rect, bgPaint);
var rect = new SKRoundRect(bounds, (float)CornerRadius);
canvas.DrawRoundRect(rect, bgPaint);
// Draw border
var borderColor = IsFocused ? ToSKColor(FocusedBorderColor) : ToSKColor(BorderColor);
var borderWidth = IsFocused ? (float)BorderWidth + 1 : (float)BorderWidth;
// Draw border
var borderColor = IsFocused ? ToSKColor(FocusedBorderColor) : ToSKColor(BorderColor);
var borderWidth = IsFocused ? (float)BorderWidth + 1 : (float)BorderWidth;
using var borderPaint = new SKPaint
{
Color = borderColor,
IsAntialias = true,
Style = SKPaintStyle.Stroke,
StrokeWidth = borderWidth
};
canvas.DrawRoundRect(rect, borderPaint);
using var borderPaint = new SKPaint
{
Color = borderColor,
IsAntialias = true,
Style = SKPaintStyle.Stroke,
StrokeWidth = borderWidth
};
canvas.DrawRoundRect(rect, borderPaint);
}
// Calculate content bounds
var contentBounds = new SKRect(

View File

@@ -693,6 +693,8 @@ public class SkiaImage : SkiaView
using var canvas = new SKCanvas(newBitmap);
canvas.Clear(SKColors.Transparent);
canvas.Scale(scale);
// Translate to handle negative viewBox coordinates (e.g., Material icons use 0 -960 960 960)
canvas.Translate(-cullRect.Left, -cullRect.Top);
canvas.DrawPicture(svg.Picture, null);
}
}, cts.Token);

View File

@@ -239,6 +239,20 @@ public class SkiaImageButton : SkiaView
#region Rendering
protected override void DrawBackground(SKCanvas canvas, SKRect bounds)
{
// Skip base background drawing if button is transparent
var baseBgColor = ImageBackgroundColor != null
? ToSKColor(ImageBackgroundColor)
: GetEffectiveBackgroundColor();
if (baseBgColor.Alpha < 10)
return;
// Otherwise let base class draw
base.DrawBackground(canvas, bounds);
}
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
{
var padding = Padding;
@@ -249,26 +263,29 @@ public class SkiaImageButton : SkiaView
bounds.Bottom - (float)padding.Bottom);
// Determine background color
var baseBgColor = ImageBackgroundColor != null
? ToSKColor(ImageBackgroundColor)
: GetEffectiveBackgroundColor();
var isTransparentButton = baseBgColor.Alpha < 10;
SKColor bgColor;
if (IsPressed)
if (IsPressed && !isTransparentButton)
{
// Only show pressed state for non-transparent buttons
bgColor = ToSKColor(PressedBackgroundColor);
}
else if (IsHovered)
else if (IsHovered && !isTransparentButton)
{
// Only show hovered state for non-transparent buttons
bgColor = ToSKColor(HoveredBackgroundColor);
}
else if (ImageBackgroundColor != null)
{
bgColor = ToSKColor(ImageBackgroundColor);
}
else
{
bgColor = GetEffectiveBackgroundColor();
bgColor = baseBgColor;
}
// Draw background
if (bgColor != SKColors.Transparent || !IsOpaque)
// Draw background (skip if fully transparent)
if (bgColor.Alpha > 0)
{
using var bgPaint = new SKPaint
{
@@ -477,9 +494,11 @@ public class SkiaImageButton : SkiaView
using var canvas = new SKCanvas(bitmap);
canvas.Clear(SKColors.Transparent);
canvas.Scale(scale);
// Translate to handle negative viewBox coordinates (e.g., Material icons use 0 -960 960 960)
canvas.Translate(-cullRect.Left, -cullRect.Top);
canvas.DrawPicture(svg.Picture);
Bitmap = bitmap;
Console.WriteLine($"[SkiaImageButton] Loaded SVG: {foundPath} ({width}x{height})");
Console.WriteLine($"[SkiaImageButton] Loaded SVG: {foundPath} ({width}x{height}), cullRect={cullRect}");
}
}
else
@@ -786,9 +805,12 @@ public class SkiaImageButton : SkiaView
}
// Fill (3) and Start (0) both use y = bounds.Top
return new Rect(x, y, finalWidth, finalHeight);
var result1 = new Rect(x, y, finalWidth, finalHeight);
Console.WriteLine($"[SkiaImageButton] ArrangeOverride output (aligned): Y={result1.Y}, Height={result1.Height}");
return result1;
}
Console.WriteLine($"[SkiaImageButton] ArrangeOverride output (unchanged): Y={bounds.Y}, Height={bounds.Height}");
return bounds;
}

View File

@@ -907,12 +907,46 @@ public class SkiaGrid : SkiaLayoutView
// Apply child's margin
var margin = child.Margin;
var marginedBounds = new Rect(
x + (float)margin.Left,
y + (float)margin.Top,
width - (float)margin.Left - (float)margin.Right,
height - (float)margin.Top - (float)margin.Bottom);
child.Arrange(marginedBounds);
var cellX = x + (float)margin.Left;
var cellY = y + (float)margin.Top;
var cellWidth = width - (float)margin.Left - (float)margin.Right;
var cellHeight = height - (float)margin.Top - (float)margin.Bottom;
// Get child's desired size
var childDesiredSize = child.Measure(new Size(cellWidth, cellHeight));
var childWidth = (float)childDesiredSize.Width;
var childHeight = (float)childDesiredSize.Height;
var vAlign = (int)child.VerticalOptions.Alignment;
// Apply HorizontalOptions
// LayoutAlignment: Start=0, Center=1, End=2, Fill=3
float finalX = cellX;
float finalWidth = cellWidth;
var hAlign = (int)child.HorizontalOptions.Alignment;
if (hAlign != 3 && childWidth < cellWidth && childWidth > 0) // 3 = Fill
{
finalWidth = childWidth;
if (hAlign == 1) // Center
finalX = cellX + (cellWidth - childWidth) / 2;
else if (hAlign == 2) // End
finalX = cellX + cellWidth - childWidth;
}
// Apply VerticalOptions
float finalY = cellY;
float finalHeight = cellHeight;
// vAlign already calculated above for debug logging
if (vAlign != 3 && childHeight < cellHeight && childHeight > 0) // 3 = Fill
{
finalHeight = childHeight;
if (vAlign == 1) // Center
finalY = cellY + (cellHeight - childHeight) / 2;
else if (vAlign == 2) // End
finalY = cellY + cellHeight - childHeight;
}
child.Arrange(new Rect(finalX, finalY, finalWidth, finalHeight));
}
return bounds;
}

View File

@@ -1534,8 +1534,8 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
canvas.DrawRect(bounds, paint);
}
}
// Fall back to BackgroundColor
else if (_backgroundColorSK != SKColors.Transparent)
// Fall back to BackgroundColor (skip if transparent)
else if (_backgroundColorSK.Alpha > 0)
{
using var paint = new SKPaint { Color = _backgroundColorSK };
canvas.DrawRect(bounds, paint);