Create the first immediate mode UI base.
This commit is contained in:
parent
ef860f39bf
commit
1cd005f827
@ -97,7 +97,7 @@ namespace Dashboard.Drawing.OpenGL.Executors
|
||||
private void DrawText(ICommandFrame frame)
|
||||
{
|
||||
TextCommandArgs args = frame.GetParameter<TextCommandArgs>();
|
||||
DbBlurgFont font = (DbBlurgFont)args.Font;
|
||||
DbBlurgFont font = Engine.InternFont(args.Font);
|
||||
|
||||
BlurgColor color;
|
||||
switch (args.TextBrush)
|
||||
|
55
Dashboard.Drawing.OpenGL/Executors/gradient.glsl
Normal file
55
Dashboard.Drawing.OpenGL/Executors/gradient.glsl
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef _GRADIENT_GLSL_
|
||||
#define _GRADIENT_GLSL_
|
||||
|
||||
#define DB_GRADIENT_MAX 16
|
||||
|
||||
struct Gradient_t {
|
||||
float fPosition;
|
||||
float pad0;
|
||||
float pad1;
|
||||
float pad2;
|
||||
vec4 v4Color;
|
||||
};
|
||||
|
||||
uniform GradientBlock
|
||||
{
|
||||
Gradient_t vstGradientStops[DB_GRADIENT_MAX];
|
||||
};
|
||||
|
||||
vec4 getGradientColor(float position, int index, int count)
|
||||
{
|
||||
position = clamp(position, 0, 1);
|
||||
|
||||
int i0 = 0;
|
||||
float p0 = vstGradientStops[index + i0].fPosition;
|
||||
|
||||
int i1 = count - 1;
|
||||
float p1 = vstGradientStops[index + i1].fPosition;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
float px = vstGradientStops[index + i].fPosition;
|
||||
|
||||
if (px > p0 && px <= position)
|
||||
{
|
||||
p0 = px;
|
||||
i0 = i;
|
||||
}
|
||||
|
||||
if (px < p1 && px >= position)
|
||||
{
|
||||
p1 = px;
|
||||
i1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 c0 = vstGradientStops[index + i0].v4Color;
|
||||
vec4 c1 = vstGradientStops[index + i1].v4Color;
|
||||
|
||||
float l = p1 - p0;
|
||||
float w = (l > 0) ? (position - p0) / (p1 - p0) : 0;
|
||||
|
||||
return mix(c0, c1, w);
|
||||
}
|
||||
|
||||
#endif
|
@ -93,7 +93,7 @@ namespace Dashboard.Drawing.OpenGL.Text
|
||||
throw new Exception("Font not found.");
|
||||
}
|
||||
|
||||
private DbBlurgFont InternFont(IFont font)
|
||||
public DbBlurgFont InternFont(IFont font)
|
||||
{
|
||||
if (font is NamedFont named)
|
||||
{
|
||||
|
13
Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
Normal file
13
Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
Normal file
@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Dashboard.Drawing\Dashboard.Drawing.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
157
Dashboard.ImmediateUI/DimUI.cs
Normal file
157
Dashboard.ImmediateUI/DimUI.cs
Normal file
@ -0,0 +1,157 @@
|
||||
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 float Margin = 4f;
|
||||
public float Padding = 4f;
|
||||
|
||||
public required IFont Font { get; init; }
|
||||
public IBrush TextBrush = new SolidBrush(Color.Black);
|
||||
|
||||
public float ButtonBorderSize = 2f;
|
||||
public IBrush ButtonBorderBrush = new SolidBrush(Color.DarkSlateGray);
|
||||
public IBrush ButtonFillBrush = new SolidBrush(Color.SlateGray);
|
||||
public IBrush? ButtonShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
|
||||
public float ButtonShadowOffset = 4f;
|
||||
|
||||
public float InputBorderSize = 2f;
|
||||
public IBrush InputPlaceholderTextBrush = new SolidBrush(Color.SlateGray);
|
||||
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 = -4f;
|
||||
|
||||
public float MenuBorderSize = 2f;
|
||||
public IBrush MenuBorderBrush = new SolidBrush(Color.DarkSlateGray);
|
||||
public IBrush MenuFillBrush = new SolidBrush(Color.SlateGray);
|
||||
public IBrush? MenuShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
|
||||
public float MenuShadowOffset = 6f;
|
||||
}
|
||||
|
||||
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;
|
||||
_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 * 2 + sz.Height;
|
||||
_queue.Text(new Vector3(_pen + new Vector2(0, _config.Margin), z), _config.TextBrush, text, _config.Font);
|
||||
|
||||
_lineHeight = Math.Max(_lineHeight, h);
|
||||
_pen.X += sz.Width;
|
||||
}
|
||||
|
||||
public bool Button(string label)
|
||||
{
|
||||
Line();
|
||||
|
||||
SizeF sz = Typesetter.MeasureString(_config.Font, label);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Input(string placeholder, StringBuilder value)
|
||||
{
|
||||
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:
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Common", "Dashboa
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Drawing.OpenGL", "Dashboard.Drawing.OpenGL\Dashboard.Drawing.OpenGL.csproj", "{454198BA-CB95-41C5-A934-B1C8FDA35A6B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.ImmediateUI", "Dashboard.ImmediateUI\Dashboard.ImmediateUI.csproj", "{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -45,6 +47,10 @@ Global
|
||||
{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -10,6 +10,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Dashboard.Drawing.OpenGL\Dashboard.Drawing.OpenGL.csproj" />
|
||||
<ProjectReference Include="..\..\Dashboard.Drawing\Dashboard.Drawing.csproj" />
|
||||
<ProjectReference Include="..\..\Dashboard.ImmediateUI\Dashboard.ImmediateUI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -3,17 +3,19 @@ using System.Drawing;
|
||||
using Dashboard;
|
||||
using Dashboard.Drawing.OpenGL;
|
||||
using Dashboard.Drawing.OpenGL.Text;
|
||||
using Dashboard.ImmediateUI;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Mathematics;
|
||||
using Box2d = Dashboard.Box2d;
|
||||
using TK = OpenTK.Platform.Toolkit;
|
||||
using sys = System.Numerics;
|
||||
using otk = OpenTK.Mathematics;
|
||||
|
||||
TK.Init(new ToolkitOptions()
|
||||
{
|
||||
ApplicationName = "Paper Punch Out!",
|
||||
ApplicationName = "DashTerm",
|
||||
Windows = new ToolkitOptions.WindowsOptions()
|
||||
{
|
||||
EnableVisualStyles = true,
|
||||
@ -39,11 +41,11 @@ WindowHandle wnd = TK.Window.Create(new OpenGLGraphicsApiHints()
|
||||
|
||||
SupportTransparentFramebufferX11 = true,
|
||||
});
|
||||
TK.Window.SetTitle(wnd, "Paper Punch Out!");
|
||||
TK.Window.SetTitle(wnd, "DashTerm");
|
||||
TK.Window.SetMinClientSize(wnd, 300, 200);
|
||||
TK.Window.SetClientSize(wnd, new Vector2i(320, 240));
|
||||
TK.Window.SetBorderStyle(wnd, WindowBorderStyle.ResizableBorder);
|
||||
TK.Window.SetTransparencyMode(wnd, WindowTransparencyMode.TransparentFramebuffer, 0.1f);
|
||||
// TK.Window.SetTransparencyMode(wnd, WindowTransparencyMode.TransparentFramebuffer, 0.1f);
|
||||
|
||||
OpenGLContextHandle context = TK.OpenGL.CreateFromWindow(wnd);
|
||||
|
||||
@ -62,6 +64,10 @@ engine.Initialize();
|
||||
|
||||
GlContext dbGlContext = new GlContext(wnd, context);
|
||||
ContextExecutor executor = engine.GetExecutor(dbGlContext);
|
||||
DimUI dimUI = new DimUI(new DimUIConfig()
|
||||
{
|
||||
Font = new NamedFont("Noto Sans", 9f),
|
||||
});
|
||||
|
||||
Vector2 mousePos = Vector2.Zero;
|
||||
Random r = new Random();
|
||||
@ -78,19 +84,6 @@ EventQueue.EventRaised += (handle, type, eventArgs) =>
|
||||
case PlatformEventType.MouseMove:
|
||||
mousePos = ((MouseMoveEventArgs)eventArgs).ClientPosition;
|
||||
break;
|
||||
case PlatformEventType.MouseUp:
|
||||
MouseButtonUpEventArgs mouseUp = (MouseButtonUpEventArgs)eventArgs;
|
||||
if (mouseUp.Button == MouseButton.Button1)
|
||||
{
|
||||
SolidBrush brush = new SolidBrush(Color.FromArgb(r.Next(256), r.Next(256), r.Next(256), 0));
|
||||
queue.Point(new sys::Vector2(mousePos.X, mousePos.Y), 0f, 24f, brush);
|
||||
}
|
||||
break;
|
||||
case PlatformEventType.KeyDown:
|
||||
KeyDownEventArgs keyDown = (KeyDownEventArgs)eventArgs;
|
||||
if (keyDown.Key == Key.Escape || keyDown.Key == Key.Delete || keyDown.Key == Key.Backspace)
|
||||
queue.Clear();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,31 +93,74 @@ List<Vector3> points = new List<Vector3>();
|
||||
|
||||
IFont font = Typesetter.LoadFont("Nimbus Mono", 12f);
|
||||
|
||||
queue.Text(new sys.Vector3(96, 96, 0), bg, "Hello World!", font);
|
||||
queue.Text(new sys.Vector3(128, 12, 0), bg, "japenis too! uwa ~~~ アホ", font);
|
||||
queue.Line(new sys.Vector2(64, 256), new sys.Vector2(64+256, 256), 0, 64f, fg);
|
||||
queue.Rect(new sys.Vector2(16, 16), new sys.Vector2(96, 96), 0, fg, bg, 8f);
|
||||
|
||||
while (!shouldExit)
|
||||
{
|
||||
TK.Window.ProcessEvents(true);
|
||||
|
||||
TK.Window.GetFramebufferSize(wnd, out Vector2i framebufferSize);
|
||||
executor.BeginFrame();
|
||||
|
||||
// queue.Line(Vector3.Zero, new Vector3(System.Numerics.Vector2.One * 256f, 0), 4f, bg);
|
||||
// queue.Rect(Vector3.UnitX, 2 * Vector3.UnitX + Vector3.UnitY, fg, bg, 2f);
|
||||
dimUI.Begin(new Box2d(0, 0, framebufferSize.X, framebufferSize.Y), queue);
|
||||
dimUI.Text("Hello World!");
|
||||
|
||||
dimUI.BeginMenu();
|
||||
|
||||
if (dimUI.MenuItem("File"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("New Window");
|
||||
dimUI.MenuItem("Preferences");
|
||||
dimUI.MenuItem("Exit");
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
if (dimUI.MenuItem("Edit"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("Cut");
|
||||
dimUI.MenuItem("Copy");
|
||||
dimUI.MenuItem("Paste");
|
||||
|
||||
if (dimUI.MenuItem("Send Char"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
if (dimUI.MenuItem("View"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("Clear");
|
||||
|
||||
if (dimUI.MenuItem("Set Size"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("24 x 40");
|
||||
dimUI.MenuItem("25 x 40");
|
||||
dimUI.MenuItem("24 x 80");
|
||||
dimUI.MenuItem("25 x 80");
|
||||
dimUI.MenuItem("25 x 120");
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.Finish();
|
||||
|
||||
GL.Viewport(0, 0, framebufferSize.X, framebufferSize.Y);
|
||||
GL.ClearColor(0.9f, 0.9f, 0.7f, 1.0f);
|
||||
GL.ClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
// GL.Enable(EnableCap.Blend);
|
||||
// GL.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.One, BlendingFactor.Zero);
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.ColorMask(true, true, true, true);
|
||||
|
||||
executor.Draw(queue);
|
||||
executor.EndFrame();
|
||||
queue.Clear();
|
||||
|
||||
TK.OpenGL.SwapBuffers(context);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user