Create basic controls without much regards to layout rules.

This commit is contained in:
2025-11-21 23:04:37 +03:00
parent 5cba1ab7db
commit 4f67e0fb75
16 changed files with 290 additions and 59 deletions

View File

@@ -6,18 +6,18 @@ namespace Dashboard.Drawing
{ {
public interface IDeviceContextBase : IDeviceContextExtension public interface IDeviceContextBase : IDeviceContextExtension
{ {
RectangleF ClipRegion { get; } Box2d ClipRegion { get; }
RectangleF ScissorRegion { get; } Box2d ScissorRegion { get; }
Matrix4x4 Transforms { get; } Matrix4x4 Transforms { get; }
float Scale { get; } float Scale { get; }
float ScaleOverride { get; set; } float ScaleOverride { get; set; }
void ResetClip(); void ResetClip();
void PushClip(RectangleF clipRegion); void PushClip(Box2d clipRegion);
void PopClip(); void PopClip();
void ResetScissor(); void ResetScissor();
void PushScissor(RectangleF scissorRegion); void PushScissor(Box2d scissorRegion);
void PopScissor(); void PopScissor();
void ResetTransforms(); void ResetTransforms();

View File

@@ -44,4 +44,16 @@ namespace Dashboard.Events
public ScanCode ScanCode { get; } = scanCode; public ScanCode ScanCode { get; } = scanCode;
public ModifierKeys ModifierKeys { get; } = modifierKeys; public ModifierKeys ModifierKeys { get; } = modifierKeys;
} }
public class TextInputEventArgs(string text) : UiEventArgs(UiEventType.TextEdit)
{
public string Text { get; } = text;
}
public class TextEditEventArgs(string candidate, int cursor, int length) : UiEventArgs(UiEventType.TextEdit)
{
public string Candidate { get; } = candidate;
public int Cursor { get; } = cursor;
public int Length { get; } = length;
}
} }

View File

@@ -76,8 +76,7 @@ namespace Dashboard.Events
} }
} }
public class ControlResizedEventArgs public class ResizeEventArgs() : UiEventArgs(UiEventType.ControlResized)
{ {
} }
} }

View File

@@ -1,4 +1,5 @@
using System.Drawing; using System.Drawing;
using System.Numerics;
namespace Dashboard.Windowing namespace Dashboard.Windowing
{ {
@@ -15,6 +16,6 @@ namespace Dashboard.Windowing
/// <summary> /// <summary>
/// The size of the window framebuffer in pixels. /// The size of the window framebuffer in pixels.
/// </summary> /// </summary>
Size FramebufferSize { get; } Vector2 FramebufferSize { get; }
} }
} }

View File

@@ -7,14 +7,15 @@ using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics.Wgl; using OpenTK.Graphics.Wgl;
using OpenTK.Mathematics; using OpenTK.Mathematics;
using ColorBuffer = OpenTK.Graphics.OpenGL.ColorBuffer; using ColorBuffer = OpenTK.Graphics.OpenGL.ColorBuffer;
using Vector2 = System.Numerics.Vector2;
namespace Dashboard.OpenGL.Drawing namespace Dashboard.OpenGL.Drawing
{ {
public class DeviceContextBase : IDeviceContextBase public class DeviceContextBase : IDeviceContextBase
{ {
private readonly Stack<Matrix4x4> _transforms = new Stack<Matrix4x4>(); private readonly Stack<Matrix4x4> _transforms = new Stack<Matrix4x4>();
private readonly Stack<RectangleF> _clipRegions = new Stack<RectangleF>(); private readonly Stack<Box2d> _clipRegions = new Stack<Box2d>();
private readonly Stack<RectangleF> _scissorRegions = new Stack<RectangleF>(); private readonly Stack<Box2d> _scissorRegions = new Stack<Box2d>();
public DeviceContext Context { get; private set; } = null!; public DeviceContext Context { get; private set; } = null!;
IContextBase IContextExtensionBase.Context => Context; IContextBase IContextExtensionBase.Context => Context;
@@ -22,8 +23,8 @@ namespace Dashboard.OpenGL.Drawing
public string DriverVendor => "Dashboard"; public string DriverVendor => "Dashboard";
public Version DriverVersion => new Version(0, 1); public Version DriverVersion => new Version(0, 1);
public RectangleF ClipRegion => _clipRegions.Peek(); public Box2d ClipRegion => _clipRegions.Peek();
public RectangleF ScissorRegion => _scissorRegions.Peek(); public Box2d ScissorRegion => _scissorRegions.Peek();
public Matrix4x4 Transforms => _transforms.Peek(); public Matrix4x4 Transforms => _transforms.Peek();
public float Scale => ScaleOverride > 0 ? ScaleOverride : (Context.Window as IDpiAwareWindow)?.Scale ?? 1; public float Scale => ScaleOverride > 0 ? ScaleOverride : (Context.Window as IDpiAwareWindow)?.Scale ?? 1;
public float ScaleOverride { get; set; } = -1f; public float ScaleOverride { get; set; } = -1f;
@@ -50,17 +51,17 @@ namespace Dashboard.OpenGL.Drawing
{ {
_clipRegions.Clear(); _clipRegions.Clear();
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
_clipRegions.Push(new RectangleF(0,0, size.Width, size.Height)); _clipRegions.Push(new Box2d(Vector2.Zero, size));
SetClip(ClipRegion); SetClip(ClipRegion);
} }
public void PushClip(RectangleF clipRegion) public void PushClip(Box2d clipRegion)
{ {
clipRegion = new RectangleF(ClipRegion.X + clipRegion.X, ClipRegion.Y + clipRegion.Y, clipRegion = new Box2d(ClipRegion.Min.X + clipRegion.Min.X, ClipRegion.Min.Y + clipRegion.Min.Y,
Math.Min(ClipRegion.Right - clipRegion.X, clipRegion.Width), Math.Min(ClipRegion.Max.X, ClipRegion.Min.X + clipRegion.Max.X),
Math.Min(ClipRegion.Bottom - clipRegion.Y, clipRegion.Height)); Math.Min(ClipRegion.Max.Y, ClipRegion.Max.Y + clipRegion.Max.Y));
_clipRegions.Push(clipRegion); _clipRegions.Push(clipRegion);
SetClip(clipRegion); SetClip(clipRegion);
@@ -76,11 +77,11 @@ namespace Dashboard.OpenGL.Drawing
{ {
GL.Disable(EnableCap.ScissorTest); GL.Disable(EnableCap.ScissorTest);
_scissorRegions.Clear(); _scissorRegions.Clear();
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
_scissorRegions.Push(new RectangleF(0,0, size.Width, size.Height)); _scissorRegions.Push(new Box2d(Vector2.Zero, size));
} }
public void PushScissor(RectangleF scissorRegion) public void PushScissor(Box2d scissorRegion)
{ {
GL.Enable(EnableCap.ScissorTest); GL.Enable(EnableCap.ScissorTest);
@@ -101,30 +102,30 @@ namespace Dashboard.OpenGL.Drawing
SetScissor(ClipRegion); SetScissor(ClipRegion);
} }
private void SetClip(RectangleF rect) private void SetClip(Box2d rect)
{ {
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
GL.Viewport( GL.Viewport(
(int)Math.Round(rect.X), (int)Math.Round(rect.Min.X),
(int)Math.Round(size.Height - rect.Y - rect.Height), (int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
(int)Math.Round(rect.Width), (int)Math.Round(rect.Size.X),
(int)Math.Round(rect.Height)); (int)Math.Round(rect.Size.Y));
} }
void SetScissor(RectangleF rect) void SetScissor(Box2d rect)
{ {
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
GL.Scissor( GL.Scissor(
(int)Math.Round(rect.X), (int)Math.Round(rect.Min.X),
(int)Math.Round(size.Height - rect.Y - rect.Height), (int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
(int)Math.Round(rect.Width), (int)Math.Round(rect.Size.X),
(int)Math.Round(rect.Height)); (int)Math.Round(rect.Size.Y));
} }
public void ResetTransforms() public void ResetTransforms()
{ {
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.Width, size.Height, 0, 1, -1); Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.X, size.Y, 0, 1, -1);
_transforms.Clear(); _transforms.Clear();
_transforms.Push(m); _transforms.Push(m);

View File

@@ -110,7 +110,6 @@ namespace Dashboard.OpenGL.Drawing
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset); GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
GL.EnableVertexAttribArray(_program_acolor); GL.EnableVertexAttribArray(_program_acolor);
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms; Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
GL.UseProgram(_program); GL.UseProgram(_program);
@@ -150,7 +149,6 @@ namespace Dashboard.OpenGL.Drawing
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset); GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
GL.EnableVertexAttribArray(_program_acolor); GL.EnableVertexAttribArray(_program_acolor);
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms; Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
GL.UseProgram(_program); GL.UseProgram(_program);
@@ -189,7 +187,6 @@ namespace Dashboard.OpenGL.Drawing
GL.EnableVertexAttribArray(_program_atexcoord); GL.EnableVertexAttribArray(_program_atexcoord);
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset); GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
GL.EnableVertexAttribArray(_program_acolor); GL.EnableVertexAttribArray(_program_acolor);
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms; Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
GL.UseProgram(_program); GL.UseProgram(_program);

View File

@@ -1,4 +1,4 @@
using System.Drawing; using System.Numerics;
using Dashboard.Windowing; using Dashboard.Windowing;
namespace Dashboard.OpenGL namespace Dashboard.OpenGL
@@ -17,7 +17,7 @@ namespace Dashboard.OpenGL
/// <summary> /// <summary>
/// The size of the framebuffer in pixels. /// The size of the framebuffer in pixels.
/// </summary> /// </summary>
public Size FramebufferSize { get; } public Vector2 FramebufferSize { get; }
/// <summary> /// <summary>
/// Called when the context is disposed. /// Called when the context is disposed.

View File

@@ -121,6 +121,7 @@ namespace Dashboard.OpenTK.PAL2
return; return;
} }
break; break;
// Mouse Events
case PlatformEventType.MouseDown: case PlatformEventType.MouseDown:
{ {
MouseButtonDownEventArgs down = (MouseButtonDownEventArgs)args; MouseButtonDownEventArgs down = (MouseButtonDownEventArgs)args;
@@ -161,6 +162,8 @@ namespace Dashboard.OpenTK.PAL2
info.Window.SendEvent(this, scroll2); info.Window.SendEvent(this, scroll2);
break; break;
} }
// Keyboard & Text Events
case PlatformEventType.KeyDown: case PlatformEventType.KeyDown:
{ {
KeyDownEventArgs down = (KeyDownEventArgs)args; KeyDownEventArgs down = (KeyDownEventArgs)args;
@@ -185,11 +188,43 @@ namespace Dashboard.OpenTK.PAL2
info.Window.SendEvent(this, up2); info.Window.SendEvent(this, up2);
break; break;
} }
case PlatformEventType.TextInput:
{
OPENTK.TextInputEventArgs textInput = (OPENTK.TextInputEventArgs)args;
DB.TextInputEventArgs textInput2 = new DB.TextInputEventArgs(textInput.Text);
info.Window.SendEvent(this, textInput2);
break;
}
case PlatformEventType.TextEditing:
{
TextEditingEventArgs textEditing = (TextEditingEventArgs)args;
TextEditEventArgs textEditing2 = new TextEditEventArgs(textEditing.Candidate, textEditing.Cursor, textEditing.Length);
info.Window.SendEvent(this, textEditing2);
break;
}
// Window/Surface related events.
case PlatformEventType.Close: case PlatformEventType.Close:
{ {
info.Window.SendEvent(this, new WindowCloseEvent()); info.Window.SendEvent(this, new WindowCloseEvent());
break; break;
} }
case PlatformEventType.WindowFramebufferResize:
{
var resize = (WindowFramebufferResizeEventArgs)args;
info.Window.SendEvent(this, new ResizeEventArgs());
info.Window.SendEvent(this, new PaintEventArgs(info.Window.DeviceContext));
break;
}
case PlatformEventType.WindowResize:
{
var resize = (WindowResizeEventArgs)args;
info.Window.SendEvent(this, new ResizeEventArgs());
info.Window.SendEvent(this, new PaintEventArgs(info.Window.DeviceContext));
break;
}
default: default:
Debugger?.LogDebug($"Unknown event type {type} with \"{args}\"."); Debugger?.LogDebug($"Unknown event type {type} with \"{args}\".");
break; break;

View File

@@ -15,14 +15,15 @@ namespace Dashboard.OpenTK.PAL2
public WindowHandle WindowHandle { get; } public WindowHandle WindowHandle { get; }
public ISwapGroup SwapGroup { get; } public ISwapGroup SwapGroup { get; }
public int ContextGroup { get; } public int ContextGroup { get; }
public Size FramebufferSize public System.Numerics.Vector2 FramebufferSize
{ {
get get
{ {
TK.Window.GetFramebufferSize(WindowHandle, out Vector2i size); TK.Window.GetFramebufferSize(WindowHandle, out Vector2i size);
return new Size(size.X, size.Y); return new System.Numerics.Vector2(size.X, size.Y);
} }
} }
@@ -64,6 +65,7 @@ namespace Dashboard.OpenTK.PAL2
private static int _contextGroupId = 0; private static int _contextGroupId = 0;
private static ConcurrentDictionary<OpenGLContextHandle, int> _contextGroupRootContexts = new ConcurrentDictionary<OpenGLContextHandle, int>(); private static ConcurrentDictionary<OpenGLContextHandle, int> _contextGroupRootContexts = new ConcurrentDictionary<OpenGLContextHandle, int>();
private Size _framebufferSize;
private static int GetContextGroup(OpenGLContextHandle handle) private static int GetContextGroup(OpenGLContextHandle handle)
{ {

View File

@@ -0,0 +1,67 @@
using System;
using System.Drawing;
using System.Numerics;
using Dashboard.Drawing;
using Dashboard.Pal;
namespace Dashboard.Controls
{
public class Button : Control
{
private Vector2 _intrinsicSize = Vector2.Zero;
public bool AutoSize { get; set; } = true;
public string Text { get; set; } = "Click!";
public Font Font { get; set; } = Font.Create(new FontInfo("Rec Mono Linear"));
public float TextSize { get; set; } = 12f;
public Brush TextBrush { get; set; } = new SolidColorBrush(Color.Black);
public Brush ButtonBrush { get; set; } = new SolidColorBrush(Color.DarkSlateGray);
public Vector2 Padding { get; set; } = new Vector2(4, 4);
public event EventHandler? Clicked;
public override Vector2 CalculateIntrinsicSize()
{
return _intrinsicSize + 2 * Padding;
}
protected void CalculateSize(DeviceContext dc)
{
Box2d box = dc.ExtensionRequire<ITextRenderer>().MeasureText(Font.Base, TextSize, Text);
_intrinsicSize = box.Size;
Size = box.Size;
ClientArea = new Box2d(ClientArea.Min, ClientArea.Min + Size);
}
public override void OnPaint(DeviceContext dc)
{
base.OnPaint(dc);
if (AutoSize)
CalculateSize(dc);
var dcb = dc.ExtensionRequire<IDeviceContextBase>();
if (HideOverflow)
dcb.PushScissor(ClientArea);
dcb.PushTransforms(Matrix4x4.CreateTranslation(ClientArea.Left, ClientArea.Top, 0));
var imm = dc.ExtensionRequire<IImmediateMode>();
Color color = (ButtonBrush as SolidColorBrush)?.Color ?? Color.Black;
Vector4 colorVector = new Vector4(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
imm.Rectangle(ClientArea, 0, colorVector);
var text = dc.ExtensionRequire<ITextRenderer>();
color = (TextBrush as SolidColorBrush)?.Color ?? Color.Black;
colorVector = new Vector4(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
text.DrawText(Vector2.Zero, colorVector, TextSize, Font.Base, Text);
if (HideOverflow)
dcb.PopScissor();
dcb.PopTransforms();
}
}
}

View File

@@ -41,7 +41,7 @@ namespace Dashboard.Controls
base.OnPaint(dc); base.OnPaint(dc);
var dcb = dc.ExtensionRequire<IDeviceContextBase>(); var dcb = dc.ExtensionRequire<IDeviceContextBase>();
dcb.PushClip(new RectangleF(ClientArea.Left, ClientArea.Bottom, ClientArea.Size.X, ClientArea.Size.Y)); dcb.PushClip(ClientArea);
// dcb.PushTransforms(Matrix4x4.CreateTranslation(ClientArea.Left, ClientArea.Bottom, 0)); // dcb.PushTransforms(Matrix4x4.CreateTranslation(ClientArea.Left, ClientArea.Bottom, 0));
LayoutChildren(); LayoutChildren();

View File

@@ -72,6 +72,11 @@ namespace Dashboard.Controls
public event EventHandler? Disposing; public event EventHandler? Disposing;
public event EventHandler? Resized; public event EventHandler? Resized;
public virtual Vector2 CalculateIntrinsicSize()
{
return Vector2.Max(Vector2.Zero, Vector2.Max(Size, MinimumSize));
}
public virtual void OnPaint(DeviceContext dc) public virtual void OnPaint(DeviceContext dc)
{ {
Painting?.Invoke(this, dc); Painting?.Invoke(this, dc);

View File

@@ -0,0 +1,27 @@
using System.Numerics;
using Dashboard.Drawing;
using Dashboard.Pal;
namespace Dashboard.Controls
{
public class ImageBox : Control
{
public Image? Image { get; set; }
public override Vector2 CalculateIntrinsicSize()
{
return new Vector2(Image?.Width ?? 0, Image?.Height ?? 0);
}
public override void OnPaint(DeviceContext dc)
{
if (Image == null)
return;
Size = CalculateIntrinsicSize();
dc.ExtensionRequire<IImmediateMode>().Image(new Box2d(ClientArea.Min, ClientArea.Min + Size), new Box2d(0, 0, 1, 1), 0, Image.InternTexture(dc));
base.OnPaint(dc);
}
}
}

View File

@@ -8,6 +8,8 @@ namespace Dashboard.Controls
{ {
public class Label : Control public class Label : Control
{ {
private Vector2 _intrinsicSize = Vector2.Zero;
public bool AutoSize { get; set; } = true; public bool AutoSize { get; set; } = true;
public string Text { get; set; } = ""; public string Text { get; set; } = "";
@@ -18,9 +20,15 @@ namespace Dashboard.Controls
public float TextSize { get; set; } = 12f; public float TextSize { get; set; } = 12f;
public Brush TextBrush { get; set; } = new SolidColorBrush(Color.Black); public Brush TextBrush { get; set; } = new SolidColorBrush(Color.Black);
public override Vector2 CalculateIntrinsicSize()
{
return _intrinsicSize;
}
protected void CalculateSize(DeviceContext dc) protected void CalculateSize(DeviceContext dc)
{ {
Box2d box = dc.ExtensionRequire<ITextRenderer>().MeasureText(Font.Base, TextSize, Text); Box2d box = dc.ExtensionRequire<ITextRenderer>().MeasureText(Font.Base, TextSize, Text);
_intrinsicSize = box.Size;
Size = box.Size; Size = box.Size;
ClientArea = new Box2d(ClientArea.Min, ClientArea.Min + Size); ClientArea = new Box2d(ClientArea.Min, ClientArea.Min + Size);
} }
@@ -34,7 +42,7 @@ namespace Dashboard.Controls
var dcb = dc.ExtensionRequire<IDeviceContextBase>(); var dcb = dc.ExtensionRequire<IDeviceContextBase>();
if (HideOverflow) if (HideOverflow)
dcb.PushScissor(new RectangleF(ClientArea.Left, ClientArea.Top, ClientArea.Size.X, ClientArea.Size.Y)); dcb.PushScissor(ClientArea);
dcb.PushTransforms(Matrix4x4.CreateTranslation(ClientArea.Left, ClientArea.Top, 0)); dcb.PushTransforms(Matrix4x4.CreateTranslation(ClientArea.Left, ClientArea.Top, 0));

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Dashboard.Drawing; using Dashboard.Drawing;
@@ -35,12 +36,47 @@ namespace Dashboard.Controls
/// </summary> /// </summary>
public class MessageBox : Form public class MessageBox : Form
{ {
private Image? _icon; private MessageBoxIcon _icon;
private MessageBoxButtons _buttons;
private ImageBox _iconBox = new ImageBox();
private Label _label = new Label(); private Label _label = new Label();
private readonly List<Label> _buttons = new List<Label>(); private readonly List<Button> _buttonControls = new List<Button>();
public MessageBoxIcon Icon { get; set; } private Image? IconImage
public Image? CustomImage { get; set; } {
get => _iconBox.Image;
set => _iconBox.Image = value;
}
public MessageBoxIcon Icon
{
get => _icon;
set
{
IconImage = value switch
{
MessageBoxIcon.Question => s_questionIcon,
MessageBoxIcon.Info => s_infoIcon,
MessageBoxIcon.Warning => s_warningIcon,
MessageBoxIcon.Error => s_errorIcon,
_ => null,
};
_icon = value;
}
}
public Image? CustomImage
{
get => Icon == MessageBoxIcon.Custom ? IconImage : null;
set
{
if (IconImage == null)
return;
Icon = MessageBoxIcon.Custom;
IconImage = value;
}
}
public string? Message public string? Message
{ {
@@ -48,13 +84,62 @@ namespace Dashboard.Controls
set => _label.Text = value ?? String.Empty; set => _label.Text = value ?? String.Empty;
} }
public MessageBoxButtons Buttons { get; set; } public MessageBoxButtons Buttons
{
get => _buttons;
set
{
_buttons = value;
UpdateButtons();
}
}
public ObservableCollection<string> CustomButtons { get; } = new ObservableCollection<string>(); public ObservableCollection<string> CustomButtons { get; } = new ObservableCollection<string>();
public int Result { get; private set; } public int Result { get; private set; }
public MessageBox(IWindow window) : base(window) public MessageBox(IWindow window) : base(window)
{ {
Add(_label); Add(_label);
Add(_iconBox);
CustomButtons.CollectionChanged += (sender, ea) => UpdateButtons();
}
private void UpdateButtons()
{
foreach (Button button in _buttonControls)
{
Remove(button);
}
IList<string> list = Buttons switch
{
MessageBoxButtons.Custom => CustomButtons,
MessageBoxButtons.AbortRetryIgnore => s_abortRetryContinue,
MessageBoxButtons.CancelRetryContinue => s_cancelRetryContinue,
MessageBoxButtons.OkCancel => s_okCancel,
MessageBoxButtons.RetryCancel => s_retryCancel,
MessageBoxButtons.YesNo => s_yesNo,
MessageBoxButtons.YesNoCancel => s_yesNoCancel,
_ => s_ok,
};
_buttonControls.Clear();
for (int i = 0; i < list.Count; i++)
{
string str = list[i];
Button button = new Button() { Text = str };
button.Clicked += (sender, ea) => ButtonClicked(sender, ea, i);
_buttonControls.Add(button);
Add(button);
}
}
private void ButtonClicked(object? sender, EventArgs ea, int i)
{
Result = i;
Dispose();
} }
public static readonly Image s_questionIcon; public static readonly Image s_questionIcon;

View File

@@ -78,19 +78,11 @@ TK.Window.SetMode(window.WindowHandle, WindowMode.Normal);
BlurgFont font = context.ExtensionRequire<BlurgDcExtension>().Blurg BlurgFont font = context.ExtensionRequire<BlurgDcExtension>().Blurg
.QueryFont("Rec Mono Linear", FontWeight.Regular, false) ?? throw new Exception("Font not found"); .QueryFont("Rec Mono Linear", FontWeight.Regular, false) ?? throw new Exception("Font not found");
window.DeviceContext.ExtensionRequire<IDeviceContextBase>().ScaleOverride = 1.5f;
window.EventRaised += (sender, ea) => { window.EventRaised += (sender, ea) => {
if (ea is not PaintEventArgs paint) if (ea is not PaintEventArgs paint)
return; return;
paint.DeviceContext.ExtensionRequire<IDeviceContextBase>().ScaleOverride = 1.5f;
ITexture texture = MessageBox.s_questionIcon.InternTexture(context);
context.Begin();
BlurgDcExtension blurg = context.ExtensionRequire<BlurgDcExtension>();
blurg.DrawBlurgFormattedText(new BlurgFormattedText("Hello world!", font) { DefaultSize = 64f }, new System.Numerics.Vector3(24, 24, 1));
context.End();
}; };
app.Run(true, source.Token); app.Run(true, source.Token);