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
|
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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
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);
|
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();
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
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
|
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));
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user