commit - cb5e051aec61c8910f1a8335320b6dd435005c1d
commit + 870fe49e4274af2aa8cdc5315feb6956330d2af7
blob - 2224ddef2b331222a6301be020522753cdebd389
blob + e6d58289f466e26b75f1e9530a22a09cf28e9568
--- Makefile
+++ Makefile
clean:
rm -rf ${OBJS} libmui.so
-.PHONY: all mui clean fonts uninstall
+.PHONY: all mui clean uninstall
blob - 3ff5ea8b0ea946d3b5df94cfb36ae72da49356b3
blob + fbc205aaa1aeef164dffa8dbda3a069d3a483556
--- demo/image/Makefile
+++ demo/image/Makefile
LIBS=-Wl,-rpath=${LIBDIR} -L ${LIBDIR} -lmui
all:
- make MUI_DEBUG=1 -C ${LIBDIR}
+ make -C ${LIBDIR}
${CC} ${SRCS} -o bin ${INCS} ${LIBS}
clean:
blob - /dev/null
blob + fbc205aaa1aeef164dffa8dbda3a069d3a483556 (mode 644)
--- /dev/null
+++ demo/event/Makefile
+SRCS=main.c
+LIBDIR=../..
+INCS= -I ${LIBDIR}
+LIBS=-Wl,-rpath=${LIBDIR} -L ${LIBDIR} -lmui
+
+all:
+ make -C ${LIBDIR}
+ ${CC} ${SRCS} -o bin ${INCS} ${LIBS}
+
+clean:
+ rm -rf bin bin.core
blob - /dev/null
blob + 043be9b90254b76b7bcdf9f49dc09e9758c7f0b4 (mode 644)
--- /dev/null
+++ demo/event/main.c
+/********************************************************/
+/*
+ * Brief example of event management using mui with a
+ * set of 5 buttons interacting with the mouse.
+ */
+/********************************************************/
+
+#include "mui.h"
+
+#define PRESS 0
+#define MOTION 1
+#define RELEASE 2
+
+#define WIDTH 100
+#define HEIGHT 100
+
+static struct {
+ struct mui_event_handler *handler;
+ struct mui_group *group;
+ struct mui_window *mw;
+} window;
+
+/*
+ * Keeps track of which drawable is held in a
+ * specific event
+ */
+static struct {
+ void *ptr;
+ uint16_t id;
+} event_recorder[3];
+
+struct button {
+ struct mui_shape *shape;
+ struct mui_layout *layout;
+ struct mui_color color[3];
+};
+
+int
+main(void)
+{
+ struct mui_event event;
+ struct button buttons[5];
+
+ /* Creating the window */
+ window.mw = mui_create_window("Events", 320, 240);
+ window.group = mui_get_window_group(window.mw);
+ window.handler = mui_get_window_event_handler(window.mw);
+
+ /* TOP LEFT */
+ buttons[0].shape = mui_create_rectangle(WIDTH, HEIGHT);
+ buttons[0].layout = mui_get_shape_layout(buttons[0].shape);
+ buttons[0].color[PRESS] = (struct mui_color){ 0.5, 0.5, 0.5, 1.0 };
+ buttons[0].color[MOTION] = (struct mui_color){ 0.75, 0.75, 0.75, 1.0 };
+ buttons[0].color[RELEASE] = (struct mui_color){ 1.0, 1.0, 1.0, 1.0 };
+
+
+ /* TOP RIGHT */
+ buttons[1].shape = mui_create_rectangle(WIDTH, HEIGHT);
+ buttons[1].layout = mui_get_shape_layout(buttons[1].shape);
+ buttons[1].color[PRESS] = (struct mui_color){ 0.5, 0.5, 0.5, 1.0 };
+ buttons[1].color[MOTION] = (struct mui_color){ 0.75, 0.75, 0.75, 1.0 };
+ buttons[1].color[RELEASE] = (struct mui_color){ 1.0, 1.0, 1.0, 1.0 };
+
+ mui_set_layout_flags(buttons[1].layout, MUI_ALIGN_RIGHT | MUI_ANCHOR_RIGHT );
+
+ /* BOTTOM RIGHT */
+ buttons[2].shape = mui_create_rectangle(WIDTH, HEIGHT);
+ buttons[2].layout = mui_get_shape_layout(buttons[2].shape);
+ buttons[2].color[PRESS] = (struct mui_color){ 0.5, 0.5, 0.5, 1.0 };
+ buttons[2].color[MOTION] = (struct mui_color){ 0.75, 0.75, 0.75, 1.0 };
+ buttons[2].color[RELEASE] = (struct mui_color){ 1.0, 1.0, 1.0, 1.0 };
+
+ mui_set_layout_flags(buttons[2].layout, MUI_ALIGN_RIGHT | MUI_ANCHOR_RIGHT |
+ MUI_ALIGN_BOTTOM | MUI_ANCHOR_BOTTOM);
+
+ /* BOTTOM LEFT */
+ buttons[3].shape = mui_create_rectangle(WIDTH, HEIGHT);
+ buttons[3].layout = mui_get_shape_layout(buttons[3].shape);
+ buttons[3].color[PRESS] = (struct mui_color){ 0.5, 0.5, 0.5, 1.0 };
+ buttons[3].color[MOTION] = (struct mui_color){ 0.75, 0.75, 0.75, 1.0 };
+ buttons[3].color[RELEASE] = (struct mui_color){ 1.0, 1.0, 1.0, 1.0 };
+
+ mui_set_layout_flags(buttons[3].layout, MUI_ALIGN_BOTTOM | MUI_ANCHOR_BOTTOM);
+
+ /* CENTER */
+ buttons[4].shape = mui_create_rectangle(WIDTH, HEIGHT);
+ buttons[4].layout = mui_get_shape_layout(buttons[4].shape);
+ buttons[4].color[PRESS] = (struct mui_color){ 0.5, 0.5, 0.5, 1.0 };
+ buttons[4].color[MOTION] = (struct mui_color){ 0.75, 0.75, 0.75, 1.0 };
+ buttons[4].color[RELEASE] = (struct mui_color){ 1.0, 1.0, 1.0, 1.0 };
+
+ mui_set_layout_flags(buttons[4].layout, MUI_ALIGN_CENTER_X | MUI_ALIGN_CENTER_Y |
+ MUI_ANCHOR_CENTER_X | MUI_ANCHOR_CENTER_Y | MUI_KEEP_RATIO);
+
+ /* Adding to the group */
+ for (int i = 0; i < 5; i++) {
+ mui_set_shape_color(buttons[i].shape, buttons[i].color[RELEASE].r,
+ buttons[i].color[RELEASE].g, buttons[i].color[RELEASE].b, buttons[i].color[RELEASE].a);
+
+ mui_group_add(window.group, MUI_SHAPE, buttons[i].shape);
+ }
+
+ while (event.type != MUI_EVENT_QUIT) {
+ event = mui_pop_event(window.handler);
+
+ switch (event.type) {
+ case MUI_EVENT_MOUSE_MOTION:
+ if (event_recorder[MOTION].ptr && event.target.ptr != event_recorder[MOTION].ptr) {
+ if (event_recorder[MOTION].ptr != event_recorder[PRESS].ptr)
+ mui_set_shape_color(event_recorder[MOTION].ptr, 1.0, 1.0, 1.0, 1.0);
+ event_recorder[MOTION].ptr = NULL;
+ }
+
+ if (event.target.ptr && event_recorder[MOTION].ptr != event.target.ptr) {
+ mui_set_shape_color(event.target.ptr, 0.75, 0.75, 0.75, 1.0);
+ event_recorder[MOTION].ptr = event.target.ptr;
+ }
+ break;
+
+ case MUI_EVENT_MOUSE_PRESS:
+ if (event.target.ptr && event_recorder[PRESS].ptr != event.target.ptr) {
+ mui_set_shape_color(event.target.ptr, 0.5, 0.5, 0.5, 1.0);
+ }
+ event_recorder[PRESS].ptr = event.target.ptr;
+ break;
+
+ case MUI_EVENT_MOUSE_RELEASE:
+ if (event_recorder[PRESS].ptr) {
+ mui_set_shape_color(event_recorder[PRESS].ptr, 1.0, 1.0, 1.0, 1.0);
+ event_recorder[PRESS].ptr = NULL;
+ }
+
+ if (event.target.ptr) {
+ if (event_recorder[MOTION].ptr)
+ mui_set_shape_color(event_recorder[MOTION].ptr, 1.0, 1.0, 1.0, 1.0);
+
+ mui_set_shape_color(event.target.ptr, 0.75, 0.75, 0.75, 1.0);
+ event_recorder[MOTION].ptr = event.target.ptr;
+ }
+ }
+ mui_update();
+ }
+
+
+ return 0;
+}
blob - 3ff5ea8b0ea946d3b5df94cfb36ae72da49356b3
blob + fbc205aaa1aeef164dffa8dbda3a069d3a483556
--- demo/shape/Makefile
+++ demo/shape/Makefile
LIBS=-Wl,-rpath=${LIBDIR} -L ${LIBDIR} -lmui
all:
- make MUI_DEBUG=1 -C ${LIBDIR}
+ make -C ${LIBDIR}
${CC} ${SRCS} -o bin ${INCS} ${LIBS}
clean:
blob - 3ff5ea8b0ea946d3b5df94cfb36ae72da49356b3
blob + fbc205aaa1aeef164dffa8dbda3a069d3a483556
--- demo/text/Makefile
+++ demo/text/Makefile
LIBS=-Wl,-rpath=${LIBDIR} -L ${LIBDIR} -lmui
all:
- make MUI_DEBUG=1 -C ${LIBDIR}
+ make -C ${LIBDIR}
${CC} ${SRCS} -o bin ${INCS} ${LIBS}
clean:
blob - 0bb4a83133f20cb4b6e2c7fea8df799d4a47cc52
blob + d555489a457852e1d81213e465561c078d6ecc12
--- event.c
+++ event.c
struct mui_event_handler {
uint8_t count;
+ struct mui_window *mw;
TAILQ_HEAD(ev_list, mui_event) head;
};
struct mui_event_handler*
-mui_create_event_handler()
+mui_create_event_handler(struct mui_window *mw)
{
struct mui_event_handler *handler;
handler = calloc(1, sizeof(*handler));
TAILQ_INIT(&handler->head);
handler->count = 0;
+ handler->mw = mw;
return handler;
}
current = calloc(1, sizeof(*current));
memcpy(current, event, sizeof(struct mui_event));
+
+ current->target.id = MUI_UNDEF;
+ current->target.ptr = NULL;
+ mui_event_set_target(handler, current);
TAILQ_INSERT_HEAD(&handler->head, current, entries);
handler->count++;
return event;
}
+
+void set_mouse_press_target(struct mui_event_handler*, struct mui_group*, struct mui_event*);
+void set_mouse_release_target(struct mui_event_handler*, struct mui_group*, struct mui_event*);
+void set_mouse_motion_target(struct mui_event_handler*, struct mui_group*, struct mui_event*);
+
void
-mui_event_set_target(struct mui_window *mw, struct mui_event *event)
+set_mouse_release_target(struct mui_event_handler *handler, struct mui_group *group,
+ struct mui_event *event)
{
- struct mui_event_handler *handler;
+ void *data;
+ float x;
+ float y;
+ uint16_t type;
+ uint16_t width;
+ uint16_t height;
+ float *matrix;
+ struct member *np;
+ struct mui_layout *layout;
+
+ np = NULL;
+ data = NULL;
+
+ while ((np = mui_get_group_next_member(group, np))) {
+ type = mui_get_group_member_type(np);
+ data = mui_get_group_member_data(np);
+
+ switch (type) {
+ case MUI_IMAGE:
+ layout = mui_get_image_layout(data);
+ break;
+ case MUI_SHAPE:
+ layout = mui_get_shape_layout(data);
+ break;
+ case MUI_LABEL:
+ layout = mui_get_label_layout(data);
+ break;
+ case MUI_GROUP:
+ set_mouse_release_target(handler, data, event);
+ continue;
+ }
+
+ if (mui_layout_collide_point(layout, event->mouse_release.x, event->mouse_release.y)) {
+ event->target.id = type;
+ event->target.ptr = data;
+ }
+ }
}
+
+void
+set_mouse_motion_target(struct mui_event_handler *handler, struct mui_group *group,
+ struct mui_event *event)
+{
+ void *data;
+ float x;
+ float y;
+ uint16_t type;
+ uint16_t width;
+ uint16_t height;
+ float *matrix;
+ struct member *np;
+ struct mui_layout *layout;
+
+ np = NULL;
+ data = NULL;
+
+ while ((np = mui_get_group_next_member(group, np))) {
+ type = mui_get_group_member_type(np);
+ data = mui_get_group_member_data(np);
+
+ switch (type) {
+ case MUI_IMAGE:
+ layout = mui_get_image_layout(data);
+ break;
+ case MUI_SHAPE:
+ layout = mui_get_shape_layout(data);
+ break;
+ case MUI_LABEL:
+ layout = mui_get_label_layout(data);
+ break;
+ case MUI_GROUP:
+ set_mouse_motion_target(handler, data, event);
+ continue;
+ }
+
+ if (mui_layout_collide_point(layout, event->mouse_motion.x, event->mouse_motion.y)) {
+ event->target.id = type;
+ event->target.ptr = data;
+ }
+ }
+}
+
+void
+set_mouse_press_target(struct mui_event_handler *handler, struct mui_group *group,
+ struct mui_event *event)
+{
+ void *data;
+ float x;
+ float y;
+ uint16_t type;
+ uint16_t width;
+ uint16_t height;
+ float *matrix;
+ struct member *np;
+ struct mui_layout *layout;
+
+ np = NULL;
+ data = NULL;
+
+ while ((np = mui_get_group_next_member(group, np))) {
+ type = mui_get_group_member_type(np);
+ data = mui_get_group_member_data(np);
+
+ switch (type) {
+ case MUI_IMAGE:
+ layout = mui_get_image_layout(data);
+ break;
+ case MUI_SHAPE:
+ layout = mui_get_shape_layout(data);
+ break;
+ case MUI_LABEL:
+ layout = mui_get_label_layout(data);
+ break;
+ case MUI_GROUP:
+ set_mouse_press_target(handler, data, event);
+ continue;
+ }
+
+ if (mui_layout_collide_point(layout, event->mouse_press.x, event->mouse_press.y)) {
+ event->target.id = type;
+ event->target.ptr = data;
+ }
+ }
+}
+
+
+void
+mui_event_set_target(struct mui_event_handler *handler, struct mui_event *event)
+{
+ struct mui_group *group;
+
+ group = mui_get_window_group(handler->mw);
+
+ switch (event->type) {
+ case MUI_EVENT_MOUSE_PRESS:
+ set_mouse_press_target(handler, group, event);
+ break;
+ case MUI_EVENT_MOUSE_RELEASE:
+ set_mouse_release_target(handler, group, event);
+ break;
+ case MUI_EVENT_MOUSE_MOTION:
+ set_mouse_motion_target(handler, group, event);
+ break;
+ default:
+ break;
+ }
+}
blob - 0c08902f9ccd746d7c575b6b0492f8a71e309c01
blob + c9736c535e1c840f9cf282847f9187ef8013f530
--- layout.c
+++ layout.c
{
return layout->scale_y;
}
+
+int
+mui_layout_collide_point(struct mui_layout *layout, int x, int y)
+{
+ float dx, dy;
+ float lx, ly;
+ uint16_t width;
+ uint16_t height;
+
+ dx = dy = 0;
+
+ if (layout->flags & MUI_ANCHOR_RIGHT)
+ dx = layout->width * layout->scale_x;
+
+ if (layout->flags & MUI_ANCHOR_CENTER_X)
+ dx = layout->width / 2.0 * layout->scale_x;
+
+ if (layout->flags & MUI_ANCHOR_CENTER_Y)
+ dy = layout->height / 2.0 * layout->scale_y;
+
+ if (layout->flags & MUI_ANCHOR_BOTTOM)
+ dy = layout->height * layout->scale_y;
+
+ lx = layout->x + layout->align_x - dx;
+ ly = layout->y + layout->align_y - dy;
+
+ width = layout->width * layout->scale_x;
+ height = layout->height * layout->scale_y;
+
+ return x > lx && x < lx + width && y > ly && y < ly + height;
+}
blob - 13b3cc23fd96597022a53dc61d2f6b811e1915f7
blob + da95889f4e0ff5ba934cfbafb008d2effea463be
--- mui.7
+++ mui.7
.sp
The context can be reimplemented to be based on OpenGL or other graphics
backend by editing the source code.
+.Sh EVENT HANDLER
+The event handler process events and attach the target drawable. Managing
+the callback of these events is up to the developer.
.sp
.Sh BASICS
A mui program needs a display to render its drawable but not to create
blob - 31472cc2453fa7899fee5ba80af4de7efa9e60ec
blob + 30a8ba0bd7cb98e97ed8cec4a94b029b0316d11e
--- mui.h
+++ mui.h
struct mui_event_handler;
-struct mui_event_handler *mui_create_event_handler(void);
+struct mui_event_handler *mui_create_event_handler(struct mui_window *mw);
void mui_push_event(struct mui_event_handler *handler, struct mui_event *event);
struct mui_event mui_pop_event(struct mui_event_handler *handler);
+void mui_event_set_target(struct mui_event_handler *handler, struct mui_event *event);
+
/*
* This function is very important and should be placed
* in the main loop of you GUI program
float mui_get_layout_scale_y(struct mui_layout *layout);
+int mui_layout_collide_point(struct mui_layout *layout, int x, int y);
+
/*
* This function should be removed later and replaced with a
* debugging marcro
blob - 5e964f11bdc556ab55781c50157a885f462f5f94
blob + ae3e6a466b9b02b4d8ac140933a1af8bb7b8f830
--- window.c
+++ window.c
layout = mui_get_group_layout(mw->group);
mui_resize_layout(layout, width, height);
mui_set_layout_flags(layout, MUI_EXPAND_X | MUI_EXPAND_Y);
- mw->handler = mui_create_event_handler();
+ mw->handler = mui_create_event_handler(mw);
mw->name = malloc(strlen(name)+1);
memcpy(mw->name, name, strlen(name));