More fixes
This commit is contained in:
@@ -341,6 +341,14 @@ public class SkiaBorder : SkiaLayoutView
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to skip rectangular background - OnDraw handles it with the correct shape.
|
||||
/// </summary>
|
||||
protected override void DrawBackground(SKCanvas canvas, SKRect bounds)
|
||||
{
|
||||
// Don't draw rectangular background - OnDraw draws background with shape path
|
||||
}
|
||||
|
||||
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
||||
{
|
||||
float strokeThickness = (float)StrokeThickness;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
nameof(BorderColor),
|
||||
typeof(Color),
|
||||
typeof(SkiaEditor),
|
||||
Color.FromRgb(0xBD, 0xBD, 0xBD),
|
||||
Colors.Transparent,
|
||||
BindingMode.TwoWay,
|
||||
propertyChanged: (b, o, n) => ((SkiaEditor)b).Invalidate());
|
||||
|
||||
@@ -301,7 +301,7 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
nameof(EditorBackgroundColor),
|
||||
typeof(Color),
|
||||
typeof(SkiaEditor),
|
||||
Colors.White,
|
||||
Colors.Transparent,
|
||||
BindingMode.TwoWay,
|
||||
propertyChanged: (b, o, n) => ((SkiaEditor)b).Invalidate());
|
||||
|
||||
@@ -891,15 +891,18 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
};
|
||||
canvas.DrawRoundRect(new SKRoundRect(bounds, cornerRadius), bgPaint);
|
||||
|
||||
// Draw border
|
||||
using var borderPaint = new SKPaint
|
||||
// Draw border only if BorderColor is not transparent
|
||||
if (BorderColor != null && BorderColor != Colors.Transparent && BorderColor.Alpha > 0)
|
||||
{
|
||||
Color = IsFocused ? ToSKColor(CursorColor) : ToSKColor(BorderColor),
|
||||
Style = SKPaintStyle.Stroke,
|
||||
StrokeWidth = IsFocused ? 2 : 1,
|
||||
IsAntialias = true
|
||||
};
|
||||
canvas.DrawRoundRect(new SKRoundRect(bounds, cornerRadius), borderPaint);
|
||||
using var borderPaint = new SKPaint
|
||||
{
|
||||
Color = IsFocused ? ToSKColor(CursorColor) : ToSKColor(BorderColor),
|
||||
Style = SKPaintStyle.Stroke,
|
||||
StrokeWidth = IsFocused ? 2 : 1,
|
||||
IsAntialias = true
|
||||
};
|
||||
canvas.DrawRoundRect(new SKRoundRect(bounds, cornerRadius), borderPaint);
|
||||
}
|
||||
|
||||
// Setup text rendering
|
||||
using var font = new SKFont(SKTypeface.Default, fontSize);
|
||||
@@ -1085,6 +1088,13 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
{
|
||||
if (!IsEnabled) return;
|
||||
|
||||
// Handle right-click context menu
|
||||
if (e.Button == PointerButton.Right)
|
||||
{
|
||||
ShowContextMenu(e.X, e.Y);
|
||||
return;
|
||||
}
|
||||
|
||||
IsFocused = true;
|
||||
|
||||
// Use screen coordinates for proper hit detection
|
||||
@@ -1491,6 +1501,39 @@ public class SkiaEditor : SkiaView, IInputContext
|
||||
_selectionLength = 0;
|
||||
}
|
||||
|
||||
private void ShowContextMenu(float x, float y)
|
||||
{
|
||||
Console.WriteLine($"[SkiaEditor] ShowContextMenu at ({x}, {y})");
|
||||
bool hasSelection = _selectionLength != 0;
|
||||
bool hasText = !string.IsNullOrEmpty(Text);
|
||||
bool hasClipboard = !string.IsNullOrEmpty(SystemClipboard.GetText());
|
||||
bool isEditable = !IsReadOnly;
|
||||
|
||||
GtkContextMenuService.ShowContextMenu(new List<GtkMenuItem>
|
||||
{
|
||||
new GtkMenuItem("Cut", () =>
|
||||
{
|
||||
CutToClipboard();
|
||||
Invalidate();
|
||||
}, hasSelection && isEditable),
|
||||
new GtkMenuItem("Copy", () =>
|
||||
{
|
||||
CopyToClipboard();
|
||||
}, hasSelection),
|
||||
new GtkMenuItem("Paste", () =>
|
||||
{
|
||||
PasteFromClipboard();
|
||||
Invalidate();
|
||||
}, hasClipboard && isEditable),
|
||||
GtkMenuItem.Separator,
|
||||
new GtkMenuItem("Select All", () =>
|
||||
{
|
||||
SelectAll();
|
||||
Invalidate();
|
||||
}, hasText)
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -129,6 +129,18 @@ public class SkiaItemsView : SkiaView
|
||||
_scrollOffset = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when theme changes to refresh all cached item views.
|
||||
/// Clears the item view cache so items are recreated with new theme colors.
|
||||
/// </summary>
|
||||
public virtual void RefreshTheme()
|
||||
{
|
||||
// Clear cached views to force recreation with new AppThemeBinding values
|
||||
_itemViewCache.Clear();
|
||||
_itemHeights.Clear();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
RefreshItems();
|
||||
|
||||
@@ -433,24 +433,50 @@ public class SkiaContentPage : SkiaPage
|
||||
};
|
||||
|
||||
float rightEdge = navBarBounds.Right - 16;
|
||||
const float iconSize = 24f;
|
||||
const float itemPadding = 12f;
|
||||
|
||||
foreach (var item in primaryItems.AsEnumerable().Reverse())
|
||||
{
|
||||
var textBounds = new SKRect();
|
||||
textPaint.MeasureText(item.Text, ref textBounds);
|
||||
float itemWidth;
|
||||
float itemLeft;
|
||||
|
||||
var itemWidth = textBounds.Width + 24; // Padding
|
||||
var itemLeft = rightEdge - itemWidth;
|
||||
if (item.Icon != null)
|
||||
{
|
||||
// Icon-based toolbar item
|
||||
itemWidth = iconSize + itemPadding * 2;
|
||||
itemLeft = rightEdge - itemWidth;
|
||||
|
||||
// Store hit area for click handling
|
||||
item.HitBounds = new SKRect(itemLeft, navBarBounds.Top, rightEdge, navBarBounds.Bottom);
|
||||
|
||||
// Draw icon centered in the hit area
|
||||
var iconX = itemLeft + itemPadding;
|
||||
var iconY = navBarBounds.MidY - iconSize / 2;
|
||||
var destRect = new SKRect(iconX, iconY, iconX + iconSize, iconY + iconSize);
|
||||
canvas.DrawBitmap(item.Icon, destRect);
|
||||
|
||||
Console.WriteLine($"[SkiaContentPage] Drew toolbar icon '{item.Text}' at ({iconX}, {iconY})");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Text-based toolbar item (fallback)
|
||||
var textBounds = new SKRect();
|
||||
textPaint.MeasureText(item.Text, ref textBounds);
|
||||
|
||||
itemWidth = textBounds.Width + 24;
|
||||
itemLeft = rightEdge - itemWidth;
|
||||
|
||||
// Store hit area for click handling
|
||||
item.HitBounds = new SKRect(itemLeft, navBarBounds.Top, rightEdge, navBarBounds.Bottom);
|
||||
|
||||
// Draw text
|
||||
var x = itemLeft + 12;
|
||||
var y = navBarBounds.MidY - textBounds.MidY;
|
||||
canvas.DrawText(item.Text, x, y, textPaint);
|
||||
}
|
||||
|
||||
// Store hit area for click handling
|
||||
item.HitBounds = new SKRect(itemLeft, navBarBounds.Top, rightEdge, navBarBounds.Bottom);
|
||||
Console.WriteLine($"[SkiaContentPage] Toolbar item '{item.Text}' HitBounds set to {item.HitBounds}");
|
||||
|
||||
// Draw text
|
||||
var x = itemLeft + 12;
|
||||
var y = navBarBounds.MidY - textBounds.MidY;
|
||||
canvas.DrawText(item.Text, x, y, textPaint);
|
||||
|
||||
rightEdge = itemLeft - 8; // Gap between items
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user