236 lines
7.1 KiB
C#
236 lines
7.1 KiB
C#
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Drawing;
|
|
using System.Net.Http;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using Dashboard.Drawing;
|
|
|
|
namespace Dashboard.ImmediateUI
|
|
{
|
|
public class DimUIConfig
|
|
{
|
|
public Vector2 Margin = new Vector2(8, 4);
|
|
public Vector2 Padding = new Vector2(4);
|
|
public required IFont Font { get; init; }
|
|
|
|
public IBrush TextBrush = new SolidBrush(Color.Black);
|
|
public IBrush DisabledText = new SolidBrush(Color.Gray);
|
|
|
|
public float ButtonBorderSize = 2f;
|
|
public IBrush ButtonBorderBrush = new SolidBrush(Color.SteelBlue);
|
|
public IBrush ButtonFillBrush = new SolidBrush(Color.SlateGray);
|
|
public IBrush? ButtonShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
|
|
public float ButtonShadowOffset = 2f;
|
|
|
|
public float InputBorderSize = 2f;
|
|
public IBrush InputPlaceholderTextBrush = new SolidBrush(Color.SteelBlue);
|
|
public IBrush InputBorderBrush = new SolidBrush(Color.SlateGray);
|
|
public IBrush InputFillBrush = new SolidBrush(Color.LightGray);
|
|
public IBrush? InputShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
|
|
public float InputShadowOffset = -2f;
|
|
|
|
public float MenuBorderSize = 2f;
|
|
public IBrush MenuBorderBrush = new SolidBrush(Color.SteelBlue);
|
|
public IBrush MenuFillBrush = new SolidBrush(Color.SlateGray);
|
|
public IBrush? MenuShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
|
|
public float MenuShadowOffset = 2f;
|
|
}
|
|
|
|
public class DimUI
|
|
{
|
|
private readonly DimUIConfig _config;
|
|
private Vector2 _pen;
|
|
private Box2d _bounds;
|
|
private bool _firstLine = false;
|
|
private bool _sameLine = false;
|
|
private float _z = -1;
|
|
private float _lineHeight;
|
|
private DrawQueue _queue;
|
|
|
|
public DimUI(DimUIConfig config)
|
|
{
|
|
_config = config;
|
|
}
|
|
|
|
[MemberNotNull(nameof(_queue))]
|
|
public void Begin(Box2d bounds, DrawQueue queue)
|
|
{
|
|
_bounds = bounds;
|
|
_pen = _bounds.Min;
|
|
_queue = queue;
|
|
_firstLine = true;
|
|
_lineHeight = 0;
|
|
_z = -1;
|
|
}
|
|
|
|
public void SameLine()
|
|
{
|
|
_sameLine = true;
|
|
}
|
|
|
|
private void Line()
|
|
{
|
|
if (!_firstLine && !_sameLine)
|
|
{
|
|
_pen = new Vector2(_bounds.Left, _pen.Y + _lineHeight);
|
|
}
|
|
else
|
|
{
|
|
_firstLine = false;
|
|
_sameLine = false;
|
|
}
|
|
|
|
_pen.X += _config.Margin.X;
|
|
_lineHeight = 0;
|
|
}
|
|
|
|
private float Z()
|
|
{
|
|
return _z += 0.001f;
|
|
}
|
|
|
|
public void Text(string text)
|
|
{
|
|
Line();
|
|
|
|
SizeF sz = Typesetter.MeasureString(_config.Font, text);
|
|
float z = Z();
|
|
float h = _config.Margin.Y * 2 + sz.Height;
|
|
_queue.Text(new Vector3(_pen + new Vector2(0, _config.Margin.X), z), _config.TextBrush, text, _config.Font);
|
|
|
|
_lineHeight = Math.Max(_lineHeight, h);
|
|
_pen.X += sz.Width;
|
|
}
|
|
|
|
public void DrawBox(
|
|
Vector2 position,
|
|
Vector2 size,
|
|
IBrush fill,
|
|
IBrush border, float borderWidth,
|
|
IBrush? shadow, float offset)
|
|
{
|
|
float z = Z();
|
|
|
|
if (shadow != null)
|
|
{
|
|
if (offset >= 0)
|
|
{
|
|
_queue.Rect(position + new Vector2(offset), position + size + new Vector2(offset + borderWidth), z, shadow);
|
|
}
|
|
else
|
|
{
|
|
// Inset shadows are draw a bit weirdly.
|
|
_queue.Rect(position, position + new Vector2(offset, size.Y), z, shadow);
|
|
_queue.Rect(position + new Vector2(offset, 0), position + new Vector2(size.X - offset, offset), z, shadow);
|
|
}
|
|
}
|
|
|
|
_queue.Rect(position, position + size, z, fill, border, borderWidth, BorderKind.Outset);
|
|
}
|
|
|
|
public bool Button(string label)
|
|
{
|
|
Line();
|
|
|
|
SizeF sz = Typesetter.MeasureString(_config.Font, label);
|
|
|
|
float h = _config.Margin.Y * 2 + _config.Padding.Y * 2 + sz.Height;
|
|
DrawBox(
|
|
_pen + new Vector2(0, _config.Margin.Y),
|
|
new Vector2(sz.Width + 2 * _config.Padding.X, sz.Height + 2 * _config.Padding.Y),
|
|
_config.ButtonFillBrush,
|
|
_config.ButtonBorderBrush,
|
|
_config.ButtonBorderSize,
|
|
_config.ButtonShadowBrush,
|
|
_config.ButtonShadowOffset);
|
|
|
|
float z = Z();
|
|
|
|
_queue.Text(new Vector3(_pen + new Vector2(_config.Padding.X, _config.Margin.Y + _config.Padding.Y), z),
|
|
_config.TextBrush, label, _config.Font);
|
|
_lineHeight = Math.Max(_lineHeight, h);
|
|
|
|
_pen.X += sz.Width + 2 * _config.Padding.X;
|
|
return false;
|
|
}
|
|
|
|
public bool Input(string placeholder, StringBuilder value)
|
|
{
|
|
Line();
|
|
|
|
IBrush textBrush;
|
|
string str;
|
|
if (value.Length == 0)
|
|
{
|
|
textBrush = _config.DisabledText;
|
|
str = placeholder;
|
|
}
|
|
else
|
|
{
|
|
textBrush = _config.TextBrush;
|
|
str = value.ToString();
|
|
}
|
|
|
|
SizeF sz = Typesetter.MeasureString(_config.Font, str);
|
|
|
|
float h = _config.Margin.Y * 2 + _config.Padding.Y * 2 + sz.Height;
|
|
DrawBox(
|
|
_pen + new Vector2(0, _config.Margin.Y),
|
|
new Vector2(sz.Width + 2 * _config.Padding.X, sz.Height + 2 * _config.Padding.Y),
|
|
_config.InputFillBrush,
|
|
_config.InputBorderBrush,
|
|
_config.InputBorderSize,
|
|
_config.InputShadowBrush,
|
|
_config.InputShadowOffset);
|
|
|
|
float z = Z();
|
|
|
|
_queue.Text(new Vector3(_pen + new Vector2(_config.Padding.X, _config.Margin.Y + _config.Padding.Y), z),
|
|
textBrush, str, _config.Font);
|
|
_lineHeight = Math.Max(_lineHeight, h);
|
|
|
|
_pen.X += sz.Width + 2 * _config.Padding.X;
|
|
return false;
|
|
}
|
|
|
|
public void BeginMenu()
|
|
{
|
|
|
|
}
|
|
|
|
public bool MenuItem(string name)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public void EndMenu()
|
|
{
|
|
|
|
}
|
|
|
|
public int Id(ReadOnlySpan<char> str)
|
|
{
|
|
// Uses the FVN-1A algorithm in 32-bit mode.
|
|
const int PRIME = 0x01000193;
|
|
const int BASIS = unchecked((int)0x811c9dc5);
|
|
|
|
int hash = BASIS;
|
|
for (int i = 0; i < str.Length; i++)
|
|
{
|
|
hash ^= str[i] & 0xFF;
|
|
hash *= PRIME;
|
|
hash ^= str[i] >> 8;
|
|
hash *= PRIME;
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
public void Finish()
|
|
{
|
|
// TODO:
|
|
}
|
|
}
|
|
}
|