More control components
This commit is contained in:
parent
deda09a4a5
commit
d0ff5d2929
@ -124,9 +124,26 @@ namespace MicroUI
|
||||
[Flags]
|
||||
public enum ResultFlags
|
||||
{
|
||||
Active = 1 << 0, // 1
|
||||
Submit = 1 << 1, // 2
|
||||
Change = 1 << 2 // 4
|
||||
Active = 1 << 0,
|
||||
Submit = 1 << 1,
|
||||
Change = 1 << 2
|
||||
}
|
||||
|
||||
public struct MuResult
|
||||
{
|
||||
public ResultFlags Flags;
|
||||
|
||||
public MuResult(ResultFlags flags)
|
||||
{
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
public static implicit operator bool(MuResult result) => result.Flags != 0;
|
||||
public static implicit operator ResultFlags(MuResult result) => result.Flags;
|
||||
public static implicit operator MuResult(ResultFlags flags) => new MuResult(flags);
|
||||
|
||||
public static MuResult operator |(MuResult a, ResultFlags b) => new MuResult(a.Flags | b);
|
||||
public static MuResult operator |(ResultFlags a, MuResult b) => new MuResult(a | b.Flags);
|
||||
}
|
||||
|
||||
[System.Flags]
|
||||
@ -504,8 +521,11 @@ namespace MicroUI
|
||||
|
||||
public static void DrawFrame(MuContext ctx, MuRect rect, ColorType colorId)
|
||||
{
|
||||
// Clamp color ID to prevent index out of range
|
||||
int colorIndex = MathUtil.Clamp((int)colorId, 0, (int)ColorType.Max - 1);
|
||||
|
||||
// Draw filled rectangle with given color
|
||||
MuCommandList.DrawRect(ctx, rect, ctx.Style.Colors[(int)colorId]);
|
||||
MuCommandList.DrawRect(ctx, rect, ctx.Style.Colors[colorIndex]);
|
||||
|
||||
// Early return for certain color IDs (skip border)
|
||||
if (colorId == ColorType.ScrollBase ||
|
||||
@ -1213,8 +1233,8 @@ namespace MicroUI
|
||||
|
||||
// Title text and drag
|
||||
uint titleId = MicroUI.GetId(ctx, System.Text.Encoding.UTF8.GetBytes("!title"));
|
||||
//MuControl.UpdateControl(ctx, titleId, tr, opt); // Implement or comment out
|
||||
//MuControl.DrawControlText(ctx, title, tr, ColorType.TitleText, opt); // Implement or comment out
|
||||
MuControl.UpdateControl(ctx, titleId, tr, opt);
|
||||
MuControl.DrawControlText(ctx, title, tr, ColorType.TitleText, opt);
|
||||
|
||||
// Move window if dragging title bar
|
||||
if (titleId == ctx.Focus && (ctx.MouseDown & (int)MouseButton.Left) != 0)
|
||||
@ -1237,8 +1257,8 @@ namespace MicroUI
|
||||
uint closeId = MicroUI.GetId(ctx, System.Text.Encoding.UTF8.GetBytes("!close"));
|
||||
var r = new MuRect(tr.X + tr.W - tr.H, tr.Y, tr.H, tr.H);
|
||||
tr.W -= r.W;
|
||||
//MuControl.DrawIcon(ctx, (int)IconType.Close, r, ctx.Style.Colors[(int)ColorType.TitleText]); // Implement or comment out
|
||||
//MuControl.UpdateControl(ctx, closeId, r, opt); // Implement or comment out
|
||||
MuCommandList.DrawIcon(ctx, (int)IconType.Close, r, ctx.Style.Colors[(int)ColorType.TitleText]);
|
||||
MuControl.UpdateControl(ctx, closeId, r, opt);
|
||||
if ((ctx.MousePressed & (int)MouseButton.Left) != 0 && closeId == ctx.Focus)
|
||||
{
|
||||
cnt.Open = false;
|
||||
@ -1255,7 +1275,7 @@ namespace MicroUI
|
||||
int sz = ctx.Style.TitleHeight;
|
||||
uint resizeId = MicroUI.GetId(ctx, System.Text.Encoding.UTF8.GetBytes("!resize"));
|
||||
var r = new MuRect(rect.X + rect.W - sz, rect.Y + rect.H - sz, sz, sz);
|
||||
//MuControl.UpdateControl(ctx, resizeId, r, opt); // Implement or comment out
|
||||
MuControl.UpdateControl(ctx, resizeId, r, opt);
|
||||
if (resizeId == ctx.Focus && (ctx.MouseDown & (int)MouseButton.Left) != 0)
|
||||
{
|
||||
cnt.Rect = new MuRect(
|
||||
@ -1298,5 +1318,176 @@ namespace MicroUI
|
||||
MuControl.EndRootContainer(ctx);
|
||||
}
|
||||
|
||||
// Helper functions for controls
|
||||
public static void DrawControlFrame(MuContext ctx, uint id, MuRect rect, ColorType colorId, int opt)
|
||||
{
|
||||
if ((opt & (int)Options.NoFrame) != 0) { return; }
|
||||
|
||||
// Adjust color based on state: normal, hover, focus
|
||||
if (ctx.Focus == id)
|
||||
{
|
||||
colorId += 2; // Focus state
|
||||
}
|
||||
else if (ctx.Hover == id)
|
||||
{
|
||||
colorId += 1; // Hover state
|
||||
}
|
||||
// else: normal state (colorId unchanged)
|
||||
|
||||
ctx.DrawFrame?.Invoke(ctx, rect, colorId);
|
||||
}
|
||||
|
||||
public static void DrawControlText(MuContext ctx, string str, MuRect rect, ColorType colorId, int opt)
|
||||
{
|
||||
if (ctx.TextWidth == null || ctx.TextHeight == null) return;
|
||||
|
||||
MuVec2 pos;
|
||||
object? font = ctx.Style.Font;
|
||||
int tw = ctx.TextWidth(font, str, -1);
|
||||
int th = ctx.TextHeight(font);
|
||||
|
||||
MicroUI.PushClipRect(ctx, rect);
|
||||
|
||||
pos.Y = rect.Y + (rect.H - th) / 2;
|
||||
|
||||
if ((opt & (int)Options.AlignCenter) != 0)
|
||||
{
|
||||
pos.X = rect.X + (rect.W - tw) / 2;
|
||||
}
|
||||
else if ((opt & (int)Options.AlignRight) != 0)
|
||||
{
|
||||
pos.X = rect.X + rect.W - tw - ctx.Style.Padding;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.X = rect.X + ctx.Style.Padding;
|
||||
}
|
||||
|
||||
MuCommandList.DrawText(ctx, font, str, pos, ctx.Style.Colors[(int)colorId]);
|
||||
MicroUI.PopClipRect(ctx);
|
||||
}
|
||||
|
||||
public static bool MouseOver(MuContext ctx, MuRect rect)
|
||||
{
|
||||
return MicroUI.RectOverlapsVec2(rect, ctx.MousePos) &&
|
||||
MicroUI.RectOverlapsVec2(MicroUI.GetClipRect(ctx), ctx.MousePos) &&
|
||||
InHoverRoot(ctx);
|
||||
}
|
||||
|
||||
private static bool InHoverRoot(MuContext ctx)
|
||||
{
|
||||
// Check if we're in the hover root container
|
||||
return ctx.HoverRoot == null || ctx.HoverRoot == MicroUI.GetCurrentContainer(ctx);
|
||||
}
|
||||
|
||||
public static void UpdateControl(MuContext ctx, uint id, MuRect rect, int opt)
|
||||
{
|
||||
bool mouseover = MouseOver(ctx, rect);
|
||||
|
||||
if (ctx.Focus == id) { ctx.UpdatedFocus = 1; }
|
||||
if ((opt & (int)Options.NoInteract) != 0) { return; }
|
||||
if (mouseover && ctx.MouseDown == 0) { ctx.Hover = id; }
|
||||
|
||||
if (ctx.Focus == id)
|
||||
{
|
||||
if (ctx.MousePressed != 0 && !mouseover) { MicroUI.SetFocus(ctx, 0); }
|
||||
if (ctx.MouseDown == 0 && (opt & (int)Options.HoldFocus) == 0) { MicroUI.SetFocus(ctx, 0); }
|
||||
}
|
||||
|
||||
if (ctx.Hover == id)
|
||||
{
|
||||
if (ctx.MousePressed != 0)
|
||||
{
|
||||
MicroUI.SetFocus(ctx, id);
|
||||
}
|
||||
else if (!mouseover)
|
||||
{
|
||||
ctx.Hover = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static MuResult ButtonEx(MuContext ctx, string? label, int icon, int opt)
|
||||
{
|
||||
ResultFlags res = 0;
|
||||
uint id;
|
||||
|
||||
if (!string.IsNullOrEmpty(label))
|
||||
{
|
||||
id = MicroUI.GetId(ctx, System.Text.Encoding.UTF8.GetBytes(label));
|
||||
}
|
||||
else
|
||||
{
|
||||
id = MicroUI.GetId(ctx, BitConverter.GetBytes(icon));
|
||||
}
|
||||
|
||||
MuRect r = MuLayoutUtil.LayoutNext(ctx);
|
||||
UpdateControl(ctx, id, r, opt);
|
||||
|
||||
// Handle click
|
||||
if ((ctx.MousePressed & (int)MouseButton.Left) != 0 && ctx.Focus == id)
|
||||
{
|
||||
res |= ResultFlags.Submit;
|
||||
}
|
||||
|
||||
// Draw
|
||||
DrawControlFrame(ctx, id, r, ColorType.Button, opt);
|
||||
if (!string.IsNullOrEmpty(label))
|
||||
{
|
||||
DrawControlText(ctx, label, r, ColorType.Text, opt);
|
||||
}
|
||||
if (icon != 0)
|
||||
{
|
||||
MuCommandList.DrawIcon(ctx, icon, r, ctx.Style.Colors[(int)ColorType.Text]);
|
||||
}
|
||||
|
||||
return new MuResult(res);
|
||||
}
|
||||
|
||||
public static MuResult Checkbox(MuContext ctx, string? label, ref bool state)
|
||||
{
|
||||
ResultFlags res = 0;
|
||||
uint id;
|
||||
|
||||
// Create ID that includes both label and state
|
||||
if (!string.IsNullOrEmpty(label))
|
||||
{
|
||||
var idData = System.Text.Encoding.UTF8.GetBytes(label + state.ToString());
|
||||
id = MicroUI.GetId(ctx, idData);
|
||||
}
|
||||
else
|
||||
{
|
||||
id = MicroUI.GetId(ctx, BitConverter.GetBytes(state ? 1 : 0));
|
||||
}
|
||||
|
||||
MuRect r = MuLayoutUtil.LayoutNext(ctx);
|
||||
UpdateControl(ctx, id, r, 0);
|
||||
|
||||
// Handle click
|
||||
if ((ctx.MousePressed & (int)MouseButton.Left) != 0 && ctx.Focus == id)
|
||||
{
|
||||
state = !state;
|
||||
res |= ResultFlags.Change;
|
||||
}
|
||||
|
||||
// Draw checkbox box
|
||||
var box = new MuRect(r.X, r.Y, r.H, r.H);
|
||||
DrawControlFrame(ctx, id, box, ColorType.Base, 0);
|
||||
|
||||
if (state)
|
||||
{
|
||||
MuCommandList.DrawIcon(ctx, (int)IconType.Check, box, ctx.Style.Colors[(int)ColorType.Text]);
|
||||
}
|
||||
|
||||
// Draw label
|
||||
if (!string.IsNullOrEmpty(label))
|
||||
{
|
||||
var labelRect = new MuRect(r.X + box.W, r.Y, r.W - box.W, r.H);
|
||||
DrawControlText(ctx, label, labelRect, ColorType.Text, 0);
|
||||
}
|
||||
|
||||
return new MuResult(res);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using Raylib_cs;
|
||||
using MicroUI;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MicroUI;
|
||||
|
||||
@ -27,22 +28,34 @@ class Program
|
||||
// Initialize microui
|
||||
MicroUI.Init(ctx);
|
||||
|
||||
bool isChecked = false;
|
||||
|
||||
|
||||
while (!Raylib.WindowShouldClose())
|
||||
{
|
||||
// Handle input
|
||||
var mousePos = Raylib.GetMousePosition();
|
||||
MuInput.MouseMove(ctx, (int)mousePos.X, (int)mousePos.Y);
|
||||
|
||||
if (Raylib.IsMouseButtonPressed(Raylib_cs.MouseButton.Left))
|
||||
{
|
||||
Console.WriteLine("Mouse down");
|
||||
MuInput.MouseDown(ctx, (int)mousePos.X, (int)mousePos.Y, 1);
|
||||
}
|
||||
if (Raylib.IsMouseButtonReleased(Raylib_cs.MouseButton.Left))
|
||||
{
|
||||
MuInput.MouseUp(ctx, (int)mousePos.X, (int)mousePos.Y, 1);
|
||||
}
|
||||
|
||||
Raylib.BeginDrawing();
|
||||
Raylib.ClearBackground(Color.White);
|
||||
Raylib.ClearBackground(Color.Black);
|
||||
|
||||
// Begin frame
|
||||
MicroUI.Begin(ctx);
|
||||
if(MuControl.BeginWindowEx(ctx, "Test Window", new MuRect(100, 100, 100, 100), 0)){
|
||||
|
||||
MuControl.EndWindow(ctx);
|
||||
for(int i = 0; i < 10; i++){
|
||||
Window(ctx, i * 15, i * 15, i, ref isChecked);
|
||||
}
|
||||
|
||||
if(MuControl.BeginWindowEx(ctx, "Test Window 2", new MuRect(120, 120, 300, 200), 0)){
|
||||
MuControl.EndWindow(ctx);
|
||||
}
|
||||
|
||||
// End frame
|
||||
MicroUI.End(ctx);
|
||||
|
||||
@ -51,36 +64,142 @@ class Program
|
||||
MuCommand? cmd = null;
|
||||
while ((cmd = MuCommandList.NextCommand(ctx, ref cmdIndex)) != null)
|
||||
{
|
||||
Console.Write($"Command: {cmd.Type}");
|
||||
//Console.Write($"Command: {cmd.Type}");
|
||||
switch (cmd)
|
||||
{
|
||||
case MuRectCommand rectCmd:
|
||||
Console.Write($" | Rect: ({rectCmd.Rect.X},{rectCmd.Rect.Y},{rectCmd.Rect.W},{rectCmd.Rect.H}) Color: {rectCmd.Color.R},{rectCmd.Color.G},{rectCmd.Color.B},{rectCmd.Color.A}");
|
||||
//Console.WriteLine($" | Rect: ({rectCmd.Rect.X},{rectCmd.Rect.Y},{rectCmd.Rect.W},{rectCmd.Rect.H}) Color: {rectCmd.Color.R},{rectCmd.Color.G},{rectCmd.Color.B},{rectCmd.Color.A}");
|
||||
Raylib.DrawRectangle(rectCmd.Rect.X, rectCmd.Rect.Y, rectCmd.Rect.W, rectCmd.Rect.H, new Color(rectCmd.Color.R, rectCmd.Color.G, rectCmd.Color.B, rectCmd.Color.A));
|
||||
break;
|
||||
case MuClipCommand clipCmd:
|
||||
Console.Write($" | Clip: ({clipCmd.Rect.X},{clipCmd.Rect.Y},{clipCmd.Rect.W},{clipCmd.Rect.H})");
|
||||
//Console.Write($" | Clip: ({clipCmd.Rect.X},{clipCmd.Rect.Y},{clipCmd.Rect.W},{clipCmd.Rect.H})");
|
||||
break;
|
||||
case MuJumpCommand jumpCmd:
|
||||
Console.Write($" | Jump to: {jumpCmd.DestinationIndex}");
|
||||
//Console.Write($" | Jump to: {jumpCmd.DestinationIndex}");
|
||||
break;
|
||||
case MuTextCommand textCmd:
|
||||
Console.Write($" | Text: '{textCmd.Text}' at ({textCmd.Position.X},{textCmd.Position.Y}) Color: {textCmd.Color.R},{textCmd.Color.G},{textCmd.Color.B},{textCmd.Color.A}");
|
||||
Raylib.DrawText(textCmd.Text, textCmd.Position.X, textCmd.Position.Y, 16, new Color(textCmd.Color.R, textCmd.Color.G, textCmd.Color.B, textCmd.Color.A));
|
||||
//Console.Write($" | Text: '{textCmd.Text}' at ({textCmd.Position.X},{textCmd.Position.Y}) Color: {textCmd.Color.R},{textCmd.Color.G},{textCmd.Color.B},{textCmd.Color.A}");
|
||||
break;
|
||||
case MuIconCommand iconCmd:
|
||||
Console.Write($" | Icon: {iconCmd.IconId} Rect: ({iconCmd.Rect.X},{iconCmd.Rect.Y},{iconCmd.Rect.W},{iconCmd.Rect.H}) Color: {iconCmd.Color.R},{iconCmd.Color.G},{iconCmd.Color.B},{iconCmd.Color.A}");
|
||||
if (iconCmd.IconId == (int)IconType.Check)
|
||||
{
|
||||
// Draw a check mark
|
||||
int centerX = iconCmd.Rect.X + iconCmd.Rect.W / 2;
|
||||
int centerY = iconCmd.Rect.Y + iconCmd.Rect.H / 2;
|
||||
int size = Math.Min(iconCmd.Rect.W, iconCmd.Rect.H) / 3;
|
||||
|
||||
// Draw check mark lines
|
||||
Raylib.DrawLine(
|
||||
centerX - size, centerY - size/2,
|
||||
centerX - size/3, centerY + size/2,
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
Raylib.DrawLine(
|
||||
centerX - size/3, centerY + size/2,
|
||||
centerX + size, centerY - size,
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
}
|
||||
else if (iconCmd.IconId == (int)IconType.Close)
|
||||
{
|
||||
// Draw an X for close
|
||||
int centerX = iconCmd.Rect.X + iconCmd.Rect.W / 2;
|
||||
int centerY = iconCmd.Rect.Y + iconCmd.Rect.H / 2;
|
||||
int size = Math.Min(iconCmd.Rect.W, iconCmd.Rect.H) / 3;
|
||||
|
||||
// Draw X lines
|
||||
Raylib.DrawLine(
|
||||
centerX - size, centerY - size,
|
||||
centerX + size, centerY + size,
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
Raylib.DrawLine(
|
||||
centerX - size, centerY + size,
|
||||
centerX + size, centerY - size,
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
}
|
||||
else if (iconCmd.IconId == (int)IconType.Collapsed)
|
||||
{
|
||||
// Draw a right-pointing triangle for collapsed
|
||||
int centerX = iconCmd.Rect.X + iconCmd.Rect.W / 2;
|
||||
int centerY = iconCmd.Rect.Y + iconCmd.Rect.H / 2;
|
||||
int size = Math.Min(iconCmd.Rect.W, iconCmd.Rect.H) / 3;
|
||||
|
||||
// Draw triangle pointing right
|
||||
Raylib.DrawTriangle(
|
||||
new Vector2(centerX - size/2, centerY - size),
|
||||
new Vector2(centerX + size/2, centerY),
|
||||
new Vector2(centerX - size/2, centerY + size),
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
}
|
||||
else if (iconCmd.IconId == (int)IconType.Expanded)
|
||||
{
|
||||
// Draw a down-pointing triangle for expanded
|
||||
int centerX = iconCmd.Rect.X + iconCmd.Rect.W / 2;
|
||||
int centerY = iconCmd.Rect.Y + iconCmd.Rect.H / 2;
|
||||
int size = Math.Min(iconCmd.Rect.W, iconCmd.Rect.H) / 3;
|
||||
|
||||
// Draw triangle pointing down
|
||||
Raylib.DrawTriangle(
|
||||
new Vector2(centerX - size, centerY - size/2),
|
||||
new Vector2(centerX + size, centerY - size/2),
|
||||
new Vector2(centerX, centerY + size/2),
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For unknown icons, draw a colored rectangle
|
||||
Raylib.DrawRectangle(iconCmd.Rect.X, iconCmd.Rect.Y, iconCmd.Rect.W, iconCmd.Rect.H,
|
||||
new Color(iconCmd.Color.R, iconCmd.Color.G, iconCmd.Color.B, iconCmd.Color.A));
|
||||
}
|
||||
break;
|
||||
}
|
||||
Console.WriteLine("");
|
||||
|
||||
}
|
||||
|
||||
Raylib.EndDrawing();
|
||||
|
||||
//break;
|
||||
|
||||
}
|
||||
|
||||
Raylib.CloseWindow();
|
||||
}
|
||||
|
||||
|
||||
public static void Window(MuContext ctx, int x, int y, int index, ref bool isChecked){
|
||||
if(MuControl.BeginWindowEx(ctx, $"Test Window {index}", new MuRect(x, y, 300, 200), 0)){
|
||||
|
||||
MuLayoutUtil.LayoutBeginColumn(ctx);
|
||||
// Test button
|
||||
// if (MuControl.ButtonEx(ctx, "Click Me!", 0, 0))
|
||||
// {
|
||||
// Console.WriteLine("Button clicked!");
|
||||
// }
|
||||
MuLayoutUtil.LayoutRow(ctx, 2, new int[]{200, 50}, 0);
|
||||
if(MuControl.Checkbox(ctx, "Checkbox1", ref isChecked)){
|
||||
Console.WriteLine("Checkbox clicked!");
|
||||
}
|
||||
if(MuControl.ButtonEx(ctx, null, (int)IconType.Check, 0)){
|
||||
Console.WriteLine("Button clicked!");
|
||||
}
|
||||
|
||||
// if(MuControl.Checkbox(ctx, "Checkbox2", ref isChecked)){
|
||||
// Console.WriteLine("Checkbox clicked!");
|
||||
// }
|
||||
// if(MuControl.Checkbox(ctx, "Checkbox3", ref isChecked)){
|
||||
// Console.WriteLine("Checkbox clicked!");
|
||||
// }
|
||||
// if(MuControl.Checkbox(ctx, "Checkbox4", ref isChecked)){
|
||||
// Console.WriteLine("Checkbox clicked!");
|
||||
// }
|
||||
|
||||
MuLayoutUtil.LayoutEndColumn(ctx);
|
||||
MuControl.EndWindow(ctx);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user