Removed duplicate

This commit is contained in:
2026-01-24 01:59:53 +00:00
parent 0c2508d715
commit 2c5036596e
19 changed files with 20 additions and 2417 deletions

View File

@@ -1,63 +0,0 @@
// 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.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for ActivityIndicator control.
/// </summary>
public class ActivityIndicatorHandler : ViewHandler<IActivityIndicator, SkiaActivityIndicator>
{
public static IPropertyMapper<IActivityIndicator, ActivityIndicatorHandler> Mapper = new PropertyMapper<IActivityIndicator, ActivityIndicatorHandler>(ViewHandler.ViewMapper)
{
["IsRunning"] = MapIsRunning,
["Color"] = MapColor,
["Background"] = MapBackground
};
public static CommandMapper<IActivityIndicator, ActivityIndicatorHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public ActivityIndicatorHandler() : base(Mapper, CommandMapper)
{
}
public ActivityIndicatorHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaActivityIndicator CreatePlatformView()
{
return new SkiaActivityIndicator();
}
public static void MapIsRunning(ActivityIndicatorHandler handler, IActivityIndicator activityIndicator)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsRunning = activityIndicator.IsRunning;
}
}
public static void MapColor(ActivityIndicatorHandler handler, IActivityIndicator activityIndicator)
{
if (handler.PlatformView != null && activityIndicator.Color != null)
{
handler.PlatformView.Color = activityIndicator.Color.ToSKColor();
}
}
public static void MapBackground(ActivityIndicatorHandler handler, IActivityIndicator activityIndicator)
{
if (handler.PlatformView != null)
{
if (activityIndicator.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
}

View File

@@ -30,6 +30,20 @@ public partial class BoxViewHandler : ViewHandler<BoxView, SkiaBoxView>
return new SkiaBoxView();
}
protected override void ConnectHandler(SkiaBoxView platformView)
{
base.ConnectHandler(platformView);
// Map size requests from MAUI BoxView
if (VirtualView is BoxView boxView)
{
if (boxView.WidthRequest >= 0)
platformView.WidthRequest = boxView.WidthRequest;
if (boxView.HeightRequest >= 0)
platformView.HeightRequest = boxView.HeightRequest;
}
}
public static void MapColor(BoxViewHandler handler, BoxView boxView)
{
if (boxView.Color != null)

View File

@@ -1,145 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Button control.
/// </summary>
public class ButtonHandler : ViewHandler<IButton, SkiaButton>
{
public static IPropertyMapper<IButton, ButtonHandler> Mapper = new PropertyMapper<IButton, ButtonHandler>(ViewHandler.ViewMapper)
{
["StrokeColor"] = MapStrokeColor,
["StrokeThickness"] = MapStrokeThickness,
["CornerRadius"] = MapCornerRadius,
["Background"] = MapBackground,
["Padding"] = MapPadding,
["IsEnabled"] = MapIsEnabled
};
public static CommandMapper<IButton, ButtonHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public ButtonHandler() : base(Mapper, CommandMapper)
{
}
public ButtonHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaButton CreatePlatformView()
{
return new SkiaButton();
}
protected override void ConnectHandler(SkiaButton platformView)
{
base.ConnectHandler(platformView);
platformView.Clicked += OnClicked;
platformView.Pressed += OnPressed;
platformView.Released += OnReleased;
if (VirtualView != null)
{
MapStrokeColor(this, VirtualView);
MapStrokeThickness(this, VirtualView);
MapCornerRadius(this, VirtualView);
MapBackground(this, VirtualView);
MapPadding(this, VirtualView);
MapIsEnabled(this, VirtualView);
}
}
protected override void DisconnectHandler(SkiaButton platformView)
{
platformView.Clicked -= OnClicked;
platformView.Pressed -= OnPressed;
platformView.Released -= OnReleased;
base.DisconnectHandler(platformView);
}
private void OnClicked(object? sender, EventArgs e)
{
VirtualView?.Clicked();
}
private void OnPressed(object? sender, EventArgs e)
{
VirtualView?.Pressed();
}
private void OnReleased(object? sender, EventArgs e)
{
VirtualView?.Released();
}
public static void MapStrokeColor(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
var strokeColor = button.StrokeColor;
if (strokeColor != null)
{
handler.PlatformView.BorderColor = strokeColor.ToSKColor();
}
}
}
public static void MapStrokeThickness(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
handler.PlatformView.BorderWidth = (float)button.StrokeThickness;
}
}
public static void MapCornerRadius(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
handler.PlatformView.CornerRadius = button.CornerRadius;
}
}
public static void MapBackground(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
var background = button.Background;
if (background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.ButtonBackgroundColor = solidPaint.Color.ToSKColor();
}
}
}
public static void MapPadding(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
var padding = button.Padding;
handler.PlatformView.Padding = new SKRect(
(float)padding.Left,
(float)padding.Top,
(float)padding.Right,
(float)padding.Bottom);
}
}
public static void MapIsEnabled(ButtonHandler handler, IButton button)
{
if (handler.PlatformView != null)
{
Console.WriteLine($"[ButtonHandler] MapIsEnabled - Text='{handler.PlatformView.Text}', IsEnabled={button.IsEnabled}");
handler.PlatformView.IsEnabled = button.IsEnabled;
handler.PlatformView.Invalidate();
}
}
}

View File

@@ -1,129 +0,0 @@
// 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.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Primitives;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for CheckBox control.
/// </summary>
public class CheckBoxHandler : ViewHandler<ICheckBox, SkiaCheckBox>
{
public static IPropertyMapper<ICheckBox, CheckBoxHandler> Mapper = new PropertyMapper<ICheckBox, CheckBoxHandler>(ViewHandler.ViewMapper)
{
["IsChecked"] = MapIsChecked,
["Foreground"] = MapForeground,
["Background"] = MapBackground,
["IsEnabled"] = MapIsEnabled,
["VerticalLayoutAlignment"] = MapVerticalLayoutAlignment,
["HorizontalLayoutAlignment"] = MapHorizontalLayoutAlignment
};
public static CommandMapper<ICheckBox, CheckBoxHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public CheckBoxHandler() : base(Mapper, CommandMapper)
{
}
public CheckBoxHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaCheckBox CreatePlatformView()
{
return new SkiaCheckBox();
}
protected override void ConnectHandler(SkiaCheckBox platformView)
{
base.ConnectHandler(platformView);
platformView.CheckedChanged += OnCheckedChanged;
}
protected override void DisconnectHandler(SkiaCheckBox platformView)
{
platformView.CheckedChanged -= OnCheckedChanged;
base.DisconnectHandler(platformView);
}
private void OnCheckedChanged(object? sender, CheckedChangedEventArgs e)
{
if (VirtualView != null && VirtualView.IsChecked != e.IsChecked)
{
VirtualView.IsChecked = e.IsChecked;
}
}
public static void MapIsChecked(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsChecked = checkBox.IsChecked;
}
}
public static void MapForeground(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
if (checkBox.Foreground is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.CheckColor = solidPaint.Color.ToSKColor();
}
}
}
public static void MapBackground(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
if (checkBox.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapIsEnabled(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsEnabled = checkBox.IsEnabled;
}
}
public static void MapVerticalLayoutAlignment(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
handler.PlatformView.VerticalOptions = (int)checkBox.VerticalLayoutAlignment switch
{
1 => LayoutOptions.Start,
2 => LayoutOptions.Center,
3 => LayoutOptions.End,
0 => LayoutOptions.Fill,
_ => LayoutOptions.Fill
};
}
}
public static void MapHorizontalLayoutAlignment(CheckBoxHandler handler, ICheckBox checkBox)
{
if (handler.PlatformView != null)
{
handler.PlatformView.HorizontalOptions = (int)checkBox.HorizontalLayoutAlignment switch
{
1 => LayoutOptions.Start,
2 => LayoutOptions.Center,
3 => LayoutOptions.End,
0 => LayoutOptions.Fill,
_ => LayoutOptions.Start
};
}
}
}

View File

@@ -1,187 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Editor control.
/// </summary>
public class EditorHandler : ViewHandler<IEditor, SkiaEditor>
{
public static IPropertyMapper<IEditor, EditorHandler> Mapper = new PropertyMapper<IEditor, EditorHandler>(ViewHandler.ViewMapper)
{
["Text"] = MapText,
["Placeholder"] = MapPlaceholder,
["PlaceholderColor"] = MapPlaceholderColor,
["TextColor"] = MapTextColor,
["CharacterSpacing"] = MapCharacterSpacing,
["IsReadOnly"] = MapIsReadOnly,
["IsTextPredictionEnabled"] = MapIsTextPredictionEnabled,
["MaxLength"] = MapMaxLength,
["CursorPosition"] = MapCursorPosition,
["SelectionLength"] = MapSelectionLength,
["Keyboard"] = MapKeyboard,
["HorizontalTextAlignment"] = MapHorizontalTextAlignment,
["VerticalTextAlignment"] = MapVerticalTextAlignment,
["Background"] = MapBackground,
["BackgroundColor"] = MapBackgroundColor
};
public static CommandMapper<IEditor, EditorHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public EditorHandler() : base(Mapper, CommandMapper)
{
}
public EditorHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaEditor CreatePlatformView()
{
return new SkiaEditor();
}
protected override void ConnectHandler(SkiaEditor platformView)
{
base.ConnectHandler(platformView);
platformView.TextChanged += OnTextChanged;
platformView.Completed += OnCompleted;
}
protected override void DisconnectHandler(SkiaEditor platformView)
{
platformView.TextChanged -= OnTextChanged;
platformView.Completed -= OnCompleted;
base.DisconnectHandler(platformView);
}
private void OnTextChanged(object? sender, EventArgs e)
{
if (VirtualView != null && PlatformView != null)
{
VirtualView.Text = PlatformView.Text;
}
}
private void OnCompleted(object? sender, EventArgs e)
{
// Editor completed - no specific action needed
}
public static void MapText(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Text = editor.Text ?? "";
handler.PlatformView.Invalidate();
}
}
public static void MapPlaceholder(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Placeholder = editor.Placeholder ?? "";
}
}
public static void MapPlaceholderColor(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null && editor.PlaceholderColor != null)
{
handler.PlatformView.PlaceholderColor = editor.PlaceholderColor;
}
}
public static void MapTextColor(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null && editor.TextColor != null)
{
handler.PlatformView.TextColor = editor.TextColor;
}
}
public static void MapCharacterSpacing(EditorHandler handler, IEditor editor)
{
// Character spacing not implemented for editor
}
public static void MapIsReadOnly(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsReadOnly = editor.IsReadOnly;
}
}
public static void MapIsTextPredictionEnabled(EditorHandler handler, IEditor editor)
{
// Text prediction is a mobile feature
}
public static void MapMaxLength(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
handler.PlatformView.MaxLength = editor.MaxLength;
}
}
public static void MapCursorPosition(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
handler.PlatformView.CursorPosition = editor.CursorPosition;
}
}
public static void MapSelectionLength(EditorHandler handler, IEditor editor)
{
// Selection length not implemented
}
public static void MapKeyboard(EditorHandler handler, IEditor editor)
{
// Keyboard type is a mobile feature
}
public static void MapHorizontalTextAlignment(EditorHandler handler, IEditor editor)
{
// Horizontal text alignment not implemented
}
public static void MapVerticalTextAlignment(EditorHandler handler, IEditor editor)
{
// Vertical text alignment not implemented
}
public static void MapBackground(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
if (editor.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapBackgroundColor(EditorHandler handler, IEditor editor)
{
if (handler.PlatformView != null)
{
if (editor is VisualElement ve && ve.BackgroundColor != null)
{
handler.PlatformView.BackgroundColor = ve.BackgroundColor;
handler.PlatformView.Invalidate();
}
}
}
}

View File

@@ -1,252 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Entry control.
/// </summary>
public class EntryHandler : ViewHandler<IEntry, SkiaEntry>
{
public static IPropertyMapper<IEntry, EntryHandler> Mapper = new PropertyMapper<IEntry, EntryHandler>(ViewHandler.ViewMapper)
{
["Text"] = MapText,
["TextColor"] = MapTextColor,
["Font"] = MapFont,
["CharacterSpacing"] = MapCharacterSpacing,
["Placeholder"] = MapPlaceholder,
["PlaceholderColor"] = MapPlaceholderColor,
["IsReadOnly"] = MapIsReadOnly,
["MaxLength"] = MapMaxLength,
["CursorPosition"] = MapCursorPosition,
["SelectionLength"] = MapSelectionLength,
["IsPassword"] = MapIsPassword,
["ReturnType"] = MapReturnType,
["ClearButtonVisibility"] = MapClearButtonVisibility,
["HorizontalTextAlignment"] = MapHorizontalTextAlignment,
["VerticalTextAlignment"] = MapVerticalTextAlignment,
["Background"] = MapBackground,
["BackgroundColor"] = MapBackgroundColor
};
public static CommandMapper<IEntry, EntryHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public EntryHandler() : base(Mapper, CommandMapper)
{
}
public EntryHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaEntry CreatePlatformView()
{
return new SkiaEntry();
}
protected override void ConnectHandler(SkiaEntry platformView)
{
base.ConnectHandler(platformView);
platformView.TextChanged += OnTextChanged;
platformView.Completed += OnCompleted;
}
protected override void DisconnectHandler(SkiaEntry platformView)
{
platformView.TextChanged -= OnTextChanged;
platformView.Completed -= OnCompleted;
base.DisconnectHandler(platformView);
}
private void OnTextChanged(object? sender, TextChangedEventArgs e)
{
if (VirtualView != null && PlatformView != null && VirtualView.Text != e.NewTextValue)
{
VirtualView.Text = e.NewTextValue ?? string.Empty;
}
}
private void OnCompleted(object? sender, EventArgs e)
{
VirtualView?.Completed();
}
public static void MapText(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null && handler.PlatformView.Text != entry.Text)
{
handler.PlatformView.Text = entry.Text ?? string.Empty;
handler.PlatformView.Invalidate();
}
}
public static void MapTextColor(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null && entry.TextColor != null)
{
handler.PlatformView.TextColor = entry.TextColor.ToSKColor();
}
}
public static void MapFont(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
var font = entry.Font;
if (font.Size > 0)
{
handler.PlatformView.FontSize = (float)font.Size;
}
if (!string.IsNullOrEmpty(font.Family))
{
handler.PlatformView.FontFamily = font.Family;
}
handler.PlatformView.IsBold = (int)font.Weight >= 700;
handler.PlatformView.IsItalic = font.Slant == FontSlant.Italic || font.Slant == FontSlant.Oblique;
}
}
public static void MapCharacterSpacing(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.CharacterSpacing = (float)entry.CharacterSpacing;
}
}
public static void MapPlaceholder(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Placeholder = entry.Placeholder ?? string.Empty;
}
}
public static void MapPlaceholderColor(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null && entry.PlaceholderColor != null)
{
handler.PlatformView.PlaceholderColor = entry.PlaceholderColor.ToSKColor();
}
}
public static void MapIsReadOnly(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsReadOnly = entry.IsReadOnly;
}
}
public static void MapMaxLength(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.MaxLength = entry.MaxLength;
}
}
public static void MapCursorPosition(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.CursorPosition = entry.CursorPosition;
}
}
public static void MapSelectionLength(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.SelectionLength = entry.SelectionLength;
}
}
public static void MapIsPassword(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsPassword = entry.IsPassword;
}
}
public static void MapReturnType(EntryHandler handler, IEntry entry)
{
// ReturnType affects keyboard on mobile; access PlatformView to ensure it exists
_ = handler.PlatformView;
}
public static void MapClearButtonVisibility(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
// ClearButtonVisibility.WhileEditing = 1
handler.PlatformView.ShowClearButton = (int)entry.ClearButtonVisibility == 1;
}
}
public static void MapHorizontalTextAlignment(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.HorizontalTextAlignment = (int)entry.HorizontalTextAlignment switch
{
0 => TextAlignment.Start,
1 => TextAlignment.Center,
2 => TextAlignment.End,
_ => TextAlignment.Start
};
}
}
public static void MapVerticalTextAlignment(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
handler.PlatformView.VerticalTextAlignment = (int)entry.VerticalTextAlignment switch
{
0 => TextAlignment.Start,
1 => TextAlignment.Center,
2 => TextAlignment.End,
_ => TextAlignment.Center
};
}
}
public static void MapBackground(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView != null)
{
if (entry.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapBackgroundColor(EntryHandler handler, IEntry entry)
{
if (handler.PlatformView == null)
{
return;
}
if (entry is Entry mauiEntry)
{
Console.WriteLine($"[EntryHandler] MapBackgroundColor: {mauiEntry.BackgroundColor}");
if (mauiEntry.BackgroundColor != null)
{
var color = mauiEntry.BackgroundColor.ToSKColor();
Console.WriteLine($"[EntryHandler] Setting EntryBackgroundColor to: {color}");
handler.PlatformView.EntryBackgroundColor = color;
}
}
}
}

View File

@@ -1,308 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.IO;
using System.Threading;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Image control.
/// </summary>
public class ImageHandler : ViewHandler<IImage, SkiaImage>
{
internal class ImageSourceServiceResultManager
{
private readonly ImageHandler _handler;
private CancellationTokenSource? _cts;
public ImageSourceServiceResultManager(ImageHandler handler)
{
_handler = handler;
}
public async void UpdateImageSourceAsync()
{
_cts?.Cancel();
_cts = new CancellationTokenSource();
var token = _cts.Token;
try
{
var source = _handler.VirtualView?.Source;
if (source == null)
{
_handler.PlatformView?.LoadFromData(Array.Empty<byte>());
return;
}
if (_handler.VirtualView is IImageSourcePart imagePart)
{
imagePart.UpdateIsLoading(true);
}
if (source is IFileImageSource fileSource)
{
var file = fileSource.File;
if (!string.IsNullOrEmpty(file))
{
await _handler.PlatformView.LoadFromFileAsync(file);
}
return;
}
if (source is IUriImageSource uriSource)
{
var uri = uriSource.Uri;
if (uri != null)
{
await _handler.PlatformView.LoadFromUriAsync(uri);
}
return;
}
if (source is IStreamImageSource streamSource)
{
var stream = await streamSource.GetStreamAsync(token);
if (stream != null)
{
await _handler.PlatformView.LoadFromStreamAsync(stream);
}
return;
}
if (source is FontImageSource fontSource)
{
var bitmap = RenderFontImageSource(fontSource, _handler.PlatformView.WidthRequest, _handler.PlatformView.HeightRequest);
if (bitmap != null)
{
_handler.PlatformView.LoadFromBitmap(bitmap);
}
}
}
catch (OperationCanceledException)
{
// Cancelled - ignore
}
catch (Exception)
{
if (_handler.VirtualView is IImageSourcePart imagePart)
{
imagePart.UpdateIsLoading(false);
}
}
}
private static SKBitmap? RenderFontImageSource(FontImageSource fontSource, double requestedWidth, double requestedHeight)
{
var glyph = fontSource.Glyph;
if (string.IsNullOrEmpty(glyph))
{
return null;
}
int size = (int)Math.Max(
requestedWidth > 0 ? requestedWidth : 24.0,
requestedHeight > 0 ? requestedHeight : 24.0);
size = Math.Max(size, 16);
var color = fontSource.Color?.ToSKColor() ?? SKColors.Black;
var bitmap = new SKBitmap(size, size, false);
using var canvas = new SKCanvas(bitmap);
canvas.Clear(SKColors.Transparent);
SKTypeface? typeface = null;
if (!string.IsNullOrEmpty(fontSource.FontFamily))
{
var fontPaths = new[]
{
"/usr/share/fonts/truetype/" + fontSource.FontFamily + ".ttf",
"/usr/share/fonts/opentype/" + fontSource.FontFamily + ".otf",
"/usr/local/share/fonts/" + fontSource.FontFamily + ".ttf",
Path.Combine(AppContext.BaseDirectory, fontSource.FontFamily + ".ttf")
};
foreach (var path in fontPaths)
{
if (File.Exists(path))
{
typeface = SKTypeface.FromFile(path);
if (typeface != null)
break;
}
}
if (typeface == null)
{
typeface = SKTypeface.FromFamilyName(fontSource.FontFamily);
}
}
typeface ??= SKTypeface.Default;
float fontSize = size * 0.8f;
using var font = new SKFont(typeface, fontSize);
using var paint = new SKPaint(font)
{
Color = color,
IsAntialias = true,
TextAlign = SKTextAlign.Center
};
var bounds = new SKRect();
paint.MeasureText(glyph, ref bounds);
float x = size / 2f;
float y = (size - bounds.Top - bounds.Bottom) / 2f;
canvas.DrawText(glyph, x, y, paint);
return bitmap;
}
}
public static IPropertyMapper<IImage, ImageHandler> Mapper = new PropertyMapper<IImage, ImageHandler>(ViewHandler.ViewMapper)
{
["Aspect"] = MapAspect,
["IsOpaque"] = MapIsOpaque,
["Source"] = MapSource,
["Background"] = MapBackground,
["Width"] = MapWidth,
["Height"] = MapHeight
};
public static CommandMapper<IImage, ImageHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
private ImageSourceServiceResultManager? _sourceLoader;
private ImageSourceServiceResultManager SourceLoader => _sourceLoader ??= new ImageSourceServiceResultManager(this);
public ImageHandler() : base(Mapper, CommandMapper)
{
}
public ImageHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaImage CreatePlatformView()
{
return new SkiaImage();
}
protected override void ConnectHandler(SkiaImage platformView)
{
base.ConnectHandler(platformView);
platformView.ImageLoaded += OnImageLoaded;
platformView.ImageLoadingError += OnImageLoadingError;
}
protected override void DisconnectHandler(SkiaImage platformView)
{
platformView.ImageLoaded -= OnImageLoaded;
platformView.ImageLoadingError -= OnImageLoadingError;
base.DisconnectHandler(platformView);
}
private void OnImageLoaded(object? sender, EventArgs e)
{
if (VirtualView is IImageSourcePart imagePart)
{
imagePart.UpdateIsLoading(false);
}
}
private void OnImageLoadingError(object? sender, ImageLoadingErrorEventArgs e)
{
if (VirtualView is IImageSourcePart imagePart)
{
imagePart.UpdateIsLoading(false);
}
}
public static void MapAspect(ImageHandler handler, IImage image)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Aspect = image.Aspect;
}
}
public static void MapIsOpaque(ImageHandler handler, IImage image)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsOpaque = image.IsOpaque;
}
}
public static void MapSource(ImageHandler handler, IImage image)
{
if (handler.PlatformView == null)
{
return;
}
if (image is Image mauiImage)
{
if (mauiImage.WidthRequest > 0)
{
handler.PlatformView.WidthRequest = mauiImage.WidthRequest;
}
if (mauiImage.HeightRequest > 0)
{
handler.PlatformView.HeightRequest = mauiImage.HeightRequest;
}
}
handler.SourceLoader.UpdateImageSourceAsync();
}
public static void MapBackground(ImageHandler handler, IImage image)
{
if (handler.PlatformView != null)
{
if (image.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapWidth(ImageHandler handler, IImage image)
{
if (handler.PlatformView != null)
{
if (image is Image mauiImage && mauiImage.WidthRequest > 0)
{
handler.PlatformView.WidthRequest = mauiImage.WidthRequest;
Console.WriteLine($"[ImageHandler] MapWidth: {mauiImage.WidthRequest}");
}
else if (image.Width > 0)
{
handler.PlatformView.WidthRequest = image.Width;
}
}
}
public static void MapHeight(ImageHandler handler, IImage image)
{
if (handler.PlatformView != null)
{
if (image is Image mauiImage && mauiImage.HeightRequest > 0)
{
handler.PlatformView.HeightRequest = mauiImage.HeightRequest;
Console.WriteLine($"[ImageHandler] MapHeight: {mauiImage.HeightRequest}");
}
else if (image.Height > 0)
{
handler.PlatformView.HeightRequest = image.Height;
}
}
}
}

View File

@@ -1,315 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform.Linux.Window;
using Microsoft.Maui.Primitives;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Label control.
/// </summary>
public class LabelHandler : ViewHandler<ILabel, SkiaLabel>
{
public static IPropertyMapper<ILabel, LabelHandler> Mapper = new PropertyMapper<ILabel, LabelHandler>(ViewHandler.ViewMapper)
{
["Text"] = MapText,
["TextColor"] = MapTextColor,
["Font"] = MapFont,
["CharacterSpacing"] = MapCharacterSpacing,
["HorizontalTextAlignment"] = MapHorizontalTextAlignment,
["VerticalTextAlignment"] = MapVerticalTextAlignment,
["TextDecorations"] = MapTextDecorations,
["LineHeight"] = MapLineHeight,
["LineBreakMode"] = MapLineBreakMode,
["MaxLines"] = MapMaxLines,
["Padding"] = MapPadding,
["Background"] = MapBackground,
["VerticalLayoutAlignment"] = MapVerticalLayoutAlignment,
["HorizontalLayoutAlignment"] = MapHorizontalLayoutAlignment,
["FormattedText"] = MapFormattedText
};
public static CommandMapper<ILabel, LabelHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public LabelHandler() : base(Mapper, CommandMapper)
{
}
public LabelHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaLabel CreatePlatformView()
{
return new SkiaLabel();
}
protected override void ConnectHandler(SkiaLabel platformView)
{
base.ConnectHandler(platformView);
if (VirtualView is View view)
{
platformView.MauiView = view;
if (view.GestureRecognizers.OfType<TapGestureRecognizer>().Any())
{
platformView.CursorType = CursorType.Hand;
}
}
platformView.Tapped += OnPlatformViewTapped;
}
protected override void DisconnectHandler(SkiaLabel platformView)
{
platformView.Tapped -= OnPlatformViewTapped;
platformView.MauiView = null;
base.DisconnectHandler(platformView);
}
private void OnPlatformViewTapped(object? sender, EventArgs e)
{
if (VirtualView is View view)
{
GestureManager.ProcessTap(view, 0.0, 0.0);
}
}
public static void MapText(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Text = label.Text ?? string.Empty;
}
}
public static void MapTextColor(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null && label.TextColor != null)
{
handler.PlatformView.TextColor = label.TextColor.ToSKColor();
}
}
public static void MapFont(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
var font = label.Font;
if (font.Size > 0)
{
handler.PlatformView.FontSize = (float)font.Size;
}
if (!string.IsNullOrEmpty(font.Family))
{
handler.PlatformView.FontFamily = font.Family;
}
handler.PlatformView.IsBold = (int)font.Weight >= 700;
handler.PlatformView.IsItalic = font.Slant == FontSlant.Italic || font.Slant == FontSlant.Oblique;
}
}
public static void MapCharacterSpacing(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.CharacterSpacing = (float)label.CharacterSpacing;
}
}
public static void MapHorizontalTextAlignment(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.HorizontalTextAlignment = (int)label.HorizontalTextAlignment switch
{
0 => TextAlignment.Start,
1 => TextAlignment.Center,
2 => TextAlignment.End,
_ => TextAlignment.Start
};
}
}
public static void MapVerticalTextAlignment(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.VerticalTextAlignment = (int)label.VerticalTextAlignment switch
{
0 => TextAlignment.Start,
1 => TextAlignment.Center,
2 => TextAlignment.End,
_ => TextAlignment.Center
};
}
}
public static void MapTextDecorations(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsUnderline = (label.TextDecorations & TextDecorations.Underline) != 0;
handler.PlatformView.IsStrikethrough = (label.TextDecorations & TextDecorations.Strikethrough) != 0;
}
}
public static void MapLineHeight(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.LineHeight = (float)label.LineHeight;
}
}
public static void MapLineBreakMode(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
if (label is Label mauiLabel)
{
handler.PlatformView.LineBreakMode = (int)mauiLabel.LineBreakMode switch
{
0 => LineBreakMode.NoWrap,
1 => LineBreakMode.WordWrap,
2 => LineBreakMode.CharacterWrap,
3 => LineBreakMode.HeadTruncation,
4 => LineBreakMode.TailTruncation,
5 => LineBreakMode.MiddleTruncation,
_ => LineBreakMode.TailTruncation
};
}
}
}
public static void MapMaxLines(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
if (label is Label mauiLabel)
{
handler.PlatformView.MaxLines = mauiLabel.MaxLines;
}
}
}
public static void MapPadding(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
var padding = label.Padding;
handler.PlatformView.Padding = new SKRect(
(float)padding.Left,
(float)padding.Top,
(float)padding.Right,
(float)padding.Bottom);
}
}
public static void MapBackground(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
if (label.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapVerticalLayoutAlignment(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.VerticalOptions = (int)label.VerticalLayoutAlignment switch
{
1 => LayoutOptions.Start,
2 => LayoutOptions.Center,
3 => LayoutOptions.End,
0 => LayoutOptions.Fill,
_ => LayoutOptions.Start
};
}
}
public static void MapHorizontalLayoutAlignment(LabelHandler handler, ILabel label)
{
if (handler.PlatformView != null)
{
handler.PlatformView.HorizontalOptions = (int)label.HorizontalLayoutAlignment switch
{
1 => LayoutOptions.Start,
2 => LayoutOptions.Center,
3 => LayoutOptions.End,
0 => LayoutOptions.Fill,
_ => LayoutOptions.Start
};
}
}
public static void MapFormattedText(LabelHandler handler, ILabel label)
{
if (handler.PlatformView == null)
{
return;
}
if (label is not Label mauiLabel)
{
handler.PlatformView.FormattedSpans = null;
return;
}
var formattedText = mauiLabel.FormattedText;
if (formattedText == null || formattedText.Spans.Count == 0)
{
handler.PlatformView.FormattedSpans = null;
return;
}
var spans = new List<SkiaTextSpan>();
foreach (var span in formattedText.Spans)
{
var skiaSpan = new SkiaTextSpan
{
Text = span.Text ?? "",
IsBold = span.FontAttributes.HasFlag(FontAttributes.Bold),
IsItalic = span.FontAttributes.HasFlag(FontAttributes.Italic),
IsUnderline = (span.TextDecorations & TextDecorations.Underline) != 0,
IsStrikethrough = (span.TextDecorations & TextDecorations.Strikethrough) != 0,
CharacterSpacing = (float)span.CharacterSpacing,
LineHeight = (float)span.LineHeight
};
if (span.TextColor != null)
{
skiaSpan.TextColor = span.TextColor.ToSKColor();
}
if (span.BackgroundColor != null)
{
skiaSpan.BackgroundColor = span.BackgroundColor.ToSKColor();
}
if (!string.IsNullOrEmpty(span.FontFamily))
{
skiaSpan.FontFamily = span.FontFamily;
}
if (span.FontSize > 0)
{
skiaSpan.FontSize = (float)span.FontSize;
}
spans.Add(skiaSpan);
}
handler.PlatformView.FormattedSpans = spans;
}
}

View File

@@ -71,7 +71,6 @@ public partial class LabelHandler : ViewHandler<ILabel, SkiaLabel>
// Explicitly map LineBreakMode on connect - MAUI may not trigger property change for defaults
if (VirtualView is Microsoft.Maui.Controls.Label mauiLabel)
{
Console.WriteLine($"[LabelHandler] ConnectHandler Text='{mauiLabel.Text?.Substring(0, Math.Min(20, mauiLabel.Text?.Length ?? 0))}...' LineBreakMode={mauiLabel.LineBreakMode} ({(int)mauiLabel.LineBreakMode})");
platformView.LineBreakMode = mauiLabel.LineBreakMode;
}

View File

@@ -1,178 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Specialized;
using System.Linq;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Picker control.
/// </summary>
public class PickerHandler : ViewHandler<IPicker, SkiaPicker>
{
public static IPropertyMapper<IPicker, PickerHandler> Mapper = new PropertyMapper<IPicker, PickerHandler>(ViewHandler.ViewMapper)
{
["Title"] = MapTitle,
["TitleColor"] = MapTitleColor,
["SelectedIndex"] = MapSelectedIndex,
["TextColor"] = MapTextColor,
["Font"] = MapFont,
["CharacterSpacing"] = MapCharacterSpacing,
["HorizontalTextAlignment"] = MapHorizontalTextAlignment,
["VerticalTextAlignment"] = MapVerticalTextAlignment,
["Background"] = MapBackground,
["ItemsSource"] = MapItemsSource
};
public static CommandMapper<IPicker, PickerHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
private INotifyCollectionChanged? _itemsCollection;
public PickerHandler() : base(Mapper, CommandMapper)
{
}
public PickerHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaPicker CreatePlatformView()
{
return new SkiaPicker();
}
protected override void ConnectHandler(SkiaPicker platformView)
{
base.ConnectHandler(platformView);
platformView.SelectedIndexChanged += OnSelectedIndexChanged;
if (VirtualView is Picker picker && picker.Items is INotifyCollectionChanged itemsCollection)
{
_itemsCollection = itemsCollection;
_itemsCollection.CollectionChanged += OnItemsCollectionChanged;
}
ReloadItems();
}
protected override void DisconnectHandler(SkiaPicker platformView)
{
platformView.SelectedIndexChanged -= OnSelectedIndexChanged;
if (_itemsCollection != null)
{
_itemsCollection.CollectionChanged -= OnItemsCollectionChanged;
_itemsCollection = null;
}
base.DisconnectHandler(platformView);
}
private void OnItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
ReloadItems();
}
private void OnSelectedIndexChanged(object? sender, EventArgs e)
{
if (VirtualView != null && PlatformView != null)
{
VirtualView.SelectedIndex = PlatformView.SelectedIndex;
}
}
private void ReloadItems()
{
if (PlatformView != null && VirtualView != null)
{
var items = VirtualView.GetItemsAsArray();
PlatformView.SetItems(items.Select(i => i?.ToString() ?? ""));
}
}
public static void MapTitle(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Title = picker.Title ?? "";
}
}
public static void MapTitleColor(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null && picker.TitleColor != null)
{
handler.PlatformView.TitleColor = picker.TitleColor.ToSKColor();
}
}
public static void MapSelectedIndex(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null)
{
handler.PlatformView.SelectedIndex = picker.SelectedIndex;
}
}
public static void MapTextColor(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null && picker.TextColor != null)
{
handler.PlatformView.TextColor = picker.TextColor.ToSKColor();
}
}
public static void MapFont(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null)
{
var font = picker.Font;
if (!string.IsNullOrEmpty(font.Family))
{
handler.PlatformView.FontFamily = font.Family;
}
if (font.Size > 0)
{
handler.PlatformView.FontSize = (float)font.Size;
}
handler.PlatformView.Invalidate();
}
}
public static void MapCharacterSpacing(PickerHandler handler, IPicker picker)
{
// Character spacing not implemented
}
public static void MapHorizontalTextAlignment(PickerHandler handler, IPicker picker)
{
// Horizontal text alignment not implemented
}
public static void MapVerticalTextAlignment(PickerHandler handler, IPicker picker)
{
// Vertical text alignment not implemented
}
public static void MapBackground(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView != null)
{
if (picker.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapItemsSource(PickerHandler handler, IPicker picker)
{
handler.ReloadItems();
}
}

View File

@@ -1,107 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for ProgressBar control.
/// </summary>
public class ProgressBarHandler : ViewHandler<IProgress, SkiaProgressBar>
{
public static IPropertyMapper<IProgress, ProgressBarHandler> Mapper = new PropertyMapper<IProgress, ProgressBarHandler>(ViewHandler.ViewMapper)
{
["Progress"] = MapProgress,
["ProgressColor"] = MapProgressColor,
["IsEnabled"] = MapIsEnabled,
["Background"] = MapBackground,
["BackgroundColor"] = MapBackgroundColor
};
public static CommandMapper<IProgress, ProgressBarHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public ProgressBarHandler() : base(Mapper, CommandMapper)
{
}
protected override SkiaProgressBar CreatePlatformView()
{
return new SkiaProgressBar();
}
protected override void ConnectHandler(SkiaProgressBar platformView)
{
base.ConnectHandler(platformView);
if (VirtualView is BindableObject bindable)
{
bindable.PropertyChanged += OnVirtualViewPropertyChanged;
}
if (VirtualView is VisualElement ve)
{
platformView.IsVisible = ve.IsVisible;
}
}
protected override void DisconnectHandler(SkiaProgressBar platformView)
{
if (VirtualView is BindableObject bindable)
{
bindable.PropertyChanged -= OnVirtualViewPropertyChanged;
}
base.DisconnectHandler(platformView);
}
private void OnVirtualViewPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (VirtualView is VisualElement ve && e.PropertyName == "IsVisible")
{
PlatformView.IsVisible = ve.IsVisible;
PlatformView.Invalidate();
}
}
public static void MapProgress(ProgressBarHandler handler, IProgress progress)
{
handler.PlatformView.Progress = progress.Progress;
}
public static void MapProgressColor(ProgressBarHandler handler, IProgress progress)
{
if (progress.ProgressColor != null)
{
handler.PlatformView.ProgressColor = progress.ProgressColor;
}
handler.PlatformView.Invalidate();
}
public static void MapIsEnabled(ProgressBarHandler handler, IProgress progress)
{
handler.PlatformView.IsEnabled = progress.IsEnabled;
handler.PlatformView.Invalidate();
}
public static void MapBackground(ProgressBarHandler handler, IProgress progress)
{
if (progress.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
handler.PlatformView.Invalidate();
}
}
public static void MapBackgroundColor(ProgressBarHandler handler, IProgress progress)
{
if (progress is VisualElement ve && ve.BackgroundColor != null)
{
handler.PlatformView.BackgroundColor = ve.BackgroundColor;
handler.PlatformView.Invalidate();
}
}
}

View File

@@ -1,105 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for RadioButton control.
/// </summary>
public class RadioButtonHandler : ViewHandler<IRadioButton, SkiaRadioButton>
{
public static IPropertyMapper<IRadioButton, RadioButtonHandler> Mapper = new PropertyMapper<IRadioButton, RadioButtonHandler>(ViewHandler.ViewMapper)
{
["IsChecked"] = MapIsChecked,
["TextColor"] = MapTextColor,
["Font"] = MapFont,
["Background"] = MapBackground
};
public static CommandMapper<IRadioButton, RadioButtonHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public RadioButtonHandler() : base(Mapper, CommandMapper)
{
}
public RadioButtonHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaRadioButton CreatePlatformView()
{
return new SkiaRadioButton();
}
protected override void ConnectHandler(SkiaRadioButton platformView)
{
base.ConnectHandler(platformView);
platformView.CheckedChanged += OnCheckedChanged;
if (VirtualView is RadioButton radioButton)
{
platformView.Content = radioButton.Content?.ToString() ?? "";
platformView.GroupName = radioButton.GroupName;
platformView.Value = radioButton.Value;
}
}
protected override void DisconnectHandler(SkiaRadioButton platformView)
{
platformView.CheckedChanged -= OnCheckedChanged;
base.DisconnectHandler(platformView);
}
private void OnCheckedChanged(object? sender, EventArgs e)
{
if (VirtualView != null && PlatformView != null)
{
VirtualView.IsChecked = PlatformView.IsChecked;
}
}
public static void MapIsChecked(RadioButtonHandler handler, IRadioButton radioButton)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsChecked = radioButton.IsChecked;
}
}
public static void MapTextColor(RadioButtonHandler handler, IRadioButton radioButton)
{
if (handler.PlatformView != null && radioButton.TextColor != null)
{
handler.PlatformView.TextColor = radioButton.TextColor.ToSKColor();
}
}
public static void MapFont(RadioButtonHandler handler, IRadioButton radioButton)
{
if (handler.PlatformView != null)
{
var font = radioButton.Font;
if (font.Size > 0)
{
handler.PlatformView.FontSize = (float)font.Size;
}
}
}
public static void MapBackground(RadioButtonHandler handler, IRadioButton radioButton)
{
if (handler.PlatformView != null)
{
if (radioButton.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
}

View File

@@ -1,109 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform.Linux.Hosting;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for ScrollView control.
/// </summary>
public class ScrollViewHandler : ViewHandler<IScrollView, SkiaScrollView>
{
public static IPropertyMapper<IScrollView, ScrollViewHandler> Mapper = new PropertyMapper<IScrollView, ScrollViewHandler>(ViewHandler.ViewMapper)
{
["Content"] = MapContent,
["HorizontalScrollBarVisibility"] = MapHorizontalScrollBarVisibility,
["VerticalScrollBarVisibility"] = MapVerticalScrollBarVisibility,
["Orientation"] = MapOrientation
};
public static CommandMapper<IScrollView, ScrollViewHandler> CommandMapper = new(ViewHandler.ViewCommandMapper)
{
["RequestScrollTo"] = MapRequestScrollTo
};
public ScrollViewHandler() : base(Mapper, CommandMapper)
{
}
public ScrollViewHandler(IPropertyMapper? mapper)
: base(mapper ?? Mapper, CommandMapper)
{
}
protected override SkiaScrollView CreatePlatformView()
{
return new SkiaScrollView();
}
public static void MapContent(ScrollViewHandler handler, IScrollView scrollView)
{
if (handler.PlatformView == null || handler.MauiContext == null)
{
return;
}
var presentedContent = scrollView.PresentedContent;
if (presentedContent != null)
{
Console.WriteLine("[ScrollViewHandler] MapContent: " + presentedContent.GetType().Name);
if (presentedContent.Handler == null)
{
presentedContent.Handler = presentedContent.ToViewHandler(handler.MauiContext);
}
if (presentedContent.Handler?.PlatformView is SkiaView skiaView)
{
Console.WriteLine("[ScrollViewHandler] Setting content: " + skiaView.GetType().Name);
handler.PlatformView.Content = skiaView;
}
}
else
{
handler.PlatformView.Content = null;
}
}
public static void MapHorizontalScrollBarVisibility(ScrollViewHandler handler, IScrollView scrollView)
{
handler.PlatformView.HorizontalScrollBarVisibility = (int)scrollView.HorizontalScrollBarVisibility switch
{
1 => ScrollBarVisibility.Always,
2 => ScrollBarVisibility.Never,
_ => ScrollBarVisibility.Default
};
}
public static void MapVerticalScrollBarVisibility(ScrollViewHandler handler, IScrollView scrollView)
{
handler.PlatformView.VerticalScrollBarVisibility = (int)scrollView.VerticalScrollBarVisibility switch
{
1 => ScrollBarVisibility.Always,
2 => ScrollBarVisibility.Never,
_ => ScrollBarVisibility.Default
};
}
public static void MapOrientation(ScrollViewHandler handler, IScrollView scrollView)
{
handler.PlatformView.Orientation = ((int)scrollView.Orientation - 1) switch
{
0 => ScrollOrientation.Horizontal,
1 => ScrollOrientation.Both,
2 => ScrollOrientation.Neither,
_ => ScrollOrientation.Vertical
};
}
public static void MapRequestScrollTo(ScrollViewHandler handler, IScrollView scrollView, object? args)
{
if (args is ScrollToRequest request)
{
handler.PlatformView.ScrollTo((float)request.HorizontalOffset, (float)request.VerticalOffset, !request.Instant);
}
}
}

View File

@@ -1,135 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for SearchBar control.
/// </summary>
public class SearchBarHandler : ViewHandler<ISearchBar, SkiaSearchBar>
{
public static IPropertyMapper<ISearchBar, SearchBarHandler> Mapper = new PropertyMapper<ISearchBar, SearchBarHandler>(ViewHandler.ViewMapper)
{
["Text"] = MapText,
["TextColor"] = MapTextColor,
["Font"] = MapFont,
["Placeholder"] = MapPlaceholder,
["PlaceholderColor"] = MapPlaceholderColor,
["CancelButtonColor"] = MapCancelButtonColor,
["Background"] = MapBackground
};
public static CommandMapper<ISearchBar, SearchBarHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public SearchBarHandler() : base(Mapper, CommandMapper)
{
}
public SearchBarHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaSearchBar CreatePlatformView()
{
return new SkiaSearchBar();
}
protected override void ConnectHandler(SkiaSearchBar platformView)
{
base.ConnectHandler(platformView);
platformView.TextChanged += OnTextChanged;
platformView.SearchButtonPressed += OnSearchButtonPressed;
}
protected override void DisconnectHandler(SkiaSearchBar platformView)
{
platformView.TextChanged -= OnTextChanged;
platformView.SearchButtonPressed -= OnSearchButtonPressed;
base.DisconnectHandler(platformView);
}
private void OnTextChanged(object? sender, TextChangedEventArgs e)
{
if (VirtualView != null && PlatformView != null && VirtualView.Text != e.NewTextValue)
{
VirtualView.Text = e.NewTextValue ?? string.Empty;
}
}
private void OnSearchButtonPressed(object? sender, EventArgs e)
{
VirtualView?.SearchButtonPressed();
}
public static void MapText(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null && handler.PlatformView.Text != searchBar.Text)
{
handler.PlatformView.Text = searchBar.Text ?? string.Empty;
}
}
public static void MapTextColor(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null && searchBar.TextColor != null)
{
handler.PlatformView.TextColor = searchBar.TextColor.ToSKColor();
}
}
public static void MapFont(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null)
{
var font = searchBar.Font;
if (font.Size > 0)
{
handler.PlatformView.FontSize = (float)font.Size;
}
if (!string.IsNullOrEmpty(font.Family))
{
handler.PlatformView.FontFamily = font.Family;
}
}
}
public static void MapPlaceholder(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Placeholder = searchBar.Placeholder ?? string.Empty;
}
}
public static void MapPlaceholderColor(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null && searchBar.PlaceholderColor != null)
{
handler.PlatformView.PlaceholderColor = searchBar.PlaceholderColor.ToSKColor();
}
}
public static void MapCancelButtonColor(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null && searchBar.CancelButtonColor != null)
{
handler.PlatformView.ClearButtonColor = searchBar.CancelButtonColor.ToSKColor();
}
}
public static void MapBackground(SearchBarHandler handler, ISearchBar searchBar)
{
if (handler.PlatformView != null)
{
if (searchBar.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
}

View File

@@ -1,152 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Slider control.
/// </summary>
public class SliderHandler : ViewHandler<ISlider, SkiaSlider>
{
public static IPropertyMapper<ISlider, SliderHandler> Mapper = new PropertyMapper<ISlider, SliderHandler>(ViewHandler.ViewMapper)
{
["Minimum"] = MapMinimum,
["Maximum"] = MapMaximum,
["Value"] = MapValue,
["MinimumTrackColor"] = MapMinimumTrackColor,
["MaximumTrackColor"] = MapMaximumTrackColor,
["ThumbColor"] = MapThumbColor,
["Background"] = MapBackground,
["IsEnabled"] = MapIsEnabled
};
public static CommandMapper<ISlider, SliderHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public SliderHandler() : base(Mapper, CommandMapper)
{
}
public SliderHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaSlider CreatePlatformView()
{
return new SkiaSlider();
}
protected override void ConnectHandler(SkiaSlider platformView)
{
base.ConnectHandler(platformView);
platformView.ValueChanged += OnValueChanged;
platformView.DragStarted += OnDragStarted;
platformView.DragCompleted += OnDragCompleted;
if (VirtualView != null)
{
MapMinimum(this, VirtualView);
MapMaximum(this, VirtualView);
MapValue(this, VirtualView);
MapIsEnabled(this, VirtualView);
}
}
protected override void DisconnectHandler(SkiaSlider platformView)
{
platformView.ValueChanged -= OnValueChanged;
platformView.DragStarted -= OnDragStarted;
platformView.DragCompleted -= OnDragCompleted;
base.DisconnectHandler(platformView);
}
private void OnValueChanged(object? sender, SliderValueChangedEventArgs e)
{
if (VirtualView != null && PlatformView != null && Math.Abs(VirtualView.Value - e.NewValue) > 0.0001)
{
VirtualView.Value = e.NewValue;
}
}
private void OnDragStarted(object? sender, EventArgs e)
{
VirtualView?.DragStarted();
}
private void OnDragCompleted(object? sender, EventArgs e)
{
VirtualView?.DragCompleted();
}
public static void MapMinimum(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Minimum = slider.Minimum;
}
}
public static void MapMaximum(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Maximum = slider.Maximum;
}
}
public static void MapValue(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null && Math.Abs(handler.PlatformView.Value - slider.Value) > 0.0001)
{
handler.PlatformView.Value = slider.Value;
}
}
public static void MapMinimumTrackColor(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null && slider.MinimumTrackColor != null)
{
handler.PlatformView.ActiveTrackColor = slider.MinimumTrackColor.ToSKColor();
}
}
public static void MapMaximumTrackColor(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null && slider.MaximumTrackColor != null)
{
handler.PlatformView.TrackColor = slider.MaximumTrackColor.ToSKColor();
}
}
public static void MapThumbColor(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null && slider.ThumbColor != null)
{
handler.PlatformView.ThumbColor = slider.ThumbColor.ToSKColor();
}
}
public static void MapBackground(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null)
{
if (slider.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapIsEnabled(SliderHandler handler, ISlider slider)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsEnabled = slider.IsEnabled;
handler.PlatformView.Invalidate();
}
}
}

View File

@@ -1,127 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Stepper control.
/// </summary>
public class StepperHandler : ViewHandler<IStepper, SkiaStepper>
{
public static IPropertyMapper<IStepper, StepperHandler> Mapper = new PropertyMapper<IStepper, StepperHandler>(ViewHandler.ViewMapper)
{
["Value"] = MapValue,
["Minimum"] = MapMinimum,
["Maximum"] = MapMaximum,
["Increment"] = MapIncrement,
["Background"] = MapBackground,
["IsEnabled"] = MapIsEnabled
};
public static CommandMapper<IStepper, StepperHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public StepperHandler() : base(Mapper, CommandMapper)
{
}
public StepperHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaStepper CreatePlatformView()
{
return new SkiaStepper();
}
protected override void ConnectHandler(SkiaStepper platformView)
{
base.ConnectHandler(platformView);
platformView.ValueChanged += OnValueChanged;
// Apply dark theme colors if needed
if (Application.Current?.UserAppTheme == AppTheme.Dark)
{
platformView.ButtonBackgroundColor = new SKColor(66, 66, 66);
platformView.ButtonPressedColor = new SKColor(97, 97, 97);
platformView.ButtonDisabledColor = new SKColor(48, 48, 48);
platformView.SymbolColor = new SKColor(224, 224, 224);
platformView.SymbolDisabledColor = new SKColor(97, 97, 97);
platformView.BorderColor = new SKColor(97, 97, 97);
}
}
protected override void DisconnectHandler(SkiaStepper platformView)
{
platformView.ValueChanged -= OnValueChanged;
base.DisconnectHandler(platformView);
}
private void OnValueChanged(object? sender, EventArgs e)
{
if (VirtualView != null && PlatformView != null)
{
VirtualView.Value = PlatformView.Value;
}
}
public static void MapValue(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Value = stepper.Value;
}
}
public static void MapMinimum(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Minimum = stepper.Minimum;
}
}
public static void MapMaximum(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
handler.PlatformView.Maximum = stepper.Maximum;
}
}
public static void MapBackground(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
if (stepper.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapIncrement(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
if (stepper is Stepper mauiStepper)
{
handler.PlatformView.Increment = mauiStepper.Increment;
}
}
}
public static void MapIsEnabled(StepperHandler handler, IStepper stepper)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsEnabled = stepper.IsEnabled;
}
}
}

View File

@@ -1,104 +0,0 @@
// 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.Handlers;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Handlers;
/// <summary>
/// Linux handler for Switch control.
/// </summary>
public class SwitchHandler : ViewHandler<ISwitch, SkiaSwitch>
{
public static IPropertyMapper<ISwitch, SwitchHandler> Mapper = new PropertyMapper<ISwitch, SwitchHandler>(ViewHandler.ViewMapper)
{
["IsOn"] = MapIsOn,
["TrackColor"] = MapTrackColor,
["ThumbColor"] = MapThumbColor,
["Background"] = MapBackground,
["IsEnabled"] = MapIsEnabled
};
public static CommandMapper<ISwitch, SwitchHandler> CommandMapper = new(ViewHandler.ViewCommandMapper);
public SwitchHandler() : base(Mapper, CommandMapper)
{
}
public SwitchHandler(IPropertyMapper? mapper, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
protected override SkiaSwitch CreatePlatformView()
{
return new SkiaSwitch();
}
protected override void ConnectHandler(SkiaSwitch platformView)
{
base.ConnectHandler(platformView);
platformView.Toggled += OnToggled;
}
protected override void DisconnectHandler(SkiaSwitch platformView)
{
platformView.Toggled -= OnToggled;
base.DisconnectHandler(platformView);
}
private void OnToggled(object? sender, ToggledEventArgs e)
{
if (VirtualView != null && VirtualView.IsOn != e.Value)
{
VirtualView.IsOn = e.Value;
}
}
public static void MapIsOn(SwitchHandler handler, ISwitch @switch)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsOn = @switch.IsOn;
}
}
public static void MapTrackColor(SwitchHandler handler, ISwitch @switch)
{
if (handler.PlatformView != null && @switch.TrackColor != null)
{
var onTrackColor = @switch.TrackColor.ToSKColor();
handler.PlatformView.OnTrackColor = onTrackColor;
handler.PlatformView.OffTrackColor = onTrackColor.WithAlpha(128);
}
}
public static void MapThumbColor(SwitchHandler handler, ISwitch @switch)
{
if (handler.PlatformView != null && @switch.ThumbColor != null)
{
handler.PlatformView.ThumbColor = @switch.ThumbColor.ToSKColor();
}
}
public static void MapBackground(SwitchHandler handler, ISwitch @switch)
{
if (handler.PlatformView != null)
{
if (@switch.Background is SolidPaint solidPaint && solidPaint.Color != null)
{
handler.PlatformView.BackgroundColor = solidPaint.Color;
}
}
}
public static void MapIsEnabled(SwitchHandler handler, ISwitch @switch)
{
if (handler.PlatformView != null)
{
handler.PlatformView.IsEnabled = @switch.IsEnabled;
}
}
}