|
@@ -1,6 +1,70 @@
|
|
#ifndef zori_H_INCLUDED
|
|
#ifndef zori_H_INCLUDED
|
|
#define zori_H_INCLUDED
|
|
#define zori_H_INCLUDED
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+* ZORI is a a GUI subsystem for use with Allegro 5 that handles
|
|
|
|
+* the user interface of Eruta.
|
|
|
|
+*
|
|
|
|
+* ZORI is a classic retained-mode GUI system that has an additional
|
|
|
|
+* pseudo-direct mode API. ZORI uses a handler system where events are handled
|
|
|
|
+* by call back functions which can be installed as specific handlers that are
|
|
|
|
+* activated on certain events. But, in the spirit of direct mode GUI's, all
|
|
|
|
+* widgets also keep state flags and value flags that can be used to see if they
|
|
|
|
+* have been activated and that can be inspected in a direct-mode GUI fashion.
|
|
|
|
+* With ZORI you can have your retained mode GUI pie and also eat it in direct
|
|
|
|
+* mode.
|
|
|
|
+*
|
|
|
|
+* In ZORI, there is only one top-level widget, the root, however, every widget
|
|
|
|
+* can contain any amount of child widgets. One level below the root widget are
|
|
|
|
+* the screen widgets which are intent to handle the GUI on one physical screen
|
|
|
|
+* or display. Every GUI page can have different "pages", but only one page
|
|
|
|
+* should be active per screen. The idea is that a GUI page represents a single
|
|
|
|
+* GUI mode such as the main menu, the settings menu, the in game menu, etc,
|
|
|
|
+* where you definitely want only one to be active at any given time.
|
|
|
|
+*
|
|
|
|
+* The box model used in Zori will be as follows (XXX implement this):
|
|
|
|
+* ......................................
|
|
|
|
+* .margin .
|
|
|
|
+* . +-------------border-----------+ .
|
|
|
|
+* . | padding | .
|
|
|
|
+* . | .......................... | .
|
|
|
|
+* . | . . | .
|
|
|
|
+* . | . contents . | .
|
|
|
|
+* . | . . | .
|
|
|
|
+* . | .......................... | .
|
|
|
|
+* . | padding | .
|
|
|
|
+* . +------------------------------+ .
|
|
|
|
+* .margin .
|
|
|
|
+* ......................................
|
|
|
|
+*
|
|
|
|
+* The padding determines the minimal distance between the border or the
|
|
|
|
+* parent widget and it's contents and/or child widgets.
|
|
|
|
+*
|
|
|
|
+* The border's thickness is only relevant for visual effects.
|
|
|
|
+* It does not change the layout. The border is effectively "inside"
|
|
|
|
+* the padding and/or contents of the widget and is unrelated to the padding.
|
|
|
|
+*
|
|
|
|
+* The margin of a widget determines how closely that widget may be packed
|
|
|
|
+* to it's sibling widgets.
|
|
|
|
+*
|
|
|
|
+* The work in UI is divided between the top-level widgets,
|
|
|
|
+* namely the root and the page, and the other widgets.
|
|
|
|
+* The root and the page handle everything that depends on and/or may influence
|
|
|
|
+* several widgets at once, such as event dispatching but also setting the
|
|
|
|
+* focus, determining which widget is being hovered, or dragged, etc.
|
|
|
|
+* The latter functions change the state of several widgets, so they
|
|
|
|
+* are handled on the level of the container widgets.
|
|
|
|
+* The zori_widget and the other concrete widgets handle the individual
|
|
|
|
+* state and actions of the various widgets individually.
|
|
|
|
+*
|
|
|
|
+
|
|
|
|
+*
|
|
|
|
+
|
|
|
|
+*
|
|
|
|
+*
|
|
|
|
+*/
|
|
|
|
+
|
|
|
|
+
|
|
#include <stdbool.h>
|
|
#include <stdbool.h>
|
|
#include "eruta.h"
|
|
#include "eruta.h"
|
|
#include "rebox.h"
|
|
#include "rebox.h"
|
|
@@ -50,6 +114,10 @@ typedef ALLEGRO_USTR zori_text;
|
|
#define ZORI_WIDGET_DEFAULT_W 640
|
|
#define ZORI_WIDGET_DEFAULT_W 640
|
|
#define ZORI_WIDGET_DEFAULT_H 480
|
|
#define ZORI_WIDGET_DEFAULT_H 480
|
|
|
|
|
|
|
|
+/* Defaut padding and margin. */
|
|
|
|
+#define ZORI_PADDING_DEFAULT 4
|
|
|
|
+#define ZORI_MARGIN_DEFAULT 0
|
|
|
|
+
|
|
/* Zori ID's. */
|
|
/* Zori ID's. */
|
|
#define ZORI_ID_OK_P(ID) ((ID) > -1)
|
|
#define ZORI_ID_OK_P(ID) ((ID) > -1)
|
|
#define ZORI_ID_OK ((zori_id)(0))
|
|
#define ZORI_ID_OK ((zori_id)(0))
|
|
@@ -74,20 +142,28 @@ typedef ALLEGRO_USTR zori_text;
|
|
and a pointer of a containing struct or union.
|
|
and a pointer of a containing struct or union.
|
|
*/
|
|
*/
|
|
#define ZORI_CONTAINER_OF(PTR, TYPE, MEMBER) \
|
|
#define ZORI_CONTAINER_OF(PTR, TYPE, MEMBER) \
|
|
- ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, MEMBER)))
|
|
|
|
|
|
+ ((PTR) ? ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, MEMBER))) : NULL)
|
|
|
|
|
|
|
|
|
|
/** Custom event types, used in conjunction with Allegro event types. */
|
|
/** Custom event types, used in conjunction with Allegro event types. */
|
|
enum zori_custom_event_type {
|
|
enum zori_custom_event_type {
|
|
ZORI_EVENT_CUSTOM = ALLEGRO_GET_EVENT_TYPE('z', 'o', 'r', 'i'),
|
|
ZORI_EVENT_CUSTOM = ALLEGRO_GET_EVENT_TYPE('z', 'o', 'r', 'i'),
|
|
|
|
+ /** Update event, called at regular intervals to update the state of the UI.*/
|
|
ZORI_EVENT_UPDATE,
|
|
ZORI_EVENT_UPDATE,
|
|
/** First draw pass. */
|
|
/** First draw pass. */
|
|
ZORI_EVENT_DRAW,
|
|
ZORI_EVENT_DRAW,
|
|
/** Second draw pass for cursors. */
|
|
/** Second draw pass for cursors. */
|
|
ZORI_EVENT_OVERDRAW,
|
|
ZORI_EVENT_OVERDRAW,
|
|
|
|
+ /** Cleanup event. */
|
|
ZORI_EVENT_DONE,
|
|
ZORI_EVENT_DONE,
|
|
|
|
+ /** Destruction event. */
|
|
ZORI_EVENT_FREE,
|
|
ZORI_EVENT_FREE,
|
|
|
|
+ /** Activation event, such as a button being clicked or a menu being opened. */
|
|
ZORI_EVENT_ACTION,
|
|
ZORI_EVENT_ACTION,
|
|
|
|
+ /** Close event, such as a menu being closed. Not for cleanup.*/
|
|
|
|
+ ZORI_EVENT_CLOSE,
|
|
|
|
+ /** Child added event to ease setup. */
|
|
|
|
+ ZORI_EVENT_NEW_CHILD,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -135,19 +211,35 @@ struct zori_action_event {
|
|
struct zori_any_event any;
|
|
struct zori_any_event any;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/* Close event. */
|
|
|
|
+struct zori_close_event {
|
|
|
|
+ struct zori_any_event any;
|
|
|
|
+ /* The widget that was closed and that sent this message to it's parent. */
|
|
|
|
+ struct zori_widget * from;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* New child event. */
|
|
|
|
+struct zori_new_child_event {
|
|
|
|
+ struct zori_any_event any;
|
|
|
|
+ /* The widget that was added as a child and that sent this message to it's parent. */
|
|
|
|
+ struct zori_widget * child;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
|
|
/** An event that ZORI can handle. The union is cunningly overlaid so
|
|
/** 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. */
|
|
* that the type field and the any field can be used in all cases. */
|
|
union zori_event {
|
|
union zori_event {
|
|
/* Type of the event, possibly copied from sysev. */
|
|
/* Type of the event, possibly copied from sysev. */
|
|
- zori_event_type type;
|
|
|
|
- struct zori_any_event any;
|
|
|
|
- struct zori_sys_event sys;
|
|
|
|
- struct zori_draw_event draw;
|
|
|
|
- struct zori_update_event update;
|
|
|
|
- struct zori_done_event done;
|
|
|
|
- struct zori_free_event free;
|
|
|
|
- struct zori_action_event action;
|
|
|
|
|
|
+ zori_event_type type;
|
|
|
|
+ struct zori_any_event any;
|
|
|
|
+ struct zori_sys_event sys;
|
|
|
|
+ struct zori_draw_event draw;
|
|
|
|
+ struct zori_update_event update;
|
|
|
|
+ struct zori_done_event done;
|
|
|
|
+ struct zori_free_event free;
|
|
|
|
+ struct zori_action_event action;
|
|
|
|
+ struct zori_close_event close;
|
|
|
|
+ struct zori_new_child_event new_child;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -195,7 +287,7 @@ static inline void * zori_event_set_data(union zori_event * event, void * data)
|
|
/* A style part is a color, image and font applied to a part of the GUI. */
|
|
/* A style part is a color, image and font applied to a part of the GUI. */
|
|
struct zori_stylepart {
|
|
struct zori_stylepart {
|
|
zori_color color;
|
|
zori_color color;
|
|
- zori_bitmap * image;
|
|
|
|
|
|
+ zori_bitmap * bitmap;
|
|
zori_font * font;
|
|
zori_font * font;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -205,6 +297,8 @@ struct zori_style {
|
|
struct zori_stylepart back;
|
|
struct zori_stylepart back;
|
|
struct zori_stylepart text;
|
|
struct zori_stylepart text;
|
|
struct zori_stylepart border;
|
|
struct zori_stylepart border;
|
|
|
|
+ struct zori_stylepart hover;
|
|
|
|
+ struct zori_stylepart mark;
|
|
};
|
|
};
|
|
|
|
|
|
struct zori_widget;
|
|
struct zori_widget;
|
|
@@ -218,7 +312,7 @@ enum zori_handle_result {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
-/* Returns whether or not a even needds to be propagated based on the
|
|
|
|
|
|
+/* Returns whether or not a event needs to be propagated based on the
|
|
* result of a handler. */
|
|
* result of a handler. */
|
|
static int zori_propagate_event_p(enum zori_handle_result result) {
|
|
static int zori_propagate_event_p(enum zori_handle_result result) {
|
|
switch(result) {
|
|
switch(result) {
|
|
@@ -227,7 +321,7 @@ static int zori_propagate_event_p(enum zori_handle_result result) {
|
|
case ZORI_HANDLE_IGNORE: return !0;
|
|
case ZORI_HANDLE_IGNORE: return !0;
|
|
case ZORI_HANDLE_PASS: return !0;
|
|
case ZORI_HANDLE_PASS: return !0;
|
|
default: return !0;
|
|
default: return !0;
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -254,7 +348,7 @@ struct zori_registry_entry {
|
|
/* A widget registry as a dynamic array of entries. */
|
|
/* A widget registry as a dynamic array of entries. */
|
|
struct zori_registry miao_of_type(struct zori_registry_entry);
|
|
struct zori_registry miao_of_type(struct zori_registry_entry);
|
|
|
|
|
|
-/* Generic flags for several zori structs. */
|
|
|
|
|
|
+/* Generic state flags for several zori structs. */
|
|
enum zori_flag {
|
|
enum zori_flag {
|
|
/* The object is not visible, though it may still be interacted with.*/
|
|
/* The object is not visible, though it may still be interacted with.*/
|
|
ZORI_FLAG_HIDDEN = 1 << 0,
|
|
ZORI_FLAG_HIDDEN = 1 << 0,
|
|
@@ -264,10 +358,20 @@ enum zori_flag {
|
|
ZORI_FLAG_DEACTIVATED = ZORI_FLAG_HIDDEN | ZORI_FLAG_DISABLED,
|
|
ZORI_FLAG_DEACTIVATED = ZORI_FLAG_HIDDEN | ZORI_FLAG_DISABLED,
|
|
/* The object is being hovered by the mouse cursor. */
|
|
/* The object is being hovered by the mouse cursor. */
|
|
ZORI_FLAG_HOVERED = 1 << 2,
|
|
ZORI_FLAG_HOVERED = 1 << 2,
|
|
- /* The object is "marked" for actovation by the keyjoy cursor */
|
|
|
|
|
|
+ /* The object is "marked" for activation by the keyjoy cursor */
|
|
ZORI_FLAG_MARKED = 1 << 3,
|
|
ZORI_FLAG_MARKED = 1 << 3,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/* Typedef for the type of a widget.
|
|
|
|
+ * Not an enum since every widget may define this itself.
|
|
|
|
+ */
|
|
|
|
+typedef uint32_t zori_widget_type;
|
|
|
|
+
|
|
|
|
+/* Generic widget types. */
|
|
|
|
+#define ZORI_WIDGET_TYPE_NONE ((zori_widget_type)(0))
|
|
|
|
+
|
|
|
|
+/* Macro to help generate widget types. */
|
|
|
|
+#define ZORI_WIDGET_TYPE(A, B, C, D) ((zori_widget_type)((A<<24) | (B<<16) | (C<<8) | D))
|
|
|
|
|
|
/* Mouse or keyboard/joystick cursor. */
|
|
/* Mouse or keyboard/joystick cursor. */
|
|
struct zori_cursor {
|
|
struct zori_cursor {
|
|
@@ -314,6 +418,13 @@ struct zori_widget {
|
|
|
|
|
|
/* Position and size of the widget. */
|
|
/* Position and size of the widget. */
|
|
zori_rebox box;
|
|
zori_rebox box;
|
|
|
|
+
|
|
|
|
+ /* Outer rectangle of the widget, with the margin added. */
|
|
|
|
+ zori_rebox outer;
|
|
|
|
+
|
|
|
|
+ /* Inner rectangle of the widget, with the padding removed. */
|
|
|
|
+ zori_rebox inner;
|
|
|
|
+
|
|
/* Z ordering. */
|
|
/* Z ordering. */
|
|
int z;
|
|
int z;
|
|
|
|
|
|
@@ -328,14 +439,20 @@ struct zori_widget {
|
|
struct zori_widget_list children;
|
|
struct zori_widget_list children;
|
|
|
|
|
|
/* Flags. */
|
|
/* Flags. */
|
|
- enum zori_flag flags;
|
|
|
|
|
|
+ enum zori_flag flags;
|
|
|
|
+
|
|
|
|
+ /* Type of the widget. */
|
|
|
|
+ zori_widget_type type;
|
|
|
|
+
|
|
|
|
+ /* Generic "result", of last operation on widget, normally zero. */
|
|
|
|
+ int result;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
/* An array of widget pointers. */
|
|
/* An array of widget pointers. */
|
|
struct zori_widget_array miao_of_type(struct zori_widget *);
|
|
struct zori_widget_array miao_of_type(struct zori_widget *);
|
|
|
|
|
|
-/* forward declarations. */
|
|
|
|
|
|
+/* Forward declarations. */
|
|
struct zori_screen;
|
|
struct zori_screen;
|
|
struct zori_console;
|
|
struct zori_console;
|
|
|
|
|
|
@@ -428,12 +545,15 @@ void zori_handlers_done(struct zori_handlers *me);
|
|
void zori_handlers_init(struct zori_handlers *me);
|
|
void zori_handlers_init(struct zori_handlers *me);
|
|
struct zori_handler *zori_handlers_search(struct zori_handlers *me, zori_event_type type);
|
|
struct zori_handler *zori_handlers_search(struct zori_handlers *me, zori_event_type type);
|
|
int zori_handlers_handle(struct zori_handlers *me, union zori_event *event);
|
|
int zori_handlers_handle(struct zori_handlers *me, union zori_event *event);
|
|
|
|
+
|
|
int zori_widget_raise_system_event(struct zori_widget *widget, zori_system_event *sysev);
|
|
int zori_widget_raise_system_event(struct zori_widget *widget, zori_system_event *sysev);
|
|
int zori_widget_raise_draw_event(struct zori_widget *widget);
|
|
int zori_widget_raise_draw_event(struct zori_widget *widget);
|
|
int zori_widget_raise_done_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_free_event(struct zori_widget *widget);
|
|
int zori_widget_raise_update_event(struct zori_widget *widget, double dt);
|
|
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_raise_action_event(struct zori_widget *widget);
|
|
|
|
+int zori_widget_raise_close_event(struct zori_widget *widget, struct zori_widget * from);
|
|
|
|
+
|
|
int zori_widget_compare(const void *v1, const void *v2);
|
|
int zori_widget_compare(const void *v1, const void *v2);
|
|
struct zori_widget *zori_get_widget(zori_id id);
|
|
struct zori_widget *zori_get_widget(zori_id id);
|
|
zori_id zori_get_unused_id(void);
|
|
zori_id zori_get_unused_id(void);
|
|
@@ -443,17 +563,21 @@ zori_id zori_start(struct zori_style *default_style);
|
|
struct zori_widget *zori_widget_done(struct zori_widget *widget);
|
|
struct zori_widget *zori_widget_done(struct zori_widget *widget);
|
|
void zori_widget_free(struct zori_widget *widget);
|
|
void zori_widget_free(struct zori_widget *widget);
|
|
struct zori_widget *zori_widget_add_child(struct zori_widget *parent, struct zori_widget *child);
|
|
struct zori_widget *zori_widget_add_child(struct zori_widget *parent, struct zori_widget *child);
|
|
-struct zori_widget *zori_widget_init(struct zori_widget *widget, zori_id id, struct zori_widget *parent, zori_rebox *box, struct zori_style *style);
|
|
|
|
|
|
+struct zori_widget *zori_widget_init(struct zori_widget *widget, zori_widget_type type, zori_id id, struct zori_widget *parent, zori_rebox *box, struct zori_style *style);
|
|
zori_id zori_shutdown(void);
|
|
zori_id zori_shutdown(void);
|
|
-struct zori_widget *zori_widget_initall(struct zori_widget *widget, zori_id id, struct zori_widget *parent, zori_rebox *box, struct zori_style *style, struct zori_handler *handlers, size_t amount);
|
|
|
|
|
|
+struct zori_widget *zori_widget_initall(struct zori_widget *widget, zori_widget_type type, zori_id id, struct zori_widget *parent, zori_rebox *box, struct zori_style *style, struct zori_handler *handlers, size_t amount);
|
|
void zori_draw_all(void);
|
|
void zori_draw_all(void);
|
|
|
|
+
|
|
int zori_widget_visible(struct zori_widget *widget);
|
|
int zori_widget_visible(struct zori_widget *widget);
|
|
|
|
+int zori_widget_visible_(struct zori_widget *widget, int set);
|
|
int zori_widget_active(struct zori_widget *widget);
|
|
int zori_widget_active(struct zori_widget *widget);
|
|
|
|
+int zori_widget_active_(struct zori_widget *widget, int set);
|
|
int zori_widget_hover(struct zori_widget *widget);
|
|
int zori_widget_hover(struct zori_widget *widget);
|
|
int zori_widget_hover_(struct zori_widget *widget, int set);
|
|
int zori_widget_hover_(struct zori_widget *widget, int set);
|
|
int zori_widget_marked(struct zori_widget *widget);
|
|
int zori_widget_marked(struct zori_widget *widget);
|
|
int zori_widget_marked_(struct zori_widget *widget, int set);
|
|
int zori_widget_marked_(struct zori_widget *widget, int set);
|
|
|
|
|
|
|
|
+
|
|
int zori_widget_active_(struct zori_widget *widget, int set);
|
|
int zori_widget_active_(struct zori_widget *widget, int set);
|
|
void zori_update(double dt);
|
|
void zori_update(double dt);
|
|
zori_font *zori_widget_font(struct zori_widget *widget);
|
|
zori_font *zori_widget_font(struct zori_widget *widget);
|
|
@@ -468,9 +592,13 @@ int zori_xy_inside_widget_p(struct zori_widget * widget, double x, double y);
|
|
|
|
|
|
void zori_widget_drawroundframe(struct zori_widget *self);
|
|
void zori_widget_drawroundframe(struct zori_widget *self);
|
|
|
|
|
|
-
|
|
|
|
int zori_handle_system_event(zori_system_event * sysev);
|
|
int zori_handle_system_event(zori_system_event * sysev);
|
|
|
|
|
|
|
|
+int zori_result(int zori_id);
|
|
|
|
+
|
|
|
|
+int zori_mark_widget(struct zori_widget * widget);
|
|
|
|
+
|
|
|
|
+
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|