392 lines
13 KiB
C
392 lines
13 KiB
C
#include <stdio.h>
|
|
#include <raylib.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "microui.h"
|
|
|
|
static char logbuf[64000];
|
|
static int logbuf_updated = 0;
|
|
static float bg[3] = { 90, 95, 100 };
|
|
|
|
|
|
static float global_scale = 1;
|
|
|
|
static int font_size = 10;
|
|
|
|
|
|
static void write_log(const char *text) {
|
|
if (logbuf[0]) { strcat(logbuf, "\n"); }
|
|
strcat(logbuf, text);
|
|
logbuf_updated = 1;
|
|
}
|
|
|
|
|
|
static void test_window(mu_Context *ctx) {
|
|
/* do window */
|
|
if (mu_begin_window(ctx, "Demo Window", mu_rect(40, 40, 300, 450))) {
|
|
mu_Container *win = mu_get_current_container(ctx);
|
|
win->rect.w = mu_max(win->rect.w, 240);
|
|
win->rect.h = mu_max(win->rect.h, 300);
|
|
|
|
/* window info */
|
|
if (mu_header(ctx, "Window Info")) {
|
|
mu_Container *win = mu_get_current_container(ctx);
|
|
char buf[64];
|
|
mu_layout_row(ctx, 2, (int[]) { 54, -1 }, 0);
|
|
mu_label(ctx,"Position:");
|
|
sprintf(buf, "%d, %d", win->rect.x, win->rect.y); mu_label(ctx, buf);
|
|
mu_label(ctx, "Size:");
|
|
sprintf(buf, "%d, %d", win->rect.w, win->rect.h); mu_label(ctx, buf);
|
|
}
|
|
|
|
/* labels + buttons */
|
|
if (mu_header_ex(ctx, "Test Buttons", MU_OPT_EXPANDED)) {
|
|
mu_layout_row(ctx, 3, (int[]) { 86, -110, -1 }, 0);
|
|
mu_label(ctx, "Test buttons 1:");
|
|
if (mu_button(ctx, "Button 1")) { write_log("Pressed button 1"); }
|
|
if (mu_button(ctx, "Button 2")) { write_log("Pressed button 2"); }
|
|
mu_label(ctx, "Test buttons 2:");
|
|
if (mu_button(ctx, "Button 3")) { write_log("Pressed button 3"); }
|
|
if (mu_button(ctx, "Popup")) { mu_open_popup(ctx, "Test Popup"); }
|
|
if (mu_begin_popup(ctx, "Test Popup")) {
|
|
mu_button(ctx, "Hello");
|
|
mu_button(ctx, "World");
|
|
mu_end_popup(ctx);
|
|
}
|
|
}
|
|
|
|
/* tree */
|
|
if (mu_header_ex(ctx, "Tree and Text", MU_OPT_EXPANDED)) {
|
|
mu_layout_row(ctx, 2, (int[]) { 140, -1 }, 0);
|
|
mu_layout_begin_column(ctx);
|
|
if (mu_begin_treenode(ctx, "Test 1")) {
|
|
if (mu_begin_treenode(ctx, "Test 1a")) {
|
|
mu_label(ctx, "Hello");
|
|
mu_label(ctx, "world");
|
|
mu_end_treenode(ctx);
|
|
}
|
|
if (mu_begin_treenode(ctx, "Test 1b")) {
|
|
if (mu_button(ctx, "Button 1")) { write_log("Pressed button 1"); }
|
|
if (mu_button(ctx, "Button 2")) { write_log("Pressed button 2"); }
|
|
mu_end_treenode(ctx);
|
|
}
|
|
mu_end_treenode(ctx);
|
|
}
|
|
if (mu_begin_treenode(ctx, "Test 2")) {
|
|
mu_layout_row(ctx, 2, (int[]) { 54, 54 }, 0);
|
|
if (mu_button(ctx, "Button 3")) { write_log("Pressed button 3"); }
|
|
if (mu_button(ctx, "Button 4")) { write_log("Pressed button 4"); }
|
|
if (mu_button(ctx, "Button 5")) { write_log("Pressed button 5"); }
|
|
if (mu_button(ctx, "Button 6")) { write_log("Pressed button 6"); }
|
|
mu_end_treenode(ctx);
|
|
}
|
|
if (mu_begin_treenode(ctx, "Test 3")) {
|
|
static int checks[3] = { 1, 0, 1 };
|
|
mu_checkbox(ctx, "Checkbox 1", &checks[0]);
|
|
mu_checkbox(ctx, "Checkbox 2", &checks[1]);
|
|
mu_checkbox(ctx, "Checkbox 3", &checks[2]);
|
|
mu_end_treenode(ctx);
|
|
}
|
|
mu_layout_end_column(ctx);
|
|
|
|
mu_layout_begin_column(ctx);
|
|
mu_layout_row(ctx, 1, (int[]) { -1 }, 0);
|
|
mu_text(ctx, "Lorem ipsum dolor sit amet, consectetur adipiscing "
|
|
"elit. Maecenas lacinia, sem eu lacinia molestie, mi risus faucibus "
|
|
"ipsum, eu varius magna felis a nulla.");
|
|
mu_layout_end_column(ctx);
|
|
}
|
|
|
|
/* background color sliders */
|
|
if (mu_header_ex(ctx, "Background Color", MU_OPT_EXPANDED)) {
|
|
mu_layout_row(ctx, 2, (int[]) { -78, -1 }, 74);
|
|
/* sliders */
|
|
mu_layout_begin_column(ctx);
|
|
mu_layout_row(ctx, 2, (int[]) { 46, -1 }, 0);
|
|
mu_label(ctx, "Red:"); mu_slider(ctx, &bg[0], 0, 255);
|
|
mu_label(ctx, "Green:"); mu_slider(ctx, &bg[1], 0, 255);
|
|
mu_label(ctx, "Blue:"); mu_slider(ctx, &bg[2], 0, 255);
|
|
mu_layout_end_column(ctx);
|
|
/* color preview */
|
|
mu_Rect r = mu_layout_next(ctx);
|
|
mu_draw_rect(ctx, r, mu_color(bg[0], bg[1], bg[2], 255));
|
|
char buf[32];
|
|
sprintf(buf, "#%02X%02X%02X", (int) bg[0], (int) bg[1], (int) bg[2]);
|
|
mu_draw_control_text(ctx, buf, r, MU_COLOR_TEXT, MU_OPT_ALIGNCENTER);
|
|
}
|
|
|
|
mu_end_window(ctx);
|
|
}
|
|
}
|
|
|
|
|
|
static void log_window(mu_Context *ctx) {
|
|
if (mu_begin_window(ctx, "Log Window", mu_rect(350, 40, 300, 200))) {
|
|
/* output text panel */
|
|
mu_layout_row(ctx, 1, (int[]) { -1 }, -25);
|
|
mu_begin_panel(ctx, "Log Output");
|
|
mu_Container *panel = mu_get_current_container(ctx);
|
|
mu_layout_row(ctx, 1, (int[]) { -1 }, -1);
|
|
mu_text(ctx, logbuf);
|
|
mu_end_panel(ctx);
|
|
if (logbuf_updated) {
|
|
panel->scroll.y = panel->content_size.y;
|
|
logbuf_updated = 0;
|
|
}
|
|
|
|
/* input textbox + submit button */
|
|
static char buf[128];
|
|
int submitted = 0;
|
|
mu_layout_row(ctx, 2, (int[]) { -70, -1 }, 0);
|
|
if (mu_textbox(ctx, buf, sizeof(buf)) & MU_RES_SUBMIT) {
|
|
mu_set_focus(ctx, ctx->last_id);
|
|
submitted = 1;
|
|
}
|
|
if (mu_button(ctx, "Submit")) { submitted = 1; }
|
|
if (submitted) {
|
|
write_log(buf);
|
|
buf[0] = '\0';
|
|
}
|
|
|
|
mu_end_window(ctx);
|
|
}
|
|
}
|
|
|
|
static int uint8_slider(mu_Context *ctx, unsigned char *value, int low, int high) {
|
|
static float tmp;
|
|
mu_push_id(ctx, &value, sizeof(value));
|
|
tmp = *value;
|
|
int res = mu_slider_ex(ctx, &tmp, low, high, 0, "%.0f", MU_OPT_ALIGNCENTER);
|
|
*value = tmp;
|
|
mu_pop_id(ctx);
|
|
return res;
|
|
}
|
|
|
|
static void style_window(mu_Context *ctx) {
|
|
static struct { const char *label; int idx; } colors[] = {
|
|
{ "text:", MU_COLOR_TEXT },
|
|
{ "border:", MU_COLOR_BORDER },
|
|
{ "windowbg:", MU_COLOR_WINDOWBG },
|
|
{ "titlebg:", MU_COLOR_TITLEBG },
|
|
{ "titletext:", MU_COLOR_TITLETEXT },
|
|
{ "panelbg:", MU_COLOR_PANELBG },
|
|
{ "button:", MU_COLOR_BUTTON },
|
|
{ "buttonhover:", MU_COLOR_BUTTONHOVER },
|
|
{ "buttonfocus:", MU_COLOR_BUTTONFOCUS },
|
|
{ "base:", MU_COLOR_BASE },
|
|
{ "basehover:", MU_COLOR_BASEHOVER },
|
|
{ "basefocus:", MU_COLOR_BASEFOCUS },
|
|
{ "scrollbase:", MU_COLOR_SCROLLBASE },
|
|
{ "scrollthumb:", MU_COLOR_SCROLLTHUMB },
|
|
{ NULL }
|
|
};
|
|
|
|
if (mu_begin_window(ctx, "Style Editor", mu_rect(350, 250, 300, 240))) {
|
|
int sw = mu_get_current_container(ctx)->body.w * 0.14;
|
|
mu_layout_row(ctx, 6, (int[]) { 80, sw, sw, sw, sw, -1 }, 0);
|
|
for (int i = 0; colors[i].label; i++) {
|
|
mu_label(ctx, colors[i].label);
|
|
uint8_slider(ctx, &ctx->style->colors[i].r, 0, 255);
|
|
uint8_slider(ctx, &ctx->style->colors[i].g, 0, 255);
|
|
uint8_slider(ctx, &ctx->style->colors[i].b, 0, 255);
|
|
uint8_slider(ctx, &ctx->style->colors[i].a, 0, 255);
|
|
mu_draw_rect(ctx, mu_layout_next(ctx), ctx->style->colors[i]);
|
|
}
|
|
mu_end_window(ctx);
|
|
}
|
|
}
|
|
|
|
static void process_frame(mu_Context *ctx) {
|
|
mu_begin(ctx);
|
|
style_window(ctx);
|
|
log_window(ctx);
|
|
test_window(ctx);
|
|
mu_end(ctx);
|
|
}
|
|
|
|
|
|
|
|
static int text_width(mu_Font font, const char *text, int len) {
|
|
//if (len == -1) { len = strlen(text); }
|
|
return MeasureText(text, font_size) * global_scale;
|
|
}
|
|
|
|
static int text_height(mu_Font font) {
|
|
return font_size * global_scale;
|
|
}
|
|
|
|
// Raylib uses MOUSE_LEFT_BUTTON, etc., which are ints from 0-2.
|
|
static const int button_map[3] = {
|
|
[MOUSE_LEFT_BUTTON] = MU_MOUSE_LEFT,
|
|
[MOUSE_RIGHT_BUTTON] = MU_MOUSE_RIGHT,
|
|
[MOUSE_MIDDLE_BUTTON] = MU_MOUSE_MIDDLE
|
|
};
|
|
|
|
static const char key_map[512] = {
|
|
[KEY_LEFT_SHIFT] = MU_KEY_SHIFT,
|
|
[KEY_RIGHT_SHIFT] = MU_KEY_SHIFT,
|
|
[KEY_LEFT_CONTROL] = MU_KEY_CTRL,
|
|
[KEY_RIGHT_CONTROL]= MU_KEY_CTRL,
|
|
[KEY_LEFT_ALT] = MU_KEY_ALT,
|
|
[KEY_RIGHT_ALT] = MU_KEY_ALT,
|
|
[KEY_ENTER] = MU_KEY_RETURN,
|
|
[KEY_BACKSPACE] = MU_KEY_BACKSPACE
|
|
};
|
|
|
|
void window();
|
|
|
|
int main(void) {
|
|
const int screenWidth = 800;
|
|
const int screenHeight = 400;
|
|
|
|
|
|
|
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
|
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
|
|
|
|
|
|
|
mu_Context *ctx = malloc(sizeof(mu_Context));
|
|
mu_init(ctx);
|
|
|
|
ctx->text_height = text_height;
|
|
ctx->text_width = text_width;
|
|
|
|
float sliderValue = 0;
|
|
|
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
|
{
|
|
|
|
|
|
// Inside your frame loop
|
|
Vector2 mouse = GetMousePosition();
|
|
mu_input_mousemove(ctx, (int)mouse.x / global_scale, (int)mouse.y / global_scale);
|
|
// Mouse button handling
|
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
|
|
mu_input_mousedown(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_LEFT);
|
|
}
|
|
else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
|
|
// Keep MouseDown state active while button is held
|
|
ctx->mouse_down |= MU_MOUSE_LEFT;
|
|
}
|
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
|
|
mu_input_mouseup(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_LEFT);
|
|
}
|
|
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
|
|
mu_input_mousedown(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_RIGHT);
|
|
}
|
|
if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON)) {
|
|
mu_input_mouseup(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_RIGHT);
|
|
}
|
|
if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) {
|
|
mu_input_mousedown(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_MIDDLE);
|
|
}
|
|
if (IsMouseButtonReleased(MOUSE_MIDDLE_BUTTON)) {
|
|
mu_input_mouseup(ctx, mouse.x / global_scale, mouse.y / global_scale, MU_MOUSE_MIDDLE);
|
|
}
|
|
|
|
// Keyboard key handling
|
|
for (int key = 0; key < 512; key++) {
|
|
if (IsKeyPressed(key)) {
|
|
int c = key_map[key & 0xff];
|
|
if (c) mu_input_keydown(ctx, c);
|
|
}
|
|
if (IsKeyReleased(key)) {
|
|
int c = key_map[key & 0xff];
|
|
if (c) mu_input_keyup(ctx, c);
|
|
}
|
|
}
|
|
|
|
int ch;
|
|
while ((ch = GetCharPressed()) != 0) {
|
|
if (ch >= 32 && ch <= 126) { // Printable ASCII range
|
|
char c = (char)ch;
|
|
char str[2] = { c, 0 }; // Create null-terminated string
|
|
mu_input_text(ctx, str);
|
|
}
|
|
}
|
|
|
|
|
|
// process_frame(ctx);
|
|
mu_begin(ctx);
|
|
window(ctx, &sliderValue);
|
|
mu_end(ctx);
|
|
|
|
BeginDrawing();
|
|
|
|
ClearBackground((Color){0,0,0,1});
|
|
|
|
mu_Command *cmd = NULL;
|
|
|
|
while (mu_next_command(ctx, &cmd)) {
|
|
switch (cmd->type) {
|
|
case MU_COMMAND_TEXT: DrawText(cmd->text.str, cmd->text.pos.x * global_scale, cmd->text.pos.y * global_scale, font_size * global_scale, (Color){cmd->text.color.r, cmd->text.color.g, cmd->text.color.b, cmd->text.color.a});
|
|
break;
|
|
case MU_COMMAND_RECT: DrawRectangle(cmd->rect.rect.x * global_scale, cmd->rect.rect.y * global_scale,cmd->rect.rect.w * global_scale, cmd->rect.rect.h * global_scale, (Color){cmd->rect.color.r, cmd->rect.color.g, cmd->rect.color.b, cmd->rect.color.a});
|
|
break;
|
|
case MU_COMMAND_ICON:
|
|
//DrawRectangle(cmd->icon.rect.x, cmd->icon.rect.y,cmd->icon.rect.w, cmd->icon.rect.h, (Color){cmd->icon.color.r, cmd->icon.color.g, cmd->icon.color.b, cmd->icon.color.a});
|
|
break;
|
|
case MU_COMMAND_CLIP: BeginScissorMode(cmd->rect.rect.x * global_scale, cmd->rect.rect.y * global_scale,cmd->rect.rect.w * global_scale, cmd->rect.rect.h * global_scale); break;
|
|
}
|
|
}
|
|
|
|
EndDrawing();
|
|
}
|
|
CloseWindow();
|
|
return 0;
|
|
}
|
|
|
|
void window(mu_Context* ctx, float* value) {
|
|
if (mu_begin_window_ex(ctx, "Test Window", mu_rect(50, 50, 300, 200), 0)) {
|
|
// Set up a row with 2 columns: left for sliders/text, right for grid
|
|
int widths[] = {120, 160};
|
|
mu_layout_row(ctx, 2, widths, 0);
|
|
|
|
// --- Left column ---
|
|
{
|
|
mu_layout_row(ctx, 1, (int[]){120}, 0);
|
|
static float slider1 = 50.0f, slider2 = 0.0f;
|
|
mu_slider_ex(ctx, &slider1, 0.0f, 100.0f, 1.0f, "%.1f", MU_OPT_ALIGNCENTER);
|
|
mu_slider_ex(ctx, &slider2, 0.0f, 100.0f, 1.0f, "%.1f", MU_OPT_ALIGNCENTER);
|
|
mu_text(ctx, "Other controls here...");
|
|
|
|
// Test TextboxRaw
|
|
static char textbox_buf[32] = "Edit me!";
|
|
mu_Rect textbox_rect = mu_layout_next(ctx);
|
|
if (mu_textbox_raw(ctx, textbox_buf, sizeof(textbox_buf), 12345, textbox_rect, 0)) {
|
|
printf("Textbox changed: %s\n", textbox_buf);
|
|
}
|
|
|
|
// Test NumberEx (number textbox)
|
|
mu_layout_row(ctx, 1, (int[]){120}, 0);
|
|
if (mu_number_ex(ctx, value, 1.0f, "%.1f", 0) & MU_RES_SUBMIT) {
|
|
printf("Number changed to: %.1f\n", *value);
|
|
}
|
|
}
|
|
|
|
// --- Right column ---
|
|
{
|
|
mu_layout_row(ctx, 1, (int[]){160}, 0);
|
|
mu_text(ctx, "4x4 Grid of Buttons with 'x' labels:");
|
|
for (int row = 0; row < 4; row++) {
|
|
int grid_widths[4] = {25, 25, 25, 25};
|
|
mu_layout_row(ctx, 4, grid_widths, 0);
|
|
for (int col = 0; col < 4; col++) {
|
|
char id[16];
|
|
snprintf(id, sizeof(id), "grid_%d_%d", row, col);
|
|
mu_push_id(ctx, id, strlen(id));
|
|
if (mu_button_ex(ctx, "x", 0, MU_OPT_ALIGNCENTER)) {
|
|
// handle click
|
|
}
|
|
mu_pop_id(ctx);
|
|
}
|
|
}
|
|
}
|
|
|
|
mu_end_window(ctx);
|
|
}
|
|
}
|
|
|