Files
maui-linux/Views/SkiaContextMenu.cs
Dave Friedel 1f096c38dc Update with recovered code from VM binaries (Jan 1)
Recovered from decompiled OpenMaui.Controls.Linux.dll:
- SkiaShell.cs: FlyoutHeader, FlyoutFooter, scroll support (918 -> 1325 lines)
- X11Window.cs: Cursor support (XCreateFontCursor, XDefineCursor)
- All handlers with dark mode support
- All services with latest implementations
- LinuxApplication with theme change handling
2026-01-01 06:22:48 -05:00

313 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using SkiaSharp;
namespace Microsoft.Maui.Platform;
public class SkiaContextMenu : SkiaView
{
private readonly List<ContextMenuItem> _items;
private readonly float _x;
private readonly float _y;
private int _hoveredIndex = -1;
private SKRect[] _itemBounds = Array.Empty<SKRect>();
private static readonly SKColor MenuBackground = new SKColor(byte.MaxValue, byte.MaxValue, byte.MaxValue);
private static readonly SKColor MenuBackgroundDark = new SKColor((byte)48, (byte)48, (byte)48);
private static readonly SKColor ItemHoverBackground = new SKColor((byte)227, (byte)242, (byte)253);
private static readonly SKColor ItemHoverBackgroundDark = new SKColor((byte)80, (byte)80, (byte)80);
private static readonly SKColor ItemTextColor = new SKColor((byte)33, (byte)33, (byte)33);
private static readonly SKColor ItemTextColorDark = new SKColor((byte)224, (byte)224, (byte)224);
private static readonly SKColor DisabledTextColor = new SKColor((byte)158, (byte)158, (byte)158);
private static readonly SKColor SeparatorColor = new SKColor((byte)224, (byte)224, (byte)224);
private static readonly SKColor ShadowColor = new SKColor((byte)0, (byte)0, (byte)0, (byte)40);
private const float MenuPadding = 4f;
private const float ItemHeight = 32f;
private const float ItemPaddingH = 16f;
private const float SeparatorHeight = 9f;
private const float CornerRadius = 4f;
private const float MinWidth = 120f;
private bool _isDarkTheme;
public SkiaContextMenu(float x, float y, List<ContextMenuItem> items, bool isDarkTheme = false)
{
_x = x;
_y = y;
_items = items;
_isDarkTheme = isDarkTheme;
base.IsFocusable = true;
}
public override void Draw(SKCanvas canvas)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Expected O, but got Unknown
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Expected O, but got Unknown
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
//IL_02d4: Expected O, but got Unknown
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
//IL_0264: Expected O, but got Unknown
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
float num = CalculateMenuWidth();
float num2 = CalculateMenuHeight();
float num3 = _x;
float num4 = _y;
SKRectI val = default(SKRectI);
canvas.GetDeviceClipBounds(ref val);
if (num3 + num > (float)((SKRectI)(ref val)).Right)
{
num3 = (float)((SKRectI)(ref val)).Right - num - 4f;
}
if (num4 + num2 > (float)((SKRectI)(ref val)).Bottom)
{
num4 = (float)((SKRectI)(ref val)).Bottom - num2 - 4f;
}
SKRect val2 = default(SKRect);
((SKRect)(ref val2))._002Ector(num3, num4, num3 + num, num4 + num2);
SKPaint val3 = new SKPaint
{
Color = ShadowColor,
MaskFilter = SKMaskFilter.CreateBlur((SKBlurStyle)0, 4f)
};
try
{
canvas.DrawRoundRect(((SKRect)(ref val2)).Left + 2f, ((SKRect)(ref val2)).Top + 2f, num, num2, 4f, 4f, val3);
SKPaint val4 = new SKPaint
{
Color = (_isDarkTheme ? MenuBackgroundDark : MenuBackground),
IsAntialias = true
};
try
{
canvas.DrawRoundRect(val2, 4f, 4f, val4);
SKPaint val5 = new SKPaint
{
Color = SeparatorColor,
Style = (SKPaintStyle)1,
StrokeWidth = 1f,
IsAntialias = true
};
try
{
canvas.DrawRoundRect(val2, 4f, 4f, val5);
_itemBounds = (SKRect[])(object)new SKRect[_items.Count];
float num5 = num4 + 4f;
SKRect val7 = default(SKRect);
for (int i = 0; i < _items.Count; i++)
{
ContextMenuItem contextMenuItem = _items[i];
if (contextMenuItem.IsSeparator)
{
float num6 = num5 + 4.5f;
SKPaint val6 = new SKPaint
{
Color = SeparatorColor,
StrokeWidth = 1f
};
try
{
canvas.DrawLine(num3 + 8f, num6, num3 + num - 8f, num6, val6);
_itemBounds[i] = new SKRect(num3, num5, num3 + num, num5 + 9f);
num5 += 9f;
}
finally
{
((IDisposable)val6)?.Dispose();
}
continue;
}
((SKRect)(ref val7))._002Ector(num3 + 4f, num5, num3 + num - 4f, num5 + 32f);
_itemBounds[i] = val7;
if (i == _hoveredIndex && contextMenuItem.IsEnabled)
{
SKPaint val8 = new SKPaint
{
Color = (_isDarkTheme ? ItemHoverBackgroundDark : ItemHoverBackground),
IsAntialias = true
};
try
{
canvas.DrawRoundRect(val7, 4f, 4f, val8);
}
finally
{
((IDisposable)val8)?.Dispose();
}
}
SKPaint val9 = new SKPaint
{
Color = ((!contextMenuItem.IsEnabled) ? DisabledTextColor : (_isDarkTheme ? ItemTextColorDark : ItemTextColor)),
TextSize = 14f,
IsAntialias = true,
Typeface = SKTypeface.Default
};
try
{
float num7 = ((SKRect)(ref val7)).MidY + val9.TextSize / 3f;
canvas.DrawText(contextMenuItem.Text, ((SKRect)(ref val7)).Left + 16f, num7, val9);
num5 += 32f;
}
finally
{
((IDisposable)val9)?.Dispose();
}
}
}
finally
{
((IDisposable)val5)?.Dispose();
}
}
finally
{
((IDisposable)val4)?.Dispose();
}
}
finally
{
((IDisposable)val3)?.Dispose();
}
}
private float CalculateMenuWidth()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
float num = 120f;
SKPaint val = new SKPaint
{
TextSize = 14f,
Typeface = SKTypeface.Default
};
try
{
foreach (ContextMenuItem item in _items)
{
if (!item.IsSeparator)
{
float val2 = val.MeasureText(item.Text) + 32f;
num = Math.Max(num, val2);
}
}
return num + 8f;
}
finally
{
((IDisposable)val)?.Dispose();
}
}
private float CalculateMenuHeight()
{
float num = 8f;
foreach (ContextMenuItem item in _items)
{
num += (item.IsSeparator ? 9f : 32f);
}
return num;
}
public override void OnPointerMoved(PointerEventArgs e)
{
int hoveredIndex = _hoveredIndex;
_hoveredIndex = -1;
for (int i = 0; i < _itemBounds.Length; i++)
{
if (((SKRect)(ref _itemBounds[i])).Contains(e.X, e.Y) && !_items[i].IsSeparator)
{
_hoveredIndex = i;
break;
}
}
if (hoveredIndex != _hoveredIndex)
{
Invalidate();
}
}
public override void OnPointerPressed(PointerEventArgs e)
{
for (int i = 0; i < _itemBounds.Length; i++)
{
if (((SKRect)(ref _itemBounds[i])).Contains(e.X, e.Y))
{
ContextMenuItem contextMenuItem = _items[i];
if (contextMenuItem.IsEnabled && !contextMenuItem.IsSeparator && contextMenuItem.Action != null)
{
LinuxDialogService.HideContextMenu();
contextMenuItem.Action();
return;
}
}
}
LinuxDialogService.HideContextMenu();
}
public override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
LinuxDialogService.HideContextMenu();
e.Handled = true;
}
}
}