X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=ui.c;h=1e4ed791c8bafaad9d5e733f30d5bf82e6e6122a;hb=d39f8c7e0427be77cc7dfa504fee8cbccf1684f6;hp=bb9398e2cbd9ccca67776e574bc4ba44405c5c6a;hpb=fc83bfe29745415b7ab325a045d637d901450b22;p=xonotic%2Fdarkplaces.git diff --git a/ui.c b/ui.c index bb9398e2..1e4ed791 100644 --- a/ui.c +++ b/ui.c @@ -1,411 +1,283 @@ #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 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 -#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 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); +} -static void ui_start(void) -{ - ui_mouse_x = vid.conwidth * 0.5; - ui_mouse_y = vid.conheight * 0.5; - ui_alive = true; +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 void ui_shutdown(void) +#define UIG_DrawPicture DrawQ_Pic +#define UIG_Fill DrawQ_Fill + +static void UIG_DrawCursor(float x, float y, float r, float g, float b, float a, float f) { - ui_alive = false; + DrawQ_Fill(x,y,1, TEXT_FONTSIZE_Y, r, g, b, a, f); } +*/ + +//#define UI_MEM_SIZE (1 << 10) << 9 // 512 KByte +#define UI_MEM_SIZE 1 -static void ui_newmap(void) +void UI_Init(void) { } -static mempool_t *uimempool; +#define UI_Alloc(size) Mem_Alloc(cl_mempool, size) +#define UI_Free(ptr) Mem_Free(ptr) -void ui_init(void) +void UI_Event(ui_itemlist_t list, ui_message_t *in) { - uimempool = Mem_AllocPool("UI"); + ui_message_queue_t out; + ui_item_t item; + int processed = true; + + if(list->list) + for(item = list->list; item != 0 && !processed; item = item->next) + { + 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]); - Cvar_RegisterVariable(&ui_showname); + if(in->type == UI_EVENT_FRAME) + processed = false; + } - R_RegisterModule("UI", ui_start, ui_shutdown, ui_newmap); + if(!processed) + list->eventhandler(list, in); } -void ui_mouseupdate(float x, float y) +void UI_Draw(ui_itemlist_t list) { - if (ui_alive) + // firstly we create the frame event here + ui_message_t msg; + ui_item_t item; + + msg.type = UI_EVENT_FRAME; + + UI_Event(list, &msg); + + // now draw everything + if(list->list) { - ui_mouse_x = bound(0, x, vid.conwidth); - ui_mouse_y = bound(0, y, vid.conheight); + unsigned int depth = 0, nextdepth = ~0; + + while(depth != nextdepth) + { + for(item = list->list; item != 0; item = item->next) + { + if(item->zorder == depth) + item->draw(list, item); + if(item->zorder > depth && item->zorder < nextdepth) + nextdepth = item->zorder; + } + depth = nextdepth; + nextdepth = ~0; + } } } -void ui_mouseupdaterelative(float x, float y) +void UI_Mouse(ui_itemlist_t list, 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); - } + ui_message_t msg; + + msg.type = UI_EVENT_MOUSE; + + msg.data.mouse.x = x; + msg.data.mouse.y = y; + + UI_Event(list, &msg); } -ui_t *ui_create(void) +void UI_Key(ui_itemlist_t list, int key, int ascii) { - 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_message_t msg; + + msg.type = UI_EVENT_KEY; + + msg.data.key.key = key; + msg.data.key.ascii = ascii; + + UI_Event(list, &msg); } -void ui_free(ui_t *ui) + +// item stuff +ui_item_t UI_CloneItem(ui_item_t item) { - if (ui) - Mem_Free(ui); + ui_item_t clone; + clone = UI_Alloc(item->size); + clone = memcpy(clone, item, item->size); + + return clone; } -void ui_clear(ui_t *ui) +ui_item_t UI_FindItemByName(ui_itemlist_t list, const char *name) { - ui->item_count = 0; + ui_item_t item, found = 0; + + if(list->list) + for(item = list->list; item != 0; item = item->next) + if(!strcmp(name, item->name)) + { + found = item; + break; + } + + return found; } -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 -) +void UI_FreeItem(ui_itemlist_t list, ui_item_t item) { - 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(!item->prev) { - if (i == MAX_UI_ITEMS) - { - 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; + // this is the first item + list->list = item->next; } - 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; + item->prev->next = item->next; + item->next->prev = item->prev; + + UI_Free(item); } -ui_item_t *ui_hititem(float x, float y) +void UI_FreeItemByName(ui_itemlist_t list, const char *name) { - 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; + ui_item_t item; + + item = UI_FindItemByName(list, name); + if(item) + UI_Free(item); } -int ui_uiactive(ui_t *ui) + +// itemlist stuff +ui_itemlist_t UI_CreateItemList(void) { - int i; - for (i = 0;i < MAX_UI_COUNT;i++) - if (ui_list[i] == ui) - return true; - return false; + return UI_Alloc(sizeof(ui_itemlist_t)); } -void ui_activate(ui_t *ui, int yes) +ui_itemlist_t UI_CloneItemList(ui_itemlist_t list) { - int i; - if (yes) - { - if (ui_uiactive(ui)) - return; + ui_itemlist_t clone; + ui_item_t item; - for (i = 0;i < MAX_UI_COUNT;i++) - { - if (ui_list[i] == NULL) - { - ui_list[i] = ui; - return; - } - } + clone = UI_CreateItemList(); - Con_Printf("ui_activate: ran out of active ui list items\n"); - } - else - { - for (i = 0;i < MAX_UI_COUNT;i++) - { - if (ui_list[i] == ui) - { - ui_list[i] = NULL; - return; - } - } - } + if(list->list) + for(item = list->list; item != 0; item = item->next) + UI_AddItem(clone, UI_CloneItem(item)); + + return clone; } -int ui_isactive(void) + +void UI_FreeItemList(ui_itemlist_t list) { - 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_Free((void*)list); } -#define UI_QUEUE_SIZE 256 -static qbyte ui_keyqueue[UI_QUEUE_SIZE]; -static int ui_keyqueuepos = 0; - -void ui_leftkeyupdate(int pressed) +void UI_AddItem(ui_itemlist_t list, ui_item_t item) { - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_LEFT; - key = pressed; + item->prev = 0; + item->next = list->list; + list->list->prev = item; + list->list = item; } -void ui_rightkeyupdate(int pressed) +// controls +ui_item_t UI_CreateButton(void) { - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_RIGHT; - key = pressed; + return NULL; } -void ui_upkeyupdate(int pressed) +ui_item_t UI_CreateLabel(void) { - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_UP; - key = pressed; + return NULL; } -void ui_downkeyupdate(int pressed) +ui_item_t UI_CreateText(void) { - static int key = false; - if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE) - ui_keyqueue[ui_keyqueuepos++] = UIKEY_DOWN; - key = pressed; + return NULL; } +// AK: callback system stuff +static ui_callback_t ui_callback_list[UI_MAX_CALLBACK_COUNT]; -void ui_mousebuttonupdate(int button, int pressed) +void UI_Callback_Init(void) { - if (button < 0 || button >= UI_MOUSEBUTTONS) - return; - if (button == 0 && ui_mousebutton[button] && !pressed) - ui_mouseclick = true; - ui_mousebutton[button] = pressed; + memset(ui_callback_list, 0, sizeof(ui_callback_list)); } -void ui_update(void) +int UI_Callback_GetFreeSlot(void) { - 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); + int i; + for(i = 0; ui_callback_list[i].flag & UI_SLOTUSED && i < UI_MAX_CALLBACK_COUNT; i++); - 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); - } + if(i == UI_MAX_CALLBACK_COUNT) + return -1; + else + return i; +} - if (ui_keyqueuepos) - { - 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; - } - } - } - ui_keyqueuepos = 0; +int UI_Callback_IsSlotUsed(int slotnr) +{ + if(slotnr < 0 || slotnr >= UI_MAX_CALLBACK_COUNT) + return false; + return (ui_callback_list[slotnr].flag & UI_SLOTUSED); +} - 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; +void UI_Callback_SetupSlot(int slotnr, void(*keydownf)(int num, char ascii), void(*drawf)(void)) +{ + ui_callback_list[slotnr].flag = UI_SLOTUSED; + ui_callback_list[slotnr].draw = drawf; + ui_callback_list[slotnr].keydown = keydownf; } -void ui_draw(void) +void UI_Callback_ResetSlot(int slotnr) { - int i, j; - ui_item_t *it; - ui_t *ui; - if (ui_alive && ui_active) - { - 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); - } + ui_callback_list[slotnr].flag = 0; } +void UI_Callback_Draw(void) +{ + int i; + for(i = 0; i < UI_MAX_CALLBACK_COUNT; i++) + if(ui_callback_list[i].flag & UI_SLOTUSED && ui_callback_list[i].draw) + ui_callback_list[i].draw(); +} + +void UI_Callback_KeyDown(int num, char ascii) +{ + if(ui_callback_list[key_dest - 3].flag & UI_SLOTUSED && ui_callback_list[key_dest - 3].keydown) + ui_callback_list[key_dest - 3].keydown(num, ascii); +}