shithub: microui

ref: c81a6c7f11ceecb213cc947b382e97bbbadce81d
dir: /demo/frame.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <microui.h>

static char logbuf[64000];
static int logbuf_updated = 0;

static void
write_log(const char *text)
{
	if (logbuf[0])
		strcat(logbuf, "\n");
	strcat(logbuf, text);
	logbuf_updated = 1;
}

#define text_width(s) (stringwidth(ctx->style->font, s) + 6)
#define text_height() ctx->style->font->height
#define max(a, b) ((a) > (b) ? (a) : (b))

static void
test_window(mu_Context *ctx)
{
	static mu_Container window;

	/* init window manually so we can set its position and size */
	if (!window.inited) {
		mu_init_window(ctx, &window, 0);
		window.rect = mu_rect(40, 40, 320, 500);
	}

	/* limit window to minimum size */
	window.rect.w = max(window.rect.w, 240);
	window.rect.h = max(window.rect.h, 300);

	/* do window */
	if (mu_begin_window(ctx, &window, "Demo Window")) {

		/* window info */
		static int show_info = 0;
		if (mu_header(ctx, &show_info, "Window Info")) {
			char buf[64];
			const int widths[] = { text_width("Position:"), -1 };
			mu_layout_row(ctx, 2, widths, 0);
			mu_label(ctx, "Position:");
			sprint(buf, "%d, %d", window.rect.x, window.rect.y); mu_label(ctx, buf);
			mu_label(ctx, "Size:");
			sprint(buf, "%d, %d", window.rect.w, window.rect.h); mu_label(ctx, buf);
		}

		/* labels + buttons */
		static int show_buttons = 1;
		if (mu_header(ctx, &show_buttons, "Test Buttons")) {
			const int widths[] = { text_width("Test buttons 2:"), -text_width("Button 2	"), -1 };
			mu_layout_row(ctx, 3, widths, 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, "Button 4")) { write_log("Pressed button 4"); }
		}

		/* tree */
		static int show_tree = 1;
		if (mu_header(ctx, &show_tree, "Tree and Text")) {
			int widths[] = { text_width("Test 1a")+text_height()*2+text_width("Button 3")+6, -1 };
			mu_layout_row(ctx, 2, widths, 0);
			mu_layout_begin_column(ctx);
			static int states[8];
			if (mu_begin_treenode(ctx, &states[0], "Test 1")) {
				if (mu_begin_treenode(ctx, &states[1], "Test 1a")) {
					mu_label(ctx, "Hello");
					mu_label(ctx, "world");
					mu_end_treenode(ctx);
				}
				if (mu_begin_treenode(ctx, &states[2], "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, &states[3], "Test 2")) {
				int widths[2];
				widths[0] = widths[1] = text_width("Button 3");
				mu_layout_row(ctx, 2, widths, 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, &states[4], "Test 3")) {
				static int checks[3] = { 1, 0, 1 };
				mu_checkbox(ctx, &checks[0], "Checkbox 1");
				mu_checkbox(ctx, &checks[1], "Checkbox 2");
				mu_checkbox(ctx, &checks[2], "Checkbox 3");
				mu_end_treenode(ctx);
			}
			mu_layout_end_column(ctx);

			mu_layout_begin_column(ctx);
			widths[0] = -1;
			mu_layout_row(ctx, 1, widths, 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);
		}

		mu_end_window(ctx);
	}
}


static void
log_window(mu_Context *ctx)
{
	static mu_Container window;

	/* init window manually so we can set its position and size */
	if (!window.inited) {
		mu_init_window(ctx, &window, 0);
		window.rect = mu_rect(370, 40, 340, 200);
	}

	if (mu_begin_window(ctx, &window, "Log Window")) {
		int widths[] = { -1, -1 };

		/* output text panel */
		static mu_Container panel;
		mu_layout_row(ctx, 1, widths, -28);
		mu_begin_panel(ctx, &panel);
		mu_layout_row(ctx, 1, widths, -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;
		widths[0] = -text_width("Submit")-8;
		mu_layout_row(ctx, 2, widths, -1);
		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 mu_Container window;
	static u8int cur[MU_COLOR_MAX][4], old[MU_COLOR_MAX][4];
	static struct { const char *label; int idx; } colors[] = {
		{ "background:", MU_COLOR_BG },
		{ "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 },
		{ nil }
	};

	/* init window manually so we can set its position and size */
	if (!window.inited) {
		mu_init_window(ctx, &window, 0);
		window.rect = mu_rect(370, 250, 340, 290);
		memmove(cur, defaultcolors, sizeof(cur));
		memmove(old, defaultcolors, sizeof(old));
	}

	if (mu_begin_window(ctx, &window, "Style Editor")) {
		int sw = max(text_width("255"), mu_get_container(ctx)->body.w * 0.14);
		const int widths[] = { text_width("scrollthumb:"), sw, sw, sw, sw, -1 };
		mu_layout_row(ctx, 6, widths, 0);
		for (int i = 0; colors[i].label; i++) {
			mu_label(ctx, colors[i].label);
			uint8_slider(ctx, &cur[i][0], 0, 255);
			uint8_slider(ctx, &cur[i][1], 0, 255);
			uint8_slider(ctx, &cur[i][2], 0, 255);
			uint8_slider(ctx, &cur[i][3], 0, 255);
			if (memcmp(cur[i], old[i], 4) != 0) {
				freeimage(ctx->style->colors[i]);
				ctx->style->colors[i] = mu_color(cur[i][0], cur[i][1], cur[i][2], cur[i][3]);
				memmove(old[i], cur[i], 4);
			}
			mu_draw_rect(ctx, mu_layout_next(ctx), ctx->style->colors[i]);
		}
		mu_end_window(ctx);
	}
}

void
process_frame(mu_Context *ctx)
{
	mu_begin(ctx);
	test_window(ctx);
	log_window(ctx);
	style_window(ctx);
	mu_end(ctx);
}