Create basic controls without much regards to layout rules.
This commit is contained in:
@@ -6,18 +6,18 @@ namespace Dashboard.Drawing
|
||||
{
|
||||
public interface IDeviceContextBase : IDeviceContextExtension
|
||||
{
|
||||
RectangleF ClipRegion { get; }
|
||||
RectangleF ScissorRegion { get; }
|
||||
Box2d ClipRegion { get; }
|
||||
Box2d ScissorRegion { get; }
|
||||
Matrix4x4 Transforms { get; }
|
||||
float Scale { get; }
|
||||
float ScaleOverride { get; set; }
|
||||
|
||||
void ResetClip();
|
||||
void PushClip(RectangleF clipRegion);
|
||||
void PushClip(Box2d clipRegion);
|
||||
void PopClip();
|
||||
|
||||
void ResetScissor();
|
||||
void PushScissor(RectangleF scissorRegion);
|
||||
void PushScissor(Box2d scissorRegion);
|
||||
void PopScissor();
|
||||
|
||||
void ResetTransforms();
|
||||
|
||||
@@ -44,4 +44,16 @@ namespace Dashboard.Events
|
||||
public ScanCode ScanCode { get; } = scanCode;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,7 @@ namespace Dashboard.Events
|
||||
}
|
||||
}
|
||||
|
||||
public class ControlResizedEventArgs
|
||||
public class ResizeEventArgs() : UiEventArgs(UiEventType.ControlResized)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Dashboard.Windowing
|
||||
{
|
||||
@@ -15,6 +16,6 @@ namespace Dashboard.Windowing
|
||||
/// <summary>
|
||||
/// The size of the window framebuffer in pixels.
|
||||
/// </summary>
|
||||
Size FramebufferSize { get; }
|
||||
Vector2 FramebufferSize { get; }
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,15 @@ using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Graphics.Wgl;
|
||||
using OpenTK.Mathematics;
|
||||
using ColorBuffer = OpenTK.Graphics.OpenGL.ColorBuffer;
|
||||
using Vector2 = System.Numerics.Vector2;
|
||||
|
||||
namespace Dashboard.OpenGL.Drawing
|
||||
{
|
||||
public class DeviceContextBase : IDeviceContextBase
|
||||
{
|
||||
private readonly Stack<Matrix4x4> _transforms = new Stack<Matrix4x4>();
|
||||
private readonly Stack<RectangleF> _clipRegions = new Stack<RectangleF>();
|
||||
private readonly Stack<RectangleF> _scissorRegions = new Stack<RectangleF>();
|
||||
private readonly Stack<Box2d> _clipRegions = new Stack<Box2d>();
|
||||
private readonly Stack<Box2d> _scissorRegions = new Stack<Box2d>();
|
||||
|
||||
public DeviceContext Context { get; private set; } = null!;
|
||||
IContextBase IContextExtensionBase.Context => Context;
|
||||
@@ -22,8 +23,8 @@ namespace Dashboard.OpenGL.Drawing
|
||||
public string DriverVendor => "Dashboard";
|
||||
public Version DriverVersion => new Version(0, 1);
|
||||
|
||||
public RectangleF ClipRegion => _clipRegions.Peek();
|
||||
public RectangleF ScissorRegion => _scissorRegions.Peek();
|
||||
public Box2d ClipRegion => _clipRegions.Peek();
|
||||
public Box2d ScissorRegion => _scissorRegions.Peek();
|
||||
public Matrix4x4 Transforms => _transforms.Peek();
|
||||
public float Scale => ScaleOverride > 0 ? ScaleOverride : (Context.Window as IDpiAwareWindow)?.Scale ?? 1;
|
||||
public float ScaleOverride { get; set; } = -1f;
|
||||
@@ -50,17 +51,17 @@ namespace Dashboard.OpenGL.Drawing
|
||||
{
|
||||
_clipRegions.Clear();
|
||||
|
||||
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
_clipRegions.Push(new RectangleF(0,0, size.Width, size.Height));
|
||||
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
_clipRegions.Push(new Box2d(Vector2.Zero, size));
|
||||
|
||||
SetClip(ClipRegion);
|
||||
}
|
||||
|
||||
public void PushClip(RectangleF clipRegion)
|
||||
public void PushClip(Box2d clipRegion)
|
||||
{
|
||||
clipRegion = new RectangleF(ClipRegion.X + clipRegion.X, ClipRegion.Y + clipRegion.Y,
|
||||
Math.Min(ClipRegion.Right - clipRegion.X, clipRegion.Width),
|
||||
Math.Min(ClipRegion.Bottom - clipRegion.Y, clipRegion.Height));
|
||||
clipRegion = new Box2d(ClipRegion.Min.X + clipRegion.Min.X, ClipRegion.Min.Y + clipRegion.Min.Y,
|
||||
Math.Min(ClipRegion.Max.X, ClipRegion.Min.X + clipRegion.Max.X),
|
||||
Math.Min(ClipRegion.Max.Y, ClipRegion.Max.Y + clipRegion.Max.Y));
|
||||
_clipRegions.Push(clipRegion);
|
||||
|
||||
SetClip(clipRegion);
|
||||
@@ -76,11 +77,11 @@ namespace Dashboard.OpenGL.Drawing
|
||||
{
|
||||
GL.Disable(EnableCap.ScissorTest);
|
||||
_scissorRegions.Clear();
|
||||
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
_scissorRegions.Push(new RectangleF(0,0, size.Width, size.Height));
|
||||
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
_scissorRegions.Push(new Box2d(Vector2.Zero, size));
|
||||
}
|
||||
|
||||
public void PushScissor(RectangleF scissorRegion)
|
||||
public void PushScissor(Box2d scissorRegion)
|
||||
{
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
|
||||
@@ -101,30 +102,30 @@ namespace Dashboard.OpenGL.Drawing
|
||||
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(
|
||||
(int)Math.Round(rect.X),
|
||||
(int)Math.Round(size.Height - rect.Y - rect.Height),
|
||||
(int)Math.Round(rect.Width),
|
||||
(int)Math.Round(rect.Height));
|
||||
(int)Math.Round(rect.Min.X),
|
||||
(int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
|
||||
(int)Math.Round(rect.Size.X),
|
||||
(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(
|
||||
(int)Math.Round(rect.X),
|
||||
(int)Math.Round(size.Height - rect.Y - rect.Height),
|
||||
(int)Math.Round(rect.Width),
|
||||
(int)Math.Round(rect.Height));
|
||||
(int)Math.Round(rect.Min.X),
|
||||
(int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
|
||||
(int)Math.Round(rect.Size.X),
|
||||
(int)Math.Round(rect.Size.Y));
|
||||
}
|
||||
|
||||
public void ResetTransforms()
|
||||
{
|
||||
SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.Width, size.Height, 0, 1, -1);
|
||||
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.X, size.Y, 0, 1, -1);
|
||||
|
||||
_transforms.Clear();
|
||||
_transforms.Push(m);
|
||||
|
||||
@@ -110,7 +110,6 @@ namespace Dashboard.OpenGL.Drawing
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
|
||||
|
||||
GL.UseProgram(_program);
|
||||
@@ -150,7 +149,6 @@ namespace Dashboard.OpenGL.Drawing
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
|
||||
|
||||
GL.UseProgram(_program);
|
||||
@@ -189,7 +187,6 @@ namespace Dashboard.OpenGL.Drawing
|
||||
GL.EnableVertexAttribArray(_program_atexcoord);
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Context.ExtensionRequire<IDeviceContextBase>().Transforms;
|
||||
|
||||
GL.UseProgram(_program);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
using Dashboard.Windowing;
|
||||
|
||||
namespace Dashboard.OpenGL
|
||||
@@ -17,7 +17,7 @@ namespace Dashboard.OpenGL
|
||||
/// <summary>
|
||||
/// The size of the framebuffer in pixels.
|
||||
/// </summary>
|
||||
public Size FramebufferSize { get; }
|
||||
public Vector2 FramebufferSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the context is disposed.
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace Dashboard.OpenTK.PAL2
|
||||
return;
|
||||
}
|
||||
break;
|
||||
// Mouse Events
|
||||
case PlatformEventType.MouseDown:
|
||||
{
|
||||
MouseButtonDownEventArgs down = (MouseButtonDownEventArgs)args;
|
||||
@@ -161,6 +162,8 @@ namespace Dashboard.OpenTK.PAL2
|
||||
info.Window.SendEvent(this, scroll2);
|
||||
break;
|
||||
}
|
||||
|
||||
// Keyboard & Text Events
|
||||
case PlatformEventType.KeyDown:
|
||||
{
|
||||
KeyDownEventArgs down = (KeyDownEventArgs)args;
|
||||
@@ -185,11 +188,43 @@ namespace Dashboard.OpenTK.PAL2
|
||||
info.Window.SendEvent(this, up2);
|
||||
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:
|
||||
{
|
||||
info.Window.SendEvent(this, new WindowCloseEvent());
|
||||
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:
|
||||
Debugger?.LogDebug($"Unknown event type {type} with \"{args}\".");
|
||||
break;
|
||||
|
||||
@@ -15,14 +15,15 @@ namespace Dashboard.OpenTK.PAL2
|
||||
public WindowHandle WindowHandle { get; }
|
||||
|
||||
public ISwapGroup SwapGroup { get; }
|
||||
|
||||
public int ContextGroup { get; }
|
||||
|
||||
public Size FramebufferSize
|
||||
public System.Numerics.Vector2 FramebufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
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 ConcurrentDictionary<OpenGLContextHandle, int> _contextGroupRootContexts = new ConcurrentDictionary<OpenGLContextHandle, int>();
|
||||
private Size _framebufferSize;
|
||||
|
||||
private static int GetContextGroup(OpenGLContextHandle handle)
|
||||
{
|
||||
|
||||
67
Dashboard/Controls/Button.cs
Normal file
67
Dashboard/Controls/Button.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Dashboard.Controls
|
||||
base.OnPaint(dc);
|
||||
|
||||
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));
|
||||
LayoutChildren();
|
||||
|
||||
|
||||
@@ -72,6 +72,11 @@ namespace Dashboard.Controls
|
||||
public event EventHandler? Disposing;
|
||||
public event EventHandler? Resized;
|
||||
|
||||
public virtual Vector2 CalculateIntrinsicSize()
|
||||
{
|
||||
return Vector2.Max(Vector2.Zero, Vector2.Max(Size, MinimumSize));
|
||||
}
|
||||
|
||||
public virtual void OnPaint(DeviceContext dc)
|
||||
{
|
||||
Painting?.Invoke(this, dc);
|
||||
|
||||
27
Dashboard/Controls/ImageBox.cs
Normal file
27
Dashboard/Controls/ImageBox.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ namespace Dashboard.Controls
|
||||
{
|
||||
public class Label : Control
|
||||
{
|
||||
private Vector2 _intrinsicSize = Vector2.Zero;
|
||||
|
||||
public bool AutoSize { get; set; } = true;
|
||||
public string Text { get; set; } = "";
|
||||
|
||||
@@ -18,9 +20,15 @@ namespace Dashboard.Controls
|
||||
public float TextSize { get; set; } = 12f;
|
||||
public Brush TextBrush { get; set; } = new SolidColorBrush(Color.Black);
|
||||
|
||||
public override Vector2 CalculateIntrinsicSize()
|
||||
{
|
||||
return _intrinsicSize;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -34,7 +42,7 @@ namespace Dashboard.Controls
|
||||
|
||||
var dcb = dc.ExtensionRequire<IDeviceContextBase>();
|
||||
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));
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Dashboard.Drawing;
|
||||
@@ -35,12 +36,47 @@ namespace Dashboard.Controls
|
||||
/// </summary>
|
||||
public class MessageBox : Form
|
||||
{
|
||||
private Image? _icon;
|
||||
private MessageBoxIcon _icon;
|
||||
private MessageBoxButtons _buttons;
|
||||
private ImageBox _iconBox = new ImageBox();
|
||||
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; }
|
||||
public Image? CustomImage { get; set; }
|
||||
private Image? IconImage
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -48,13 +84,62 @@ namespace Dashboard.Controls
|
||||
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 int Result { get; private set; }
|
||||
|
||||
public MessageBox(IWindow window) : base(window)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -78,19 +78,11 @@ TK.Window.SetMode(window.WindowHandle, WindowMode.Normal);
|
||||
BlurgFont font = context.ExtensionRequire<BlurgDcExtension>().Blurg
|
||||
.QueryFont("Rec Mono Linear", FontWeight.Regular, false) ?? throw new Exception("Font not found");
|
||||
|
||||
window.DeviceContext.ExtensionRequire<IDeviceContextBase>().ScaleOverride = 1.5f;
|
||||
|
||||
window.EventRaised += (sender, ea) => {
|
||||
if (ea is not PaintEventArgs paint)
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user