]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Hopefully finished the core of the new ui.
authorblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 11 Jan 2004 17:35:27 +0000 (17:35 +0000)
committerblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 11 Jan 2004 17:35:27 +0000 (17:35 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3801 d7cf8633-e32d-0410-b094-e92efae38249

ui.c
ui.h

diff --git a/ui.c b/ui.c
index d41b206ffa64260cbc5e23f71aac483c93ed52cd..a8b3b9ea78169a872dac405af3f5edcde78baf2a 100644 (file)
--- a/ui.c
+++ b/ui.c
 
 #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 b73c6e40d744d7873e593b7052747c9195f1f77a..1f20e185700e26a7e30935fbf93c3872f45fd6c8 100644 (file)
--- a/ui.h
+++ b/ui.h
 
 #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