More fixes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
|
||||
@@ -24,12 +25,12 @@ public class GtkWebViewProxy : SkiaView
|
||||
_platformView = platformView;
|
||||
}
|
||||
|
||||
public override void Arrange(SKRect bounds)
|
||||
public override void Arrange(Rect bounds)
|
||||
{
|
||||
base.Arrange(bounds);
|
||||
// Bounds are already in absolute window coordinates - use them directly
|
||||
// The Skia layout system uses absolute coordinates throughout
|
||||
_handler.RegisterWithHost(Bounds);
|
||||
_handler.RegisterWithHost(new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)Bounds.Right, (float)Bounds.Bottom));
|
||||
}
|
||||
|
||||
public override void Draw(SKCanvas canvas)
|
||||
@@ -40,7 +41,7 @@ public class GtkWebViewProxy : SkiaView
|
||||
Color = new SKColor(0, 0, 0, 0),
|
||||
Style = SKPaintStyle.Fill
|
||||
};
|
||||
canvas.DrawRect(Bounds, paint);
|
||||
canvas.DrawRect(new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)Bounds.Right, (float)Bounds.Bottom), paint);
|
||||
}
|
||||
|
||||
public void Navigate(string url)
|
||||
|
||||
@@ -177,8 +177,8 @@ public class SkiaWindow
|
||||
// Draw main content
|
||||
if (_content != null)
|
||||
{
|
||||
_content.Measure(new SKSize(_width, _height));
|
||||
_content.Arrange(new SKRect(0, 0, _width, _height));
|
||||
_content.Measure(new Size(_width, _height));
|
||||
_content.Arrange(new Rect(0, 0, _width, _height));
|
||||
_content.Draw(canvas);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ public class LinuxApplication : IDisposable
|
||||
_rootView = value;
|
||||
if (_rootView != null && _mainWindow != null)
|
||||
{
|
||||
_rootView.Arrange(new SkiaSharp.SKRect(
|
||||
_rootView.Arrange(new Microsoft.Maui.Graphics.Rect(
|
||||
0, 0,
|
||||
_mainWindow.Width,
|
||||
_mainWindow.Height));
|
||||
@@ -542,8 +542,8 @@ public class LinuxApplication : IDisposable
|
||||
{
|
||||
if (_rootView != null)
|
||||
{
|
||||
_rootView.Measure(new SKSize(width, height));
|
||||
_rootView.Arrange(new SKRect(0, 0, width, height));
|
||||
_rootView.Measure(new Size(width, height));
|
||||
_rootView.Arrange(new Rect(0, 0, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,9 +569,9 @@ public class LinuxApplication : IDisposable
|
||||
if (_rootView != null)
|
||||
{
|
||||
// Re-measure with new available size, then arrange
|
||||
var availableSize = new SkiaSharp.SKSize(size.Width, size.Height);
|
||||
var availableSize = new Size(size.Width, size.Height);
|
||||
_rootView.Measure(availableSize);
|
||||
_rootView.Arrange(new SkiaSharp.SKRect(0, 0, size.Width, size.Height));
|
||||
_rootView.Arrange(new Rect(0, 0, size.Width, size.Height));
|
||||
}
|
||||
_renderingEngine?.InvalidateAll();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using SkiaSharp;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform.Linux.Window;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -207,9 +208,9 @@ public class GpuRenderingEngine : IDisposable
|
||||
if (_canvas == null) return;
|
||||
|
||||
// Measure and arrange
|
||||
var availableSize = new SKSize(Width, Height);
|
||||
var availableSize = new Size(Width, Height);
|
||||
rootView.Measure(availableSize);
|
||||
rootView.Arrange(new SKRect(0, 0, Width, Height));
|
||||
rootView.Arrange(new Rect(0, 0, Width, Height));
|
||||
|
||||
// Determine regions to redraw
|
||||
List<SKRect> regionsToRedraw;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using SkiaSharp;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform.Linux.Window;
|
||||
using Microsoft.Maui.Platform;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -167,9 +168,9 @@ public class SkiaRenderingEngine : IDisposable
|
||||
return;
|
||||
|
||||
// Measure and arrange
|
||||
var availableSize = new SKSize(Width, Height);
|
||||
var availableSize = new Size(Width, Height);
|
||||
rootView.Measure(availableSize);
|
||||
rootView.Arrange(new SKRect(0, 0, Width, Height));
|
||||
rootView.Arrange(new Rect(0, 0, Width, Height));
|
||||
|
||||
// Determine what to redraw
|
||||
List<SKRect> regionsToRedraw;
|
||||
|
||||
@@ -3,15 +3,55 @@
|
||||
|
||||
namespace Microsoft.Maui.Platform.Linux.Services;
|
||||
|
||||
public enum HotkeyKey
|
||||
/// <summary>
|
||||
/// X11 keysym values for global hotkey registration.
|
||||
/// </summary>
|
||||
public enum HotkeyKey : uint
|
||||
{
|
||||
None,
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M,
|
||||
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
Space, Enter, Escape, Tab, Backspace, Delete, Insert,
|
||||
Home, End, PageUp, PageDown,
|
||||
Left, Right, Up, Down,
|
||||
PrintScreen, Pause, NumLock, ScrollLock, CapsLock
|
||||
None = 0,
|
||||
|
||||
// Letters (lowercase X11 keysyms)
|
||||
A = 0x61, B = 0x62, C = 0x63, D = 0x64, E = 0x65,
|
||||
F = 0x66, G = 0x67, H = 0x68, I = 0x69, J = 0x6A,
|
||||
K = 0x6B, L = 0x6C, M = 0x6D, N = 0x6E, O = 0x6F,
|
||||
P = 0x70, Q = 0x71, R = 0x72, S = 0x73, T = 0x74,
|
||||
U = 0x75, V = 0x76, W = 0x77, X = 0x78, Y = 0x79,
|
||||
Z = 0x7A,
|
||||
|
||||
// Digits
|
||||
D0 = 0x30, D1 = 0x31, D2 = 0x32, D3 = 0x33, D4 = 0x34,
|
||||
D5 = 0x35, D6 = 0x36, D7 = 0x37, D8 = 0x38, D9 = 0x39,
|
||||
|
||||
// Function keys
|
||||
F1 = 0xFFBE, F2 = 0xFFBF, F3 = 0xFFC0, F4 = 0xFFC1,
|
||||
F5 = 0xFFC2, F6 = 0xFFC3, F7 = 0xFFC4, F8 = 0xFFC5,
|
||||
F9 = 0xFFC6, F10 = 0xFFC7, F11 = 0xFFC8, F12 = 0xFFC9,
|
||||
|
||||
// Special keys
|
||||
Space = 0x20,
|
||||
Enter = 0xFF0D,
|
||||
Escape = 0xFF1B,
|
||||
Tab = 0xFF09,
|
||||
Backspace = 0xFF08,
|
||||
Delete = 0xFFFF,
|
||||
Insert = 0xFF63,
|
||||
|
||||
// Navigation keys
|
||||
Home = 0xFF50,
|
||||
End = 0xFF57,
|
||||
PageUp = 0xFF55,
|
||||
PageDown = 0xFF56,
|
||||
|
||||
// Arrow keys
|
||||
Left = 0xFF51,
|
||||
Right = 0xFF53,
|
||||
Up = 0xFF52,
|
||||
Down = 0xFF54,
|
||||
|
||||
// Lock keys
|
||||
PrintScreen = 0xFF61,
|
||||
Pause = 0xFF13,
|
||||
NumLock = 0xFF7F,
|
||||
ScrollLock = 0xFF14,
|
||||
CapsLock = 0xFFE5
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Microsoft.Maui.Platform;
|
||||
@@ -64,8 +65,8 @@ public static class LinuxDialogService
|
||||
{
|
||||
foreach (var dialog in _activeDialogs)
|
||||
{
|
||||
dialog.Measure(new SKSize(bounds.Width, bounds.Height));
|
||||
dialog.Arrange(bounds);
|
||||
dialog.Measure(new Size(bounds.Width, bounds.Height));
|
||||
dialog.Arrange(new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height));
|
||||
dialog.Draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,11 +284,11 @@ public class SkiaActivityIndicator : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var size = (float)Size;
|
||||
var strokeWidth = (float)StrokeWidth;
|
||||
return new SKSize(size + strokeWidth * 2, size + strokeWidth * 2);
|
||||
return new Size(size + strokeWidth * 2, size + strokeWidth * 2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -311,7 +311,7 @@ public class SkiaAlertDialog : SkiaView
|
||||
_tcs.TrySetResult(result);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Dialog takes full screen for the overlay
|
||||
return availableSize;
|
||||
|
||||
@@ -423,7 +423,7 @@ public class SkiaBorder : SkiaLayoutView
|
||||
|
||||
protected override SKRect GetContentBounds()
|
||||
{
|
||||
return GetContentBounds(Bounds);
|
||||
return GetContentBounds(new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)Bounds.Right, (float)Bounds.Bottom));
|
||||
}
|
||||
|
||||
protected new SKRect GetContentBounds(SKRect bounds)
|
||||
@@ -437,7 +437,7 @@ public class SkiaBorder : SkiaLayoutView
|
||||
bounds.Bottom - (float)padding.Bottom - strokeThickness);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
float strokeThickness = (float)StrokeThickness;
|
||||
var padding = BorderPadding;
|
||||
@@ -445,43 +445,43 @@ public class SkiaBorder : SkiaLayoutView
|
||||
float paddingHeight = (float)(padding.Top + padding.Bottom) + strokeThickness * 2f;
|
||||
|
||||
// Respect explicit size requests
|
||||
var requestedWidth = WidthRequest >= 0.0 ? (float)WidthRequest : availableSize.Width;
|
||||
var requestedHeight = HeightRequest >= 0.0 ? (float)HeightRequest : availableSize.Height;
|
||||
var requestedWidth = WidthRequest >= 0.0 ? (float)WidthRequest : (float)availableSize.Width;
|
||||
var requestedHeight = HeightRequest >= 0.0 ? (float)HeightRequest : (float)availableSize.Height;
|
||||
|
||||
var childAvailable = new SKSize(
|
||||
var childAvailable = new Size(
|
||||
Math.Max(0f, requestedWidth - paddingWidth),
|
||||
Math.Max(0f, requestedHeight - paddingHeight));
|
||||
|
||||
var maxChildSize = SKSize.Empty;
|
||||
var maxChildSize = Size.Zero;
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
var childSize = child.Measure(childAvailable);
|
||||
maxChildSize = new SKSize(
|
||||
maxChildSize = new Size(
|
||||
Math.Max(maxChildSize.Width, childSize.Width),
|
||||
Math.Max(maxChildSize.Height, childSize.Height));
|
||||
}
|
||||
|
||||
// Use requested size if set, otherwise use child size + padding
|
||||
var width = WidthRequest >= 0.0 ? (float)WidthRequest : maxChildSize.Width + paddingWidth;
|
||||
var height = HeightRequest >= 0.0 ? (float)HeightRequest : maxChildSize.Height + paddingHeight;
|
||||
var width = WidthRequest >= 0.0 ? (float)WidthRequest : (float)maxChildSize.Width + paddingWidth;
|
||||
var height = HeightRequest >= 0.0 ? (float)HeightRequest : (float)maxChildSize.Height + paddingHeight;
|
||||
|
||||
return new SKSize(width, height);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
var contentBounds = GetContentBounds(bounds);
|
||||
var contentBounds = GetContentBounds(new SKRect((float)bounds.Left, (float)bounds.Top, (float)bounds.Right, (float)bounds.Bottom));
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
// Apply child's margin
|
||||
var margin = child.Margin;
|
||||
var marginedBounds = new SKRect(
|
||||
contentBounds.Left + (float)margin.Left,
|
||||
contentBounds.Top + (float)margin.Top,
|
||||
contentBounds.Right - (float)margin.Right,
|
||||
contentBounds.Bottom - (float)margin.Bottom);
|
||||
var marginedBounds = new Rect(
|
||||
contentBounds.Left + margin.Left,
|
||||
contentBounds.Top + margin.Top,
|
||||
contentBounds.Width - margin.Left - margin.Right,
|
||||
contentBounds.Height - margin.Top - margin.Bottom);
|
||||
child.Arrange(marginedBounds);
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ public class SkiaBorder : SkiaLayoutView
|
||||
if (IsVisible && IsEnabled)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
if (bounds.Contains(new SKPoint(x, y)))
|
||||
if (bounds.Contains(x, y))
|
||||
{
|
||||
if (HasTapGestureRecognizers())
|
||||
{
|
||||
|
||||
@@ -103,19 +103,19 @@ public class SkiaBoxView : SkiaView
|
||||
|
||||
#region Measurement
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// BoxView uses explicit size or a default size when in unbounded context
|
||||
var width = WidthRequest >= 0 ? (float)WidthRequest :
|
||||
(float.IsInfinity(availableSize.Width) ? 40f : availableSize.Width);
|
||||
var height = HeightRequest >= 0 ? (float)HeightRequest :
|
||||
(float.IsInfinity(availableSize.Height) ? 40f : availableSize.Height);
|
||||
var width = WidthRequest >= 0 ? WidthRequest :
|
||||
(double.IsInfinity(availableSize.Width) ? 40.0 : availableSize.Width);
|
||||
var height = HeightRequest >= 0 ? HeightRequest :
|
||||
(double.IsInfinity(availableSize.Height) ? 40.0 : availableSize.Height);
|
||||
|
||||
// Ensure no NaN values
|
||||
if (float.IsNaN(width)) width = 40f;
|
||||
if (float.IsNaN(height)) height = 40f;
|
||||
if (double.IsNaN(width)) width = 40.0;
|
||||
if (double.IsNaN(height)) height = 40.0;
|
||||
|
||||
return new SKSize(width, height);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -940,7 +940,7 @@ public class SkiaButton : SkiaView, IButtonController
|
||||
|
||||
#region Measurement
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var padding = Padding;
|
||||
float paddingH = (float)(padding.Left + padding.Right);
|
||||
@@ -1037,7 +1037,7 @@ public class SkiaButton : SkiaView, IButtonController
|
||||
height = (float)HeightRequest;
|
||||
}
|
||||
|
||||
return new SKSize(Math.Max(width, 44f), Math.Max(height, 30f));
|
||||
return new Size(Math.Max(width, 44f), Math.Max(height, 30f));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -204,39 +204,39 @@ public class SkiaCarouselView : SkiaLayoutView
|
||||
|
||||
private float GetOffsetForPosition(int position)
|
||||
{
|
||||
float itemWidth = Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
float itemWidth = (float)Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
return position * (itemWidth + (float)ItemSpacing);
|
||||
}
|
||||
|
||||
private int GetPositionForOffset(float offset)
|
||||
{
|
||||
float itemWidth = Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
float itemWidth = (float)Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
if (itemWidth <= 0) return 0;
|
||||
return Math.Clamp((int)Math.Round(offset / (itemWidth + (float)ItemSpacing)), 0, Math.Max(0, _items.Count - 1));
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
float itemWidth = availableSize.Width - (float)PeekAreaInsets * 2;
|
||||
float itemHeight = availableSize.Height - (ShowIndicators ? 30 : 0);
|
||||
float itemWidth = (float)availableSize.Width - (float)PeekAreaInsets * 2;
|
||||
float itemHeight = (float)availableSize.Height - (ShowIndicators ? 30 : 0);
|
||||
|
||||
foreach (var item in _items)
|
||||
{
|
||||
item.Measure(new SKSize(itemWidth, itemHeight));
|
||||
item.Measure(new Size(itemWidth, itemHeight));
|
||||
}
|
||||
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
float itemWidth = bounds.Width - (float)PeekAreaInsets * 2;
|
||||
float itemHeight = bounds.Height - (ShowIndicators ? 30 : 0);
|
||||
float itemWidth = (float)bounds.Width - (float)PeekAreaInsets * 2;
|
||||
float itemHeight = (float)bounds.Height - (ShowIndicators ? 30 : 0);
|
||||
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
float x = bounds.Left + (float)PeekAreaInsets + i * (itemWidth + (float)ItemSpacing) - _scrollOffset;
|
||||
var itemBounds = new SKRect(x, bounds.Top, x + itemWidth, bounds.Top + itemHeight);
|
||||
float x = (float)bounds.Left + (float)PeekAreaInsets + i * (itemWidth + (float)ItemSpacing) - _scrollOffset;
|
||||
var itemBounds = new Rect(x, bounds.Top, itemWidth, itemHeight);
|
||||
_items[i].Arrange(itemBounds);
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ public class SkiaCarouselView : SkiaLayoutView
|
||||
_isDragging = false;
|
||||
|
||||
// Determine target position based on velocity and position
|
||||
float itemWidth = Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
float itemWidth = (float)Bounds.Width - (float)PeekAreaInsets * 2;
|
||||
int targetPosition = GetPositionForOffset(_scrollOffset);
|
||||
|
||||
// Apply velocity influence
|
||||
|
||||
@@ -431,10 +431,10 @@ public class SkiaCheckBox : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var boxSize = (float)BoxSize;
|
||||
return new SKSize(boxSize + 8f, boxSize + 8f);
|
||||
var boxSize = BoxSize;
|
||||
return new Size(boxSize + 8.0, boxSize + 8.0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -420,10 +420,10 @@ public class SkiaCollectionView : SkiaItemsView
|
||||
{
|
||||
try
|
||||
{
|
||||
var availableSize = new SKSize(bounds.Width, float.MaxValue);
|
||||
var availableSize = new Size(bounds.Width, float.MaxValue);
|
||||
var measuredSize = itemView.Measure(availableSize);
|
||||
|
||||
var rawHeight = measuredSize.Height;
|
||||
var rawHeight = (float)measuredSize.Height;
|
||||
if (float.IsNaN(rawHeight) || float.IsInfinity(rawHeight) || rawHeight > 10000f)
|
||||
{
|
||||
rawHeight = ItemHeight;
|
||||
@@ -437,7 +437,7 @@ public class SkiaCollectionView : SkiaItemsView
|
||||
}
|
||||
|
||||
var actualBounds = new SKRect(bounds.Left, bounds.Top, bounds.Right, bounds.Top + measuredHeight);
|
||||
itemView.Arrange(actualBounds);
|
||||
itemView.Arrange(new Rect(actualBounds.Left, actualBounds.Top, actualBounds.Width, actualBounds.Height));
|
||||
itemView.Draw(canvas);
|
||||
|
||||
if (isSelected)
|
||||
|
||||
@@ -125,42 +125,42 @@ public class SkiaContentPresenter : SkiaView
|
||||
Content?.Draw(canvas);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var padding = Padding;
|
||||
var paddingLeft = (float)padding.Left;
|
||||
var paddingTop = (float)padding.Top;
|
||||
var paddingRight = (float)padding.Right;
|
||||
var paddingBottom = (float)padding.Bottom;
|
||||
var paddingLeft = padding.Left;
|
||||
var paddingTop = padding.Top;
|
||||
var paddingRight = padding.Right;
|
||||
var paddingBottom = padding.Bottom;
|
||||
|
||||
if (Content == null)
|
||||
return new SKSize(paddingLeft + paddingRight, paddingTop + paddingBottom);
|
||||
return new Size(paddingLeft + paddingRight, paddingTop + paddingBottom);
|
||||
|
||||
// When alignment is not Fill, give content unlimited size in that dimension
|
||||
// so it can measure its natural size without truncation
|
||||
var measureWidth = HorizontalContentAlignment == LayoutAlignment.Fill
|
||||
? Math.Max(0, availableSize.Width - paddingLeft - paddingRight)
|
||||
? (float)Math.Max(0, availableSize.Width - paddingLeft - paddingRight)
|
||||
: float.PositiveInfinity;
|
||||
var measureHeight = VerticalContentAlignment == LayoutAlignment.Fill
|
||||
? Math.Max(0, availableSize.Height - paddingTop - paddingBottom)
|
||||
? (float)Math.Max(0, availableSize.Height - paddingTop - paddingBottom)
|
||||
: float.PositiveInfinity;
|
||||
|
||||
var contentSize = Content.Measure(new SKSize(measureWidth, measureHeight));
|
||||
return new SKSize(
|
||||
var contentSize = Content.Measure(new Size(measureWidth, measureHeight));
|
||||
return new Size(
|
||||
contentSize.Width + paddingLeft + paddingRight,
|
||||
contentSize.Height + paddingTop + paddingBottom);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
if (Content != null)
|
||||
{
|
||||
var padding = Padding;
|
||||
var contentBounds = new SKRect(
|
||||
bounds.Left + (float)padding.Left,
|
||||
bounds.Top + (float)padding.Top,
|
||||
bounds.Right - (float)padding.Right,
|
||||
bounds.Bottom - (float)padding.Bottom);
|
||||
var contentBounds = new Rect(
|
||||
bounds.Left + padding.Left,
|
||||
bounds.Top + padding.Top,
|
||||
bounds.Width - padding.Left - padding.Right,
|
||||
bounds.Height - padding.Top - padding.Bottom);
|
||||
|
||||
// Apply alignment
|
||||
var contentSize = Content.DesiredSize;
|
||||
@@ -171,12 +171,12 @@ public class SkiaContentPresenter : SkiaView
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private static SKRect ApplyAlignment(SKRect availableBounds, SKSize contentSize, LayoutAlignment horizontal, LayoutAlignment vertical)
|
||||
private static Rect ApplyAlignment(Rect availableBounds, Size contentSize, LayoutAlignment horizontal, LayoutAlignment vertical)
|
||||
{
|
||||
float x = availableBounds.Left;
|
||||
float y = availableBounds.Top;
|
||||
float width = horizontal == LayoutAlignment.Fill ? availableBounds.Width : contentSize.Width;
|
||||
float height = vertical == LayoutAlignment.Fill ? availableBounds.Height : contentSize.Height;
|
||||
double x = availableBounds.Left;
|
||||
double y = availableBounds.Top;
|
||||
double width = horizontal == LayoutAlignment.Fill ? availableBounds.Width : contentSize.Width;
|
||||
double height = vertical == LayoutAlignment.Fill ? availableBounds.Height : contentSize.Height;
|
||||
|
||||
// Horizontal alignment
|
||||
switch (horizontal)
|
||||
@@ -200,7 +200,7 @@ public class SkiaContentPresenter : SkiaView
|
||||
break;
|
||||
}
|
||||
|
||||
return new SKRect(x, y, x + width, y + height);
|
||||
return new Rect(x, y, width, height);
|
||||
}
|
||||
|
||||
public override SkiaView? HitTest(float x, float y)
|
||||
|
||||
@@ -299,7 +299,8 @@ public class SkiaDatePicker : SkiaView
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
DrawCalendar(canvas, ScreenBounds);
|
||||
var skScreenBounds = new SKRect((float)ScreenBounds.Left, (float)ScreenBounds.Top, (float)(ScreenBounds.Left + ScreenBounds.Width), (float)(ScreenBounds.Top + ScreenBounds.Height));
|
||||
DrawCalendar(canvas, skScreenBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,7 +580,7 @@ public class SkiaDatePicker : SkiaView
|
||||
|
||||
if (IsOpen)
|
||||
{
|
||||
SKRect screenBounds = ScreenBounds;
|
||||
SKRect screenBounds = new SKRect((float)ScreenBounds.Left, (float)ScreenBounds.Top, (float)(ScreenBounds.Left + ScreenBounds.Width), (float)(ScreenBounds.Top + ScreenBounds.Height));
|
||||
SKRect calendarRect = GetCalendarRect(screenBounds);
|
||||
|
||||
SKRect headerRect = new SKRect(calendarRect.Left, calendarRect.Top, calendarRect.Right, calendarRect.Top + 48f);
|
||||
@@ -680,14 +681,14 @@ public class SkiaDatePicker : SkiaView
|
||||
}
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return new SKSize(availableSize.Width < float.MaxValue ? Math.Min(availableSize.Width, 200f) : 200f, 40f);
|
||||
return new Size(availableSize.Width < double.MaxValue ? Math.Min(availableSize.Width, 200.0) : 200.0, 40.0);
|
||||
}
|
||||
|
||||
protected override bool HitTestPopupArea(float x, float y)
|
||||
{
|
||||
SKRect screenBounds = ScreenBounds;
|
||||
SKRect screenBounds = new SKRect((float)ScreenBounds.Left, (float)ScreenBounds.Top, (float)(ScreenBounds.Left + ScreenBounds.Width), (float)(ScreenBounds.Top + ScreenBounds.Height));
|
||||
if (screenBounds.Contains(x, y))
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -1075,9 +1075,9 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
{
|
||||
_scrollOffsetY = cursorY;
|
||||
}
|
||||
else if (cursorY + lineSpacing > _scrollOffsetY + viewHeight)
|
||||
else if (cursorY + lineSpacing > _scrollOffsetY + (float)viewHeight)
|
||||
{
|
||||
_scrollOffsetY = cursorY + lineSpacing - viewHeight;
|
||||
_scrollOffsetY = cursorY + lineSpacing - (float)viewHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,7 +1377,7 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
var lineHeight = (float)LineHeight;
|
||||
var lineSpacing = fontSize * lineHeight;
|
||||
var totalHeight = _lines.Count * lineSpacing;
|
||||
var viewHeight = Bounds.Height - (float)(Padding.Top + Padding.Bottom);
|
||||
var viewHeight = (float)Bounds.Height - (float)(Padding.Top + Padding.Bottom);
|
||||
var maxScroll = Math.Max(0, totalHeight - viewHeight);
|
||||
|
||||
_scrollOffsetY = Math.Clamp(_scrollOffsetY - e.DeltaY * 3, 0, maxScroll);
|
||||
@@ -1578,22 +1578,22 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
_inputMethodService.SetCursorLocation(x, y, 2, height);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (AutoSize)
|
||||
{
|
||||
var fontSize = (float)FontSize;
|
||||
var lineHeight = (float)LineHeight;
|
||||
var lineSpacing = fontSize * lineHeight;
|
||||
var verticalPadding = (float)(Padding.Top + Padding.Bottom);
|
||||
var verticalPadding = Padding.Top + Padding.Bottom;
|
||||
var height = Math.Max(lineSpacing + verticalPadding, _lines.Count * lineSpacing + verticalPadding);
|
||||
return new SKSize(
|
||||
availableSize.Width < float.MaxValue ? availableSize.Width : 200,
|
||||
(float)Math.Min(height, availableSize.Height < float.MaxValue ? availableSize.Height : 200));
|
||||
return new Size(
|
||||
availableSize.Width < double.MaxValue ? availableSize.Width : 200,
|
||||
Math.Min(height, availableSize.Height < double.MaxValue ? availableSize.Height : 200));
|
||||
}
|
||||
|
||||
return new SKSize(
|
||||
availableSize.Width < float.MaxValue ? Math.Min(availableSize.Width, 200) : 200,
|
||||
availableSize.Height < float.MaxValue ? Math.Min(availableSize.Height, 150) : 150);
|
||||
return new Size(
|
||||
availableSize.Width < double.MaxValue ? Math.Min(availableSize.Width, 200) : 200,
|
||||
availableSize.Height < double.MaxValue ? Math.Min(availableSize.Height, 150) : 150);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1367,8 +1367,8 @@ public class SkiaEntry : SkiaView, IInputContext
|
||||
{
|
||||
var clearButtonSize = 20f;
|
||||
var clearButtonMargin = 8f;
|
||||
var clearCenterX = Bounds.Right - clearButtonMargin - clearButtonSize / 2;
|
||||
var clearCenterY = Bounds.MidY;
|
||||
var clearCenterX = (float)(Bounds.Left + Bounds.Width) - clearButtonMargin - clearButtonSize / 2;
|
||||
var clearCenterY = (float)(Bounds.Top + Bounds.Height / 2);
|
||||
|
||||
var dx = e.X - clearCenterX;
|
||||
var dy = e.Y - clearCenterY;
|
||||
@@ -1385,7 +1385,7 @@ public class SkiaEntry : SkiaView, IInputContext
|
||||
|
||||
// Calculate cursor position from click using screen coordinates
|
||||
var screenBounds = ScreenBounds;
|
||||
var clickX = e.X - screenBounds.Left - (float)Padding.Left + _scrollOffset;
|
||||
var clickX = e.X - (float)screenBounds.Left - (float)Padding.Left + _scrollOffset;
|
||||
_cursorPosition = GetCharacterIndexAtX(clickX);
|
||||
|
||||
// Check for double-click (select word)
|
||||
@@ -1446,7 +1446,7 @@ public class SkiaEntry : SkiaView, IInputContext
|
||||
|
||||
// Extend selection to current mouse position
|
||||
var screenBounds = ScreenBounds;
|
||||
var clickX = e.X - screenBounds.Left - (float)Padding.Left + _scrollOffset;
|
||||
var clickX = e.X - (float)screenBounds.Left - (float)Padding.Left + _scrollOffset;
|
||||
var newPosition = GetCharacterIndexAtX(clickX);
|
||||
|
||||
if (newPosition != _cursorPosition)
|
||||
@@ -1675,7 +1675,7 @@ public class SkiaEntry : SkiaView, IInputContext
|
||||
_inputMethodService.SetCursorLocation(x, y, 2, height);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var fontStyle = GetFontStyle();
|
||||
var typeface = SkiaRenderingEngine.Current?.ResourceCache.GetTypeface(GetEffectiveFontFamily(), fontStyle)
|
||||
@@ -1688,9 +1688,9 @@ public class SkiaEntry : SkiaView, IInputContext
|
||||
var metrics = font.Metrics;
|
||||
var textHeight = metrics.Descent - metrics.Ascent + metrics.Leading;
|
||||
|
||||
return new SKSize(
|
||||
return new Size(
|
||||
200, // Default width, will be overridden by layout
|
||||
textHeight + (float)Padding.Top + (float)Padding.Bottom + (float)BorderWidth * 2);
|
||||
textHeight + Padding.Top + Padding.Bottom + BorderWidth * 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,34 +88,36 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
public static FlexAlignSelf GetAlignSelf(SkiaView view) => (FlexAlignSelf)view.GetValue(AlignSelfProperty);
|
||||
public static void SetAlignSelf(SkiaView view, FlexAlignSelf value) => view.SetValue(AlignSelfProperty, value);
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
bool isRow = Direction == FlexDirection.Row || Direction == FlexDirection.RowReverse;
|
||||
float totalMain = 0f;
|
||||
float maxCross = 0f;
|
||||
|
||||
var sizeAvailable = new Size(availableSize.Width, availableSize.Height);
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
if (!child.IsVisible)
|
||||
continue;
|
||||
|
||||
var childSize = child.Measure(availableSize);
|
||||
var childSize = child.Measure(sizeAvailable);
|
||||
if (isRow)
|
||||
{
|
||||
totalMain += childSize.Width;
|
||||
maxCross = Math.Max(maxCross, childSize.Height);
|
||||
totalMain += (float)childSize.Width;
|
||||
maxCross = Math.Max(maxCross, (float)childSize.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalMain += childSize.Height;
|
||||
maxCross = Math.Max(maxCross, childSize.Width);
|
||||
totalMain += (float)childSize.Height;
|
||||
maxCross = Math.Max(maxCross, (float)childSize.Width);
|
||||
}
|
||||
}
|
||||
|
||||
return isRow ? new SKSize(totalMain, maxCross) : new SKSize(maxCross, totalMain);
|
||||
return isRow ? new Size(totalMain, maxCross) : new Size(maxCross, totalMain);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
if (Children.Count == 0)
|
||||
return bounds;
|
||||
@@ -127,10 +129,10 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
if (orderedChildren.Count == 0)
|
||||
return bounds;
|
||||
|
||||
float mainSize = isRow ? bounds.Width : bounds.Height;
|
||||
float crossSize = isRow ? bounds.Height : bounds.Width;
|
||||
float mainSize = isRow ? (float)bounds.Width : (float)bounds.Height;
|
||||
float crossSize = isRow ? (float)bounds.Height : (float)bounds.Width;
|
||||
|
||||
var childInfos = new List<(SkiaView child, SKSize size, float grow, float shrink)>();
|
||||
var childInfos = new List<(SkiaView child, Size size, float grow, float shrink)>();
|
||||
float totalBasis = 0f;
|
||||
float totalGrow = 0f;
|
||||
float totalShrink = 0f;
|
||||
@@ -141,21 +143,21 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
float grow = GetGrow(child);
|
||||
float shrink = GetShrink(child);
|
||||
|
||||
SKSize size;
|
||||
Size size;
|
||||
if (basis.IsAuto)
|
||||
{
|
||||
size = child.Measure(new SKSize(bounds.Width, bounds.Height));
|
||||
size = child.Measure(new Size(bounds.Width, bounds.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
float length = basis.Length;
|
||||
size = isRow
|
||||
? child.Measure(new SKSize(length, bounds.Height))
|
||||
: child.Measure(new SKSize(bounds.Width, length));
|
||||
? child.Measure(new Size(length, bounds.Height))
|
||||
: child.Measure(new Size(bounds.Width, length));
|
||||
}
|
||||
|
||||
childInfos.Add((child, size, grow, shrink));
|
||||
totalBasis += isRow ? size.Width : size.Height;
|
||||
totalBasis += isRow ? (float)size.Width : (float)size.Height;
|
||||
totalGrow += grow;
|
||||
totalShrink += shrink;
|
||||
}
|
||||
@@ -165,8 +167,8 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
var resolvedSizes = new List<(SkiaView child, float mainSize, float crossSize)>();
|
||||
foreach (var (child, size, grow, shrink) in childInfos)
|
||||
{
|
||||
float childMainSize = isRow ? size.Width : size.Height;
|
||||
float childCrossSize = isRow ? size.Height : size.Width;
|
||||
float childMainSize = isRow ? (float)size.Width : (float)size.Height;
|
||||
float childCrossSize = isRow ? (float)size.Height : (float)size.Width;
|
||||
|
||||
if (freeSpace > 0f && totalGrow > 0f)
|
||||
{
|
||||
@@ -183,7 +185,7 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
float usedSpace = resolvedSizes.Sum(s => s.mainSize);
|
||||
float remainingSpace = Math.Max(0f, mainSize - usedSpace);
|
||||
|
||||
float position = isRow ? bounds.Left : bounds.Top;
|
||||
float position = isRow ? (float)bounds.Left : (float)bounds.Top;
|
||||
float spacing = 0f;
|
||||
|
||||
switch (JustifyContent)
|
||||
@@ -221,13 +223,13 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
var alignSelf = GetAlignSelf(child);
|
||||
var effectiveAlign = alignSelf == FlexAlignSelf.Auto ? AlignItems : (FlexAlignItems)alignSelf;
|
||||
|
||||
float crossPos = isRow ? bounds.Top : bounds.Left;
|
||||
float crossPos = isRow ? (float)bounds.Top : (float)bounds.Left;
|
||||
float finalCrossSize = childCrossSize;
|
||||
|
||||
switch (effectiveAlign)
|
||||
{
|
||||
case FlexAlignItems.End:
|
||||
crossPos = (isRow ? bounds.Bottom : bounds.Right) - finalCrossSize;
|
||||
crossPos = (isRow ? (float)bounds.Bottom : (float)bounds.Right) - finalCrossSize;
|
||||
break;
|
||||
case FlexAlignItems.Center:
|
||||
crossPos += (crossSize - finalCrossSize) / 2f;
|
||||
@@ -237,14 +239,14 @@ public class SkiaFlexLayout : SkiaLayoutView
|
||||
break;
|
||||
}
|
||||
|
||||
SKRect childBounds;
|
||||
Rect childBounds;
|
||||
if (isRow)
|
||||
{
|
||||
childBounds = new SKRect(position, crossPos, position + childMainSize, crossPos + finalCrossSize);
|
||||
childBounds = new Rect(position, crossPos, childMainSize, finalCrossSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
childBounds = new SKRect(crossPos, position, crossPos + finalCrossSize, position + childMainSize);
|
||||
childBounds = new Rect(crossPos, position, finalCrossSize, childMainSize);
|
||||
}
|
||||
|
||||
child.Arrange(childBounds);
|
||||
|
||||
@@ -154,40 +154,36 @@ public class SkiaFlyoutPage : SkiaLayoutView
|
||||
/// </summary>
|
||||
public event EventHandler? IsPresentedChanged;
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Measure flyout
|
||||
if (_flyout != null)
|
||||
{
|
||||
_flyout.Measure(new SKSize(FlyoutWidth, availableSize.Height));
|
||||
_flyout.Measure(new Size(FlyoutWidth, availableSize.Height));
|
||||
}
|
||||
|
||||
// Measure detail to full size
|
||||
if (_detail != null)
|
||||
{
|
||||
_detail.Measure(availableSize);
|
||||
_detail.Measure(new Size(availableSize.Width, availableSize.Height));
|
||||
}
|
||||
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
// Arrange detail to fill the entire area
|
||||
if (_detail != null)
|
||||
{
|
||||
_detail.Arrange(bounds);
|
||||
_detail.Arrange(new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height));
|
||||
}
|
||||
|
||||
// Arrange flyout (positioned based on animation progress)
|
||||
if (_flyout != null)
|
||||
{
|
||||
float flyoutX = bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(
|
||||
flyoutX,
|
||||
bounds.Top,
|
||||
flyoutX + FlyoutWidth,
|
||||
bounds.Bottom);
|
||||
float flyoutX = (float)bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new Rect(flyoutX, bounds.Top, FlyoutWidth, bounds.Height);
|
||||
_flyout.Arrange(flyoutBounds);
|
||||
}
|
||||
|
||||
@@ -211,7 +207,8 @@ public class SkiaFlyoutPage : SkiaLayoutView
|
||||
Color = _scrimColorSK.WithAlpha((byte)(_scrimColorSK.Alpha * _flyoutAnimationProgress)),
|
||||
Style = SKPaintStyle.Fill
|
||||
};
|
||||
canvas.DrawRect(Bounds, scrimPaint);
|
||||
var skBounds = new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
canvas.DrawRect(skBounds, scrimPaint);
|
||||
|
||||
// Draw flyout shadow
|
||||
if (_flyout != null && ShadowWidth > 0)
|
||||
@@ -230,12 +227,12 @@ public class SkiaFlyoutPage : SkiaLayoutView
|
||||
{
|
||||
if (_flyout == null) return;
|
||||
|
||||
float shadowRight = _flyout.Bounds.Right;
|
||||
float shadowRight = (float)(_flyout.Bounds.Left + _flyout.Bounds.Width);
|
||||
var shadowRect = new SKRect(
|
||||
shadowRight,
|
||||
Bounds.Top,
|
||||
(float)Bounds.Top,
|
||||
shadowRight + ShadowWidth,
|
||||
Bounds.Bottom);
|
||||
(float)(Bounds.Top + Bounds.Height));
|
||||
|
||||
using var shadowPaint = new SKPaint
|
||||
{
|
||||
|
||||
@@ -49,17 +49,17 @@ public class SkiaGraphicsView : SkiaView
|
||||
}
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Graphics view takes all available space by default
|
||||
if (availableSize.Width < float.MaxValue && availableSize.Height < float.MaxValue)
|
||||
if (availableSize.Width < double.MaxValue && availableSize.Height < double.MaxValue)
|
||||
{
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
// Return a reasonable default size
|
||||
return new SKSize(
|
||||
availableSize.Width < float.MaxValue ? availableSize.Width : 100,
|
||||
availableSize.Height < float.MaxValue ? availableSize.Height : 100);
|
||||
return new Size(
|
||||
availableSize.Width < double.MaxValue ? availableSize.Width : 100,
|
||||
availableSize.Height < double.MaxValue ? availableSize.Height : 100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,7 +1028,7 @@ public class SkiaImage : SkiaView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
public override void Arrange(SKRect bounds)
|
||||
public override void Arrange(Rect bounds)
|
||||
{
|
||||
base.Arrange(bounds);
|
||||
|
||||
@@ -1037,21 +1037,21 @@ public class SkiaImage : SkiaView
|
||||
{
|
||||
if (_isSvg && !string.IsNullOrEmpty(_currentFilePath) && !_isLoading)
|
||||
{
|
||||
float width = bounds.Width;
|
||||
float height = bounds.Height;
|
||||
float width = (float)bounds.Width;
|
||||
float height = (float)bounds.Height;
|
||||
|
||||
if ((width > _svgLoadedWidth * 1.1 || height > _svgLoadedHeight * 1.1) &&
|
||||
width > 0f && height > 0f &&
|
||||
(width != _lastArrangedBounds.Width || height != _lastArrangedBounds.Height))
|
||||
{
|
||||
_lastArrangedBounds = bounds;
|
||||
_lastArrangedBounds = new SKRect((float)bounds.Left, (float)bounds.Top, (float)bounds.Right, (float)bounds.Bottom);
|
||||
_ = LoadSvgAtSizeAsync(_currentFilePath, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
var desiredWidth = DesiredSize.Width;
|
||||
var desiredHeight = DesiredSize.Height;
|
||||
@@ -1059,38 +1059,38 @@ public class SkiaImage : SkiaView
|
||||
if (desiredWidth > 0 && desiredHeight > 0 &&
|
||||
(desiredWidth < bounds.Width || desiredHeight < bounds.Height))
|
||||
{
|
||||
float finalWidth = Math.Min(desiredWidth, bounds.Width);
|
||||
float finalHeight = Math.Min(desiredHeight, bounds.Height);
|
||||
double finalWidth = Math.Min(desiredWidth, bounds.Width);
|
||||
double finalHeight = Math.Min(desiredHeight, bounds.Height);
|
||||
|
||||
float x = bounds.Left;
|
||||
double x = bounds.Left;
|
||||
var hAlignValue = (int)HorizontalOptions.Alignment;
|
||||
if (hAlignValue == 1) x = bounds.Left + (bounds.Width - finalWidth) / 2;
|
||||
else if (hAlignValue == 2) x = bounds.Right - finalWidth;
|
||||
|
||||
float y = bounds.Top;
|
||||
double y = bounds.Top;
|
||||
var vAlignValue = (int)VerticalOptions.Alignment;
|
||||
if (vAlignValue == 1) y = bounds.Top + (bounds.Height - finalHeight) / 2;
|
||||
else if (vAlignValue == 2) y = bounds.Bottom - finalHeight;
|
||||
|
||||
return new SKRect(x, y, x + finalWidth, y + finalHeight);
|
||||
return new Rect(x, y, finalWidth, finalHeight);
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
double widthRequest = base.WidthRequest;
|
||||
double heightRequest = base.HeightRequest;
|
||||
|
||||
if (widthRequest > 0.0 && heightRequest > 0.0)
|
||||
return new SKSize((float)widthRequest, (float)heightRequest);
|
||||
return new Size(widthRequest, heightRequest);
|
||||
|
||||
if (_image == null)
|
||||
{
|
||||
if (widthRequest > 0.0) return new SKSize((float)widthRequest, (float)widthRequest);
|
||||
if (heightRequest > 0.0) return new SKSize((float)heightRequest, (float)heightRequest);
|
||||
return new SKSize(100f, 100f);
|
||||
if (widthRequest > 0.0) return new Size(widthRequest, widthRequest);
|
||||
if (heightRequest > 0.0) return new Size(heightRequest, heightRequest);
|
||||
return new Size(100.0, 100.0);
|
||||
}
|
||||
|
||||
float imageWidth = _image.Width;
|
||||
@@ -1098,35 +1098,35 @@ public class SkiaImage : SkiaView
|
||||
|
||||
if (widthRequest > 0.0)
|
||||
{
|
||||
float scale = (float)widthRequest / imageWidth;
|
||||
return new SKSize((float)widthRequest, imageHeight * scale);
|
||||
double scale = widthRequest / imageWidth;
|
||||
return new Size(widthRequest, imageHeight * scale);
|
||||
}
|
||||
|
||||
if (heightRequest > 0.0)
|
||||
{
|
||||
float scale = (float)heightRequest / imageHeight;
|
||||
return new SKSize(imageWidth * scale, (float)heightRequest);
|
||||
double scale = heightRequest / imageHeight;
|
||||
return new Size(imageWidth * scale, heightRequest);
|
||||
}
|
||||
|
||||
if (availableSize.Width < float.MaxValue && availableSize.Height < float.MaxValue)
|
||||
if (availableSize.Width < double.MaxValue && availableSize.Height < double.MaxValue)
|
||||
{
|
||||
float scale = Math.Min(availableSize.Width / imageWidth, availableSize.Height / imageHeight);
|
||||
return new SKSize(imageWidth * scale, imageHeight * scale);
|
||||
double scale = Math.Min(availableSize.Width / imageWidth, availableSize.Height / imageHeight);
|
||||
return new Size(imageWidth * scale, imageHeight * scale);
|
||||
}
|
||||
|
||||
if (availableSize.Width < float.MaxValue)
|
||||
if (availableSize.Width < double.MaxValue)
|
||||
{
|
||||
float scale = availableSize.Width / imageWidth;
|
||||
return new SKSize(availableSize.Width, imageHeight * scale);
|
||||
double scale = availableSize.Width / imageWidth;
|
||||
return new Size(availableSize.Width, imageHeight * scale);
|
||||
}
|
||||
|
||||
if (availableSize.Height < float.MaxValue)
|
||||
if (availableSize.Height < double.MaxValue)
|
||||
{
|
||||
float scale = availableSize.Height / imageHeight;
|
||||
return new SKSize(imageWidth * scale, availableSize.Height);
|
||||
double scale = availableSize.Height / imageHeight;
|
||||
return new Size(imageWidth * scale, availableSize.Height);
|
||||
}
|
||||
|
||||
return new SKSize(imageWidth, imageHeight);
|
||||
return new Size(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -641,7 +641,7 @@ public class SkiaImageButton : SkiaView
|
||||
|
||||
Released?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
if (wasPressed && Bounds.Contains(new SKPoint(e.X, e.Y)))
|
||||
if (wasPressed && Bounds.Contains(e.X, e.Y))
|
||||
{
|
||||
Clicked?.Invoke(this, EventArgs.Empty);
|
||||
ExecuteCommand();
|
||||
@@ -687,66 +687,65 @@ public class SkiaImageButton : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var padding = Padding;
|
||||
var paddingWidth = (float)(padding.Left + padding.Right);
|
||||
var paddingHeight = (float)(padding.Top + padding.Bottom);
|
||||
var paddingWidth = padding.Left + padding.Right;
|
||||
var paddingHeight = padding.Top + padding.Bottom;
|
||||
|
||||
// Respect explicit WidthRequest/HeightRequest first (MAUI standard behavior)
|
||||
if (WidthRequest > 0 && HeightRequest > 0)
|
||||
{
|
||||
return new SKSize((float)WidthRequest, (float)HeightRequest);
|
||||
return new Size(WidthRequest, HeightRequest);
|
||||
}
|
||||
if (WidthRequest > 0)
|
||||
{
|
||||
// Fixed width, calculate height from aspect ratio or use width
|
||||
float height = HeightRequest > 0 ? (float)HeightRequest
|
||||
: _image != null ? (float)WidthRequest * _image.Height / _image.Width
|
||||
: (float)WidthRequest;
|
||||
return new SKSize((float)WidthRequest, height);
|
||||
double height = HeightRequest > 0 ? HeightRequest
|
||||
: _image != null ? WidthRequest * _image.Height / _image.Width
|
||||
: WidthRequest;
|
||||
return new Size(WidthRequest, height);
|
||||
}
|
||||
if (HeightRequest > 0)
|
||||
{
|
||||
// Fixed height, calculate width from aspect ratio or use height
|
||||
float width = WidthRequest > 0 ? (float)WidthRequest
|
||||
: _image != null ? (float)HeightRequest * _image.Width / _image.Height
|
||||
: (float)HeightRequest;
|
||||
return new SKSize(width, (float)HeightRequest);
|
||||
double width = WidthRequest > 0 ? WidthRequest
|
||||
: _image != null ? HeightRequest * _image.Width / _image.Height
|
||||
: HeightRequest;
|
||||
return new Size(width, HeightRequest);
|
||||
}
|
||||
|
||||
// No explicit size - calculate from content
|
||||
if (_image == null)
|
||||
return new SKSize(44 + paddingWidth, 44 + paddingHeight); // Default touch target size
|
||||
return new Size(44 + paddingWidth, 44 + paddingHeight); // Default touch target size
|
||||
|
||||
var imageWidth = _image.Width;
|
||||
var imageHeight = _image.Height;
|
||||
|
||||
if (availableSize.Width < float.MaxValue && availableSize.Height < float.MaxValue)
|
||||
if (availableSize.Width < double.MaxValue && availableSize.Height < double.MaxValue)
|
||||
{
|
||||
var availableContent = new SKSize(
|
||||
availableSize.Width - paddingWidth,
|
||||
availableSize.Height - paddingHeight);
|
||||
var scale = Math.Min(availableContent.Width / imageWidth, availableContent.Height / imageHeight);
|
||||
return new SKSize(imageWidth * scale + paddingWidth, imageHeight * scale + paddingHeight);
|
||||
var availableContentW = availableSize.Width - paddingWidth;
|
||||
var availableContentH = availableSize.Height - paddingHeight;
|
||||
var scale = Math.Min(availableContentW / imageWidth, availableContentH / imageHeight);
|
||||
return new Size(imageWidth * scale + paddingWidth, imageHeight * scale + paddingHeight);
|
||||
}
|
||||
else if (availableSize.Width < float.MaxValue)
|
||||
else if (availableSize.Width < double.MaxValue)
|
||||
{
|
||||
var availableWidth = availableSize.Width - paddingWidth;
|
||||
var scale = availableWidth / imageWidth;
|
||||
return new SKSize(availableSize.Width, imageHeight * scale + paddingHeight);
|
||||
return new Size(availableSize.Width, imageHeight * scale + paddingHeight);
|
||||
}
|
||||
else if (availableSize.Height < float.MaxValue)
|
||||
else if (availableSize.Height < double.MaxValue)
|
||||
{
|
||||
var availableHeight = availableSize.Height - paddingHeight;
|
||||
var scale = availableHeight / imageHeight;
|
||||
return new SKSize(imageWidth * scale + paddingWidth, availableSize.Height);
|
||||
return new Size(imageWidth * scale + paddingWidth, availableSize.Height);
|
||||
}
|
||||
|
||||
return new SKSize(imageWidth + paddingWidth, imageHeight + paddingHeight);
|
||||
return new Size(imageWidth + paddingWidth, imageHeight + paddingHeight);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
// If we have explicit size requests, constrain to desired size
|
||||
// This follows MAUI standard behavior - controls respect WidthRequest/HeightRequest
|
||||
@@ -757,12 +756,12 @@ public class SkiaImageButton : SkiaView
|
||||
if (desiredWidth > 0 && desiredHeight > 0 &&
|
||||
(desiredWidth < bounds.Width || desiredHeight < bounds.Height))
|
||||
{
|
||||
float finalWidth = Math.Min(desiredWidth, bounds.Width);
|
||||
float finalHeight = Math.Min(desiredHeight, bounds.Height);
|
||||
double finalWidth = Math.Min(desiredWidth, bounds.Width);
|
||||
double finalHeight = Math.Min(desiredHeight, bounds.Height);
|
||||
|
||||
// Calculate position based on HorizontalOptions
|
||||
// LayoutAlignment: Start=0, Center=1, End=2, Fill=3
|
||||
float x = bounds.Left;
|
||||
double x = bounds.Left;
|
||||
var hAlignValue = (int)HorizontalOptions.Alignment;
|
||||
if (hAlignValue == 1) // Center
|
||||
{
|
||||
@@ -775,7 +774,7 @@ public class SkiaImageButton : SkiaView
|
||||
// Fill (3) and Start (0) both use x = bounds.Left
|
||||
|
||||
// Calculate position based on VerticalOptions
|
||||
float y = bounds.Top;
|
||||
double y = bounds.Top;
|
||||
var vAlignValue = (int)VerticalOptions.Alignment;
|
||||
if (vAlignValue == 1) // Center
|
||||
{
|
||||
@@ -787,7 +786,7 @@ public class SkiaImageButton : SkiaView
|
||||
}
|
||||
// Fill (3) and Start (0) both use y = bounds.Top
|
||||
|
||||
return new SKRect(x, y, x + finalWidth, y + finalHeight);
|
||||
return new Rect(x, y, finalWidth, finalHeight);
|
||||
}
|
||||
|
||||
return bounds;
|
||||
|
||||
@@ -145,18 +145,18 @@ public class SkiaIndicatorView : SkiaView
|
||||
/// </summary>
|
||||
public bool HideSingle { get; set; } = true;
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_count <= 0 || (HideSingle && _count <= 1))
|
||||
{
|
||||
return SKSize.Empty;
|
||||
return Size.Zero;
|
||||
}
|
||||
|
||||
int visibleCount = Math.Min(_count, MaximumVisible);
|
||||
float totalWidth = visibleCount * (float)IndicatorSize + (visibleCount - 1) * (float)IndicatorSpacing;
|
||||
float height = Math.Max((float)IndicatorSize, (float)SelectedIndicatorSize);
|
||||
double totalWidth = visibleCount * IndicatorSize + (visibleCount - 1) * IndicatorSpacing;
|
||||
double height = Math.Max(IndicatorSize, SelectedIndicatorSize);
|
||||
|
||||
return new SKSize(totalWidth, height);
|
||||
return new Size(totalWidth, height);
|
||||
}
|
||||
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
@@ -164,12 +164,13 @@ public class SkiaIndicatorView : SkiaView
|
||||
if (_count <= 0 || (HideSingle && _count <= 1)) return;
|
||||
|
||||
canvas.Save();
|
||||
canvas.ClipRect(Bounds);
|
||||
var skBounds = new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
canvas.ClipRect(skBounds);
|
||||
|
||||
int visibleCount = Math.Min(_count, MaximumVisible);
|
||||
float totalWidth = visibleCount * (float)IndicatorSize + (visibleCount - 1) * (float)IndicatorSpacing;
|
||||
float startX = Bounds.MidX - totalWidth / 2 + (float)IndicatorSize / 2;
|
||||
float centerY = Bounds.MidY;
|
||||
float startX = (float)(Bounds.Left + Bounds.Width / 2) - totalWidth / 2 + (float)IndicatorSize / 2;
|
||||
float centerY = (float)(Bounds.Top + Bounds.Height / 2);
|
||||
|
||||
// Determine visible range if count > MaximumVisible
|
||||
int startIndex = 0;
|
||||
@@ -283,7 +284,7 @@ public class SkiaIndicatorView : SkiaView
|
||||
{
|
||||
int visibleCount = Math.Min(_count, MaximumVisible);
|
||||
float totalWidth = visibleCount * (float)IndicatorSize + (visibleCount - 1) * (float)IndicatorSpacing;
|
||||
float startX = Bounds.MidX - totalWidth / 2;
|
||||
float startX = (float)(Bounds.Left + Bounds.Width / 2) - totalWidth / 2;
|
||||
|
||||
int startIndex = 0;
|
||||
if (_count > MaximumVisible)
|
||||
@@ -316,7 +317,7 @@ public class SkiaIndicatorView : SkiaView
|
||||
// Calculate which indicator was clicked
|
||||
int visibleCount = Math.Min(_count, MaximumVisible);
|
||||
float totalWidth = visibleCount * (float)IndicatorSize + (visibleCount - 1) * (float)IndicatorSpacing;
|
||||
float startX = Bounds.MidX - totalWidth / 2;
|
||||
float startX = (float)(Bounds.Left + Bounds.Width / 2) - totalWidth / 2;
|
||||
|
||||
int startIndex = 0;
|
||||
if (_count > MaximumVisible)
|
||||
|
||||
@@ -176,7 +176,7 @@ public class SkiaItemsView : SkiaView
|
||||
}
|
||||
|
||||
// Use ScreenBounds.Height for visible viewport
|
||||
protected float MaxScrollOffset => Math.Max(0, TotalContentHeight - ScreenBounds.Height);
|
||||
protected float MaxScrollOffset => Math.Max(0, TotalContentHeight - (float)ScreenBounds.Height);
|
||||
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
{
|
||||
@@ -284,11 +284,11 @@ public class SkiaItemsView : SkiaView
|
||||
if (itemView != null)
|
||||
{
|
||||
// Measure with large height to get natural size
|
||||
var availableSize = new SKSize(bounds.Width, float.MaxValue);
|
||||
var availableSize = new Size(bounds.Width, float.MaxValue);
|
||||
var measuredSize = itemView.Measure(availableSize);
|
||||
|
||||
// Store individual item height (with minimum of default height)
|
||||
var measuredHeight = Math.Max(measuredSize.Height, _itemHeight);
|
||||
var measuredHeight = Math.Max((float)measuredSize.Height, _itemHeight);
|
||||
if (!_itemHeights.TryGetValue(index, out var cachedHeight) || Math.Abs(cachedHeight - measuredHeight) > 1)
|
||||
{
|
||||
_itemHeights[index] = measuredHeight;
|
||||
@@ -300,7 +300,7 @@ public class SkiaItemsView : SkiaView
|
||||
}
|
||||
|
||||
// Arrange with the actual measured height
|
||||
var actualBounds = new SKRect(bounds.Left, bounds.Top, bounds.Right, bounds.Top + measuredHeight);
|
||||
var actualBounds = new Rect(bounds.Left, bounds.Top, bounds.Width, measuredHeight);
|
||||
itemView.Arrange(actualBounds);
|
||||
itemView.Draw(canvas);
|
||||
return;
|
||||
@@ -423,8 +423,8 @@ public class SkiaItemsView : SkiaView
|
||||
_scrollbarDragStartY = e.Y;
|
||||
_scrollbarDragStartScrollOffset = _scrollOffset;
|
||||
// Cache values to prevent stutter
|
||||
var thumbHeight = Math.Max(20, Bounds.Height * (Bounds.Height / TotalContentHeight));
|
||||
_scrollbarDragAvailableTrack = Bounds.Height - thumbHeight;
|
||||
var thumbHeight = Math.Max(20f, (float)Bounds.Height * ((float)Bounds.Height / TotalContentHeight));
|
||||
_scrollbarDragAvailableTrack = (float)Bounds.Height - thumbHeight;
|
||||
_scrollbarDragMaxScroll = MaxScrollOffset;
|
||||
return;
|
||||
}
|
||||
@@ -445,15 +445,15 @@ public class SkiaItemsView : SkiaView
|
||||
{
|
||||
// Use ScreenBounds for hit testing (input events use screen coordinates)
|
||||
var screenBounds = ScreenBounds;
|
||||
var viewportRatio = screenBounds.Height / TotalContentHeight;
|
||||
var thumbHeight = Math.Max(20, screenBounds.Height * viewportRatio);
|
||||
var scrollRatio = MaxScrollOffset > 0 ? _scrollOffset / MaxScrollOffset : 0;
|
||||
var thumbY = screenBounds.Top + (screenBounds.Height - thumbHeight) * scrollRatio;
|
||||
var viewportRatio = (float)screenBounds.Height / TotalContentHeight;
|
||||
var thumbHeight = Math.Max(20f, (float)screenBounds.Height * viewportRatio);
|
||||
var scrollRatio = MaxScrollOffset > 0 ? _scrollOffset / MaxScrollOffset : 0f;
|
||||
var thumbY = (float)screenBounds.Top + ((float)screenBounds.Height - thumbHeight) * scrollRatio;
|
||||
|
||||
return new SKRect(
|
||||
screenBounds.Right - _scrollBarWidth,
|
||||
(float)(screenBounds.Left + screenBounds.Width) - _scrollBarWidth,
|
||||
thumbY,
|
||||
screenBounds.Right,
|
||||
(float)(screenBounds.Left + screenBounds.Width),
|
||||
thumbY + thumbHeight);
|
||||
}
|
||||
|
||||
@@ -621,12 +621,12 @@ public class SkiaItemsView : SkiaView
|
||||
break;
|
||||
|
||||
case Key.PageUp:
|
||||
SetScrollOffset(_scrollOffset - Bounds.Height);
|
||||
SetScrollOffset(_scrollOffset - (float)Bounds.Height);
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.PageDown:
|
||||
SetScrollOffset(_scrollOffset + Bounds.Height);
|
||||
SetScrollOffset(_scrollOffset + (float)Bounds.Height);
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
@@ -663,9 +663,9 @@ public class SkiaItemsView : SkiaView
|
||||
{
|
||||
SetScrollOffset(itemTop);
|
||||
}
|
||||
else if (itemBottom > _scrollOffset + Bounds.Height)
|
||||
else if (itemBottom > _scrollOffset + (float)Bounds.Height)
|
||||
{
|
||||
SetScrollOffset(itemBottom - Bounds.Height);
|
||||
SetScrollOffset(itemBottom - (float)Bounds.Height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,14 +679,14 @@ public class SkiaItemsView : SkiaView
|
||||
public override SkiaView? HitTest(float x, float y)
|
||||
{
|
||||
// HitTest uses Bounds (content space) - coordinates are transformed by parent
|
||||
if (!IsVisible || !Bounds.Contains(new SKPoint(x, y)))
|
||||
if (!IsVisible || !Bounds.Contains(x, y))
|
||||
return null;
|
||||
|
||||
// Check scrollbar area FIRST before content
|
||||
// This ensures scrollbar clicks are handled by this view
|
||||
if (_showVerticalScrollBar && TotalContentHeight > Bounds.Height)
|
||||
if (_showVerticalScrollBar && TotalContentHeight > (float)Bounds.Height)
|
||||
{
|
||||
var trackArea = new SKRect(Bounds.Right - _scrollBarWidth, Bounds.Top, Bounds.Right, Bounds.Bottom);
|
||||
var trackArea = new SKRect((float)(Bounds.Left + Bounds.Width) - _scrollBarWidth, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
if (trackArea.Contains(x, y))
|
||||
return this;
|
||||
}
|
||||
@@ -694,21 +694,21 @@ public class SkiaItemsView : SkiaView
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var width = availableSize.Width < float.MaxValue ? availableSize.Width : 200;
|
||||
var height = availableSize.Height < float.MaxValue ? availableSize.Height : 300;
|
||||
var width = availableSize.Width < double.MaxValue ? availableSize.Width : 200;
|
||||
var height = availableSize.Height < double.MaxValue ? availableSize.Height : 300;
|
||||
|
||||
// Clear item caches when width changes significantly (items need re-measurement for text wrapping)
|
||||
if (Math.Abs(width - _lastMeasuredWidth) > 5)
|
||||
{
|
||||
_itemHeights.Clear();
|
||||
_itemViewCache.Clear();
|
||||
_lastMeasuredWidth = width;
|
||||
_lastMeasuredWidth = (float)width;
|
||||
}
|
||||
|
||||
// Items view takes all available space
|
||||
return new SKSize(width, height);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -410,7 +410,7 @@ public class SkiaLabel : SkiaView
|
||||
|
||||
// Calculate character position from click
|
||||
var screenBounds = ScreenBounds;
|
||||
var clickX = e.X - screenBounds.Left - (float)Padding.Left;
|
||||
var clickX = e.X - (float)screenBounds.Left - (float)Padding.Left;
|
||||
var charIndex = GetCharacterIndexAtX(clickX);
|
||||
|
||||
// Check for double-click (select word)
|
||||
@@ -448,7 +448,7 @@ public class SkiaLabel : SkiaView
|
||||
if (string.IsNullOrEmpty(text)) return;
|
||||
|
||||
var screenBounds = ScreenBounds;
|
||||
var clickX = e.X - screenBounds.Left - (float)Padding.Left;
|
||||
var clickX = e.X - (float)screenBounds.Left - (float)Padding.Left;
|
||||
var charIndex = GetCharacterIndexAtX(clickX);
|
||||
|
||||
_selectionLength = charIndex - _selectionStart;
|
||||
@@ -1192,16 +1192,16 @@ public class SkiaLabel : SkiaView
|
||||
|
||||
#region Measurement
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var padding = Padding;
|
||||
float paddingH = (float)(padding.Left + padding.Right);
|
||||
float paddingV = (float)(padding.Top + padding.Bottom);
|
||||
double paddingH = padding.Left + padding.Right;
|
||||
double paddingV = padding.Top + padding.Bottom;
|
||||
|
||||
string displayText = GetDisplayText();
|
||||
if (string.IsNullOrEmpty(displayText) && (FormattedText == null || FormattedText.Spans.Count == 0))
|
||||
{
|
||||
return new SKSize(paddingH, paddingV + (float)FontSize);
|
||||
return new Size(paddingH, paddingV + FontSize);
|
||||
}
|
||||
|
||||
float fontSize = FontSize > 0 ? (float)FontSize : 14f;
|
||||
@@ -1213,7 +1213,7 @@ public class SkiaLabel : SkiaView
|
||||
|
||||
using var paint = new SKPaint(font);
|
||||
|
||||
float width, height;
|
||||
double width, height;
|
||||
// LineHeight -1 means platform default (use 1.0 multiplier)
|
||||
double effectiveLineHeight = LineHeight < 0 ? 1.0 : LineHeight;
|
||||
|
||||
@@ -1221,7 +1221,7 @@ public class SkiaLabel : SkiaView
|
||||
{
|
||||
// Measure formatted text
|
||||
width = 0;
|
||||
height = (float)(fontSize * effectiveLineHeight);
|
||||
height = fontSize * effectiveLineHeight;
|
||||
foreach (var span in FormattedText.Spans)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(span.Text))
|
||||
@@ -1240,7 +1240,7 @@ public class SkiaLabel : SkiaView
|
||||
// Account for character spacing
|
||||
if (CharacterSpacing != 0 && displayText.Length > 1)
|
||||
{
|
||||
width += (float)(CharacterSpacing * (displayText.Length - 1));
|
||||
width += CharacterSpacing * (displayText.Length - 1);
|
||||
}
|
||||
|
||||
// Account for multi-line
|
||||
@@ -1248,7 +1248,7 @@ public class SkiaLabel : SkiaView
|
||||
{
|
||||
var lines = displayText.Split('\n');
|
||||
int lineCount = MaxLines > 0 ? Math.Min(lines.Length, MaxLines) : lines.Length;
|
||||
height = (float)(lineCount * fontSize * effectiveLineHeight);
|
||||
height = lineCount * fontSize * effectiveLineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1258,14 +1258,14 @@ public class SkiaLabel : SkiaView
|
||||
// Respect explicit size requests
|
||||
if (WidthRequest >= 0)
|
||||
{
|
||||
width = (float)WidthRequest;
|
||||
width = WidthRequest;
|
||||
}
|
||||
if (HeightRequest >= 0)
|
||||
{
|
||||
height = (float)HeightRequest;
|
||||
height = HeightRequest;
|
||||
}
|
||||
|
||||
return new SKSize(Math.Max(width, 1f), Math.Max(height, 1f));
|
||||
return new Size(Math.Max(width, 1.0), Math.Max(height, 1.0));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -193,7 +193,7 @@ public abstract class SkiaLayoutView : SkiaView
|
||||
/// </summary>
|
||||
protected virtual SKRect GetContentBounds()
|
||||
{
|
||||
return GetContentBounds(Bounds);
|
||||
return GetContentBounds(new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -247,7 +247,7 @@ public abstract class SkiaLayoutView : SkiaView
|
||||
|
||||
public override SkiaView? HitTest(float x, float y)
|
||||
{
|
||||
if (!IsVisible || !IsEnabled || !Bounds.Contains(new SKPoint(x, y)))
|
||||
if (!IsVisible || !IsEnabled || !Bounds.Contains(x, y))
|
||||
{
|
||||
if (this is SkiaBorder)
|
||||
{
|
||||
@@ -357,7 +357,7 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
set => SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Handle NaN/Infinity in padding
|
||||
var paddingLeft = (float)(double.IsNaN(Padding.Left) ? 0 : Padding.Left);
|
||||
@@ -365,8 +365,8 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
var paddingTop = (float)(double.IsNaN(Padding.Top) ? 0 : Padding.Top);
|
||||
var paddingBottom = (float)(double.IsNaN(Padding.Bottom) ? 0 : Padding.Bottom);
|
||||
|
||||
var contentWidth = availableSize.Width - paddingLeft - paddingRight;
|
||||
var contentHeight = availableSize.Height - paddingTop - paddingBottom;
|
||||
var contentWidth = (float)availableSize.Width - paddingLeft - paddingRight;
|
||||
var contentHeight = (float)availableSize.Height - paddingTop - paddingBottom;
|
||||
|
||||
// Clamp negative sizes to 0
|
||||
if (contentWidth < 0 || float.IsNaN(contentWidth)) contentWidth = 0;
|
||||
@@ -377,7 +377,7 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
float maxWidth = 0;
|
||||
float maxHeight = 0;
|
||||
|
||||
var childAvailable = new SKSize(contentWidth, contentHeight);
|
||||
var childAvailable = new Size(contentWidth, contentHeight);
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
@@ -386,8 +386,8 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
var childSize = child.Measure(childAvailable);
|
||||
|
||||
// Skip NaN sizes from child measurements
|
||||
var childWidth = float.IsNaN(childSize.Width) ? 0 : childSize.Width;
|
||||
var childHeight = float.IsNaN(childSize.Height) ? 0 : childSize.Height;
|
||||
var childWidth = double.IsNaN(childSize.Width) ? 0f : (float)childSize.Width;
|
||||
var childHeight = double.IsNaN(childSize.Height) ? 0f : (float)childSize.Height;
|
||||
|
||||
if (Orientation == StackOrientation.Vertical)
|
||||
{
|
||||
@@ -408,22 +408,22 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
if (Orientation == StackOrientation.Vertical)
|
||||
{
|
||||
totalHeight += totalSpacing;
|
||||
return new SKSize(
|
||||
return new Size(
|
||||
maxWidth + paddingLeft + paddingRight,
|
||||
totalHeight + paddingTop + paddingBottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalWidth += totalSpacing;
|
||||
return new SKSize(
|
||||
return new Size(
|
||||
totalWidth + paddingLeft + paddingRight,
|
||||
maxHeight + paddingTop + paddingBottom);
|
||||
}
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
var content = GetContentBounds(bounds);
|
||||
var content = GetContentBounds(new SKRect((float)bounds.Left, (float)bounds.Top, (float)bounds.Right, (float)bounds.Bottom));
|
||||
|
||||
// Clamp content dimensions if infinite - use reasonable defaults
|
||||
var contentWidth = float.IsInfinity(content.Width) || float.IsNaN(content.Width) ? 800f : content.Width;
|
||||
@@ -438,14 +438,14 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
var childDesired = child.DesiredSize;
|
||||
|
||||
// Handle NaN and Infinity in desired size
|
||||
var childWidth = float.IsNaN(childDesired.Width) || float.IsInfinity(childDesired.Width)
|
||||
var childWidth = double.IsNaN(childDesired.Width) || double.IsInfinity(childDesired.Width)
|
||||
? contentWidth
|
||||
: childDesired.Width;
|
||||
var childHeight = float.IsNaN(childDesired.Height) || float.IsInfinity(childDesired.Height)
|
||||
: (float)childDesired.Width;
|
||||
var childHeight = double.IsNaN(childDesired.Height) || double.IsInfinity(childDesired.Height)
|
||||
? contentHeight
|
||||
: childDesired.Height;
|
||||
: (float)childDesired.Height;
|
||||
|
||||
SKRect childBounds;
|
||||
float childBoundsLeft, childBoundsTop, childBoundsWidth, childBoundsHeight;
|
||||
if (Orientation == StackOrientation.Vertical)
|
||||
{
|
||||
// For ScrollView children, give them the remaining viewport height
|
||||
@@ -455,11 +455,10 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
? remainingHeight
|
||||
: Math.Min(childHeight, remainingHeight > 0 ? remainingHeight : childHeight);
|
||||
|
||||
childBounds = new SKRect(
|
||||
content.Left,
|
||||
content.Top + offset,
|
||||
content.Left + contentWidth,
|
||||
content.Top + offset + useHeight);
|
||||
childBoundsLeft = content.Left;
|
||||
childBoundsTop = content.Top + offset;
|
||||
childBoundsWidth = contentWidth;
|
||||
childBoundsHeight = useHeight;
|
||||
offset += useHeight + (float)Spacing;
|
||||
}
|
||||
else
|
||||
@@ -473,7 +472,7 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
// Respect child's VerticalOptions for horizontal layouts
|
||||
var useHeight = Math.Min(childHeight, contentHeight);
|
||||
float childTop = content.Top;
|
||||
float childBottom = content.Top + useHeight;
|
||||
float childBottomCalc = content.Top + useHeight;
|
||||
|
||||
var verticalOptions = child.VerticalOptions;
|
||||
var alignmentValue = (int)verticalOptions.Alignment;
|
||||
@@ -482,34 +481,33 @@ public class SkiaStackLayout : SkiaLayoutView
|
||||
if (alignmentValue == 1) // Center
|
||||
{
|
||||
childTop = content.Top + (contentHeight - useHeight) / 2;
|
||||
childBottom = childTop + useHeight;
|
||||
childBottomCalc = childTop + useHeight;
|
||||
}
|
||||
else if (alignmentValue == 2) // End
|
||||
{
|
||||
childTop = content.Top + contentHeight - useHeight;
|
||||
childBottom = content.Top + contentHeight;
|
||||
childBottomCalc = content.Top + contentHeight;
|
||||
}
|
||||
else if (alignmentValue == 3) // Fill
|
||||
{
|
||||
childTop = content.Top;
|
||||
childBottom = content.Top + contentHeight;
|
||||
childBottomCalc = content.Top + contentHeight;
|
||||
}
|
||||
|
||||
childBounds = new SKRect(
|
||||
content.Left + offset,
|
||||
childTop,
|
||||
content.Left + offset + useWidth,
|
||||
childBottom);
|
||||
childBoundsLeft = content.Left + offset;
|
||||
childBoundsTop = childTop;
|
||||
childBoundsWidth = useWidth;
|
||||
childBoundsHeight = childBottomCalc - childTop;
|
||||
offset += useWidth + (float)Spacing;
|
||||
}
|
||||
|
||||
// Apply child's margin
|
||||
var margin = child.Margin;
|
||||
var marginedBounds = new SKRect(
|
||||
childBounds.Left + (float)margin.Left,
|
||||
childBounds.Top + (float)margin.Top,
|
||||
childBounds.Right - (float)margin.Right,
|
||||
childBounds.Bottom - (float)margin.Bottom);
|
||||
var marginedBounds = new Rect(
|
||||
childBoundsLeft + (float)margin.Left,
|
||||
childBoundsTop + (float)margin.Top,
|
||||
childBoundsWidth - (float)margin.Left - (float)margin.Right,
|
||||
childBoundsHeight - (float)margin.Top - (float)margin.Bottom);
|
||||
child.Arrange(marginedBounds);
|
||||
}
|
||||
return bounds;
|
||||
@@ -626,10 +624,10 @@ public class SkiaGrid : SkiaLayoutView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var contentWidth = availableSize.Width - (float)Padding.Left - (float)Padding.Right;
|
||||
var contentHeight = availableSize.Height - (float)Padding.Top - (float)Padding.Bottom;
|
||||
var contentWidth = (float)(availableSize.Width - Padding.Left - Padding.Right);
|
||||
var contentHeight = (float)(availableSize.Height - Padding.Top - Padding.Bottom);
|
||||
|
||||
// Handle NaN/Infinity
|
||||
if (float.IsNaN(contentWidth) || float.IsInfinity(contentWidth)) contentWidth = 800;
|
||||
@@ -652,8 +650,8 @@ public class SkiaGrid : SkiaLayoutView
|
||||
var def = pos.Column < _columnDefinitions.Count ? _columnDefinitions[pos.Column] : GridLength.Star;
|
||||
if (def.IsAuto && pos.ColumnSpan == 1)
|
||||
{
|
||||
var childSize = child.Measure(new SKSize(float.PositiveInfinity, float.PositiveInfinity));
|
||||
var childWidth = float.IsNaN(childSize.Width) ? 0 : childSize.Width;
|
||||
var childSize = child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||
var childWidth = double.IsNaN(childSize.Width) ? 0f : (float)childSize.Width;
|
||||
columnNaturalWidths[pos.Column] = Math.Max(columnNaturalWidths[pos.Column], childWidth);
|
||||
}
|
||||
}
|
||||
@@ -670,11 +668,11 @@ public class SkiaGrid : SkiaLayoutView
|
||||
var cellWidth = GetCellWidth(pos.Column, pos.ColumnSpan);
|
||||
|
||||
// Give infinite height for initial measure
|
||||
var childSize = child.Measure(new SKSize(cellWidth, float.PositiveInfinity));
|
||||
var childSize = child.Measure(new Size(cellWidth, double.PositiveInfinity));
|
||||
|
||||
// Track max height for each row
|
||||
// Cap infinite/very large heights - child returning infinity means it doesn't have a natural height
|
||||
var childHeight = childSize.Height;
|
||||
var childHeight = (float)childSize.Height;
|
||||
if (float.IsNaN(childHeight) || float.IsInfinity(childHeight) || childHeight > 100000)
|
||||
{
|
||||
// Use a default minimum - will be expanded by Star sizing if finite height is available
|
||||
@@ -706,16 +704,16 @@ public class SkiaGrid : SkiaLayoutView
|
||||
var cellWidth = GetCellWidth(pos.Column, pos.ColumnSpan);
|
||||
var cellHeight = GetCellHeight(pos.Row, pos.RowSpan);
|
||||
|
||||
child.Measure(new SKSize(cellWidth, cellHeight));
|
||||
child.Measure(new Size(cellWidth, cellHeight));
|
||||
}
|
||||
|
||||
// Calculate total size
|
||||
var totalWidth = _columnWidths.Sum() + Math.Max(0, columnCount - 1) * ColumnSpacing;
|
||||
var totalHeight = _rowHeights.Sum() + Math.Max(0, rowCount - 1) * RowSpacing;
|
||||
|
||||
return new SKSize(
|
||||
totalWidth + (float)Padding.Left + (float)Padding.Right,
|
||||
totalHeight + (float)Padding.Top + (float)Padding.Bottom);
|
||||
return new Size(
|
||||
totalWidth + Padding.Left + Padding.Right,
|
||||
totalHeight + Padding.Top + Padding.Bottom);
|
||||
}
|
||||
|
||||
private int GetMaxRow()
|
||||
@@ -827,11 +825,11 @@ public class SkiaGrid : SkiaLayoutView
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var content = GetContentBounds(bounds);
|
||||
var content = GetContentBounds(new SKRect((float)bounds.Left, (float)bounds.Top, (float)bounds.Right, (float)bounds.Bottom));
|
||||
|
||||
// Recalculate row heights for arrange bounds if they differ from measurement
|
||||
// This ensures Star rows expand to fill available space
|
||||
@@ -909,11 +907,11 @@ public class SkiaGrid : SkiaLayoutView
|
||||
|
||||
// Apply child's margin
|
||||
var margin = child.Margin;
|
||||
var marginedBounds = new SKRect(
|
||||
var marginedBounds = new Rect(
|
||||
x + (float)margin.Left,
|
||||
y + (float)margin.Top,
|
||||
x + width - (float)margin.Right,
|
||||
y + height - (float)margin.Bottom);
|
||||
width - (float)margin.Left - (float)margin.Right,
|
||||
height - (float)margin.Top - (float)margin.Bottom);
|
||||
child.Arrange(marginedBounds);
|
||||
}
|
||||
return bounds;
|
||||
@@ -1024,7 +1022,7 @@ public class SkiaAbsoluteLayout : SkiaLayoutView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
float maxRight = 0;
|
||||
float maxBottom = 0;
|
||||
@@ -1036,20 +1034,20 @@ public class SkiaAbsoluteLayout : SkiaLayoutView
|
||||
var layout = GetLayoutBounds(child);
|
||||
var bounds = layout.Bounds;
|
||||
|
||||
child.Measure(new SKSize(bounds.Width, bounds.Height));
|
||||
child.Measure(new Size(bounds.Width, bounds.Height));
|
||||
|
||||
maxRight = Math.Max(maxRight, bounds.Right);
|
||||
maxBottom = Math.Max(maxBottom, bounds.Bottom);
|
||||
}
|
||||
|
||||
return new SKSize(
|
||||
maxRight + (float)Padding.Left + (float)Padding.Right,
|
||||
maxBottom + (float)Padding.Top + (float)Padding.Bottom);
|
||||
return new Size(
|
||||
maxRight + Padding.Left + Padding.Right,
|
||||
maxBottom + Padding.Top + Padding.Bottom);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
var content = GetContentBounds(bounds);
|
||||
var content = GetContentBounds(new SKRect((float)bounds.Left, (float)bounds.Top, (float)bounds.Right, (float)bounds.Bottom));
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
@@ -1077,7 +1075,7 @@ public class SkiaAbsoluteLayout : SkiaLayoutView
|
||||
if (flags.HasFlag(AbsoluteLayoutFlags.WidthProportional))
|
||||
width = childBounds.Width * content.Width;
|
||||
else if (childBounds.Width < 0)
|
||||
width = child.DesiredSize.Width;
|
||||
width = (float)child.DesiredSize.Width;
|
||||
else
|
||||
width = childBounds.Width;
|
||||
|
||||
@@ -1085,17 +1083,17 @@ public class SkiaAbsoluteLayout : SkiaLayoutView
|
||||
if (flags.HasFlag(AbsoluteLayoutFlags.HeightProportional))
|
||||
height = childBounds.Height * content.Height;
|
||||
else if (childBounds.Height < 0)
|
||||
height = child.DesiredSize.Height;
|
||||
height = (float)child.DesiredSize.Height;
|
||||
else
|
||||
height = childBounds.Height;
|
||||
|
||||
// Apply child's margin
|
||||
var margin = child.Margin;
|
||||
var marginedBounds = new SKRect(
|
||||
var marginedBounds = new Rect(
|
||||
x + (float)margin.Left,
|
||||
y + (float)margin.Top,
|
||||
x + width - (float)margin.Right,
|
||||
y + height - (float)margin.Bottom);
|
||||
width - (float)margin.Left - (float)margin.Right,
|
||||
height - (float)margin.Top - (float)margin.Bottom);
|
||||
child.Arrange(marginedBounds);
|
||||
}
|
||||
return bounds;
|
||||
|
||||
@@ -104,9 +104,9 @@ public class SkiaMenuBar : SkiaView
|
||||
/// </summary>
|
||||
public float ItemPadding { get; set; } = 12f;
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return new SKSize(availableSize.Width, BarHeight);
|
||||
return new Size(availableSize.Width, BarHeight);
|
||||
}
|
||||
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
@@ -119,7 +119,8 @@ public class SkiaMenuBar : SkiaView
|
||||
Color = _menuBackgroundColorSK,
|
||||
Style = SKPaintStyle.Fill
|
||||
};
|
||||
canvas.DrawRect(Bounds, bgPaint);
|
||||
var skBounds = new SKRect((float)Bounds.Left, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
canvas.DrawRect(skBounds, bgPaint);
|
||||
|
||||
// Draw bottom border
|
||||
using var borderPaint = new SKPaint
|
||||
@@ -128,7 +129,7 @@ public class SkiaMenuBar : SkiaView
|
||||
Style = SKPaintStyle.Stroke,
|
||||
StrokeWidth = 1
|
||||
};
|
||||
canvas.DrawLine(Bounds.Left, Bounds.Bottom, Bounds.Right, Bounds.Bottom, borderPaint);
|
||||
canvas.DrawLine((float)Bounds.Left, (float)(Bounds.Top + Bounds.Height), (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height), borderPaint);
|
||||
|
||||
// Draw menu items
|
||||
using var textPaint = new SKPaint
|
||||
@@ -138,7 +139,7 @@ public class SkiaMenuBar : SkiaView
|
||||
IsAntialias = true
|
||||
};
|
||||
|
||||
float x = Bounds.Left;
|
||||
float x = (float)Bounds.Left;
|
||||
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
@@ -147,7 +148,7 @@ public class SkiaMenuBar : SkiaView
|
||||
textPaint.MeasureText(item.Text, ref textBounds);
|
||||
|
||||
float itemWidth = textBounds.Width + ItemPadding * 2;
|
||||
var itemBounds = new SKRect(x, Bounds.Top, x + itemWidth, Bounds.Bottom);
|
||||
var itemBounds = new SKRect(x, (float)Bounds.Top, x + itemWidth, (float)(Bounds.Top + Bounds.Height));
|
||||
|
||||
// Draw item background
|
||||
if (i == _openIndex)
|
||||
@@ -161,9 +162,9 @@ public class SkiaMenuBar : SkiaView
|
||||
canvas.DrawRect(itemBounds, hoverPaint);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
// Draw text (MidY = Top + Height/2)
|
||||
float textX = x + ItemPadding;
|
||||
float textY = Bounds.MidY - textBounds.MidY;
|
||||
float textY = (float)(Bounds.Top + Bounds.Height / 2) - textBounds.MidY;
|
||||
canvas.DrawText(item.Text, textX, textY, textPaint);
|
||||
|
||||
item.Bounds = itemBounds;
|
||||
|
||||
@@ -287,7 +287,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
{
|
||||
canvas.Save();
|
||||
canvas.Translate(currentOffset, 0);
|
||||
_currentPage.Bounds = bounds;
|
||||
_currentPage.Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
_currentPage.Draw(canvas);
|
||||
canvas.Restore();
|
||||
}
|
||||
@@ -295,7 +295,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
// Draw incoming page
|
||||
canvas.Save();
|
||||
canvas.Translate(incomingOffset, 0);
|
||||
_incomingPage.Bounds = bounds;
|
||||
_incomingPage.Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
_incomingPage.Draw(canvas);
|
||||
canvas.Restore();
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
// Draw incoming page (sliding in)
|
||||
canvas.Save();
|
||||
canvas.Translate(incomingOffset, 0);
|
||||
_incomingPage.Bounds = bounds;
|
||||
_incomingPage.Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
_incomingPage.Draw(canvas);
|
||||
canvas.Restore();
|
||||
|
||||
@@ -317,7 +317,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
{
|
||||
canvas.Save();
|
||||
canvas.Translate(currentOffset, 0);
|
||||
_currentPage.Bounds = bounds;
|
||||
_currentPage.Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
_currentPage.Draw(canvas);
|
||||
canvas.Restore();
|
||||
}
|
||||
@@ -327,7 +327,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
{
|
||||
// Draw current page normally
|
||||
Console.WriteLine("[SkiaNavigationPage] OnDraw: drawing _currentPage=" + _currentPage.Title);
|
||||
_currentPage.Bounds = bounds;
|
||||
_currentPage.Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
_currentPage.Draw(canvas);
|
||||
|
||||
// Draw back button if applicable
|
||||
@@ -368,7 +368,7 @@ public class SkiaNavigationPage : SkiaView
|
||||
return 1 - (float)Math.Pow(1 - t, 3);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
@@ -187,9 +187,9 @@ public class SkiaPage : SkiaView
|
||||
contentBounds.Bottom - (float)margin.Bottom);
|
||||
|
||||
// Measure and arrange the content before drawing
|
||||
var availableSize = new SKSize(adjustedBounds.Width, adjustedBounds.Height);
|
||||
var availableSize = new Size(adjustedBounds.Width, adjustedBounds.Height);
|
||||
_content.Measure(availableSize);
|
||||
_content.Arrange(adjustedBounds);
|
||||
_content.Arrange(new Rect(adjustedBounds.Left, adjustedBounds.Top, adjustedBounds.Width, adjustedBounds.Height));
|
||||
Console.WriteLine($"[SkiaPage] Drawing content: {_content.GetType().Name}, Bounds={_content.Bounds}, IsVisible={_content.IsVisible}");
|
||||
_content.Draw(canvas);
|
||||
}
|
||||
@@ -294,7 +294,7 @@ public class SkiaPage : SkiaView
|
||||
NavigatingFrom?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Page takes all available space
|
||||
return availableSize;
|
||||
|
||||
@@ -419,7 +419,8 @@ public class SkiaPicker : SkiaView
|
||||
private void DrawDropdownOverlay(SKCanvas canvas)
|
||||
{
|
||||
if (_items.Count == 0 || !_isOpen) return;
|
||||
DrawDropdown(canvas, ScreenBounds);
|
||||
var skScreenBounds = new SKRect((float)ScreenBounds.Left, (float)ScreenBounds.Top, (float)(ScreenBounds.Left + ScreenBounds.Width), (float)(ScreenBounds.Top + ScreenBounds.Height));
|
||||
DrawDropdown(canvas, skScreenBounds);
|
||||
}
|
||||
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
@@ -808,10 +809,10 @@ public class SkiaPicker : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return new SKSize(
|
||||
availableSize.Width < float.MaxValue ? Math.Min(availableSize.Width, 200) : 200,
|
||||
return new Size(
|
||||
availableSize.Width < double.MaxValue ? Math.Min(availableSize.Width, 200) : 200,
|
||||
40);
|
||||
}
|
||||
|
||||
@@ -837,10 +838,10 @@ public class SkiaPicker : SkiaView
|
||||
var dropdownMaxHeight = (float)_dropdownMaxHeight;
|
||||
var dropdownHeight = Math.Min(_items.Count * itemHeight, dropdownMaxHeight);
|
||||
var dropdownRect = new SKRect(
|
||||
screenBounds.Left,
|
||||
screenBounds.Bottom + 4,
|
||||
screenBounds.Right,
|
||||
screenBounds.Bottom + 4 + dropdownHeight);
|
||||
(float)screenBounds.Left,
|
||||
(float)(screenBounds.Top + screenBounds.Height) + 4,
|
||||
(float)(screenBounds.Left + screenBounds.Width),
|
||||
(float)(screenBounds.Top + screenBounds.Height) + 4 + dropdownHeight);
|
||||
|
||||
return dropdownRect.Contains(x, y);
|
||||
}
|
||||
|
||||
@@ -244,10 +244,10 @@ public class SkiaProgressBar : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var barHeight = (float)BarHeight;
|
||||
return new SKSize(200f, barHeight + 8f);
|
||||
var barHeight = BarHeight;
|
||||
return new Size(200, barHeight + 8);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -507,7 +507,7 @@ public class SkiaRadioButton : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var radioSize = (float)RadioSize;
|
||||
var fontSize = (float)FontSize;
|
||||
@@ -520,7 +520,7 @@ public class SkiaRadioButton : SkiaView
|
||||
using var paint = new SKPaint(font);
|
||||
textWidth = paint.MeasureText(Content) + spacing;
|
||||
}
|
||||
return new SKSize(radioSize + textWidth, Math.Max(radioSize, fontSize * 1.5f));
|
||||
return new Size(radioSize + textWidth, Math.Max(radioSize, fontSize * 1.5f));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -130,25 +130,21 @@ public class SkiaRefreshView : SkiaLayoutView
|
||||
/// </summary>
|
||||
public event EventHandler? Refreshing;
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_content != null)
|
||||
{
|
||||
_content.Measure(availableSize);
|
||||
_content.Measure(new Size(availableSize.Width, availableSize.Height));
|
||||
}
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
if (_content != null)
|
||||
{
|
||||
float offset = _isRefreshing ? _refreshThreshold : _pullDistance;
|
||||
var contentBounds = new SKRect(
|
||||
bounds.Left,
|
||||
bounds.Top + offset,
|
||||
bounds.Right,
|
||||
bounds.Bottom + offset);
|
||||
var contentBounds = new Rect(bounds.Left, bounds.Top + offset, bounds.Width, bounds.Height);
|
||||
_content.Arrange(contentBounds);
|
||||
}
|
||||
return bounds;
|
||||
|
||||
@@ -240,9 +240,9 @@ public class SkiaScrollView : SkiaView
|
||||
get
|
||||
{
|
||||
// Handle infinite or NaN bounds - use a reasonable default viewport
|
||||
var viewportWidth = float.IsInfinity(Bounds.Width) || float.IsNaN(Bounds.Width) || Bounds.Width <= 0
|
||||
var viewportWidth = double.IsInfinity(Bounds.Width) || double.IsNaN(Bounds.Width) || Bounds.Width <= 0
|
||||
? 800f
|
||||
: Bounds.Width;
|
||||
: (float)Bounds.Width;
|
||||
return Math.Max(0, ContentSize.Width - viewportWidth);
|
||||
}
|
||||
}
|
||||
@@ -256,9 +256,9 @@ public class SkiaScrollView : SkiaView
|
||||
{
|
||||
// Handle infinite, NaN, or unreasonably large bounds - use a reasonable default viewport
|
||||
var boundsHeight = Bounds.Height;
|
||||
var viewportHeight = (float.IsInfinity(boundsHeight) || float.IsNaN(boundsHeight) || boundsHeight <= 0 || boundsHeight > 10000)
|
||||
var viewportHeight = (double.IsInfinity(boundsHeight) || double.IsNaN(boundsHeight) || boundsHeight <= 0 || boundsHeight > 10000)
|
||||
? 544f // Default viewport height (600 - 56 for shell header)
|
||||
: boundsHeight;
|
||||
: (float)boundsHeight;
|
||||
return Math.Max(0, ContentSize.Height - viewportHeight);
|
||||
}
|
||||
}
|
||||
@@ -290,17 +290,18 @@ public class SkiaScrollView : SkiaView
|
||||
// Reserve space for vertical scrollbar if content might be taller than viewport
|
||||
effectiveWidth -= ScrollBarWidth;
|
||||
}
|
||||
var availableSize = new SKSize(effectiveWidth, float.PositiveInfinity);
|
||||
var availableSize = new Size(effectiveWidth, double.PositiveInfinity);
|
||||
// Update ContentSize with the properly constrained measurement
|
||||
ContentSize = _content.Measure(availableSize);
|
||||
var contentDesired = _content.Measure(availableSize);
|
||||
ContentSize = new SKSize((float)contentDesired.Width, (float)contentDesired.Height);
|
||||
|
||||
// Apply content's margin
|
||||
var margin = _content.Margin;
|
||||
var contentBounds = new SKRect(
|
||||
bounds.Left + (float)margin.Left,
|
||||
bounds.Top + (float)margin.Top,
|
||||
bounds.Left + Math.Max(bounds.Width, _content.DesiredSize.Width) - (float)margin.Right,
|
||||
bounds.Top + Math.Max(bounds.Height, _content.DesiredSize.Height) - (float)margin.Bottom);
|
||||
var contentLeft = bounds.Left + (float)margin.Left;
|
||||
var contentTop = bounds.Top + (float)margin.Top;
|
||||
var contentWidth = Math.Max(bounds.Width, (float)_content.DesiredSize.Width) - (float)margin.Left - (float)margin.Right;
|
||||
var contentHeight = Math.Max(bounds.Height, (float)_content.DesiredSize.Height) - (float)margin.Top - (float)margin.Bottom;
|
||||
var contentBounds = new Rect(contentLeft, contentTop, contentWidth, contentHeight);
|
||||
_content.Arrange(contentBounds);
|
||||
|
||||
canvas.Save();
|
||||
@@ -358,8 +359,8 @@ public class SkiaScrollView : SkiaView
|
||||
private void DrawVerticalScrollbar(SKCanvas canvas, SKRect bounds, bool hasHorizontal)
|
||||
{
|
||||
var trackHeight = bounds.Height - (hasHorizontal ? ScrollBarWidth : 0);
|
||||
var thumbHeight = Math.Max(20, (bounds.Height / ContentSize.Height) * trackHeight);
|
||||
var thumbY = (ScrollY / ScrollableHeight) * (trackHeight - thumbHeight);
|
||||
var thumbHeight = Math.Max(20f, (bounds.Height / ContentSize.Height) * trackHeight);
|
||||
var thumbY = ScrollableHeight > 0 ? (ScrollY / ScrollableHeight) * (trackHeight - thumbHeight) : 0f;
|
||||
|
||||
using var paint = new SKPaint
|
||||
{
|
||||
@@ -381,8 +382,8 @@ public class SkiaScrollView : SkiaView
|
||||
private void DrawHorizontalScrollbar(SKCanvas canvas, SKRect bounds, bool hasVertical)
|
||||
{
|
||||
var trackWidth = bounds.Width - (hasVertical ? ScrollBarWidth : 0);
|
||||
var thumbWidth = Math.Max(20, (bounds.Width / ContentSize.Width) * trackWidth);
|
||||
var thumbX = (ScrollX / ScrollableWidth) * (trackWidth - thumbWidth);
|
||||
var thumbWidth = Math.Max(20f, (bounds.Width / ContentSize.Width) * trackWidth);
|
||||
var thumbX = ScrollableWidth > 0 ? (ScrollX / ScrollableWidth) * (trackWidth - thumbWidth) : 0f;
|
||||
|
||||
using var paint = new SKPaint
|
||||
{
|
||||
@@ -444,8 +445,8 @@ public class SkiaScrollView : SkiaView
|
||||
_scrollbarDragStartScrollY = _scrollY;
|
||||
// Cache values to prevent stutter from floating-point recalculations
|
||||
var hasHorizontal = ShouldShowHorizontalScrollbar();
|
||||
var trackHeight = Bounds.Height - (hasHorizontal ? ScrollBarWidth : 0);
|
||||
var thumbHeight = Math.Max(20, (Bounds.Height / ContentSize.Height) * trackHeight);
|
||||
var trackHeight = (float)Bounds.Height - (hasHorizontal ? ScrollBarWidth : 0);
|
||||
var thumbHeight = Math.Max(20f, ((float)Bounds.Height / ContentSize.Height) * trackHeight);
|
||||
_scrollbarDragAvailableTrack = trackHeight - thumbHeight;
|
||||
_scrollbarDragScrollableExtent = ScrollableHeight;
|
||||
return;
|
||||
@@ -463,8 +464,8 @@ public class SkiaScrollView : SkiaView
|
||||
_scrollbarDragStartScrollX = _scrollX;
|
||||
// Cache values to prevent stutter from floating-point recalculations
|
||||
var hasVertical = ShouldShowVerticalScrollbar();
|
||||
var trackWidth = Bounds.Width - (hasVertical ? ScrollBarWidth : 0);
|
||||
var thumbWidth = Math.Max(20, (Bounds.Width / ContentSize.Width) * trackWidth);
|
||||
var trackWidth = (float)Bounds.Width - (hasVertical ? ScrollBarWidth : 0);
|
||||
var thumbWidth = Math.Max(20f, ((float)Bounds.Width / ContentSize.Width) * trackWidth);
|
||||
_scrollbarDragAvailableTrack = trackWidth - thumbWidth;
|
||||
_scrollbarDragScrollableExtent = ScrollableWidth;
|
||||
return;
|
||||
@@ -549,34 +550,34 @@ public class SkiaScrollView : SkiaView
|
||||
private SKRect GetVerticalScrollbarThumbBounds()
|
||||
{
|
||||
var hasHorizontal = ShouldShowHorizontalScrollbar();
|
||||
var trackHeight = Bounds.Height - (hasHorizontal ? ScrollBarWidth : 0);
|
||||
var thumbHeight = Math.Max(20, (Bounds.Height / ContentSize.Height) * trackHeight);
|
||||
var thumbY = ScrollableHeight > 0 ? (ScrollY / ScrollableHeight) * (trackHeight - thumbHeight) : 0;
|
||||
var trackHeight = (float)Bounds.Height - (hasHorizontal ? ScrollBarWidth : 0);
|
||||
var thumbHeight = Math.Max(20f, ((float)Bounds.Height / ContentSize.Height) * trackHeight);
|
||||
var thumbY = ScrollableHeight > 0 ? (ScrollY / ScrollableHeight) * (trackHeight - thumbHeight) : 0f;
|
||||
|
||||
return new SKRect(
|
||||
Bounds.Right - ScrollBarWidth,
|
||||
Bounds.Top + thumbY,
|
||||
Bounds.Right,
|
||||
Bounds.Top + thumbY + thumbHeight);
|
||||
(float)(Bounds.Left + Bounds.Width) - ScrollBarWidth,
|
||||
(float)Bounds.Top + thumbY,
|
||||
(float)(Bounds.Left + Bounds.Width),
|
||||
(float)Bounds.Top + thumbY + thumbHeight);
|
||||
}
|
||||
|
||||
private SKRect GetHorizontalScrollbarThumbBounds()
|
||||
{
|
||||
var hasVertical = ShouldShowVerticalScrollbar();
|
||||
var trackWidth = Bounds.Width - (hasVertical ? ScrollBarWidth : 0);
|
||||
var thumbWidth = Math.Max(20, (Bounds.Width / ContentSize.Width) * trackWidth);
|
||||
var thumbX = ScrollableWidth > 0 ? (ScrollX / ScrollableWidth) * (trackWidth - thumbWidth) : 0;
|
||||
var trackWidth = (float)Bounds.Width - (hasVertical ? ScrollBarWidth : 0);
|
||||
var thumbWidth = Math.Max(20f, ((float)Bounds.Width / ContentSize.Width) * trackWidth);
|
||||
var thumbX = ScrollableWidth > 0 ? (ScrollX / ScrollableWidth) * (trackWidth - thumbWidth) : 0f;
|
||||
|
||||
return new SKRect(
|
||||
Bounds.Left + thumbX,
|
||||
Bounds.Bottom - ScrollBarWidth,
|
||||
Bounds.Left + thumbX + thumbWidth,
|
||||
Bounds.Bottom);
|
||||
(float)Bounds.Left + thumbX,
|
||||
(float)(Bounds.Top + Bounds.Height) - ScrollBarWidth,
|
||||
(float)Bounds.Left + thumbX + thumbWidth,
|
||||
(float)(Bounds.Top + Bounds.Height));
|
||||
}
|
||||
|
||||
public override SkiaView? HitTest(float x, float y)
|
||||
{
|
||||
if (!IsVisible || !IsEnabled || !Bounds.Contains(new SKPoint(x, y)))
|
||||
if (!IsVisible || !IsEnabled || !Bounds.Contains(x, y))
|
||||
return null;
|
||||
|
||||
// Check scrollbar areas FIRST before content
|
||||
@@ -585,14 +586,14 @@ public class SkiaScrollView : SkiaView
|
||||
{
|
||||
var thumbBounds = GetVerticalScrollbarThumbBounds();
|
||||
// Check if click is in the scrollbar track area (not just thumb)
|
||||
var trackArea = new SKRect(Bounds.Right - ScrollBarWidth, Bounds.Top, Bounds.Right, Bounds.Bottom);
|
||||
var trackArea = new SKRect((float)(Bounds.Left + Bounds.Width) - ScrollBarWidth, (float)Bounds.Top, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
if (trackArea.Contains(x, y))
|
||||
return this;
|
||||
}
|
||||
|
||||
if (ShouldShowHorizontalScrollbar() && ScrollableWidth > 0)
|
||||
{
|
||||
var trackArea = new SKRect(Bounds.Left, Bounds.Bottom - ScrollBarWidth, Bounds.Right, Bounds.Bottom);
|
||||
var trackArea = new SKRect((float)Bounds.Left, (float)(Bounds.Top + Bounds.Height) - ScrollBarWidth, (float)(Bounds.Left + Bounds.Width), (float)(Bounds.Top + Bounds.Height));
|
||||
if (trackArea.Contains(x, y))
|
||||
return this;
|
||||
}
|
||||
@@ -680,38 +681,40 @@ public class SkiaScrollView : SkiaView
|
||||
float targetY = _scrollY;
|
||||
|
||||
// Calculate viewport dimensions
|
||||
float viewportWidth = Bounds.Width;
|
||||
float viewportHeight = Bounds.Height;
|
||||
float viewportWidth = (float)Bounds.Width;
|
||||
float viewportHeight = (float)Bounds.Height;
|
||||
float elementRight = (float)(elementBounds.Left + elementBounds.Width);
|
||||
float elementBottom = (float)(elementBounds.Top + elementBounds.Height);
|
||||
|
||||
switch (position)
|
||||
{
|
||||
case ScrollToPosition.Start:
|
||||
targetX = elementBounds.Left;
|
||||
targetY = elementBounds.Top;
|
||||
targetX = (float)elementBounds.Left;
|
||||
targetY = (float)elementBounds.Top;
|
||||
break;
|
||||
|
||||
case ScrollToPosition.Center:
|
||||
targetX = elementBounds.Left - (viewportWidth - elementBounds.Width) / 2;
|
||||
targetY = elementBounds.Top - (viewportHeight - elementBounds.Height) / 2;
|
||||
targetX = (float)elementBounds.Left - (viewportWidth - (float)elementBounds.Width) / 2;
|
||||
targetY = (float)elementBounds.Top - (viewportHeight - (float)elementBounds.Height) / 2;
|
||||
break;
|
||||
|
||||
case ScrollToPosition.End:
|
||||
targetX = elementBounds.Right - viewportWidth;
|
||||
targetY = elementBounds.Bottom - viewportHeight;
|
||||
targetX = elementRight - viewportWidth;
|
||||
targetY = elementBottom - viewportHeight;
|
||||
break;
|
||||
|
||||
case ScrollToPosition.MakeVisible:
|
||||
default:
|
||||
// Only scroll if element is not fully visible
|
||||
if (elementBounds.Left < _scrollX)
|
||||
targetX = elementBounds.Left;
|
||||
else if (elementBounds.Right > _scrollX + viewportWidth)
|
||||
targetX = elementBounds.Right - viewportWidth;
|
||||
targetX = (float)elementBounds.Left;
|
||||
else if (elementRight > _scrollX + viewportWidth)
|
||||
targetX = elementRight - viewportWidth;
|
||||
|
||||
if (elementBounds.Top < _scrollY)
|
||||
targetY = elementBounds.Top;
|
||||
else if (elementBounds.Bottom > _scrollY + viewportHeight)
|
||||
targetY = elementBounds.Bottom - viewportHeight;
|
||||
targetY = (float)elementBounds.Top;
|
||||
else if (elementBottom > _scrollY + viewportHeight)
|
||||
targetY = elementBottom - viewportHeight;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -730,15 +733,18 @@ public class SkiaScrollView : SkiaView
|
||||
if (_content == null) return;
|
||||
|
||||
var viewBounds = view.Bounds;
|
||||
float viewRight = (float)(viewBounds.Left + viewBounds.Width);
|
||||
float viewBottom = (float)(viewBounds.Top + viewBounds.Height);
|
||||
|
||||
// Check if view is fully visible
|
||||
var visibleRect = new SKRect(
|
||||
ScrollX,
|
||||
ScrollY,
|
||||
ScrollX + Bounds.Width,
|
||||
ScrollY + Bounds.Height);
|
||||
ScrollX + (float)Bounds.Width,
|
||||
ScrollY + (float)Bounds.Height);
|
||||
|
||||
if (visibleRect.Contains(viewBounds))
|
||||
var viewSKRect = new SKRect((float)viewBounds.Left, (float)viewBounds.Top, viewRight, viewBottom);
|
||||
if (visibleRect.Contains(viewSKRect))
|
||||
return;
|
||||
|
||||
// Calculate scroll position to bring view into view
|
||||
@@ -746,14 +752,14 @@ public class SkiaScrollView : SkiaView
|
||||
float targetY = ScrollY;
|
||||
|
||||
if (viewBounds.Left < visibleRect.Left)
|
||||
targetX = viewBounds.Left;
|
||||
else if (viewBounds.Right > visibleRect.Right)
|
||||
targetX = viewBounds.Right - Bounds.Width;
|
||||
targetX = (float)viewBounds.Left;
|
||||
else if (viewRight > visibleRect.Right)
|
||||
targetX = viewRight - (float)Bounds.Width;
|
||||
|
||||
if (viewBounds.Top < visibleRect.Top)
|
||||
targetY = viewBounds.Top;
|
||||
else if (viewBounds.Bottom > visibleRect.Bottom)
|
||||
targetY = viewBounds.Bottom - Bounds.Height;
|
||||
targetY = (float)viewBounds.Top;
|
||||
else if (viewBottom > visibleRect.Bottom)
|
||||
targetY = viewBottom - (float)Bounds.Height;
|
||||
|
||||
ScrollTo(targetX, targetY, animated);
|
||||
}
|
||||
@@ -770,7 +776,7 @@ public class SkiaScrollView : SkiaView
|
||||
return Math.Clamp(value, 0, ScrollableHeight);
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_content != null)
|
||||
{
|
||||
@@ -787,17 +793,17 @@ public class SkiaScrollView : SkiaView
|
||||
{
|
||||
case ScrollOrientation.Horizontal:
|
||||
contentWidth = float.PositiveInfinity;
|
||||
contentHeight = float.IsInfinity(availableSize.Height) ? 400f : availableSize.Height;
|
||||
contentHeight = double.IsInfinity(availableSize.Height) ? 400f : (float)availableSize.Height;
|
||||
break;
|
||||
case ScrollOrientation.Neither:
|
||||
contentWidth = float.IsInfinity(availableSize.Width) ? 400f : availableSize.Width;
|
||||
contentHeight = float.IsInfinity(availableSize.Height) ? 400f : availableSize.Height;
|
||||
contentWidth = double.IsInfinity(availableSize.Width) ? 400f : (float)availableSize.Width;
|
||||
contentHeight = double.IsInfinity(availableSize.Height) ? 400f : (float)availableSize.Height;
|
||||
break;
|
||||
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;
|
||||
contentWidth = double.IsInfinity(availableSize.Width) ? 800f : (float)availableSize.Width;
|
||||
if (VerticalScrollBarVisibility != ScrollBarVisibility.Never)
|
||||
contentWidth -= ScrollBarWidth;
|
||||
contentHeight = float.PositiveInfinity;
|
||||
@@ -805,14 +811,15 @@ public class SkiaScrollView : SkiaView
|
||||
case ScrollOrientation.Vertical:
|
||||
default:
|
||||
// Reserve space for vertical scrollbar to prevent horizontal scrollbar
|
||||
contentWidth = float.IsInfinity(availableSize.Width) ? 800f : availableSize.Width;
|
||||
contentWidth = double.IsInfinity(availableSize.Width) ? 800f : (float)availableSize.Width;
|
||||
if (VerticalScrollBarVisibility != ScrollBarVisibility.Never)
|
||||
contentWidth -= ScrollBarWidth;
|
||||
contentHeight = float.PositiveInfinity;
|
||||
break;
|
||||
}
|
||||
|
||||
ContentSize = _content.Measure(new SKSize(contentWidth, contentHeight));
|
||||
var contentDesiredMeasure = _content.Measure(new Size(contentWidth, contentHeight));
|
||||
ContentSize = new SKSize((float)contentDesiredMeasure.Width, (float)contentDesiredMeasure.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -823,41 +830,41 @@ public class SkiaScrollView : SkiaView
|
||||
// IMPORTANT: When available is infinite, return a reasonable viewport size, NOT content size
|
||||
// A ScrollView should NOT expand to fit its content - it should stay at a fixed viewport
|
||||
// and scroll the content. Use a default viewport size when parent gives infinity.
|
||||
const float DefaultViewportWidth = 400f;
|
||||
const float DefaultViewportHeight = 400f;
|
||||
const double DefaultViewportWidth = 400.0;
|
||||
const double DefaultViewportHeight = 400.0;
|
||||
|
||||
var width = float.IsInfinity(availableSize.Width) || float.IsNaN(availableSize.Width)
|
||||
var width = double.IsInfinity(availableSize.Width) || double.IsNaN(availableSize.Width)
|
||||
? Math.Min(ContentSize.Width, DefaultViewportWidth)
|
||||
: availableSize.Width;
|
||||
var height = float.IsInfinity(availableSize.Height) || float.IsNaN(availableSize.Height)
|
||||
var height = double.IsInfinity(availableSize.Height) || double.IsNaN(availableSize.Height)
|
||||
? Math.Min(ContentSize.Height, DefaultViewportHeight)
|
||||
: availableSize.Height;
|
||||
|
||||
return new SKSize(width, height);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
|
||||
// CRITICAL: If bounds has infinite height, use a fixed viewport size
|
||||
// NOT ContentSize.Height - that would make ScrollableHeight = 0
|
||||
const float DefaultViewportHeight = 544f; // 600 - 56 for shell header
|
||||
var actualBounds = bounds;
|
||||
if (float.IsInfinity(bounds.Height) || float.IsNaN(bounds.Height))
|
||||
if (double.IsInfinity(bounds.Height) || double.IsNaN(bounds.Height))
|
||||
{
|
||||
Console.WriteLine($"[SkiaScrollView] WARNING: Infinite/NaN height, using default viewport={DefaultViewportHeight}");
|
||||
actualBounds = new SKRect(bounds.Left, bounds.Top, bounds.Right, bounds.Top + DefaultViewportHeight);
|
||||
actualBounds = new Rect(bounds.Left, bounds.Top, bounds.Width, DefaultViewportHeight);
|
||||
}
|
||||
|
||||
if (_content != null)
|
||||
{
|
||||
// Apply content's margin and arrange content at its full size
|
||||
var margin = _content.Margin;
|
||||
var contentBounds = new SKRect(
|
||||
actualBounds.Left + (float)margin.Left,
|
||||
actualBounds.Top + (float)margin.Top,
|
||||
actualBounds.Left + Math.Max(actualBounds.Width, ContentSize.Width) - (float)margin.Right,
|
||||
actualBounds.Top + Math.Max(actualBounds.Height, ContentSize.Height) - (float)margin.Bottom);
|
||||
var contentLeft = (float)actualBounds.Left + (float)margin.Left;
|
||||
var contentTop = (float)actualBounds.Top + (float)margin.Top;
|
||||
var contentWidth = Math.Max((float)actualBounds.Width, ContentSize.Width) - (float)margin.Left - (float)margin.Right;
|
||||
var contentHeight = Math.Max((float)actualBounds.Height, ContentSize.Height) - (float)margin.Top - (float)margin.Bottom;
|
||||
var contentBounds = new Rect(contentLeft, contentTop, contentWidth, contentHeight);
|
||||
|
||||
_content.Arrange(contentBounds);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class SkiaSearchBar : SkiaView
|
||||
? bounds.Right - clearButtonSize - iconPadding * 2
|
||||
: bounds.Right - iconPadding;
|
||||
|
||||
var entryBounds = new SKRect(entryLeft, bounds.Top, entryRight, bounds.Bottom);
|
||||
var entryBounds = new Rect(entryLeft, bounds.Top, entryRight - entryLeft, bounds.Height);
|
||||
_entry.Arrange(entryBounds);
|
||||
_entry.Draw(canvas);
|
||||
|
||||
@@ -306,9 +306,9 @@ public class SkiaSearchBar : SkiaView
|
||||
|
||||
#region Measurement
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return new SKSize(250, 40);
|
||||
return new Size(250, 40);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -750,36 +750,36 @@ public class SkiaShell : SkiaLayoutView
|
||||
}
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// 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 - (float)Padding.Left - (float)Padding.Right,
|
||||
availableSize.Height - contentTop - contentBottom - (float)Padding.Top - (float)Padding.Bottom);
|
||||
var contentSize = new Size(
|
||||
availableSize.Width - Padding.Left - Padding.Right,
|
||||
availableSize.Height - contentTop - contentBottom - Padding.Top - Padding.Bottom);
|
||||
_currentContent.Measure(contentSize);
|
||||
}
|
||||
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
Console.WriteLine($"[SkiaShell] ArrangeOverride - bounds={bounds}");
|
||||
|
||||
// Arrange current content with padding
|
||||
if (_currentContent != null)
|
||||
{
|
||||
float contentTop = bounds.Top + (NavBarIsVisible ? NavBarHeight : 0) + ContentPadding;
|
||||
float contentBottom = bounds.Bottom - (TabBarIsVisible ? TabBarHeight : 0) - ContentPadding;
|
||||
var contentBounds = new SKRect(
|
||||
float contentTop = (float)bounds.Top + (NavBarIsVisible ? NavBarHeight : 0) + ContentPadding;
|
||||
float contentBottom = (float)bounds.Bottom - (TabBarIsVisible ? TabBarHeight : 0) - ContentPadding;
|
||||
var contentBounds = new Rect(
|
||||
bounds.Left + ContentPadding,
|
||||
contentTop,
|
||||
bounds.Right - ContentPadding,
|
||||
contentBottom);
|
||||
bounds.Width - ContentPadding * 2,
|
||||
contentBottom - contentTop);
|
||||
Console.WriteLine($"[SkiaShell] Arranging content with bounds={contentBounds}, padding={ContentPadding}");
|
||||
_currentContent.Arrange(contentBounds);
|
||||
}
|
||||
@@ -1011,8 +1011,8 @@ public class SkiaShell : SkiaLayoutView
|
||||
// Check flyout area
|
||||
if (_flyoutAnimationProgress > 0)
|
||||
{
|
||||
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
||||
float flyoutX = (float)Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, (float)Bounds.Top, flyoutX + FlyoutWidth, (float)Bounds.Bottom);
|
||||
|
||||
if (flyoutBounds.Contains(x, y))
|
||||
{
|
||||
@@ -1027,13 +1027,13 @@ public class SkiaShell : SkiaLayoutView
|
||||
}
|
||||
|
||||
// Check nav bar
|
||||
if (NavBarIsVisible && y < Bounds.Top + NavBarHeight)
|
||||
if (NavBarIsVisible && y < (float)Bounds.Top + NavBarHeight)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
// Check tab bar
|
||||
if (TabBarIsVisible && y > Bounds.Bottom - TabBarHeight)
|
||||
if (TabBarIsVisible && y > (float)Bounds.Bottom - TabBarHeight)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@@ -1055,8 +1055,8 @@ public class SkiaShell : SkiaLayoutView
|
||||
// Check flyout tap
|
||||
if (_flyoutAnimationProgress > 0)
|
||||
{
|
||||
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
||||
float flyoutX = (float)Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, (float)Bounds.Top, flyoutX + FlyoutWidth, (float)Bounds.Bottom);
|
||||
|
||||
if (flyoutBounds.Contains(e.X, e.Y))
|
||||
{
|
||||
@@ -1105,13 +1105,13 @@ public class SkiaShell : SkiaLayoutView
|
||||
}
|
||||
|
||||
// Check tab bar tap
|
||||
if (TabBarIsVisible && e.Y > Bounds.Bottom - TabBarHeight)
|
||||
if (TabBarIsVisible && e.Y > (float)Bounds.Bottom - TabBarHeight)
|
||||
{
|
||||
if (_selectedSectionIndex >= 0 && _selectedSectionIndex < _sections.Count)
|
||||
{
|
||||
var section = _sections[_selectedSectionIndex];
|
||||
float tabWidth = Bounds.Width / section.Items.Count;
|
||||
int tappedIndex = (int)((e.X - Bounds.Left) / tabWidth);
|
||||
float tabWidth = (float)Bounds.Width / section.Items.Count;
|
||||
int tappedIndex = (int)((e.X - (float)Bounds.Left) / tabWidth);
|
||||
tappedIndex = Math.Clamp(tappedIndex, 0, section.Items.Count - 1);
|
||||
|
||||
if (tappedIndex != _selectedItemIndex)
|
||||
@@ -1130,8 +1130,8 @@ public class SkiaShell : SkiaLayoutView
|
||||
{
|
||||
if (FlyoutIsPresented && _flyoutAnimationProgress > 0)
|
||||
{
|
||||
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
||||
float flyoutX = (float)Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
||||
var flyoutBounds = new SKRect(flyoutX, (float)Bounds.Top, flyoutX + FlyoutWidth, (float)Bounds.Bottom);
|
||||
|
||||
if (flyoutBounds.Contains(e.X, e.Y))
|
||||
{
|
||||
|
||||
@@ -476,10 +476,10 @@ public class SkiaSlider : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var thumbRadius = (float)ThumbRadius;
|
||||
return new SKSize(200, thumbRadius * 2 + 16);
|
||||
var thumbRadius = ThumbRadius;
|
||||
return new Size(200, thumbRadius * 2 + 16);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -520,10 +520,10 @@ public class SkiaStepper : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var buttonWidth = (float)ButtonWidth;
|
||||
return new SKSize(buttonWidth * 2 + 1, 32);
|
||||
var buttonWidth = ButtonWidth;
|
||||
return new Size(buttonWidth * 2 + 1, 32);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -137,24 +137,24 @@ public class SkiaSwipeView : SkiaLayoutView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_content != null)
|
||||
{
|
||||
_content.Measure(availableSize);
|
||||
_content.Measure(new Size(availableSize.Width, availableSize.Height));
|
||||
}
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
if (_content != null)
|
||||
{
|
||||
var contentBounds = new SKRect(
|
||||
var contentBounds = new Rect(
|
||||
bounds.Left + _swipeOffset,
|
||||
bounds.Top,
|
||||
bounds.Right + _swipeOffset,
|
||||
bounds.Bottom);
|
||||
bounds.Width,
|
||||
bounds.Height);
|
||||
_content.Arrange(contentBounds);
|
||||
}
|
||||
return bounds;
|
||||
|
||||
@@ -439,11 +439,11 @@ public class SkiaSwitch : SkiaView
|
||||
|
||||
#region Layout
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var trackWidth = (float)TrackWidth;
|
||||
var trackHeight = (float)TrackHeight;
|
||||
return new SKSize(trackWidth + 8f, trackHeight + 8f);
|
||||
var trackWidth = TrackWidth;
|
||||
var trackHeight = TrackHeight;
|
||||
return new Size(trackWidth + 8, trackHeight + 8);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -216,11 +216,11 @@ public class SkiaTabbedPage : SkiaLayoutView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Measure the content area (excluding tab bar)
|
||||
var contentHeight = availableSize.Height - TabBarHeight;
|
||||
var contentSize = new SKSize(availableSize.Width, contentHeight);
|
||||
var contentSize = new Size(availableSize.Width, contentHeight);
|
||||
|
||||
foreach (var tab in _tabs)
|
||||
{
|
||||
@@ -230,25 +230,25 @@ public class SkiaTabbedPage : SkiaLayoutView
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
protected override SKRect ArrangeOverride(SKRect bounds)
|
||||
protected override Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
// Calculate content bounds based on tab bar position
|
||||
SKRect contentBounds;
|
||||
Rect contentBounds;
|
||||
if (TabBarOnBottom)
|
||||
{
|
||||
contentBounds = new SKRect(
|
||||
contentBounds = new Rect(
|
||||
bounds.Left,
|
||||
bounds.Top,
|
||||
bounds.Right,
|
||||
bounds.Bottom - TabBarHeight);
|
||||
bounds.Width,
|
||||
bounds.Height - TabBarHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
contentBounds = new SKRect(
|
||||
contentBounds = new Rect(
|
||||
bounds.Left,
|
||||
bounds.Top + TabBarHeight,
|
||||
bounds.Right,
|
||||
bounds.Bottom);
|
||||
bounds.Width,
|
||||
bounds.Height - TabBarHeight);
|
||||
}
|
||||
|
||||
// Arrange each tab's content to fill the content area
|
||||
@@ -284,18 +284,18 @@ public class SkiaTabbedPage : SkiaLayoutView
|
||||
if (TabBarOnBottom)
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Bottom - TabBarHeight,
|
||||
Bounds.Right,
|
||||
Bounds.Bottom);
|
||||
(float)Bounds.Left,
|
||||
(float)Bounds.Bottom - TabBarHeight,
|
||||
(float)Bounds.Right,
|
||||
(float)Bounds.Bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Top,
|
||||
Bounds.Right,
|
||||
Bounds.Top + TabBarHeight);
|
||||
(float)Bounds.Left,
|
||||
(float)Bounds.Top,
|
||||
(float)Bounds.Right,
|
||||
(float)Bounds.Top + TabBarHeight);
|
||||
}
|
||||
|
||||
// Draw background
|
||||
@@ -377,18 +377,18 @@ public class SkiaTabbedPage : SkiaLayoutView
|
||||
if (TabBarOnBottom)
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Bottom - TabBarHeight,
|
||||
Bounds.Right,
|
||||
Bounds.Bottom);
|
||||
(float)Bounds.Left,
|
||||
(float)(Bounds.Top + Bounds.Height) - TabBarHeight,
|
||||
(float)(Bounds.Left + Bounds.Width),
|
||||
(float)(Bounds.Top + Bounds.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Top,
|
||||
Bounds.Right,
|
||||
Bounds.Top + TabBarHeight);
|
||||
(float)Bounds.Left,
|
||||
(float)Bounds.Top,
|
||||
(float)(Bounds.Left + Bounds.Width),
|
||||
(float)Bounds.Top + TabBarHeight);
|
||||
}
|
||||
|
||||
if (tabBarBounds.Contains(x, y))
|
||||
@@ -415,18 +415,18 @@ public class SkiaTabbedPage : SkiaLayoutView
|
||||
if (TabBarOnBottom)
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Bottom - TabBarHeight,
|
||||
Bounds.Right,
|
||||
Bounds.Bottom);
|
||||
(float)Bounds.Left,
|
||||
(float)(Bounds.Top + Bounds.Height) - TabBarHeight,
|
||||
(float)(Bounds.Left + Bounds.Width),
|
||||
(float)(Bounds.Top + Bounds.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
tabBarBounds = new SKRect(
|
||||
Bounds.Left,
|
||||
Bounds.Top,
|
||||
Bounds.Right,
|
||||
Bounds.Top + TabBarHeight);
|
||||
(float)Bounds.Left,
|
||||
(float)Bounds.Top,
|
||||
(float)(Bounds.Left + Bounds.Width),
|
||||
(float)Bounds.Top + TabBarHeight);
|
||||
}
|
||||
|
||||
if (tabBarBounds.Contains(e.X, e.Y) && _tabs.Count > 0)
|
||||
|
||||
@@ -323,11 +323,12 @@ public abstract class SkiaTemplatedView : SkiaView
|
||||
/// </summary>
|
||||
protected abstract void DrawDefaultAppearance(SKCanvas canvas, SKRect bounds);
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_templateRoot != null && _templateApplied)
|
||||
{
|
||||
return _templateRoot.Measure(availableSize);
|
||||
var measured = _templateRoot.Measure(new Size(availableSize.Width, availableSize.Height));
|
||||
return new Size(measured.Width, measured.Height);
|
||||
}
|
||||
|
||||
return MeasureDefaultAppearance(availableSize);
|
||||
@@ -337,12 +338,12 @@ public abstract class SkiaTemplatedView : SkiaView
|
||||
/// Measures the default appearance when no template is applied.
|
||||
/// Override in derived classes.
|
||||
/// </summary>
|
||||
protected virtual SKSize MeasureDefaultAppearance(SKSize availableSize)
|
||||
protected virtual Size MeasureDefaultAppearance(Size availableSize)
|
||||
{
|
||||
return new SKSize(100, 40);
|
||||
return new Size(100, 40);
|
||||
}
|
||||
|
||||
public new void Arrange(SKRect bounds)
|
||||
public new void Arrange(Rect bounds)
|
||||
{
|
||||
base.Arrange(bounds);
|
||||
|
||||
|
||||
@@ -278,7 +278,8 @@ public class SkiaTimePicker : SkiaView
|
||||
private void DrawClockOverlay(SKCanvas canvas)
|
||||
{
|
||||
if (!_isOpen) return;
|
||||
DrawClockPopup(canvas, ScreenBounds);
|
||||
var sb = ScreenBounds;
|
||||
DrawClockPopup(canvas, new SKRect((float)sb.Left, (float)sb.Top, (float)sb.Right, (float)sb.Bottom));
|
||||
}
|
||||
|
||||
private void DrawPickerButton(SKCanvas canvas, SKRect bounds)
|
||||
@@ -499,7 +500,7 @@ public class SkiaTimePicker : SkiaView
|
||||
if (IsOpen)
|
||||
{
|
||||
var screenBounds = ScreenBounds;
|
||||
var popupRect = GetPopupRect(screenBounds);
|
||||
var popupRect = GetPopupRect(new SKRect((float)screenBounds.Left, (float)screenBounds.Top, (float)screenBounds.Right, (float)screenBounds.Bottom));
|
||||
|
||||
var headerRect = new SKRect(popupRect.Left, popupRect.Top, popupRect.Right, popupRect.Top + HeaderHeight);
|
||||
if (headerRect.Contains(e.X, e.Y))
|
||||
@@ -598,9 +599,9 @@ public class SkiaTimePicker : SkiaView
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override SKSize MeasureOverride(SKSize availableSize)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return new SKSize(availableSize.Width < float.MaxValue ? Math.Min(availableSize.Width, 200) : 200, 40);
|
||||
return new Size(availableSize.Width < double.MaxValue ? Math.Min(availableSize.Width, 200) : 200, 40);
|
||||
}
|
||||
|
||||
protected override bool HitTestPopupArea(float x, float y)
|
||||
@@ -611,7 +612,7 @@ public class SkiaTimePicker : SkiaView
|
||||
|
||||
if (_isOpen)
|
||||
{
|
||||
var popupRect = GetPopupRect(screenBounds);
|
||||
var popupRect = GetPopupRect(new SKRect((float)screenBounds.Left, (float)screenBounds.Top, (float)screenBounds.Right, (float)screenBounds.Bottom));
|
||||
return popupRect.Contains(x, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui.Controls.Shapes;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform.Linux;
|
||||
using Microsoft.Maui.Platform.Linux.Handlers;
|
||||
using Microsoft.Maui.Platform.Linux.Rendering;
|
||||
@@ -701,14 +702,14 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
#endregion
|
||||
|
||||
private bool _disposed;
|
||||
private SKRect _bounds;
|
||||
private Rect _bounds;
|
||||
private SkiaView? _parent;
|
||||
private readonly List<SkiaView> _children = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute bounds of this view in screen coordinates.
|
||||
/// </summary>
|
||||
public SKRect GetAbsoluteBounds()
|
||||
public Rect GetAbsoluteBounds()
|
||||
{
|
||||
var bounds = Bounds;
|
||||
var current = Parent;
|
||||
@@ -717,11 +718,11 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
// Adjust for scroll offset if parent is a ScrollView
|
||||
if (current is SkiaScrollView scrollView)
|
||||
{
|
||||
bounds = new SKRect(
|
||||
bounds = new Rect(
|
||||
bounds.Left - scrollView.ScrollX,
|
||||
bounds.Top - scrollView.ScrollY,
|
||||
bounds.Right - scrollView.ScrollX,
|
||||
bounds.Bottom - scrollView.ScrollY);
|
||||
bounds.Width,
|
||||
bounds.Height);
|
||||
}
|
||||
current = current.Parent;
|
||||
}
|
||||
@@ -730,8 +731,9 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bounds of this view in parent coordinates.
|
||||
/// Uses MAUI Rect for public API compliance.
|
||||
/// </summary>
|
||||
public SKRect Bounds
|
||||
public Rect Bounds
|
||||
{
|
||||
get => _bounds;
|
||||
set
|
||||
@@ -744,6 +746,15 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bounds as SKRect for internal SkiaSharp rendering.
|
||||
/// </summary>
|
||||
internal SKRect BoundsSK => new SKRect(
|
||||
(float)_bounds.Left,
|
||||
(float)_bounds.Top,
|
||||
(float)_bounds.Right,
|
||||
(float)_bounds.Bottom);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether this view is visible.
|
||||
/// </summary>
|
||||
@@ -1115,7 +1126,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
/// <summary>
|
||||
/// Gets the bounds of this view in screen coordinates (accounting for scroll offsets).
|
||||
/// </summary>
|
||||
public SKRect ScreenBounds
|
||||
public Rect ScreenBounds
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1127,11 +1138,11 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
{
|
||||
if (parent is SkiaScrollView scrollView)
|
||||
{
|
||||
bounds = new SKRect(
|
||||
bounds = new Rect(
|
||||
bounds.Left - scrollView.ScrollX,
|
||||
bounds.Top - scrollView.ScrollY,
|
||||
bounds.Right - scrollView.ScrollX,
|
||||
bounds.Bottom - scrollView.ScrollY);
|
||||
bounds.Width,
|
||||
bounds.Height);
|
||||
}
|
||||
parent = parent.Parent;
|
||||
}
|
||||
@@ -1142,8 +1153,14 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
|
||||
/// <summary>
|
||||
/// Gets the desired size calculated during measure.
|
||||
/// Uses MAUI Size for public API compliance.
|
||||
/// </summary>
|
||||
public SKSize DesiredSize { get; protected set; }
|
||||
public Size DesiredSize { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the desired size as SKSize for internal SkiaSharp rendering.
|
||||
/// </summary>
|
||||
internal SKSize DesiredSizeSK => new SKSize((float)DesiredSize.Width, (float)DesiredSize.Height);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the child views.
|
||||
@@ -1262,7 +1279,9 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
// Notify rendering engine of dirty region
|
||||
if (Bounds.Width > 0 && Bounds.Height > 0)
|
||||
{
|
||||
SkiaRenderingEngine.Current?.InvalidateRegion(Bounds);
|
||||
SkiaRenderingEngine.Current?.InvalidateRegion(new SKRect(
|
||||
(float)Bounds.Left, (float)Bounds.Top,
|
||||
(float)Bounds.Right, (float)Bounds.Bottom));
|
||||
}
|
||||
|
||||
if (_parent != null)
|
||||
@@ -1280,7 +1299,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
/// </summary>
|
||||
public void InvalidateMeasure()
|
||||
{
|
||||
DesiredSize = SKSize.Empty;
|
||||
DesiredSize = Size.Zero;
|
||||
_parent?.InvalidateMeasure();
|
||||
Invalidate();
|
||||
}
|
||||
@@ -1297,14 +1316,17 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
|
||||
canvas.Save();
|
||||
|
||||
// Get SKRect for internal rendering
|
||||
var skBounds = BoundsSK;
|
||||
|
||||
// Apply transforms if any are set
|
||||
if (Scale != 1.0 || ScaleX != 1.0 || ScaleY != 1.0 ||
|
||||
Rotation != 0.0 || RotationX != 0.0 || RotationY != 0.0 ||
|
||||
TranslationX != 0.0 || TranslationY != 0.0)
|
||||
{
|
||||
// Calculate anchor point in absolute coordinates
|
||||
float anchorAbsX = Bounds.Left + (float)(Bounds.Width * AnchorX);
|
||||
float anchorAbsY = Bounds.Top + (float)(Bounds.Height * AnchorY);
|
||||
float anchorAbsX = skBounds.Left + (float)(Bounds.Width * AnchorX);
|
||||
float anchorAbsY = skBounds.Top + (float)(Bounds.Height * AnchorY);
|
||||
|
||||
// Move origin to anchor point
|
||||
canvas.Translate(anchorAbsX, anchorAbsY);
|
||||
@@ -1342,20 +1364,20 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
// Draw shadow if set
|
||||
if (Shadow != null)
|
||||
{
|
||||
DrawShadow(canvas, Bounds);
|
||||
DrawShadow(canvas, skBounds);
|
||||
}
|
||||
|
||||
// Apply clip geometry if set
|
||||
if (Clip != null)
|
||||
{
|
||||
ApplyClip(canvas, Bounds);
|
||||
ApplyClip(canvas, skBounds);
|
||||
}
|
||||
|
||||
// Draw background at absolute bounds
|
||||
DrawBackground(canvas, Bounds);
|
||||
DrawBackground(canvas, skBounds);
|
||||
|
||||
// Draw content at absolute bounds
|
||||
OnDraw(canvas, Bounds);
|
||||
OnDraw(canvas, skBounds);
|
||||
|
||||
// Draw children - they draw at their own absolute bounds
|
||||
foreach (var child in _children)
|
||||
@@ -1530,8 +1552,9 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
|
||||
/// <summary>
|
||||
/// Measures the desired size of this view.
|
||||
/// Uses MAUI Size for public API compliance.
|
||||
/// </summary>
|
||||
public SKSize Measure(SKSize availableSize)
|
||||
public Size Measure(Size availableSize)
|
||||
{
|
||||
DesiredSize = MeasureOverride(availableSize);
|
||||
return DesiredSize;
|
||||
@@ -1539,36 +1562,40 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
|
||||
|
||||
/// <summary>
|
||||
/// Override to provide custom measurement.
|
||||
/// Uses MAUI Size for public API compliance.
|
||||
/// </summary>
|
||||
protected virtual SKSize MeasureOverride(SKSize availableSize)
|
||||
protected virtual Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var width = WidthRequest >= 0 ? (float)WidthRequest : 0;
|
||||
var height = HeightRequest >= 0 ? (float)HeightRequest : 0;
|
||||
return new SKSize(width, height);
|
||||
var width = WidthRequest >= 0 ? WidthRequest : 0;
|
||||
var height = HeightRequest >= 0 ? HeightRequest : 0;
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Arranges this view within the given bounds.
|
||||
/// Uses MAUI Rect for public API compliance.
|
||||
/// </summary>
|
||||
public virtual void Arrange(SKRect bounds)
|
||||
public virtual void Arrange(Rect bounds)
|
||||
{
|
||||
Bounds = ArrangeOverride(bounds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to customize arrangement within the given bounds.
|
||||
/// Uses MAUI Rect for public API compliance.
|
||||
/// </summary>
|
||||
protected virtual SKRect ArrangeOverride(SKRect bounds)
|
||||
protected virtual Rect ArrangeOverride(Rect bounds)
|
||||
{
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs hit testing to find the view at the given point.
|
||||
/// Uses MAUI Point for public API compliance.
|
||||
/// </summary>
|
||||
public virtual SkiaView? HitTest(SKPoint point)
|
||||
public virtual SkiaView? HitTest(Point point)
|
||||
{
|
||||
return HitTest(point.X, point.Y);
|
||||
return HitTest((float)point.X, (float)point.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -137,7 +137,7 @@ public class SkiaWebView : SkiaView
|
||||
private string? _userAgent;
|
||||
private CookieContainer _cookies = new();
|
||||
private double _loadProgress;
|
||||
private SKRect _lastBounds;
|
||||
private Rect _lastBounds;
|
||||
private int _lastMainX;
|
||||
private int _lastMainY;
|
||||
private int _lastPosX;
|
||||
@@ -1340,7 +1340,7 @@ public class SkiaWebView : SkiaView
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
{
|
||||
base.OnDraw(canvas, bounds);
|
||||
Bounds = bounds;
|
||||
Bounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
|
||||
if (_isInitialized)
|
||||
{
|
||||
@@ -1364,7 +1364,7 @@ public class SkiaWebView : SkiaView
|
||||
if (needsUpdate && bounds.Width > 50f && bounds.Height > 50f)
|
||||
{
|
||||
PositionUsingGtk();
|
||||
_lastBounds = bounds;
|
||||
_lastBounds = new Rect(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="3.116.1" />
|
||||
<!-- Match main project SkiaSharp version for native library compatibility -->
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.9" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
@@ -42,7 +43,7 @@ public class SkiaButtonTests
|
||||
var button = new SkiaButton { Text = "Test" };
|
||||
|
||||
// Act
|
||||
var size = button.Measure(new SKSize(1000, 1000));
|
||||
var size = button.Measure(new Size(1000, 1000));
|
||||
|
||||
// Assert
|
||||
size.Width.Should().BeGreaterThan(0);
|
||||
@@ -61,7 +62,7 @@ public class SkiaButtonTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var size = button.Measure(new SKSize(1000, 1000));
|
||||
var size = button.Measure(new Size(1000, 1000));
|
||||
|
||||
// Assert - Measure returns content-based size
|
||||
size.Width.Should().BeGreaterThan(0);
|
||||
@@ -100,7 +101,7 @@ public class SkiaButtonTests
|
||||
{
|
||||
// Arrange
|
||||
var button = new SkiaButton { Text = "Test" };
|
||||
button.Bounds = new SKRect(0, 0, 100, 40);
|
||||
button.Bounds = new Rect(0, 0, 100, 40);
|
||||
|
||||
using var surface = SKSurface.Create(new SKImageInfo(200, 100));
|
||||
var canvas = surface.Canvas;
|
||||
@@ -129,7 +130,7 @@ public class SkiaButtonTests
|
||||
{
|
||||
// Arrange
|
||||
var button = new SkiaButton();
|
||||
var color = new SKColor(0, 255, 0);
|
||||
var color = Microsoft.Maui.Graphics.Color.FromRgb(0, 255, 0);
|
||||
|
||||
// Act
|
||||
button.BackgroundColor = color;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
|
||||
@@ -15,7 +16,7 @@ public class SkiaCarouselViewTests
|
||||
|
||||
Assert.Equal(0, carousel.Position);
|
||||
Assert.False(carousel.Loop);
|
||||
Assert.Equal(0f, carousel.PeekAreaInsets);
|
||||
Assert.Equal(0.0, carousel.PeekAreaInsets);
|
||||
Assert.Equal(0, carousel.ItemCount);
|
||||
}
|
||||
|
||||
@@ -71,9 +72,9 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
|
||||
carousel.PeekAreaInsets = 20f;
|
||||
carousel.PeekAreaInsets = 20.0;
|
||||
|
||||
Assert.Equal(20f, carousel.PeekAreaInsets);
|
||||
Assert.Equal(20.0, carousel.PeekAreaInsets);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -180,9 +181,9 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
|
||||
carousel.IndicatorColor = SKColors.Gray;
|
||||
carousel.IndicatorColor = Colors.Grey;
|
||||
|
||||
Assert.Equal(SKColors.Gray, carousel.IndicatorColor);
|
||||
Assert.Equal(Colors.Grey, carousel.IndicatorColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -190,9 +191,9 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
|
||||
carousel.SelectedIndicatorColor = SKColors.Blue;
|
||||
carousel.SelectedIndicatorColor = Colors.Blue;
|
||||
|
||||
Assert.Equal(SKColors.Blue, carousel.SelectedIndicatorColor);
|
||||
Assert.Equal(Colors.Blue, carousel.SelectedIndicatorColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -213,7 +214,7 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
|
||||
Assert.Equal(0f, carousel.ItemSpacing);
|
||||
Assert.Equal(0.0, carousel.ItemSpacing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -221,9 +222,9 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
|
||||
carousel.ItemSpacing = 16f;
|
||||
carousel.ItemSpacing = 16.0;
|
||||
|
||||
Assert.Equal(16f, carousel.ItemSpacing);
|
||||
Assert.Equal(16.0, carousel.ItemSpacing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -245,7 +246,7 @@ public class SkiaCarouselViewTests
|
||||
{
|
||||
var carousel = new SkiaCarouselView();
|
||||
carousel.AddItem(new SkiaLabel { Text = "Item" });
|
||||
carousel.Arrange(new SKRect(0, 0, 300, 200));
|
||||
carousel.Arrange(new Rect(0, 0, 300, 200));
|
||||
|
||||
var hit = carousel.HitTest(150, 100);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
@@ -104,7 +105,7 @@ public class SkiaEntryTests
|
||||
{
|
||||
// Arrange
|
||||
var entry = new SkiaEntry { Text = "Hello" };
|
||||
entry.Bounds = new SKRect(0, 0, 200, 40);
|
||||
entry.Bounds = new Rect(0, 0, 200, 40);
|
||||
entry.OnFocusGained();
|
||||
var originalLength = entry.Text.Length;
|
||||
|
||||
@@ -120,7 +121,7 @@ public class SkiaEntryTests
|
||||
{
|
||||
// Arrange
|
||||
var entry = new SkiaEntry { Text = "Hello" };
|
||||
entry.Bounds = new SKRect(0, 0, 200, 40);
|
||||
entry.Bounds = new Rect(0, 0, 200, 40);
|
||||
entry.OnFocusGained();
|
||||
|
||||
// Act - Verify OnKeyDown doesn't throw
|
||||
@@ -136,7 +137,7 @@ public class SkiaEntryTests
|
||||
// Arrange
|
||||
var entry = new SkiaEntry { Text = "Hello", IsReadOnly = true };
|
||||
var originalText = entry.Text;
|
||||
entry.Bounds = new SKRect(0, 0, 200, 40);
|
||||
entry.Bounds = new Rect(0, 0, 200, 40);
|
||||
entry.OnFocusGained();
|
||||
|
||||
// Act
|
||||
@@ -164,7 +165,7 @@ public class SkiaEntryTests
|
||||
{
|
||||
// Arrange
|
||||
var entry = new SkiaEntry { Text = "Test", Placeholder = "Enter..." };
|
||||
entry.Bounds = new SKRect(0, 0, 200, 40);
|
||||
entry.Bounds = new Rect(0, 0, 200, 40);
|
||||
|
||||
using var surface = SKSurface.Create(new SKImageInfo(300, 100));
|
||||
var canvas = surface.Canvas;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
|
||||
@@ -66,9 +67,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.IndicatorColor = SKColors.Gray;
|
||||
indicator.IndicatorColor = Colors.Grey;
|
||||
|
||||
Assert.Equal(SKColors.Gray, indicator.IndicatorColor);
|
||||
Assert.Equal(Colors.Grey, indicator.IndicatorColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -76,9 +77,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.SelectedIndicatorColor = SKColors.Blue;
|
||||
indicator.SelectedIndicatorColor = Colors.Blue;
|
||||
|
||||
Assert.Equal(SKColors.Blue, indicator.SelectedIndicatorColor);
|
||||
Assert.Equal(Colors.Blue, indicator.SelectedIndicatorColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -86,9 +87,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.IndicatorSize = 12f;
|
||||
indicator.IndicatorSize = 12.0;
|
||||
|
||||
Assert.Equal(12f, indicator.IndicatorSize);
|
||||
Assert.Equal(12.0, indicator.IndicatorSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -96,9 +97,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.SelectedIndicatorSize = 16f;
|
||||
indicator.SelectedIndicatorSize = 16.0;
|
||||
|
||||
Assert.Equal(16f, indicator.SelectedIndicatorSize);
|
||||
Assert.Equal(16.0, indicator.SelectedIndicatorSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -106,9 +107,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.IndicatorSpacing = 10f;
|
||||
indicator.IndicatorSpacing = 10.0;
|
||||
|
||||
Assert.Equal(10f, indicator.IndicatorSpacing);
|
||||
Assert.Equal(10.0, indicator.IndicatorSpacing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -164,9 +165,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.BorderColor = SKColors.Black;
|
||||
indicator.BorderColor = Colors.Black;
|
||||
|
||||
Assert.Equal(SKColors.Black, indicator.BorderColor);
|
||||
Assert.Equal(Colors.Black, indicator.BorderColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -174,9 +175,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
|
||||
indicator.BorderWidth = 2f;
|
||||
indicator.BorderWidth = 2.0;
|
||||
|
||||
Assert.Equal(2f, indicator.BorderWidth);
|
||||
Assert.Equal(2.0, indicator.BorderWidth);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -232,9 +233,9 @@ public class SkiaIndicatorViewTests
|
||||
{
|
||||
var indicator = new SkiaIndicatorView();
|
||||
indicator.Count = 5;
|
||||
indicator.IndicatorSize = 10f;
|
||||
indicator.IndicatorSpacing = 8f;
|
||||
indicator.Arrange(new SKRect(0, 0, 200, 20));
|
||||
indicator.IndicatorSize = 10.0;
|
||||
indicator.IndicatorSpacing = 8.0;
|
||||
indicator.Arrange(new Rect(0, 0, 200, 20));
|
||||
|
||||
var hit = indicator.HitTest(100, 10);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
|
||||
@@ -145,9 +146,9 @@ public class SkiaMenuBarTests
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
|
||||
menuBar.BackgroundColor = SKColors.White;
|
||||
menuBar.BackgroundColor = Colors.White;
|
||||
|
||||
Assert.Equal(SKColors.White, menuBar.BackgroundColor);
|
||||
Assert.Equal(Colors.White, menuBar.BackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -155,9 +156,9 @@ public class SkiaMenuBarTests
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
|
||||
menuBar.TextColor = SKColors.Black;
|
||||
menuBar.TextColor = Colors.Black;
|
||||
|
||||
Assert.Equal(SKColors.Black, menuBar.TextColor);
|
||||
Assert.Equal(Colors.Black, menuBar.TextColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -165,9 +166,9 @@ public class SkiaMenuBarTests
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
|
||||
menuBar.HoverBackgroundColor = SKColors.LightGray;
|
||||
menuBar.HoverBackgroundColor = Colors.LightGrey;
|
||||
|
||||
Assert.Equal(SKColors.LightGray, menuBar.HoverBackgroundColor);
|
||||
Assert.Equal(Colors.LightGrey, menuBar.HoverBackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -175,9 +176,9 @@ public class SkiaMenuBarTests
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
|
||||
menuBar.ActiveBackgroundColor = SKColors.DarkGray;
|
||||
menuBar.ActiveBackgroundColor = Colors.DarkGrey;
|
||||
|
||||
Assert.Equal(SKColors.DarkGray, menuBar.ActiveBackgroundColor);
|
||||
Assert.Equal(Colors.DarkGrey, menuBar.ActiveBackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -186,7 +187,7 @@ public class SkiaMenuBarTests
|
||||
var menuBar = new SkiaMenuBar();
|
||||
menuBar.BarHeight = 30f;
|
||||
|
||||
var size = menuBar.Measure(new SKSize(800, 600));
|
||||
var size = menuBar.Measure(new Size(800, 600));
|
||||
|
||||
Assert.Equal(30f, size.Height);
|
||||
}
|
||||
@@ -196,7 +197,7 @@ public class SkiaMenuBarTests
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
|
||||
var size = menuBar.Measure(new SKSize(800, 600));
|
||||
var size = menuBar.Measure(new Size(800, 600));
|
||||
|
||||
Assert.Equal(800f, size.Width);
|
||||
}
|
||||
@@ -205,7 +206,7 @@ public class SkiaMenuBarTests
|
||||
public void HitTest_WithinBounds_ReturnsMenuBar()
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
menuBar.Arrange(new SKRect(0, 0, 800, 28));
|
||||
menuBar.Arrange(new Rect(0, 0, 800, 28));
|
||||
|
||||
var hit = menuBar.HitTest(400, 14);
|
||||
|
||||
@@ -216,7 +217,7 @@ public class SkiaMenuBarTests
|
||||
public void HitTest_OutsideBounds_ReturnsNull()
|
||||
{
|
||||
var menuBar = new SkiaMenuBar();
|
||||
menuBar.Arrange(new SKRect(0, 0, 800, 28));
|
||||
menuBar.Arrange(new Rect(0, 0, 800, 28));
|
||||
|
||||
var hit = menuBar.HitTest(400, 50);
|
||||
|
||||
@@ -266,9 +267,9 @@ public class SkiaMenuFlyoutTests
|
||||
{
|
||||
var flyout = new SkiaMenuFlyout();
|
||||
|
||||
flyout.BackgroundColor = SKColors.White;
|
||||
flyout.BackgroundColor = Colors.White;
|
||||
|
||||
Assert.Equal(SKColors.White, flyout.BackgroundColor);
|
||||
Assert.Equal(Colors.White, flyout.BackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -276,9 +277,9 @@ public class SkiaMenuFlyoutTests
|
||||
{
|
||||
var flyout = new SkiaMenuFlyout();
|
||||
|
||||
flyout.TextColor = SKColors.Black;
|
||||
flyout.TextColor = Colors.Black;
|
||||
|
||||
Assert.Equal(SKColors.Black, flyout.TextColor);
|
||||
Assert.Equal(Colors.Black, flyout.TextColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -286,9 +287,9 @@ public class SkiaMenuFlyoutTests
|
||||
{
|
||||
var flyout = new SkiaMenuFlyout();
|
||||
|
||||
flyout.DisabledTextColor = new SKColor(160, 160, 160);
|
||||
flyout.DisabledTextColor = Color.FromRgb(160, 160, 160);
|
||||
|
||||
Assert.Equal(new SKColor(160, 160, 160), flyout.DisabledTextColor);
|
||||
Assert.Equal(Color.FromRgb(160, 160, 160), flyout.DisabledTextColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -296,9 +297,9 @@ public class SkiaMenuFlyoutTests
|
||||
{
|
||||
var flyout = new SkiaMenuFlyout();
|
||||
|
||||
flyout.HoverBackgroundColor = SKColors.LightBlue;
|
||||
flyout.HoverBackgroundColor = Colors.LightBlue;
|
||||
|
||||
Assert.Equal(SKColors.LightBlue, flyout.HoverBackgroundColor);
|
||||
Assert.Equal(Colors.LightBlue, flyout.HoverBackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -306,9 +307,9 @@ public class SkiaMenuFlyoutTests
|
||||
{
|
||||
var flyout = new SkiaMenuFlyout();
|
||||
|
||||
flyout.SeparatorColor = SKColors.Gray;
|
||||
flyout.SeparatorColor = Colors.Grey;
|
||||
|
||||
Assert.Equal(SKColors.Gray, flyout.SeparatorColor);
|
||||
Assert.Equal(Colors.Grey, flyout.SeparatorColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
|
||||
@@ -87,7 +88,7 @@ public class SkiaRefreshViewTests
|
||||
{
|
||||
var refreshView = new SkiaRefreshView();
|
||||
|
||||
Assert.Equal(new SKColor(33, 150, 243), refreshView.RefreshColor);
|
||||
Assert.Equal(Color.FromRgb(33, 150, 243), refreshView.RefreshColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -95,9 +96,9 @@ public class SkiaRefreshViewTests
|
||||
{
|
||||
var refreshView = new SkiaRefreshView();
|
||||
|
||||
refreshView.RefreshColor = SKColors.Red;
|
||||
refreshView.RefreshColor = Colors.Red;
|
||||
|
||||
Assert.Equal(SKColors.Red, refreshView.RefreshColor);
|
||||
Assert.Equal(Colors.Red, refreshView.RefreshColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -105,7 +106,7 @@ public class SkiaRefreshViewTests
|
||||
{
|
||||
var refreshView = new SkiaRefreshView();
|
||||
|
||||
Assert.Equal(SKColors.White, refreshView.RefreshBackgroundColor);
|
||||
Assert.Equal(Colors.White, refreshView.RefreshBackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -113,9 +114,9 @@ public class SkiaRefreshViewTests
|
||||
{
|
||||
var refreshView = new SkiaRefreshView();
|
||||
|
||||
refreshView.RefreshBackgroundColor = SKColors.LightGray;
|
||||
refreshView.RefreshBackgroundColor = Colors.LightGrey;
|
||||
|
||||
Assert.Equal(SKColors.LightGray, refreshView.RefreshBackgroundColor);
|
||||
Assert.Equal(Colors.LightGrey, refreshView.RefreshBackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -135,7 +136,7 @@ public class SkiaRefreshViewTests
|
||||
var refreshView = new SkiaRefreshView();
|
||||
var content = new SkiaLabel { Text = "Test" };
|
||||
refreshView.Content = content;
|
||||
refreshView.Arrange(new SKRect(0, 0, 200, 400));
|
||||
refreshView.Arrange(new Rect(0, 0, 200, 400));
|
||||
|
||||
var hit = refreshView.HitTest(100, 200);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
@@ -46,8 +47,8 @@ public class SkiaScrollViewTests
|
||||
content.AddChild(new SkiaButton { Text = "1", RequestedHeight = 100 });
|
||||
content.AddChild(new SkiaButton { Text = "2", RequestedHeight = 100 });
|
||||
scrollView.Content = content;
|
||||
scrollView.Measure(new SKSize(200, 100)); // Viewport smaller than content
|
||||
scrollView.Arrange(new SKRect(0, 0, 200, 100));
|
||||
scrollView.Measure(new Size(200, 100)); // Viewport smaller than content
|
||||
scrollView.Arrange(new Rect(0, 0, 200, 100));
|
||||
|
||||
// Act - Try to scroll below 0
|
||||
scrollView.ScrollY = -50;
|
||||
@@ -67,8 +68,8 @@ public class SkiaScrollViewTests
|
||||
content.AddChild(new SkiaButton { Text = $"Button {i}", RequestedHeight = 50 });
|
||||
}
|
||||
scrollView.Content = content;
|
||||
scrollView.Measure(new SKSize(200, 300));
|
||||
scrollView.Arrange(new SKRect(0, 0, 200, 300));
|
||||
scrollView.Measure(new Size(200, 300));
|
||||
scrollView.Arrange(new Rect(0, 0, 200, 300));
|
||||
|
||||
var initialScrollY = scrollView.ScrollY;
|
||||
|
||||
@@ -89,8 +90,8 @@ public class SkiaScrollViewTests
|
||||
content.AddChild(button);
|
||||
scrollView.Content = content;
|
||||
|
||||
scrollView.Measure(new SKSize(200, 200));
|
||||
scrollView.Arrange(new SKRect(0, 0, 200, 200));
|
||||
scrollView.Measure(new Size(200, 200));
|
||||
scrollView.Arrange(new Rect(0, 0, 200, 200));
|
||||
|
||||
// Act
|
||||
var hit = scrollView.HitTest(100, 25);
|
||||
@@ -111,8 +112,8 @@ public class SkiaScrollViewTests
|
||||
}
|
||||
scrollView.Content = content;
|
||||
|
||||
scrollView.Measure(new SKSize(200, 100));
|
||||
scrollView.Arrange(new SKRect(0, 0, 200, 100));
|
||||
scrollView.Measure(new Size(200, 100));
|
||||
scrollView.Arrange(new Rect(0, 0, 200, 100));
|
||||
|
||||
// Act
|
||||
scrollView.ScrollY = 50;
|
||||
@@ -129,7 +130,7 @@ public class SkiaScrollViewTests
|
||||
var content = new SkiaStackLayout();
|
||||
content.AddChild(new SkiaButton { Text = "Test" });
|
||||
scrollView.Content = content;
|
||||
scrollView.Bounds = new SKRect(0, 0, 200, 200);
|
||||
scrollView.Bounds = new Rect(0, 0, 200, 200);
|
||||
|
||||
using var surface = SKSurface.Create(new SKImageInfo(300, 300));
|
||||
var canvas = surface.Canvas;
|
||||
@@ -150,8 +151,8 @@ public class SkiaScrollViewTests
|
||||
content.AddChild(new SkiaButton { Text = $"Button {i}", RequestedHeight = 50 });
|
||||
}
|
||||
scrollView.Content = content;
|
||||
scrollView.Measure(new SKSize(200, 200));
|
||||
scrollView.Arrange(new SKRect(0, 0, 200, 200));
|
||||
scrollView.Measure(new Size(200, 200));
|
||||
scrollView.Arrange(new Rect(0, 0, 200, 200));
|
||||
|
||||
// Act - Scroll to maximum
|
||||
scrollView.ScrollY = 10000; // Very large value
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
@@ -19,7 +20,7 @@ public class SkiaSliderTests
|
||||
// Assert
|
||||
slider.Value.Should().Be(0);
|
||||
slider.Minimum.Should().Be(0);
|
||||
slider.Maximum.Should().Be(100); // Default maximum is 100
|
||||
slider.Maximum.Should().Be(1.0); // MAUI Slider.Maximum default is 1.0
|
||||
slider.IsEnabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ public class SkiaSliderTests
|
||||
{
|
||||
// Arrange
|
||||
var slider = new SkiaSlider { Value = 50, Minimum = 0, Maximum = 100 };
|
||||
slider.Bounds = new SKRect(0, 0, 200, 40);
|
||||
slider.Bounds = new Rect(0, 0, 200, 40);
|
||||
|
||||
using var surface = SKSurface.Create(new SKImageInfo(300, 100));
|
||||
var canvas = surface.Canvas;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using FluentAssertions;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
@@ -68,7 +69,7 @@ public class SkiaStackLayoutTests
|
||||
layout.AddChild(new SkiaButton { Text = "3" });
|
||||
|
||||
// Act
|
||||
var size = layout.Measure(new SKSize(200, 1000));
|
||||
var size = layout.Measure(new Size(200, 1000));
|
||||
|
||||
// Assert - Size should account for 3 children with spacing
|
||||
size.Height.Should().BeGreaterThan(0);
|
||||
@@ -89,7 +90,7 @@ public class SkiaStackLayoutTests
|
||||
layout.AddChild(new SkiaButton { Text = "3" });
|
||||
|
||||
// Act
|
||||
var size = layout.Measure(new SKSize(1000, 200));
|
||||
var size = layout.Measure(new Size(1000, 200));
|
||||
|
||||
// Assert - Size should account for 3 children with spacing
|
||||
size.Width.Should().BeGreaterThan(0);
|
||||
@@ -111,8 +112,8 @@ public class SkiaStackLayoutTests
|
||||
layout.AddChild(button2);
|
||||
|
||||
// Act
|
||||
layout.Measure(new SKSize(200, 500));
|
||||
layout.Arrange(new SKRect(0, 0, 200, 500));
|
||||
layout.Measure(new Size(200, 500));
|
||||
layout.Arrange(new Rect(0, 0, 200, 500));
|
||||
|
||||
// Assert - Button2 should be below Button1
|
||||
button2.Bounds.Top.Should().BeGreaterThan(button1.Bounds.Top);
|
||||
@@ -133,8 +134,8 @@ public class SkiaStackLayoutTests
|
||||
layout.AddChild(button2);
|
||||
|
||||
// Act
|
||||
layout.Measure(new SKSize(500, 200));
|
||||
layout.Arrange(new SKRect(0, 0, 500, 200));
|
||||
layout.Measure(new Size(500, 200));
|
||||
layout.Arrange(new Rect(0, 0, 500, 200));
|
||||
|
||||
// Assert - Button2 should be to the right of Button1
|
||||
button2.Bounds.Left.Should().BeGreaterThan(button1.Bounds.Left);
|
||||
@@ -147,14 +148,14 @@ public class SkiaStackLayoutTests
|
||||
var layout = new SkiaStackLayout
|
||||
{
|
||||
Orientation = PlatformStackOrientation.Vertical,
|
||||
Padding = new SKRect(20, 20, 20, 20)
|
||||
Padding = new Microsoft.Maui.Thickness(20, 20, 20, 20)
|
||||
};
|
||||
var button = new SkiaButton { Text = "Test" };
|
||||
layout.AddChild(button);
|
||||
|
||||
// Act
|
||||
layout.Measure(new SKSize(300, 300));
|
||||
layout.Arrange(new SKRect(0, 0, 300, 300));
|
||||
layout.Measure(new Size(300, 300));
|
||||
layout.Arrange(new Rect(0, 0, 300, 300));
|
||||
|
||||
// Assert - Padding property is set
|
||||
layout.Padding.Left.Should().Be(20);
|
||||
@@ -168,7 +169,7 @@ public class SkiaStackLayoutTests
|
||||
var layout = new SkiaStackLayout();
|
||||
layout.AddChild(new SkiaButton { Text = "1" });
|
||||
layout.AddChild(new SkiaButton { Text = "2" });
|
||||
layout.Bounds = new SKRect(0, 0, 200, 200);
|
||||
layout.Bounds = new Rect(0, 0, 200, 200);
|
||||
|
||||
using var surface = SKSurface.Create(new SKImageInfo(300, 300));
|
||||
var canvas = surface.Canvas;
|
||||
@@ -188,8 +189,8 @@ public class SkiaStackLayoutTests
|
||||
layout.AddChild(button1);
|
||||
layout.AddChild(button2);
|
||||
|
||||
layout.Measure(new SKSize(200, 200));
|
||||
layout.Arrange(new SKRect(0, 0, 200, 200));
|
||||
layout.Measure(new Size(200, 200));
|
||||
layout.Arrange(new Rect(0, 0, 200, 200));
|
||||
|
||||
// Act - Hit test within layout bounds
|
||||
var hit = layout.HitTest(100, 10);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.Maui.Graphics;
|
||||
using SkiaSharp;
|
||||
using Xunit;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class SkiaSwipeViewTests
|
||||
public void LeftItems_CanAddItems()
|
||||
{
|
||||
var swipeView = new SkiaSwipeView();
|
||||
var item = new SwipeItem { Text = "Delete", BackgroundColor = SKColors.Red };
|
||||
var item = new SwipeItem { Text = "Delete", BackgroundColor = Colors.Red };
|
||||
|
||||
swipeView.LeftItems.Add(item);
|
||||
|
||||
@@ -48,7 +49,7 @@ public class SkiaSwipeViewTests
|
||||
public void RightItems_CanAddItems()
|
||||
{
|
||||
var swipeView = new SkiaSwipeView();
|
||||
var item = new SwipeItem { Text = "Archive", BackgroundColor = SKColors.Blue };
|
||||
var item = new SwipeItem { Text = "Archive", BackgroundColor = Colors.Blue };
|
||||
|
||||
swipeView.RightItems.Add(item);
|
||||
|
||||
@@ -146,17 +147,17 @@ public class SkiaSwipeViewTests
|
||||
[Fact]
|
||||
public void SwipeItem_TextColor_CanBeSet()
|
||||
{
|
||||
var item = new SwipeItem { TextColor = SKColors.Yellow };
|
||||
var item = new SwipeItem { TextColor = Colors.Yellow };
|
||||
|
||||
Assert.Equal(SKColors.Yellow, item.TextColor);
|
||||
Assert.Equal(Colors.Yellow, item.TextColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SwipeItem_BackgroundColor_CanBeSet()
|
||||
{
|
||||
var item = new SwipeItem { BackgroundColor = SKColors.Green };
|
||||
var item = new SwipeItem { BackgroundColor = Colors.Green };
|
||||
|
||||
Assert.Equal(SKColors.Green, item.BackgroundColor);
|
||||
Assert.Equal(Colors.Green, item.BackgroundColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -190,7 +191,7 @@ public class SkiaSwipeViewTests
|
||||
{
|
||||
var swipeView = new SkiaSwipeView();
|
||||
swipeView.Content = new SkiaLabel { Text = "Content" };
|
||||
swipeView.Arrange(new SKRect(0, 0, 300, 50));
|
||||
swipeView.Arrange(new Rect(0, 0, 300, 50));
|
||||
|
||||
var hit = swipeView.HitTest(150, 25);
|
||||
|
||||
@@ -203,7 +204,7 @@ public class SkiaSwipeViewTests
|
||||
var swipeView = new SkiaSwipeView();
|
||||
swipeView.Content = new SkiaLabel { Text = "Test" };
|
||||
|
||||
var size = swipeView.Measure(new SKSize(300, 100));
|
||||
var size = swipeView.Measure(new Size(300, 100));
|
||||
|
||||
Assert.True(size.Width <= 300);
|
||||
Assert.True(size.Height <= 100);
|
||||
|
||||
Reference in New Issue
Block a user