#ifndef zori_H_INCLUDED #define zori_H_INCLUDED #include "eruta.h" #include "rebox.h" #include "miao.h" /* Typedefs for possible later portability. */ typedef ALLEGRO_COLOR zori_color; typedef ALLEGRO_BITMAP zori_bitmap; typedef ALLEGRO_FONT zori_font; typedef ALLEGRO_EVENT zori_system_event; typedef ALLEGRO_EVENT_TYPE zori_event_type; typedef ALLEGRO_DISPLAY zori_display; typedef Point zori_point; typedef Rebox zori_rebox; typedef int zori_id; #define ZORI_ID_OK_P(ID) ((ID) > -1) #define ZORI_ID_OK ((zori_id)(0)) #define ZORI_ID_ERROR ((zori_id)(-1)) #define ZORI_ID_ENOMEM ((zori_id)(-2)) #define ZORI_ID_EINVAL ((zori_id)(-3)) /* Macro: ZORI_CONTAINER_OF(PTR, TYPE, MEMBER) This macro returns, for the given pointer, a pointer to a containing struct of type TYPE, in which PTR is a member named MEMBER. This enables cool ways of type genericity and extension in plain C. It does not run afoul of strict aliasing since it passes over a char * pointer and a pointer of a containing struct or union. */ #define ZORI_CONTAINER_OF(PTR, TYPE, MEMBER) \ ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, MEMBER))) /** Custom event types, used in conjunction with Allegro event types. */ enum zori_custom_event_type { ZORI_EVENT_CUSTOM = ALLEGRO_GET_EVENT_TYPE('z', 'o', 'r', 'i'), ZORI_EVENT_UPDATE, ZORI_EVENT_DRAW, }; struct zori_widget; struct zori_event { zori_system_event sysev; struct zori_widget * widget; void * data; }; struct zori_stylepart { zori_color color; zori_bitmap * image; zori_font * font; }; struct zori_style { struct zori_stylepart fore; struct zori_stylepart back; struct zori_stylepart text; struct zori_stylepart border; }; struct zori_widget; typedef int zori_handler_func(struct zori_event * event); /* A single event handler */ struct zori_handler { zori_event_type type; zori_handler_func * handler; void * data; }; /* A dynamic array of event handlers event handlers. */ struct zori_handlers miao_of_type(struct zori_handler); /* An entry in a widget registry. */ struct zori_registry_entry { zori_id id; struct zori_widget * widget; }; /* A widget registry as a dynamic array of entries. */ struct zori_registry miao_of_type(struct zori_registry_entry); /* Generic flags for several zori structs. */ enum zori_flag { /* The object is not visible, though it may still be interacted with.*/ ZORI_FLAG_HIDDEN = 1 << 0, /* The object cannot be interacted with, though it is still visible. */ ZORI_FLAG_DISABLED = 1 << 1, /* The object is both hidden and disabled. */ ZORI_FLAG_DEACTIVATED = ZORI_FLAG_HIDDEN | ZORI_FLAG_DISABLED, }; /* Mouse or keyboard/joystick cursor. */ struct zori_cursor { zori_point p; struct zori_widget * hover; struct zori_widget * focus; zori_bitmap * bitmap; enum zori_flag flags; }; /* Support multiple cursors... */ struct zori_cursors { struct zori_cursor mouse; struct zori_cursor keyjoy; }; /* on_enter on_enter(data = {}) on_event(*args) on_event(*data) on_key_down(*args) on_leave(name=nil) on_mouse_axes(t, x, y, z, w, dx, dy, dz, dw) on_mouse_button_down(t, x, y, z, w, b) on_mouse_button_up(t, x, y, z, w, b) on_mouse_in(x, y, from) on_mouse_out(x, y, to) on_resize */ struct zori_widget { /* ID of the widget, used in most external API's. */ zori_id id; /* Root level widget under which this widget is active. */ struct zori_widget * root; /* Position and size of the widget. */ zori_rebox box; /* Z ordering. */ int z; /* Style. */ struct zori_style style; /* Handlers. */ struct zori_handlers handlers; /* Related widgets. */ struct zori_widget * parent; struct zori_widget * child; struct zori_widget * sibling; /* Flags. */ enum zori_flag flags; }; /* An array of widget pointers. */ struct zori_widget_array miao_of_type(struct zori_widget *); /* forward declaration. */ struct zori_screen; /* * Root level widget, my spread out over several displays. * In Zori, there can only be a single root level widget active. * It's ID is always 0; */ struct zori_root { /* A root is a widget. */ struct zori_widget widget; /* It has an array of all GUI widgets it manages. */ struct zori_widget_array * widgets; /* Current active screen widget if any. */ struct zori_screen * active_screen; }; /* Forward declaration of a page. */ struct zori_page; /* The top level widget for a single display. */ struct zori_screen { /* A screen is a widget. */ struct zori_widget widget; /* It also manages the cursors. */ struct zori_cursors cursors; /* Display this screen is on. */ zori_display * display; /* The GUI page that is active on this screen if any. */ struct zori_page * active_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; }; /* Initializes Zori and creates a top level widget. Returns 0 on success * or negative on error. The style will be copied and set as default * if it is not NULL. Otherwise a built-in style will be used. * Not that ZORI will NOT clean up any images or fonts it uses by itself. */ zori_id zori_start(struct zori_style * default_style); /* Shut down Zori and destroys all widgets. Return 0 on succes or * negative on error. */ zori_id zori_shutdown(); /* Creates a new screen widget. Normally this should be the first widget * you create after zori_start. */ zori_id zori_new_screen(zori_display * display); /* 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); /* Creates a new generic widget on the given screen with the given * dimensions. */ zori_id zori_new(zori_id screen, zori_rebox * box); /* Sets the flags of a widget. */ zori_id zori_set_flags(zori_id widget, enum zori_flag flags); /* Sets the whole style of a widget. */ zori_id zori_set_style(zori_id id, struct zori_style * style); /* Sets the background color of the widget. */ zori_id zori_set_background_color(zori_id id, zori_color color); /* Sets the foreground color of the widget. */ zori_id zori_set_foreground_color(zori_id id, zori_color color); /* Creates a new frame widget. */ zori_id zori_new_frame_widget(zori_id parent, zori_rebox box); /* Creates a new (vertical) menu widget. */ zori_id zori_new_menu_widget(zori_id parent, zori_rebox box, char * text); /* Creates a new button widget. */ 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 whole UI and all visible parts. */ void zori_draw_all(void); /* Updates the state of the UI. Pass in the time passed since last update. */ void zori_update(double dt); /* Registers an event handler for a widget. */ zori_id zori_register(zori_id id, zori_event_type type, zori_handler_func handler, void * extra); #endif