shithub: microui

ref: b53399a1815178d6a221f580be4e5bce9614474d
dir: /demo/plan9.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <mouse.h>
#include <keyboard.h>
#include <thread.h>
#include "common.h"

static Mousectl *mctl;
static Keyboardctl *kctl;

void
threadmain(int argc, char **argv)
{
	Rune key;
	Mouse m;
	Alt a[] = {
		{ nil, &m, CHANRCV },
		{ nil, nil, CHANRCV },
		{ nil, &key, CHANRCV },
		{ nil, nil,  CHANNOBLK},
	};
	int oldbuttons, b, nkey;
	char text[5];
	mu_Command *cmd;
	mu_Context *ctx;

	USED(argc); USED(argv);

	if (initdraw(nil, nil, "microui demo") < 0)
		sysfatal("initdraw: %r");
	if ((mctl = initmouse(nil, screen)) == nil)
		sysfatal("initmouse: %r");
	if ((kctl = initkeyboard(nil)) == nil)
		sysfatal("initkeyboard: %r");

	a[0].c = mctl->c;
	a[1].c = mctl->resizec;
	a[2].c = kctl->c;

	srand(time(0));
	threadsetname("microui demo");

	ctx = malloc(sizeof(mu_Context));
	r_init();

	/* init microui */
	mu_init(ctx);
	ctx->text_width = r_get_text_width;
	ctx->text_height = r_get_text_height;
	ctx->style->font = display->defaultfont;

	oldbuttons = 0;
	for (;;) {
		/* process frame */
		process_frame(ctx);

		/* render */
		r_clear(mu_color(bg[0], bg[1], bg[2], 255));
		cmd = nil;
		while (mu_next_command(ctx, &cmd)) {
			switch (cmd->type) {
			case MU_COMMAND_TEXT: r_draw_text(ctx->style->font, cmd->text.str, cmd->text.pos, cmd->text.color); break;
			case MU_COMMAND_RECT: r_draw_rect(cmd->rect.rect, cmd->rect.color); break;
			case MU_COMMAND_ICON: r_draw_icon(cmd->icon.id, cmd->icon.rect, cmd->icon.color); break;
			case MU_COMMAND_CLIP: r_set_clip_rect(cmd->clip.rect); break;
			}
		}
		r_present();

		switch (alt(a)) {
		case 0: /* mouse */
			m.xy.x -= screen->r.min.x;
			m.xy.y -= screen->r.min.y;
			mu_input_mousemove(ctx, m.xy.x, m.xy.y);
			if ((b = (m.buttons & 1)) != (oldbuttons & 1))
				(b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_LEFT);
			else if ((b = (m.buttons & 2)) != (oldbuttons & 2))
				(b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_MIDDLE);
			else if ((b = (m.buttons & 4)) != (oldbuttons & 4))
				(b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_RIGHT);
			oldbuttons = m.buttons;
			break;

		case 1: /* resize */
			getwindow(display, Refnone);
			break;

		case 2: /* keyboard */
			nkey = -1;
			switch (key) {
			case Kdel: goto end;
			case Kshift: nkey = MU_KEY_SHIFT; break;
			case Kbs: nkey = MU_KEY_BACKSPACE; break;
			case '\n': nkey = MU_KEY_RETURN; break;
			default:
				if (key < 0xf000 || key > 0xffff) {
					memset(text, 0, sizeof(text));
					if (runetochar(text, &key) > 0)
						mu_input_text(ctx, text);
				}
				break;
			}
			if (nkey >= 0) {
				mu_input_keydown(ctx, nkey);
				mu_input_keyup(ctx, nkey);
			}
		}

		a[nelem(a)-1].op = a[nelem(a)-1].op == CHANNOBLK ? CHANEND : CHANNOBLK;
	}

end:
	closemouse(mctl);
	closekeyboard(kctl);
	threadexitsall(nil);
}