Commit cf6a8983 by beoran

Work on cursor display.

parent b812466d
......@@ -52,6 +52,13 @@ typedef ALLEGRO_USTR zori_string;
#define ZORI_ID_EINVAL ((zori_id)(-3))
/** Macro for the number of elements of an array .*/
#define ZORI_ARRAY_AMOUNT(A) ((sizeof(A))/(sizeof(*A)))
/** Macro that expands to the amount of elemnts in the array and the array
* itself, in that order. */
#define ZORI_AMOUNT_AND_ARRAY(A) ZORI_ARRAY_AMOUNT(A), (A)
/* Macro: ZORI_CONTAINER_OF(PTR, TYPE, MEMBER)
This macro returns, for the given pointer, a pointer to a containing struct
......@@ -68,7 +75,10 @@ typedef ALLEGRO_USTR zori_string;
enum zori_custom_event_type {
ZORI_EVENT_CUSTOM = ALLEGRO_GET_EVENT_TYPE('z', 'o', 'r', 'i'),
ZORI_EVENT_UPDATE,
ZORI_EVENT_DRAW,
/** First draw pass. */
ZORI_EVENT_DRAW,
/** Second draw pass for cursors. */
ZORI_EVENT_OVERDRAW,
ZORI_EVENT_DONE,
ZORI_EVENT_FREE,
ZORI_EVENT_ACTION,
......@@ -195,12 +205,25 @@ struct zori_widget;
/* Event handler results. */
enum zori_handle_result {
ZORI_HANDLE_ERROR = -1,
ZORI_HANDLE_OK = 0,
ZORI_HANDLE_IGNORE = 1,
ZORI_HANDLE_ERROR = -1, /* An error ocurred, stop propagating to children.*/
ZORI_HANDLE_DONE = 0, /* The event was handled and consumed, no need to propagate to children automatically (widget may re-send event manually to children.)*/
ZORI_HANDLE_IGNORE = 1, /* Event wasn't handled, propagate to children. */
ZORI_HANDLE_PASS = 2, /* Event was handled, but needs to be propagated.*/
};
/* Returns whether or not a even needds to be propagated based on the
* result of a handler. */
static int zori_propagate_event_p(enum zori_handle_result result) {
switch(result) {
case ZORI_HANDLE_ERROR: return 0;
case ZORI_HANDLE_DONE: return 0;
case ZORI_HANDLE_IGNORE: return !0;
case ZORI_HANDLE_PASS: return !0;
default: return !0;
}
}
typedef enum zori_handle_result (zori_handler_func)(union zori_event * event);
......
......@@ -13,6 +13,9 @@ struct zori_page {
};
struct zori_page * zori_widget_to_page(struct zori_widget * widget);
struct zori_page * zori_page_new(zori_id id, struct zori_widget * parent);
zori_id zori_new_page(zori_id id, zori_id parent_id);
......
......@@ -427,8 +427,8 @@ USTR * ustrlist_joinwithustr(USTRList * self, USTR * sep) {
return result;
}
/* Retruns drom the list the node reached after skipping skip nodes from head.
* Returns NULL if there sis no such node or on other failures.
/* Returns the list the node reached after skipping skip nodes from head.
* Returns NULL if there is no such node or on other failures.
*/
USTRListNode * ustrlist_skipnode(USTRList * self, int skip) {
USTRListNode * now ;
......
......@@ -120,39 +120,97 @@ struct zori_handler * zori_handlers_search(struct zori_handlers * me, zori_even
int zori_handlers_handle(struct zori_handlers * me, union zori_event * event) {
struct zori_handler * handler = zori_handlers_search(me, event->type);
if (!handler) return 0;
if (!handler) return ZORI_HANDLE_IGNORE;
event->any.data = handler->data;
return handler->handler(event);
}
/** Returns whether or not a widget will even handle an event in the first place.
* For example, a hidden widget won't draw, and a disabled widget won't
* accept any system events, and a NULL event doesn't accept events at all.. */
int zori_widget_accepts_event(struct zori_widget * widget, union zori_event * event) {
if (!widget) return 0;
switch(event->any.type) {
case ZORI_EVENT_DRAW:
return zori_widget_visible(widget);
default:
return zori_widget_active(widget);
}
}
/** Raises an event on the widget itself only. */
int zori_widget_self_raise_event(struct zori_widget * widget,
union zori_event * event) {
enum zori_handle_result result;
if (zori_widget_accepts_event(widget, event)) {
event->any.widget = widget;
return zori_handlers_handle(&widget->handlers, event);
}
/* If the event is not accepted, it is passed on to the child widgets. */
return ZORI_HANDLE_PASS;
}
/* Raises an event on the widget, and if necessary, propagates it on to it's
* children automatically and recursively. */
int
zori_widget_raise_event(struct zori_widget * widget, union zori_event * event) {
enum zori_handle_result result =
zori_widget_self_raise_event(widget, event);
if (zori_propagate_event_p(result)) {
enum zori_handle_result sub;
size_t index;
for (index = 0; index < miao_size(&widget->children); index++) {
struct zori_widget * child = miao_unsafe_get(&widget->children, index);
event->any.widget = child;
sub = zori_widget_raise_event(child, event);
if (sub == ZORI_HANDLE_DONE) {
result = ZORI_HANDLE_DONE;
break;
}
}
}
return result;
}
int zori_widget_raise_system_event
(struct zori_widget * widget, zori_system_event * sysev) {
union zori_event event;
event.sys.any.type = sysev->type;
event.sys.any.widget = widget;
event.sys.ev = sysev;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_draw_event(struct zori_widget * widget) {
union zori_event event;
event.draw.any.type = ZORI_EVENT_DRAW;
event.draw.any.widget = widget;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_overdraw_event(struct zori_widget * widget) {
union zori_event event;
event.draw.any.type = ZORI_EVENT_OVERDRAW;
event.draw.any.widget = widget;
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_done_event(struct zori_widget * widget) {
union zori_event event;
event.done.any.type = ZORI_EVENT_DONE;
event.done.any.widget = widget;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_free_event(struct zori_widget * widget) {
union zori_event event;
event.free.any.type = ZORI_EVENT_FREE;
event.free.any.widget = widget;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_update_event
......@@ -161,7 +219,7 @@ int zori_widget_raise_update_event
event.update.any.type = ZORI_EVENT_DONE;
event.update.any.widget = widget;
event.update.dt = dt;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
int zori_widget_raise_action_event
......@@ -169,7 +227,7 @@ int zori_widget_raise_action_event
union zori_event event;
event.action.any.type = ZORI_EVENT_ACTION;
event.action.any.widget = widget;
return zori_handlers_handle(&widget->handlers, &event);
return zori_widget_raise_event(widget, &event);
}
......@@ -241,6 +299,8 @@ zori_id zori_start(struct zori_style * default_style) {
the_default_style->text.color = al_color_name("white");
the_default_style->border.color = al_color_name("white");
the_default_style->back.color = al_color_name("green");
the_default_style->fore.color = al_color_name("white");
if (default_style) {
the_zori_root->widget.style = *default_style;
......@@ -393,23 +453,23 @@ zori_id zori_new_button_widget(zori_id parent, zori_rebox box, char * text);
/* Creates a new conversation widget. */
zori_id zori_new_conversation_widget(zori_id parent, zori_rebox box, char * text);
/* Draws the widget and it's children recursively. */
void zori_draw_widget(struct zori_widget * widget) {
size_t index;
if (widget && zori_widget_visible(widget)) {
zori_widget_raise_draw_event(widget);
for (index = 0; index < miao_size(&widget->children); index++) {
struct zori_widget * child = miao_unsafe_get(&widget->children, index);
zori_draw_widget(child);
}
}
/* Lets the widget handle an event and bubbles it on to it's children
* recursively depending on the need to do that. */
void zori_widget_handle_event(struct zori_widget * widget, union zori_event * event) {
zori_widget_raise_event(widget, event);
}
/* Draws the whole UI and all visible parts. */
void zori_draw_all(void) {
zori_draw_widget(&the_zori_root->widget);
zori_widget_raise_draw_event(&the_zori_root->widget);
zori_widget_raise_overdraw_event(&the_zori_root->widget);
}
int zori_widget_visible(struct zori_widget * widget) {
return widget && ((widget->flags & ZORI_FLAG_HIDDEN) != ZORI_FLAG_HIDDEN);
}
......@@ -437,7 +497,6 @@ int zori_widget_visible_(struct zori_widget * widget, int set) {
}
/* Updates the state of the UI. Pass in the time passed since last update. */
void zori_update(double dt)
{
......@@ -448,7 +507,6 @@ void zori_update(double dt)
zori_id zori_register(zori_id id, zori_event_type type, zori_handler_func handler, void * extra);
zori_font * zori_widget_font(struct zori_widget * widget) {
return widget->style.text.font;
}
......@@ -753,8 +811,8 @@ int zori_console_draw(union zori_event * zevent) {
y = zori_widget_y(widget) - 5;
linehigh = zori_font_lineheight(font);
now = ustrlist_head(&self->text);
// skip start lines (to allow scrolling backwards)
/* now = ustrlist_head(&self->text); */
/* skip start lines (to allow scrolling backwards) */
now = ustrlist_skipnode(&self->text, self->start);
for (index = high-(linehigh*2); index > 0; index -= linehigh) {
......@@ -767,14 +825,16 @@ int zori_console_draw(union zori_event * zevent) {
now = ustrlistnode_next(now);
}
// draw input string
zori_font_drawstr(font, color, x, y + high - linehigh, 0, self->input);
if (self->input) {
zori_font_drawstr(font, color, x, y + high - linehigh, 0, self->input);
}
// Draw cursor
linew = al_get_ustr_width(font, self->input);
al_draw_line(x + linew, y + high - linehigh, x + linew, y + high, color, 1);
// draw start for debugging
al_draw_textf(font, color, x, y, 0, "start: %d, size: %d", self->start,
ustrlist_size(&self->text));
return ZORI_HANDLE_OK;
return ZORI_HANDLE_PASS;
}
/** Activates or deactivates the console. */
......@@ -797,7 +857,7 @@ int zori_console_scroll(struct zori_console * self, int direction) {
if(direction > 0) self->start++;
/* Clamp start between 0 and size of list. */
self->start = bad_clampi(self->start, 0, ustrlist_size(&self->text));
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
......@@ -812,13 +872,13 @@ int zori_console_handle_keychar(union zori_event * zevent) {
// ignore the start-console key
case ALLEGRO_KEY_F1:
case ALLEGRO_KEY_F3:
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
case ALLEGRO_KEY_PGUP: return zori_console_scroll(self, 1);
case ALLEGRO_KEY_PGDN: return zori_console_scroll(self, -1);
case ALLEGRO_KEY_BACKSPACE:
// remove last character typed.
ustr_remove_chr(self->input, ustr_offset(self->input, -1));
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
break;
case ALLEGRO_KEY_ENTER: {
const char * command = ustr_c(self->input);
......@@ -829,14 +889,14 @@ int zori_console_handle_keychar(union zori_event * zevent) {
}
ustr_truncate(self->input, 0);
// empty string by truncating it
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
default:
break;
}
ustr_appendch(self->input, ch);
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
......@@ -853,7 +913,7 @@ int zori_console_handle_keydown(union zori_event * zevent) {
/* disable console if F1 is pressed.
* Note: this shouldnever happen if react is set up well.
*/
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
default:
break;
}
......@@ -869,7 +929,7 @@ int zori_console_handle_mouseaxes(union zori_event * zevent) {
if(z == 0) return ZORI_HANDLE_IGNORE;
if(z < 0) return zori_console_scroll(self, -1);
if(z > 0) return zori_console_scroll(self, +1);
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
int zori_console_handle_ignore(union zori_event * zevent) {
......@@ -909,7 +969,7 @@ int zori_console_done(struct zori_widget * widget) {
ustr_free(self->input);
self->input = NULL;
ustrlist_done(&self->text);
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
......@@ -918,7 +978,7 @@ int zori_console_free(struct zori_widget * widget) {
struct zori_console * self = zori_widget_console(widget);
zori_console_done(&self->widget);
free(self);
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
/** Allocates a console. */
......
......@@ -6,10 +6,6 @@ struct zori_page * zori_widget_to_page(struct zori_widget * widget) {
return ZORI_CONTAINER_OF(widget, struct zori_page, widget);
}
struct zori_page * zori_page_new(zori_id id, struct zori_widget * parent);
zori_id zori_new_page(zori_id id, zori_id parent_id);
struct zori_page * zori_page_new(zori_id id, struct zori_widget * parent) {
struct zori_page * page = NULL;
if (!parent) return NULL;
......
......@@ -7,19 +7,29 @@ struct zori_screen * zori_widget_to_screen(struct zori_widget * widget) {
}
int zori_screen_on_sysevent(union zori_event * event) {
/** Handles a mouse axis event and then pass it on to the active page. */
int zori_screen_on_mouse_axes(union zori_event * event) {
struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
/* Move the mouse cursor before passing on the event to the active page, if any. */
if (event->any.type == ALLEGRO_EVENT_MOUSE_AXES) {
screen->cursors.mouse.p.x = event->sys.ev->mouse.x;
screen->cursors.mouse.p.y = event->sys.ev->mouse.y;
}
screen->cursors.mouse.p.x = event->sys.ev->mouse.x;
screen->cursors.mouse.p.y = event->sys.ev->mouse.y;
if (screen->active_page) {
return zori_widget_raise_sys_event(&screen->active_page->widget, &event->sys);
return zori_widget_raise_system_event(&screen->active_page->widget,
event->sys.ev);
}
return ZORI_HANDLE_DONE;
}
/** Handles a system event by passing it on to the active page. */
int zori_screen_on_sysevent(union zori_event * event) {
struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
if (screen->active_page) {
return zori_widget_raise_system_event(&screen->active_page->widget,
event->sys.ev);
}
return ZORI_HANDLE_OK;
return ZORI_HANDLE_DONE;
}
......@@ -30,11 +40,12 @@ void zori_draw_cursor(const struct zori_cursor * cursor, const struct zori_style
float x1, x2, x3, y1, y2, y3;
x1 = cursor->p.x;
y1 = cursor->p.y;
x2 = x1 + 5;
y2 = y1 + 10;
x3 = x1 + 3;
y3 = y1 + 12;
x2 = x1 + 24 + 8;
y2 = y1 + 24 - 8;
x3 = x1 + 24 - 8;
y3 = y1 + 24 + 8;
al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, style->fore.color);
al_draw_triangle(x1, y1, x2, y2, x3, y3, style->back.color, 1.0);
}
};
......@@ -44,24 +55,22 @@ void zori_draw_cursors(const struct zori_cursors * cursors, const struct zori_st
zori_draw_cursor(&cursors->mouse, style);
};
int zori_screen_on_draw(union zori_event * event) {
int zori_screen_on_overdraw(union zori_event * event) {
struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
zori_draw_cursors(&screen->cursors, &screen->widget.style);
return ZORI_HANDLE_OK;
return ZORI_HANDLE_PASS;
}
/*
struct zori_handler zori_screen_handlers[] = {
{ ZORI_SYSTEM_EVENT_KEY_DOWN , zori_console_handle_keydown , NULL },
{ ZORI_SYSTEM_EVENT_KEY_UP , zori_console_handle_ignore , NULL },
{ ZORI_SYSTEM_EVENT_KEY_CHAR , zori_console_handle_keychar , NULL },
{ ZORI_EVENT_ _MOUSE_AXES, zori_console_handle_mouseaxes , NULL },
{ ZORI_EVENT_DRAW , zori_console_draw , NULL },
{ ZORI_EVENT_DONE , zori_console_handle_ignore , NULL },
{ ZORI_EVENT_FREE , zori_console_handle_ignore , NULL },
{ ZORI_SYSTEM_EVENT_KEY_DOWN , zori_screen_on_sysevent , NULL },
{ ZORI_SYSTEM_EVENT_KEY_UP , zori_screen_on_sysevent , NULL },
{ ZORI_SYSTEM_EVENT_KEY_CHAR , zori_screen_on_sysevent , NULL },
{ ZORI_SYSTEM_EVENT_MOUSE_AXES, zori_screen_on_mouse_axes , NULL },
{ ZORI_EVENT_OVERDRAW , zori_screen_on_overdraw , NULL },
{ -1, NULL, NULL }
};
*/
struct zori_screen *
zori_screen_init(struct zori_screen * screen, zori_display * display) {
......@@ -81,7 +90,7 @@ struct zori_screen * zori_screen_new(zori_id id, zori_display * display) {
box.size.x = al_get_display_width(display);
box.size.y = al_get_display_height(display);
zori_widget_initall(&screen->widget, id, &zori_get_root()->widget,
&box, NULL, 0, NULL);
&box, NULL, ZORI_AMOUNT_AND_ARRAY(zori_screen_handlers));
if (!zori_screen_init(screen, display)) {
free(screen);
screen = NULL;
......@@ -98,7 +107,7 @@ zori_id zori_new_screen(zori_id id, zori_display * display) {
zori_id zori_active_page(zori_id screen_id) {
struct zori_screen * screen = zori_widget_to_page(zori_get_widget(screen_id));
struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
if (!screen) {
return ZORI_ID_EINVAL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment