Commit b812466d by beoran

Working on zori GUI module.

parent bc3ab2a2
......@@ -77,7 +77,13 @@ set(ERUTA_SRC_FILES
src/ui.c
src/utf8.c
src/xresor.c
src/zori/zori_button.c
src/zori/zori.c
src/zori/zori_screen.c
src/zori/zori_console.c
src/zori/zori_longtext.c
src/zori/zori_menu.c
src/zori/zori_page.c
src/zori/zori_root.c
src/zori/zori_screen.c
src/zori/zori_widget.c
)
......@@ -32,13 +32,17 @@ typedef ALLEGRO_DISPLAY zori_display;
typedef Point zori_point;
typedef Rebox zori_rebox;
typedef int zori_id;
typedef int zori_id;
typedef ALLEGRO_USTR zori_string;
/* Macros for possible portability. */
#define zori_font_lineheight(FONT) al_get_font_line_height(FONT)
#define zori_font_drawstr(FONT, COLOR, X, Y, ATTR, TEXT) al_draw_ustr(FONT, COLOR, X, Y, ATTR, TEXT)
/* Default sizes of a widget. */
#define ZORI_WIDGET_DEFAULT_W 640
#define ZORI_WIDGET_DEFAULT_H 480
/* Zori ID's. */
#define ZORI_ID_OK_P(ID) ((ID) > -1)
......@@ -67,6 +71,7 @@ enum zori_custom_event_type {
ZORI_EVENT_DRAW,
ZORI_EVENT_DONE,
ZORI_EVENT_FREE,
ZORI_EVENT_ACTION,
};
......@@ -85,7 +90,7 @@ struct zori_any_event {
/* System event, that is coming from the underlying library used, e.g. Allegro. */
struct zori_sys_event {
struct zori_any_event any;
zori_system_event * sysev;
zori_system_event * ev;
};
/* Update event, when UI has to update (animations, etc). */
......@@ -109,6 +114,11 @@ struct zori_free_event {
struct zori_any_event any;
};
/* Action event. */
struct zori_action_event {
struct zori_any_event any;
};
/** An event that ZORI can handle. The union is cunningly overlaid so
* that the type field and the any field can be used in all cases. */
......@@ -121,6 +131,7 @@ union zori_event {
struct zori_update_event update;
struct zori_done_event done;
struct zori_free_event free;
struct zori_action_event action;
};
......@@ -149,7 +160,7 @@ static inline bool zori_event_is_sys_event(union zori_event * event) {
static inline zori_system_event * zori_event_system_event(union zori_event * event) {
if (!event) return NULL;
if (!zori_event_is_sys_event(event)) return NULL;
return event->sys.sysev;
return event->sys.ev;
}
/* Helper functions to set widget for an event. */
......@@ -309,17 +320,6 @@ struct zori_root {
/* Forward declaration of a page. */
struct zori_page;
/* In Zori, the GUI is paginated. This means that on any
* screen, only a single GUI page can be active. The intent is to
* support different GUI modes such as startup screen, status view,
* settings, HUD, and so on between which can be switched easily. */
struct zori_page {
/* A page is a widget. */
struct zori_widget widget;
};
struct zori_root * zori_get_root(void);
/* Initializes Zori and creates a top level widget. Returns 0 on success
......@@ -337,10 +337,6 @@ zori_id zori_shutdown();
/* Creates a new screen widget. Normally this should be the first widget
* you create after zori_start. */
/* Creates a new page widget on the given screen. The page is not
* made the active page, unless if it is the first one created. */
zori_id zori_new_page(zori_id screen);
/* Activates the page on it's display. All other pages are dectivated and
* hidden. */
zori_id zori_activate_page(zori_id page);
......@@ -401,6 +397,7 @@ int zori_widget_raise_draw_event(struct zori_widget *widget);
int zori_widget_raise_done_event(struct zori_widget *widget);
int zori_widget_raise_free_event(struct zori_widget *widget);
int zori_widget_raise_update_event(struct zori_widget *widget, double dt);
int zori_widget_raise_action_event(struct zori_widget *widget);
int zori_widget_compare(const void *v1, const void *v2);
struct zori_widget *zori_get_widget(zori_id id);
zori_id zori_get_unused_id(void);
......
#ifndef zori_button_H_INCLUDED
#define zori_button_H_INCLUDED
#include <zori.h>
struct zori_button {
struct zori_widget widget;
zori_string * caption;
int align;
};
#endif
#ifndef zori_console_H_INCLUDED
#define zori_console_H_INCLUDED
#endif
#ifndef zori_longtext_H_INCLUDED
#define zori_longtext_H_INCLUDED
#include "zori.h"
struct zori_longtext {
struct zori_widget widget;
int align;
zori_string * caption;
zori_string * text;
int line_start, line_stop, line_pos; /* Current text "window". */
int line_max, line_height; /* text constants. */
int page_lines;
/* Text "window" size for one "page" of text in amount of lines. */
int paused;
double delay_total;
};
#endif
#ifndef zori_menu_H_INCLUDED
#define zori_menu_H_INCLUDED
#endif
#ifndef zori_page_H_INCLUDED
#define zori_page_H_INCLUDED
#include "zori.h"
/* In Zori, the GUI is paginated. This means that on any
* screen, only a single GUI page can be active. The intent is to
* support different GUI modes such as startup screen, status view,
* settings, HUD, and so on between which can be switched easily. */
struct zori_page {
/* A page is a widget. */
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);
#endif
......
#ifndef zori_root_H_INCLUDED
#define zori_root_H_INCLUDED
#endif
#ifndef zori_widget_H_INCLUDED
#define zori_widget_H_INCLUDED
#endif
......@@ -130,7 +130,7 @@ int zori_widget_raise_system_event
union zori_event event;
event.sys.any.type = sysev->type;
event.sys.any.widget = widget;
event.sys.sysev = sysev;
event.sys.ev = sysev;
return zori_handlers_handle(&widget->handlers, &event);
}
......@@ -164,6 +164,14 @@ int zori_widget_raise_update_event
return zori_handlers_handle(&widget->handlers, &event);
}
int zori_widget_raise_action_event
(struct zori_widget * widget) {
union zori_event event;
event.action.any.type = ZORI_EVENT_ACTION;
event.action.any.widget = widget;
return zori_handlers_handle(&widget->handlers, &event);
}
......@@ -306,7 +314,7 @@ struct zori_widget * zori_widget_init
} else if (parent) {
widget->box = parent->box;
} else {
widget->box = rebox_make(0, 0, 200, 100);
widget->box = rebox_make(0, 0, ZORI_WIDGET_DEFAULT_W, ZORI_WIDGET_DEFAULT_H);
}
zori_widget_add_child(parent, widget);
zori_registry_add(the_zori_registry, widget->id, widget);
......
#include "zori_button.h"
#include "zori_console.h"
#include "zori_longtext.h"
#include "zori_menu.h"
......@@ -2,7 +2,31 @@
#include "zori_page.h"
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;
page = calloc(1, sizeof(*page));
if (!page) return NULL;
zori_widget_initall(&page->widget, id, parent,
NULL, NULL, 0, NULL);
return page;
}
zori_id zori_new_page(zori_id id, zori_id parent_id) {
struct zori_widget * parent = zori_get_widget(parent_id);
struct zori_page * page = zori_page_new(id, parent);
if (!page) return ZORI_ID_ENOMEM;
return page->widget.id;
}
......
#include "zori_root.h"
#include "zori.h"
#include "zori_page.h"
#include "zori_screen.h"
struct zori_screen * zori_widget_to_screen(struct zori_widget * widget) {
return ZORI_CONTAINER_OF(widget, struct zori_screen, widget);
}
int zori_screen_on_sysevent(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;
}
if (screen->active_page) {
return zori_widget_raise_sys_event(&screen->active_page->widget, &event->sys);
}
return ZORI_HANDLE_OK;
}
void zori_draw_cursor(const struct zori_cursor * cursor, const struct zori_style * style) {
if (cursor->bitmap) {
al_draw_bitmap(cursor->bitmap, cursor->p.x, cursor->p.y, 0);
} else {
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;
al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, style->fore.color);
}
};
void zori_draw_cursors(const struct zori_cursors * cursors, const struct zori_style * style) {
zori_draw_cursor(&cursors->keyjoy, style);
zori_draw_cursor(&cursors->mouse, style);
};
int zori_screen_on_draw(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;
}
/*
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 },
{ -1, NULL, NULL }
};
*/
struct zori_screen *
zori_screen_init(struct zori_screen * screen, zori_display * display) {
memset(&screen->cursors, 0, sizeof(screen->cursors));
screen->display = display;
screen->active_page = NULL;
return screen;
}
struct zori_screen * zori_screen_new(zori_id id, zori_display * display) {
struct zori_screen * screen = NULL; zori_rebox box;
box.at.x = 0;
......@@ -12,6 +82,10 @@ struct zori_screen * zori_screen_new(zori_id id, zori_display * display) {
box.size.y = al_get_display_height(display);
zori_widget_initall(&screen->widget, id, &zori_get_root()->widget,
&box, NULL, 0, NULL);
if (!zori_screen_init(screen, display)) {
free(screen);
screen = NULL;
}
return screen;
}
......@@ -23,6 +97,32 @@ 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));
if (!screen) {
return ZORI_ID_EINVAL;
}
if (!screen->active_page) {
return ZORI_ID_EINVAL;
}
return screen->active_page->widget.id;
}
zori_id zori_screen_go(zori_id screen_id, zori_id page_id, void * data) {
struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
struct zori_page * page = zori_widget_to_page(zori_get_widget(page_id));
if ((screen) && (page)) {
screen->active_page = page;
zori_widget_raise_action_event(&page->widget);
return page->widget.id;
} else {
return ZORI_ID_EINVAL;
}
}
#include "zori_widget.h"
/**
* This is a test for zori_button in $package$
*/
#include "si_test.h"
#include "zori_button.h"
TEST_FUNC(zori_button) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_button);
TEST_REPORT();
}
/**
* This is a test for zori_console in $package$
*/
#include "si_test.h"
#include "zori_console.h"
TEST_FUNC(zori_console) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_console);
TEST_REPORT();
}
/**
* This is a test for zori_longtext in $package$
*/
#include "si_test.h"
#include "zori_longtext.h"
TEST_FUNC(zori_longtext) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_longtext);
TEST_REPORT();
}
/**
* This is a test for zori_menu in $package$
*/
#include "si_test.h"
#include "zori_menu.h"
TEST_FUNC(zori_menu) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_menu);
TEST_REPORT();
}
/**
* This is a test for zori_root in $package$
*/
#include "si_test.h"
#include "zori_root.h"
TEST_FUNC(zori_root) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_root);
TEST_REPORT();
}
/**
* This is a test for zori_widget in $package$
*/
#include "si_test.h"
#include "zori_widget.h"
TEST_FUNC(zori_widget) {
TEST_DONE();
}
int main(void) {
TEST_INIT();
TEST_RUN(zori_widget);
TEST_REPORT();
}
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