2025-12-19 09:30:16 +00:00
|
|
|
// Licensed to the .NET Foundation under one or more agreements.
|
|
|
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
using System;
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
using Microsoft.Maui.Controls;
|
2025-12-19 09:30:16 +00:00
|
|
|
using Microsoft.Maui.Platform.Linux.Rendering;
|
2026-01-01 13:51:12 -05:00
|
|
|
using SkiaSharp;
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
namespace Microsoft.Maui.Platform;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-21 13:26:56 -05:00
|
|
|
/// Skia-rendered button control with full XAML styling support.
|
2025-12-19 09:30:16 +00:00
|
|
|
/// </summary>
|
|
|
|
|
public class SkiaButton : SkiaView
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
#region BindableProperties
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
public static readonly BindableProperty TextProperty = BindableProperty.Create(
|
|
|
|
|
nameof(Text),
|
|
|
|
|
typeof(string),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
"",
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnTextChanged());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty TextColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(TextColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
SKColors.White,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty ButtonBackgroundColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(ButtonBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
new SKColor(33, 150, 243), // Material Blue
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty PressedBackgroundColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(PressedBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
new SKColor(25, 118, 210),
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty DisabledBackgroundColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(DisabledBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
new SKColor(189, 189, 189),
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty HoveredBackgroundColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(HoveredBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
new SKColor(66, 165, 245),
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(
|
|
|
|
|
nameof(BorderColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
SKColors.Transparent,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(
|
|
|
|
|
nameof(FontFamily),
|
|
|
|
|
typeof(string),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
"Sans",
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnFontChanged());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty FontSizeProperty = BindableProperty.Create(
|
|
|
|
|
nameof(FontSize),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
14f,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnFontChanged());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty IsBoldProperty = BindableProperty.Create(
|
|
|
|
|
nameof(IsBold),
|
|
|
|
|
typeof(bool),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
false,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnFontChanged());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty IsItalicProperty = BindableProperty.Create(
|
|
|
|
|
nameof(IsItalic),
|
|
|
|
|
typeof(bool),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
false,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnFontChanged());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty CharacterSpacingProperty = BindableProperty.Create(
|
|
|
|
|
nameof(CharacterSpacing),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
0f,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
|
|
|
|
|
nameof(CornerRadius),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
4f,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create(
|
|
|
|
|
nameof(BorderWidth),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
0f,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty PaddingProperty = BindableProperty.Create(
|
|
|
|
|
nameof(Padding),
|
|
|
|
|
typeof(SKRect),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
new SKRect(16f, 8f, 16f, 8f),
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty CommandProperty = BindableProperty.Create(
|
|
|
|
|
nameof(Command),
|
|
|
|
|
typeof(ICommand),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
null,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).OnCommandChanged((ICommand?)o, (ICommand?)n));
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(
|
|
|
|
|
nameof(CommandParameter),
|
|
|
|
|
typeof(object),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
null,
|
|
|
|
|
BindingMode.TwoWay);
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty ImageSourceProperty = BindableProperty.Create(
|
|
|
|
|
nameof(ImageSource),
|
|
|
|
|
typeof(SKBitmap),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
null,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty ImageSpacingProperty = BindableProperty.Create(
|
|
|
|
|
nameof(ImageSpacing),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
8f,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
public static readonly BindableProperty ContentLayoutPositionProperty = BindableProperty.Create(
|
|
|
|
|
nameof(ContentLayoutPosition),
|
|
|
|
|
typeof(int),
|
|
|
|
|
typeof(SkiaButton),
|
|
|
|
|
0,
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaButton)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Fields
|
|
|
|
|
|
|
|
|
|
private bool _focusFromKeyboard;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Properties
|
|
|
|
|
|
|
|
|
|
public string Text
|
|
|
|
|
{
|
|
|
|
|
get => (string)GetValue(TextProperty);
|
|
|
|
|
set => SetValue(TextProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor TextColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(TextColorProperty);
|
|
|
|
|
set => SetValue(TextColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor ButtonBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(ButtonBackgroundColorProperty);
|
|
|
|
|
set => SetValue(ButtonBackgroundColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor PressedBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(PressedBackgroundColorProperty);
|
|
|
|
|
set => SetValue(PressedBackgroundColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor DisabledBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(DisabledBackgroundColorProperty);
|
|
|
|
|
set => SetValue(DisabledBackgroundColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor HoveredBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(HoveredBackgroundColorProperty);
|
|
|
|
|
set => SetValue(HoveredBackgroundColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKColor BorderColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(BorderColorProperty);
|
|
|
|
|
set => SetValue(BorderColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string FontFamily
|
|
|
|
|
{
|
|
|
|
|
get => (string)GetValue(FontFamilyProperty);
|
|
|
|
|
set => SetValue(FontFamilyProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float FontSize
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(FontSizeProperty);
|
|
|
|
|
set => SetValue(FontSizeProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsBold
|
|
|
|
|
{
|
|
|
|
|
get => (bool)GetValue(IsBoldProperty);
|
|
|
|
|
set => SetValue(IsBoldProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
public bool IsItalic
|
|
|
|
|
{
|
|
|
|
|
get => (bool)GetValue(IsItalicProperty);
|
|
|
|
|
set => SetValue(IsItalicProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float CharacterSpacing
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(CharacterSpacingProperty);
|
|
|
|
|
set => SetValue(CharacterSpacingProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float CornerRadius
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(CornerRadiusProperty);
|
|
|
|
|
set => SetValue(CornerRadiusProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float BorderWidth
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(BorderWidthProperty);
|
|
|
|
|
set => SetValue(BorderWidthProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SKRect Padding
|
|
|
|
|
{
|
|
|
|
|
get => (SKRect)GetValue(PaddingProperty);
|
|
|
|
|
set => SetValue(PaddingProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
public ICommand? Command
|
2025-12-21 13:26:56 -05:00
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
get => (ICommand?)GetValue(CommandProperty);
|
2025-12-21 13:26:56 -05:00
|
|
|
set => SetValue(CommandProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public object? CommandParameter
|
|
|
|
|
{
|
|
|
|
|
get => GetValue(CommandParameterProperty);
|
|
|
|
|
set => SetValue(CommandParameterProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
public SKBitmap? ImageSource
|
|
|
|
|
{
|
|
|
|
|
get => (SKBitmap?)GetValue(ImageSourceProperty);
|
|
|
|
|
set => SetValue(ImageSourceProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float ImageSpacing
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(ImageSpacingProperty);
|
|
|
|
|
set => SetValue(ImageSpacingProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ContentLayoutPosition
|
|
|
|
|
{
|
|
|
|
|
get => (int)GetValue(ContentLayoutPositionProperty);
|
|
|
|
|
set => SetValue(ContentLayoutPositionProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public bool IsPressed { get; private set; }
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public bool IsHovered { get; private set; }
|
2025-12-21 13:26:56 -05:00
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#region Events
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
public event EventHandler? Clicked;
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public event EventHandler? Pressed;
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public event EventHandler? Released;
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Constructor
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public SkiaButton()
|
|
|
|
|
{
|
|
|
|
|
IsFocusable = true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Private Methods
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
private void OnTextChanged()
|
|
|
|
|
{
|
|
|
|
|
InvalidateMeasure();
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnFontChanged()
|
|
|
|
|
{
|
|
|
|
|
InvalidateMeasure();
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
private void OnCommandChanged(ICommand? oldCommand, ICommand? newCommand)
|
2025-12-21 13:26:56 -05:00
|
|
|
{
|
|
|
|
|
if (oldCommand != null)
|
|
|
|
|
{
|
|
|
|
|
oldCommand.CanExecuteChanged -= OnCanExecuteChanged;
|
|
|
|
|
}
|
|
|
|
|
if (newCommand != null)
|
|
|
|
|
{
|
|
|
|
|
newCommand.CanExecuteChanged += OnCanExecuteChanged;
|
|
|
|
|
UpdateIsEnabled();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnCanExecuteChanged(object? sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
UpdateIsEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateIsEnabled()
|
|
|
|
|
{
|
|
|
|
|
if (Command != null)
|
|
|
|
|
{
|
|
|
|
|
IsEnabled = Command.CanExecute(CommandParameter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Drawing
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
SKColor buttonBackgroundColor = ButtonBackgroundColor;
|
|
|
|
|
bool isTextOnly = buttonBackgroundColor.Alpha == 0;
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
SKColor color;
|
2025-12-21 13:26:56 -05:00
|
|
|
if (!IsEnabled)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
color = isTextOnly ? SKColors.Transparent : DisabledBackgroundColor;
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
|
|
|
|
else if (IsPressed)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
color = isTextOnly ? new SKColor(0, 0, 0, 20) : PressedBackgroundColor;
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
|
|
|
|
else if (IsHovered)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
color = isTextOnly ? new SKColor(0, 0, 0, 10) : HoveredBackgroundColor;
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
color = ButtonBackgroundColor;
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
if (IsEnabled && !IsPressed && !isTextOnly)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
DrawShadow(canvas, bounds);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
var roundRect = new SKRoundRect(bounds, CornerRadius);
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
if (color.Alpha > 0)
|
2025-12-21 13:26:56 -05:00
|
|
|
{
|
|
|
|
|
using var bgPaint = new SKPaint
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
Color = color,
|
2025-12-21 13:26:56 -05:00
|
|
|
IsAntialias = true,
|
|
|
|
|
Style = SKPaintStyle.Fill
|
|
|
|
|
};
|
2026-01-01 13:51:12 -05:00
|
|
|
canvas.DrawRoundRect(roundRect, bgPaint);
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
if (BorderWidth > 0f && BorderColor != SKColors.Transparent)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
using var borderPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = BorderColor,
|
|
|
|
|
IsAntialias = true,
|
|
|
|
|
Style = SKPaintStyle.Stroke,
|
|
|
|
|
StrokeWidth = BorderWidth
|
|
|
|
|
};
|
2026-01-01 13:51:12 -05:00
|
|
|
canvas.DrawRoundRect(roundRect, borderPaint);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsFocused && _focusFromKeyboard)
|
|
|
|
|
{
|
|
|
|
|
using var focusPaint = new SKPaint
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
Color = new SKColor(33, 150, 243, 128),
|
2025-12-19 09:30:16 +00:00
|
|
|
IsAntialias = true,
|
|
|
|
|
Style = SKPaintStyle.Stroke,
|
2026-01-01 13:51:12 -05:00
|
|
|
StrokeWidth = 2f
|
2025-12-19 09:30:16 +00:00
|
|
|
};
|
2026-01-01 13:51:12 -05:00
|
|
|
var focusRect = new SKRoundRect(bounds, CornerRadius + 2f);
|
|
|
|
|
focusRect.Inflate(2f, 2f);
|
2025-12-19 09:30:16 +00:00
|
|
|
canvas.DrawRoundRect(focusRect, focusPaint);
|
|
|
|
|
}
|
|
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
DrawContent(canvas, bounds, isTextOnly);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawContent(SKCanvas canvas, SKRect bounds, bool isTextOnly)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
var style = new SKFontStyle(
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
IsBold ? SKFontStyleWeight.Bold : SKFontStyleWeight.Normal,
|
|
|
|
|
SKFontStyleWidth.Normal,
|
|
|
|
|
IsItalic ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright);
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
using var font = new SKFont(
|
|
|
|
|
SkiaRenderingEngine.Current?.ResourceCache.GetTypeface(FontFamily, style) ?? SKTypeface.Default,
|
|
|
|
|
FontSize, 1f, 0f);
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
|
|
|
|
|
SKColor textColorToUse;
|
|
|
|
|
if (!IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
textColorToUse = TextColor.WithAlpha(128);
|
|
|
|
|
}
|
|
|
|
|
else if (isTextOnly && (IsHovered || IsPressed))
|
|
|
|
|
{
|
|
|
|
|
textColorToUse = new SKColor(
|
|
|
|
|
(byte)Math.Max(0, TextColor.Red - 40),
|
|
|
|
|
(byte)Math.Max(0, TextColor.Green - 40),
|
|
|
|
|
(byte)Math.Max(0, TextColor.Blue - 40),
|
|
|
|
|
TextColor.Alpha);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
textColorToUse = TextColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using var textPaint = new SKPaint(font)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
Color = textColorToUse,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
2025-12-19 09:30:16 +00:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
var textBounds = new SKRect();
|
|
|
|
|
bool hasText = !string.IsNullOrEmpty(Text);
|
|
|
|
|
if (hasText)
|
|
|
|
|
{
|
|
|
|
|
textPaint.MeasureText(Text, ref textBounds);
|
|
|
|
|
}
|
2025-12-21 13:26:56 -05:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
bool hasImage = ImageSource != null;
|
2026-01-01 13:51:12 -05:00
|
|
|
float imageWidth = 0f;
|
|
|
|
|
float imageHeight = 0f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
if (hasImage)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
float maxSize = Math.Min(bounds.Height - 8f, 24f);
|
|
|
|
|
float scale = Math.Min(maxSize / ImageSource!.Width, maxSize / ImageSource.Height);
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
imageWidth = ImageSource.Width * scale;
|
|
|
|
|
imageHeight = ImageSource.Height * scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isHorizontal = ContentLayoutPosition == 0 || ContentLayoutPosition == 2;
|
2026-01-01 13:51:12 -05:00
|
|
|
float totalWidth;
|
|
|
|
|
float totalHeight;
|
|
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
if (hasImage && hasText)
|
|
|
|
|
{
|
|
|
|
|
if (isHorizontal)
|
2025-12-21 13:26:56 -05:00
|
|
|
{
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
totalWidth = imageWidth + ImageSpacing + textBounds.Width;
|
|
|
|
|
totalHeight = Math.Max(imageHeight, textBounds.Height);
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
totalWidth = Math.Max(imageWidth, textBounds.Width);
|
|
|
|
|
totalHeight = imageHeight + ImageSpacing + textBounds.Height;
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
}
|
|
|
|
|
else if (hasImage)
|
|
|
|
|
{
|
|
|
|
|
totalWidth = imageWidth;
|
|
|
|
|
totalHeight = imageHeight;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
totalWidth = textBounds.Width;
|
|
|
|
|
totalHeight = textBounds.Height;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
float startX = bounds.MidX - totalWidth / 2f;
|
|
|
|
|
float startY = bounds.MidY - totalHeight / 2f;
|
2025-12-21 13:26:56 -05:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
if (hasImage)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
float imageX;
|
|
|
|
|
float imageY;
|
|
|
|
|
float textX = 0f;
|
|
|
|
|
float textY = 0f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
|
|
|
|
|
switch (ContentLayoutPosition)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
case 1: // Top
|
|
|
|
|
imageX = bounds.MidX - imageWidth / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
imageY = startY;
|
2026-01-01 13:51:12 -05:00
|
|
|
textX = bounds.MidX - textBounds.Width / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
textY = startY + imageHeight + ImageSpacing - textBounds.Top;
|
|
|
|
|
break;
|
2026-01-01 13:51:12 -05:00
|
|
|
case 2: // Right
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
textX = startX;
|
|
|
|
|
textY = bounds.MidY - textBounds.MidY;
|
|
|
|
|
imageX = startX + textBounds.Width + ImageSpacing;
|
2026-01-01 13:51:12 -05:00
|
|
|
imageY = bounds.MidY - imageHeight / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
break;
|
2026-01-01 13:51:12 -05:00
|
|
|
case 3: // Bottom
|
|
|
|
|
textX = bounds.MidX - textBounds.Width / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
textY = startY - textBounds.Top;
|
2026-01-01 13:51:12 -05:00
|
|
|
imageX = bounds.MidX - imageWidth / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
imageY = startY + textBounds.Height + ImageSpacing;
|
|
|
|
|
break;
|
2026-01-01 13:51:12 -05:00
|
|
|
default: // 0 = Left
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
imageX = startX;
|
2026-01-01 13:51:12 -05:00
|
|
|
imageY = bounds.MidY - imageHeight / 2f;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
textX = startX + imageWidth + ImageSpacing;
|
|
|
|
|
textY = bounds.MidY - textBounds.MidY;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
var imageRect = new SKRect(imageX, imageY, imageX + imageWidth, imageY + imageHeight);
|
|
|
|
|
using var imagePaint = new SKPaint { IsAntialias = true };
|
2026-01-01 13:51:12 -05:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
if (!IsEnabled)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
imagePaint.ColorFilter = SKColorFilter.CreateBlendMode(
|
|
|
|
|
new SKColor(128, 128, 128, 128), SKBlendMode.Modulate);
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
}
|
2026-01-01 13:51:12 -05:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
canvas.DrawBitmap(ImageSource!, imageRect, imagePaint);
|
2025-12-19 09:30:16 +00:00
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
if (hasText)
|
|
|
|
|
{
|
|
|
|
|
canvas.DrawText(Text!, textX, textY, textPaint);
|
|
|
|
|
}
|
2026-01-01 13:51:12 -05:00
|
|
|
return;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
}
|
2026-01-01 13:51:12 -05:00
|
|
|
|
|
|
|
|
if (hasText)
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
float x = bounds.MidX - textBounds.MidX;
|
|
|
|
|
float y = bounds.MidY - textBounds.MidY;
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
canvas.DrawText(Text!, x, y, textPaint);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawShadow(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
|
|
|
|
using var shadowPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = new SKColor(0, 0, 0, 50),
|
|
|
|
|
IsAntialias = true,
|
2026-01-01 13:51:12 -05:00
|
|
|
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f)
|
2025-12-19 09:30:16 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
var shadowRect = new SKRoundRect(
|
|
|
|
|
new SKRect(bounds.Left + 2f, bounds.Top + 4f, bounds.Right + 2f, bounds.Bottom + 4f),
|
|
|
|
|
CornerRadius);
|
|
|
|
|
canvas.DrawRoundRect(shadowRect, shadowPaint);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Pointer Events
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public override void OnPointerEntered(PointerEventArgs e)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
if (IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
IsHovered = true;
|
|
|
|
|
SkiaVisualStateManager.GoToState(this, "PointerOver");
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnPointerExited(PointerEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
IsHovered = false;
|
|
|
|
|
if (IsPressed)
|
|
|
|
|
{
|
|
|
|
|
IsPressed = false;
|
|
|
|
|
}
|
2026-01-01 13:51:12 -05:00
|
|
|
SkiaVisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled");
|
2025-12-19 09:30:16 +00:00
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnPointerPressed(PointerEventArgs e)
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
Console.WriteLine($"[SkiaButton] OnPointerPressed - Text='{Text}', IsEnabled={IsEnabled}");
|
2026-01-01 13:51:12 -05:00
|
|
|
if (IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
IsPressed = true;
|
|
|
|
|
_focusFromKeyboard = false;
|
|
|
|
|
SkiaVisualStateManager.GoToState(this, "Pressed");
|
|
|
|
|
Invalidate();
|
|
|
|
|
Pressed?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnPointerReleased(PointerEventArgs e)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
if (IsEnabled)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
bool wasPressed = IsPressed;
|
|
|
|
|
IsPressed = false;
|
|
|
|
|
SkiaVisualStateManager.GoToState(this, IsHovered ? "PointerOver" : "Normal");
|
|
|
|
|
Invalidate();
|
|
|
|
|
Released?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
if (wasPressed)
|
|
|
|
|
{
|
|
|
|
|
Clicked?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
Command?.Execute(CommandParameter);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Keyboard Events
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
public override void OnKeyDown(KeyEventArgs e)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
if (IsEnabled && (e.Key == Key.Enter || e.Key == Key.Space))
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
IsPressed = true;
|
2025-12-21 13:26:56 -05:00
|
|
|
_focusFromKeyboard = true;
|
2026-01-01 13:51:12 -05:00
|
|
|
SkiaVisualStateManager.GoToState(this, "Pressed");
|
2025-12-19 09:30:16 +00:00
|
|
|
Invalidate();
|
|
|
|
|
Pressed?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnKeyUp(KeyEventArgs e)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
if (IsEnabled && (e.Key == Key.Enter || e.Key == Key.Space))
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
if (IsPressed)
|
|
|
|
|
{
|
|
|
|
|
IsPressed = false;
|
2026-01-01 13:51:12 -05:00
|
|
|
SkiaVisualStateManager.GoToState(this, "Normal");
|
2025-12-19 09:30:16 +00:00
|
|
|
Invalidate();
|
|
|
|
|
Released?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
Clicked?.Invoke(this, EventArgs.Empty);
|
2025-12-21 13:26:56 -05:00
|
|
|
Command?.Execute(CommandParameter);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region State Changes
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
protected override void OnEnabledChanged()
|
|
|
|
|
{
|
|
|
|
|
base.OnEnabledChanged();
|
2026-01-01 13:51:12 -05:00
|
|
|
SkiaVisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled");
|
2025-12-21 13:26:56 -05:00
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Measurement
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
protected override SKSize MeasureOverride(SKSize availableSize)
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
SKRect padding = Padding;
|
|
|
|
|
float paddingLeft = float.IsNaN(padding.Left) ? 16f : padding.Left;
|
|
|
|
|
float paddingRight = float.IsNaN(padding.Right) ? 16f : padding.Right;
|
|
|
|
|
float paddingTop = float.IsNaN(padding.Top) ? 8f : padding.Top;
|
|
|
|
|
float paddingBottom = float.IsNaN(padding.Bottom) ? 8f : padding.Bottom;
|
|
|
|
|
float fontSize = (float.IsNaN(FontSize) || FontSize <= 0f) ? 14f : FontSize;
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
if (string.IsNullOrEmpty(Text))
|
|
|
|
|
{
|
2026-01-01 13:51:12 -05:00
|
|
|
return new SKSize(paddingLeft + paddingRight + 40f, paddingTop + paddingBottom + fontSize);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
var style = new SKFontStyle(
|
|
|
|
|
IsBold ? SKFontStyleWeight.Bold : SKFontStyleWeight.Normal,
|
|
|
|
|
SKFontStyleWidth.Normal,
|
|
|
|
|
IsItalic ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright);
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
using var font = new SKFont(
|
|
|
|
|
SkiaRenderingEngine.Current?.ResourceCache.GetTypeface(FontFamily, style) ?? SKTypeface.Default,
|
|
|
|
|
fontSize, 1f, 0f);
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
using var paint = new SKPaint(font);
|
2025-12-19 09:30:16 +00:00
|
|
|
var textBounds = new SKRect();
|
|
|
|
|
paint.MeasureText(Text, ref textBounds);
|
|
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
float width = textBounds.Width + paddingLeft + paddingRight;
|
|
|
|
|
float height = textBounds.Height + paddingTop + paddingBottom;
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
if (float.IsNaN(width) || width < 0f)
|
|
|
|
|
{
|
|
|
|
|
width = 72f;
|
|
|
|
|
}
|
|
|
|
|
if (float.IsNaN(height) || height < 0f)
|
|
|
|
|
{
|
|
|
|
|
height = 30f;
|
|
|
|
|
}
|
2025-12-21 13:26:56 -05:00
|
|
|
|
2026-01-01 13:51:12 -05:00
|
|
|
if (WidthRequest >= 0.0)
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
width = (float)WidthRequest;
|
2026-01-01 13:51:12 -05:00
|
|
|
}
|
|
|
|
|
if (HeightRequest >= 0.0)
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
height = (float)HeightRequest;
|
2026-01-01 13:51:12 -05:00
|
|
|
}
|
2025-12-21 13:26:56 -05:00
|
|
|
|
|
|
|
|
return new SKSize(width, height);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
2026-01-01 13:51:12 -05:00
|
|
|
|
|
|
|
|
#endregion
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|