From 75515ccad0e2622bc94d816dc14738d357747617 Mon Sep 17 00:00:00 2001 From: black Date: Sun, 11 Jan 2004 17:35:27 +0000 Subject: [PATCH] Hopefully finished the core of the new ui. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3801 d7cf8633-e32d-0410-b094-e92efae38249 --- ui.c | 547 +++++++++++++++-------------------------------------------- ui.h | 220 ++++++++++++++---------- 2 files changed, 267 insertions(+), 500 deletions(-) diff --git a/ui.c b/ui.c index d41b206f..a8b3b9ea 100644 --- a/ui.c +++ b/ui.c @@ -1,507 +1,236 @@ #include "quakedef.h" -/*cvar_t ui_showname = {0, "ui_showname", "0"}; +// here is the real ui drawing engine -#define ITEM_CLICKABLE 1 -#define ITEM_DRAWABLE 2 - -#define UIKEY_LEFT 1 -#define UIKEY_RIGHT 2 -#define UIKEY_UP 3 -#define UIKEY_DOWN 4 -#define UIKEY_ENTER 5 - -#define UI_MOUSEBUTTONS 3 - -static int ui_alive, ui_active; -static float ui_mouse_x, ui_mouse_y; -static int ui_mousebutton[UI_MOUSEBUTTONS], ui_mouseclick; -static int ui_keyui, ui_keyitem; -static ui_item_t *ui_keyrealitem; - -static ui_t *ui_list[MAX_UI_COUNT]; - -static void ui_start(void) -{ - ui_mouse_x = vid.conwidth * 0.5; - ui_mouse_y = vid.conheight * 0.5; - ui_alive = true; -} +#define FRAME_THICKNESS 2 +#define FRAME_COLOR1 0.2, 0.2, 0.5, 0, 0 +#define FRAME_COLOR2 0, 0, 0, 0.6, 0 +#define TEXT_FONTSIZE_X 10 +#define TEXT_FONTSIZE_Y 10 -static void ui_shutdown(void) +static void UIG_DrawFrame(float x, float y, float w, float h) { - ui_alive = false; -} + // bottom + DrawQ_Fill(x - FRAME_THICKNESS, y - FRAME_THICKNESS, w + 2 * FRAME_THICKNESS, FRAME_THICKNESS, FRAME_COLOR1); + // top + DrawQ_Fill(x - FRAME_THICKNESS, y + h, w + 2 * FRAME_THICKNESS, FRAME_THICKNESS, FRAME_COLOR1); + // left + DrawQ_Fill(x - FRAME_THICKNESS, y, FRAME_THICKNESS, h, FRAME_COLOR1); + // right + DrawQ_Fill(x + w, y, FRAME_THICKNESS, h, FRAME_COLOR1); + // area + DrawQ_Fill(x, y, w, h, FRAME_COLOR2); +} -static void ui_newmap(void) +static void UIG_DrawText(const char *text, float x, float y, float w, float h, float r, float g, float b, float a, float f) { + if(w != 0 && h != 0) + DrawQ_SetClipArea(x, y, w, h); + DrawQ_String(x, y, text, 0, TEXT_FONTSIZE_X, TEXT_FONTSIZE_Y, r, g, b, a, f); + if(w != 0 && h != 0) + DrawQ_ResetClipArea(); } -static mempool_t *uimempool; +#define UIG_DrawPicture DrawQ_Pic +#define UIG_Fill DrawQ_Fill -void ui_init(void) +static void UIG_DrawCursor(float x, float y, float r, float g, float b, float a, float f) { - uimempool = Mem_AllocPool("UI"); - - Cvar_RegisterVariable(&ui_showname); - - R_RegisterModule("UI", ui_start, ui_shutdown, ui_newmap); + DrawQ_Fill(x,y,1, TEXT_FONTSIZE_Y, r, g, b, a, f); } -void ui_mouseupdate(float x, float y) -{ - if (ui_alive) - { - ui_mouse_x = bound(0, x, vid.conwidth); - ui_mouse_y = bound(0, y, vid.conheight); - } -} +static mempool_t *ui_mem; -void ui_mouseupdaterelative(float x, float y) -{ - if (ui_alive) - { - ui_mouse_x += x; - ui_mouse_y += y; - ui_mouse_x = bound(0, ui_mouse_x, vid.conwidth); - ui_mouse_y = bound(0, ui_mouse_y, vid.conheight); - } -} +//#define UI_MEM_SIZE (1 << 10) << 9 // 512 KByte +#define UI_MEM_SIZE 1 -ui_t *ui_create(void) +void UI_Init(void) { - ui_t *ui; - ui = Mem_Alloc(uimempool, sizeof(*ui)); - if (ui == NULL) - Sys_Error("ui_create: unable to allocate memory for new ui\n"); - memset(ui, 0, sizeof(*ui)); - return ui; + ui_mem = Mem_AllocPool("Intern UI Memory"); } -void ui_free(ui_t *ui) -{ - if (ui) - Mem_Free(ui); -} +#define UI_Alloc(size) Mem_Alloc(ui_mem, size) +#define UI_Free(ptr) Mem_Free(ptr) -void ui_clear(ui_t *ui) +void UI_Event(ui_itemlist_t list, ui_message_t *in) { - ui->item_count = 0; -} + ui_message_queue_t out; + ui_item_t item; + int processed = true; -void ui_item -( - ui_t *ui, char *basename, int number, - float x, float y, char *picname, char *string, - float left, float top, float width, float height, - void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*enterkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*mouseclick)(void *nativedata1, void *nativedata2, float data1, float data2, float xfrac, float yfrac), - void *nativedata1, void *nativedata2, float data1, float data2 -) -{ - int i; - ui_item_t *it; - char itemname[32]; - snprintf(itemname, sizeof(itemname), "%s%04d", basename, number); - for (it = ui->items, i = 0;i < ui->item_count;it++, i++) - if (it->name == NULL || !strncmp(itemname, it->name, 32)) - break; - if (i == ui->item_count) - { - if (i == MAX_UI_ITEMS) + if(list->list) + for(item = list->list; item != 0 && !processed; item = item->next) { - Con_Printf("ui_item: ran out of UI item slots\n"); - return; - } - ui->item_count++; - } - memset(it, 0, sizeof(ui_item_t)); - strlcpy (it->name, itemname, sizeof (it->name)); - it->flags = 0; - if (picname || string) - { - it->flags |= ITEM_DRAWABLE; - it->draw_picname = picname; - it->draw_string = string; - it->draw_x = x; - it->draw_y = y; - } - if (leftkey || rightkey || enterkey || mouseclick) - { - it->flags |= ITEM_CLICKABLE; - it->click_x = x + left; - it->click_y = y + top; - it->click_x2 = it->click_x + width; - it->click_y2 = it->click_y + height; - it->leftkey = leftkey; - it->rightkey = rightkey; - it->enterkey = enterkey; - it->mouseclick = mouseclick; - if (it->mouseclick == NULL) - it->mouseclick = (void *)it->enterkey; - if (it->leftkey == NULL) - it->leftkey = it->enterkey; - if (it->rightkey == NULL) - it->rightkey = it->enterkey; - it->nativedata1 = nativedata1; - it->nativedata2 = nativedata2; - } -} - -void ui_item_remove(ui_t *ui, char *basename, int number) -{ - int i; - ui_item_t *it; - char itemname[32]; - snprintf(itemname, sizeof(itemname), "%s%04d", basename, number); - for (it = ui->items, i = 0;i < ui->item_count;it++, i++) - if (it->name && !strncmp(itemname, it->name, 32)) - break; - if (i < ui->item_count) - it->name[0] = 0; -} + unsigned int i; + + processed = item->eventhandler(list, item, in, &out); + + // process posted messages + for(i = 0; i < out.used; i++) + list->eventhandler(list, &out.queue[i]); + + if(in->type == UI_EVENT_FRAME) + processed = false; + } -ui_item_t *ui_hititem(float x, float y) -{ - int i, j; - ui_item_t *it; - ui_t *ui; - for (j = 0;j < MAX_UI_COUNT;j++) - if ((ui = ui_list[j])) - for (it = ui->items, i = 0;i < ui->item_count;it++, i++) - if (it->name[0] && (it->flags & ITEM_CLICKABLE)) - if (x >= it->click_x && y >= it->click_y && x < it->click_x2 && y < it->click_y2) - return it; - return NULL; + if(!processed) + list->eventhandler(list, in); } -int ui_uiactive(ui_t *ui) +void UI_Draw(ui_itemlist_t list) { - int i; - for (i = 0;i < MAX_UI_COUNT;i++) - if (ui_list[i] == ui) - return true; - return false; -} + // firstly we create the frame event here + ui_message_t msg; + ui_item_t item; -void ui_activate(ui_t *ui, int yes) -{ - int i; - if (yes) - { - if (ui_uiactive(ui)) - return; + msg.type = UI_EVENT_FRAME; - for (i = 0;i < MAX_UI_COUNT;i++) - { - if (ui_list[i] == NULL) - { - ui_list[i] = ui; - return; - } - } + UI_Event(list, &msg); - Con_Printf("ui_activate: ran out of active ui list items\n"); - } - else + // now draw everything + if(list->list) { - for (i = 0;i < MAX_UI_COUNT;i++) + unsigned int depth = 0, nextdepth = ~0; + + while(depth != nextdepth) { - if (ui_list[i] == ui) + for(item = list->list; item != 0; item = item->next) { - ui_list[i] = NULL; - return; + if(item->zorder == depth) + item->draw(list, item); + if(item->zorder > depth && item->zorder < nextdepth) + nextdepth = item->zorder; } + depth = nextdepth; + nextdepth = ~0; } } } -int ui_isactive(void) +void UI_Mouse(ui_itemlist_t list, float x, float y) { - int j; - ui_t *ui; - if (ui_alive) - { - for (j = 0;j < MAX_UI_COUNT;j++) - if ((ui = ui_list[j])) - if (ui->item_count) - return true; - } - return false; -} + ui_message_t msg; -#define UI_QUEUE_SIZE 256 -static qbyte ui_keyqueue[UI_QUEUE_SIZE]; -static int ui_keyqueuepos = 0; + msg.type = UI_EVENT_MOUSE; -void ui_leftkeyupdate(int pressed) -{ - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_LEFT; - key = pressed; -} + msg.data.mouse.x = x; + msg.data.mouse.y = y; -void ui_rightkeyupdate(int pressed) -{ - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_RIGHT; - key = pressed; + UI_Event(list, &msg); } -void ui_upkeyupdate(int pressed) +void UI_Key(ui_itemlist_t list, int key, int ascii) { - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_UP; - key = pressed; -} + ui_message_t msg; -void ui_downkeyupdate(int pressed) -{ - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_DOWN; - key = pressed; + msg.type = UI_EVENT_KEY; + + msg.data.key.key = key; + msg.data.key.ascii = ascii; + + UI_Event(list, &msg); } -void ui_mousebuttonupdate(int button, int pressed) + +// item stuff +ui_item_t UI_CloneItem(ui_item_t item) { - if (button < 0 || button >= UI_MOUSEBUTTONS) - return; - if (button == 0 && ui_mousebutton[button] && !pressed) - ui_mouseclick = true; - ui_mousebutton[button] = pressed; + ui_item_t clone; + clone = UI_Alloc(item->size); + clone = memcpy(clone, item, item->size); + + return clone; } -void ui_update(void) +ui_item_t UI_FindItemByName(ui_itemlist_t list, const char *name) { - ui_item_t *startitem, *it; - if (ui_alive) - { - ui_mouse_x = bound(0, ui_mouse_x, vid.conwidth); - ui_mouse_y = bound(0, ui_mouse_y, vid.conheight); - - if ((ui_active = ui_isactive())) - { - // validate currently selected item - if(ui_list[ui_keyui] == NULL) - { - while (ui_list[ui_keyui] == NULL) - ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT; - ui_keyitem = 0; - } - ui_keyitem = bound(0, ui_keyitem, ui_list[ui_keyui]->item_count - 1); - startitem = ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem]; - if ((ui_keyrealitem->flags & ITEM_CLICKABLE) == 0) - { - do - { - // FIXME: cycle through UIs as well as items in a UI - ui_keyitem = (ui_keyitem - 1) % ui_list[ui_keyui]->item_count - 1; - ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem]; - } - while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0); - } + ui_item_t item, found = 0; - if (ui_keyqueuepos) + if(list->list) + for(item = list->list; item != 0; item = item->next) + if(!strcmp(name, item->name)) { - int i; - for (i = 0;i < ui_keyqueuepos;i++) - { - startitem = ui_keyrealitem; - switch(ui_keyqueue[i]) - { - case UIKEY_UP: - do - { - ui_keyitem--; - if (ui_keyitem < 0) - { - do - ui_keyui = (ui_keyui - 1) % MAX_UI_COUNT; - while(ui_list[ui_keyui] == NULL); - ui_keyitem = ui_list[ui_keyui]->item_count - 1; - } - ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem]; - } - while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0); - break; - case UIKEY_DOWN: - do - { - ui_keyitem++; - if (ui_keyitem >= ui_list[ui_keyui]->item_count) - { - do - ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT; - while(ui_list[ui_keyui] == NULL); - ui_keyitem = 0; - } - ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem]; - } - while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0); - break; - case UIKEY_LEFT: - if (ui_keyrealitem->leftkey) - ui_keyrealitem->leftkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2); - break; - case UIKEY_RIGHT: - if (ui_keyrealitem->rightkey) - ui_keyrealitem->rightkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2); - break; - case UIKEY_ENTER: - if (ui_keyrealitem->enterkey) - ui_keyrealitem->enterkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2); - break; - } - } + found = item; + break; } - ui_keyqueuepos = 0; - if (ui_mouseclick && (it = ui_hititem(ui_mouse_x, ui_mouse_y)) && it->mouseclick) - it->mouseclick(it->nativedata1, it->nativedata2, it->data1, it->data2, ui_mouse_x - it->click_x, ui_mouse_y - it->click_y); - } - } - ui_mouseclick = false; + return found; } -void ui_draw(void) +void UI_FreeItem(ui_itemlist_t list, ui_item_t item) { - int i, j; - ui_item_t *it; - ui_t *ui; - if (ui_alive && ui_active) + if(!item->prev) { - for (j = 0;j < MAX_UI_COUNT;j++) - if ((ui = ui_list[j])) - if (ui->item_count) - for (i = 0, it = ui->items;i < ui->item_count;i++, it++) - if (it->flags & ITEM_DRAWABLE) - { - if (it->draw_picname) - DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, 0); - if (it->draw_string) - DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, 0); - } - - if ((it = ui_hititem(ui_mouse_x, ui_mouse_y))) - { - if (it->draw_picname) - DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); - if (it->draw_string) - DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); - if (ui_showname.integer) - DrawQ_String(ui_mouse_x, ui_mouse_y + 16, it->name, 0, 8, 8, 1, 1, 1, 1, 0); - } - - it = ui_keyrealitem; - if (it->draw_picname) - DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); - if (it->draw_string) - DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); - - DrawQ_Pic(ui_mouse_x, ui_mouse_y, "ui/mousepointer.tga", 0, 0, 1, 1, 1, 1, 0); + // this is the first item + list->list = item->next; } -}*/ -#define FRAME_THICKNESS 2 -#define FRAME_COLOR1 0.2, 0.2, 0.5, 0, 0 -#define FRAME_COLOR2 0, 0, 0, 0.6, 0 -#define TEXT_FONTSIZE 10, 10 - -#if 0 -static void UIG_DrawFrame(float x, float y, float w, float h) -{ - // bottom - DrawQ_Fill(x - FRAME_THICKNESS, y - FRAME_THICKNESS, w + 2 * FRAME_THICKNESS, FRAME_THICKNESS, FRAME_COLOR1); - // top - DrawQ_Fill(x - FRAME_THICKNESS, y + h, w + 2 * FRAME_THICKNESS, FRAME_THICKNESS, FRAME_COLOR1); - // left - DrawQ_Fill(x - FRAME_THICKNESS, y, FRAME_THICKNESS, h, FRAME_COLOR1); - // right - DrawQ_Fill(x + w, y, FRAME_THICKNESS, h, FRAME_COLOR1); - // area - DrawQ_Fill(x, y, w, h, FRAME_COLOR2); -} + item->prev->next = item->next; + item->next->prev = item->prev; -static void UIG_DrawText(const char *text, float x, float y, float w, float h, float r, float g, float b, float a, float f) -{ - if(w != 0 && h != 0) - DrawQ_SetClipArea(x, y, w, h); - DrawQ_String(x, y, text, 0, TEXT_FONTSIZE, r, g, b, a , f); - if(w != 0 && h != 0) - DrawQ_ResetClipArea(); + UI_Free(item); } -#endif -void UI_Init(void) +void UI_FreeItemByName(ui_itemlist_t list, const char *name) { -} + ui_item_t item; -void UI_Key(ui_itemlist_t list, int key, int ascii) -{ + item = UI_FindItemByName(list, name); + if(item) + UI_Free(item); } -void UI_Draw(ui_itemlist_t list) -{ -} -void UI_SetFocus(ui_itemlist_t list, ui_item_t item) +// itemlist stuff +ui_itemlist_t UI_CreateItemList(void) { + return UI_Alloc(sizeof(ui_itemlist_t)); } -void UI_SetNeighbors(ui_item_t left, ui_item_t right, ui_item_t up, ui_item_t down) +ui_itemlist_t UI_CloneItemList(ui_itemlist_t list) { -} + ui_itemlist_t clone; + ui_item_t item; -// item stuff -ui_item_t UI_CreateButton(const char *caption, float x, float y, void(*action)(ui_item_t)) -{ - return NULL; -} + clone = UI_CreateItemList(); -ui_item_t UI_CreateLabel(const char *caption, float x, float y) -{ - return NULL; -} + if(list->list) + for(item = list->list; item != 0; item = item->next) + UI_AddItem(clone, UI_CloneItem(item)); -ui_item_t UI_CreateText(const char *caption, float x, float y, const char *allowed, int maxlen, int scrolllen) -{ - return NULL; + return clone; } -void UI_FreeItem(ui_item_t item) -{ -} -const char* UI_GetCaption(ui_item_t item) +void UI_FreeItemList(ui_itemlist_t list) { - return NULL; + UI_Free((void*)list); } -void UI_SetCaption(ui_item_t item, const char * caption) +void UI_AddItem(ui_itemlist_t list, ui_item_t item) { + item->prev = 0; + item->next = list->list; + list->list->prev = item; + list->list = item; } -// itemlist stuff -ui_itemlist_t UI_CreateItemList(float x, float y) +// controls +ui_item_t UI_CreateButton(void) { return NULL; } -void UI_FreeItemList(ui_itemlist_t list) +ui_item_t UI_CreateLabel(void) { + return NULL; } -void UI_AddItem(ui_itemlist_t list, ui_item_t item) +ui_item_t UI_CreateText(void) { + return NULL; } - // AK: callback system stuff static ui_callback_t ui_callback_list[UI_MAX_CALLBACK_COUNT]; diff --git a/ui.h b/ui.h index b73c6e40..1f20e185 100644 --- a/ui.h +++ b/ui.h @@ -1,112 +1,150 @@ #ifndef UI_H #define UI_H -/* -// these defines and structures are for internal use only -// (ui_t is passed around by users of the system, but should not be altered) -#define MAX_UI_COUNT 16 -#define MAX_UI_ITEMS 256 -typedef struct +// AK: new passive ui (like the menu stuff) +/* some ideas: +1. two different structs (one for the ui core code and one for the rest) +2. each item has a size field +*/ + +#define UI_EVENT_QUEUE_SIZE 32 + +typedef enum { UI_BUTTON, UI_LABEL } ui_control_type; + +typedef struct ui_message_s ui_message_t; +typedef struct ui_item_s *ui_item_t; +typedef struct ui_itemlist_s *ui_itemlist_t; +typedef struct ui_message_queue_s ui_message_queue_t; + +struct ui_item_s { - char name[32]; - int flags; - char *draw_picname; - char *draw_string; - int draw_x, draw_y; - int click_x, click_y, click_x2, click_y2; - void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2); - void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2); - void(*enterkey)(void *nativedata1, void *nativedata2, float data1, float data2); - void(*mouseclick)(void *nativedata1, void *nativedata2, float data1, float data2, float xfrac, float yfrac); - void *nativedata1, *nativedata2; - float data1, data2; -} -ui_item_t; - -typedef struct + unsigned int size; + + ui_control_type type; + + const char *name; // used for debugging purposes and to identify an object + +//private: + // used to build the item list + struct ui_item_s *prev, *next; // items are allowed to be freed everywhere + + // called for system events (true means message processed) + int (*eventhandler)(ui_itemlist_t list, ui_item_t self, ui_message_t *in, ui_message_queue_t *out); + + // z-order (the higher, the later it is drawn) + unsigned int zorder; + + // called to draw the object + void (*draw)(ui_itemlist_t list, struct ui_item_s * self); + +}; + +struct ui_message_s; + +struct ui_itemlist_s { - int item_count; - int pad; - ui_item_t items[MAX_UI_ITEMS]; -} -ui_t; - -// engine use: -// initializes the ui system -void ui_init(void); -// updates the mouse position, given an absolute loation (some input systems use this) -void ui_mouseupdate(float x, float y); -// updates the mouse position, by an offset from the previous location (some input systems use this) -void ui_mouseupdaterelative(float x, float y); -// left key update -void ui_leftkeyupdate(int pressed); -// right key update -void ui_rightkeyupdate(int pressed); -// up key update -void ui_upkeyupdate(int pressed); -// down key update -void ui_downkeyupdate(int pressed); -// mouse button update (note: 0 = left, 1 = right, 2 = middle, 3+ not supported yet) -void ui_mousebuttonupdate(int button, int pressed); -// perform input updates and check for clicks on items (note: calls callbacks) -void ui_update(void); -// draw all items of all panels -void ui_draw(void); - -// intentionally public functions: -// creates a panel -ui_t *ui_create(void); -// frees a panel -void ui_free(ui_t *ui); -// empties a panel, removing all the items -void ui_clear(ui_t *ui); -// sets an item in a panel (adds or replaces the item) -void ui_item -( - ui_t *ui, char *basename, int number, - float x, float y, char *picname, char *string, - float left, float top, float width, float height, - void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*enterkey)(void *nativedata1, void *nativedata2, float data1, float data2), - void(*mouseclick)(void *nativedata1, void *nativedata2, float data1, float data2, float xfrac, float yfrac), - void *nativedata1, void *nativedata2, float data1, float data2 -); -// removes an item from a panel -void ui_item_remove(ui_t *ui, char *basename, int number); -// checks if a panel is enabled -int ui_uiactive(ui_t *ui); -// enables/disables a panel on the screen -void ui_activate(ui_t *ui, int yes);*/ + float org_x, org_y; -// AK: new passive ui (like the menu stuff) -#define UI_TEXT_DEFAULT_LENGTH 255 -typedef void * ui_item_t; -typedef void * ui_itemlist_t; + ui_item_t selected; + + void (*eventhandler)(struct ui_itemlist_s * list, struct ui_message_s *msg); + +// private: + ui_item_t list; +}; + +// this is structure contains *all* possible messages +enum ui_message_type_e { UI_EVENT_FRAME, UI_EVENT_KEY, UI_EVENT_MOUSE, UI_BUTTON_PRESSED }; + +struct ui_ev_key_s +{ + int key, ascii; +}; + +// in_mouse_x and in_mouse_y can be also used... +struct ui_ev_mouse_s +{ + float x, y; +}; + +union ui_message_data_u +{ + unsigned char reserved; + struct ui_ev_key_s key; + struct ui_ev_mouse_s mouse; +}; + +struct ui_message_s +{ + // empty for input messages, but contains a valid item for all other events + ui_item_t target; + + // used to determine which data struct was used + enum ui_message_type_e type; + + union ui_message_data_u data; +}; + +struct ui_message_queue_s +{ + unsigned int used; + ui_message_t queue[UI_EVENT_QUEUE_SIZE]; +}; void UI_Init(void); -void UI_Key(ui_itemlist_t, int key, int ascii); -void UI_Draw(ui_itemlist_t); +#define UI_MOUSEEVENT 1 +#define UI_KEYEVENT 2 +#define UI_FRAME 4 +void UI_Draw(ui_itemlist_t list); -void UI_SetFocus(ui_itemlist_t, ui_item_t); -void UI_SetNeighbors(ui_item_t left, ui_item_t right, ui_item_t up, ui_item_t down); +void UI_Mouse(ui_itemlist_t list, float x, float y); +void UI_Key(ui_itemlist_t list, int key, int ascii); // item stuff -ui_item_t UI_CreateButton(const char *caption, float x, float y, void(*action)(ui_item_t)); -ui_item_t UI_CreateLabel(const char *caption, float x, float y); -ui_item_t UI_CreateText(const char *caption, float x, float y, const char *allowed, int maxlen, int scrolllen); -void UI_FreeItem(ui_item_t); +#define UI_ITEM(item) ((ui_item_t*)item) + +ui_item_t UI_CloneItem(ui_item_t); + +ui_item_t UI_FindItemByName(ui_itemlist_t, const char *); -const char* UI_GetCaption(ui_item_t); -void UI_SetCaption(ui_item_t, const char *); +void UI_FreeItem(ui_itemlist_t, ui_item_t); +void UI_FreeItemByName(ui_itemlist_t, const char *); // itemlist stuff -ui_itemlist_t UI_CreateItemList(float x, float y); +ui_itemlist_t UI_CreateItemList(); +ui_itemlist_t UI_CloneItemList(ui_itemlist_t); void UI_FreeItemList(ui_itemlist_t); -void UI_AddItem(ui_itemlist_t, ui_item_t); +void UI_AddItem(ui_itemlist_t list, ui_item_t item); + +// controls +#define UI_TEXT_DEFAULT_LENGTH 255 + +typedef struct ui_button_s *ui_button_t; +typedef struct ui_label_s *ui_label_t; +typedef struct ui_text_s *ui_text_t; + +struct ui_label_t +{ + struct ui_item_s item; + + const char *text; + float x, y; + float r, g, b, a, f; +}; + +struct ui_button +{ + struct ui_item_s item; + + const char *caption; +}; + +ui_item_t UI_CreateButton(void); +ui_item_t UI_CreateLabel(void); +ui_item_t UI_CreateText(void); // AK: new callback system #define UI_MAX_CALLBACK_COUNT 10 -- 2.39.2