915 lines
19 KiB
C
915 lines
19 KiB
C
///////////////////////////////////////////////
|
|
// Menu Manager Source File
|
|
///////////////////////
|
|
// This file belongs to dpmod/darkplaces
|
|
// AK contains the manager code
|
|
///////////////////////////////////////////////
|
|
|
|
void(void) menu_init =
|
|
{
|
|
//registercvar("menu_reloadlist","0");
|
|
|
|
menu_load();
|
|
};
|
|
|
|
void(void) menu_load =
|
|
{
|
|
// load the menu files
|
|
float i;
|
|
|
|
for(i = 0; i < NUM_RESFILES; i++ )
|
|
{
|
|
menu_loadmenu(MENU_FILENAME_LIST[i]);
|
|
}
|
|
menu_linkwindows();
|
|
};
|
|
|
|
void(string file) menu_addfiletolist =
|
|
{
|
|
error("menu_addfiletolist called\n");
|
|
};
|
|
|
|
void(void) menu_restart =
|
|
{
|
|
// actually we empty the ent list and load everything one more time, thats it
|
|
entity ent;
|
|
float pevused;
|
|
string oldpev;
|
|
string oldactive;
|
|
string oldselected;
|
|
|
|
// we backup the active window name and the name of the selected item
|
|
oldactive = menu_activewindow.name;
|
|
oldselected = menu_selected.name;
|
|
// backup pev's name
|
|
if(pev != null_entity)
|
|
{
|
|
oldpev = pev.name;
|
|
pevused = true;
|
|
}
|
|
else
|
|
{
|
|
pevused = false;
|
|
}
|
|
|
|
// first clear the history
|
|
menu_clearhistory();
|
|
|
|
// we remove all items
|
|
ent = null_entity;
|
|
while((ent = nextent(ent)) != null_entity)
|
|
{
|
|
menu_removeitem(ent);
|
|
}
|
|
|
|
// FIXME: here's a "little" hack (so PRVM_ED_Alloc replaces the items instead of creating new ones)
|
|
time = time + 1.0;
|
|
|
|
// now call menu_load
|
|
menu_load();
|
|
|
|
time = time - 1.0; // we cant use gettime cause that always returns time :-/
|
|
|
|
// perform the init
|
|
menu_performreinit();
|
|
|
|
ent = menu_getitem(oldactive);
|
|
if(ent)
|
|
{
|
|
menu_activewindow = ent;
|
|
ent = menu_getitem(oldselected);
|
|
if(ent)
|
|
{
|
|
menu_selected = ent;
|
|
}
|
|
}
|
|
|
|
if(pevused)
|
|
{
|
|
ent = menu_getitem(oldpev);
|
|
if(ent)
|
|
{
|
|
pev = ent;
|
|
} else // we have no current pev...
|
|
{
|
|
error("Reloaded menu files, but the former pev (", oldpev ,") item is missing !\n");
|
|
}
|
|
}
|
|
};
|
|
void menu_loadmenu (string file)
|
|
{
|
|
if(loadfromfile(file) == -1)
|
|
{
|
|
dprint("^3Warning:^7 couldn't load ", file, "\n");
|
|
}
|
|
}
|
|
|
|
entity(entity start, .entity find1, entity match, .float find2, float match2) findef =
|
|
{
|
|
while(1)
|
|
{
|
|
start = findentity(start, find1, match);
|
|
if(start == null_entity)
|
|
break;
|
|
if(start.find2 == match2)
|
|
break;
|
|
}
|
|
return start;
|
|
/*while((start = findentity(start,find1,match))!=null_entity)
|
|
if(start.find2 == match2)
|
|
break;
|
|
return start;*/
|
|
};
|
|
|
|
void(void) menu_linkwindows =
|
|
{
|
|
// first verify that MENU_NORMAL_NAME and MENU_INGAME_NAME exist
|
|
// if not add the default strings
|
|
entity ent;
|
|
float x, opos;
|
|
|
|
ent = findstring(null_entity, name, MENU_NORMAL_NAME);
|
|
if(ent == null_entity) loadfromdata(MENU_NORMAL_DEFAULT);
|
|
|
|
// verify again if MENI_INGAME_NAME is there now
|
|
ent = findstring(null_entity,name, MENU_NORMAL_NAME);
|
|
if(ent == null_entity) error("Bad MENU_NORMAL_DEFAULT !\n");
|
|
|
|
ent = findstring(null_entity,name, MENU_INGAME_NAME);
|
|
if(ent == null_entity) loadfromdata(MENU_INGAME_DEFAULT);
|
|
|
|
// verify again if MENI_INGAME_NAME is there now
|
|
ent = findstring(null_entity, name, MENU_INGAME_NAME);
|
|
if(ent == null_entity) error("Bad MENU_INGAME_DEFAULT !\n");
|
|
|
|
// verify that every name is only used *once*
|
|
ent = null_entity;
|
|
while((ent = nextent(ent)) != null_entity)
|
|
{
|
|
pev = ent;
|
|
while((pev = findstring(pev, name, ent.name)) != null_entity)
|
|
{
|
|
if(pev != null_entity)
|
|
{
|
|
objerror("Name ", ent.name, " already used !\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
// now we have to :
|
|
// set the parent field with parent_name
|
|
// set the next and prev fields
|
|
// set the child field
|
|
pev = null_entity;
|
|
while((pev = nextent(pev)) != null_entity)
|
|
{
|
|
if(pev.name == "")
|
|
{
|
|
objerror("Name is missing !\n");
|
|
continue;
|
|
}
|
|
|
|
if(pev.type == "")
|
|
{
|
|
objerror("Type is missing !\n");
|
|
continue;
|
|
}
|
|
|
|
if(!isfunction(pev.type))
|
|
{
|
|
objerror("Control ", pev.type, " not found !\n");
|
|
continue;
|
|
}
|
|
|
|
// find parent
|
|
// if parent_name is "" do nothing else set parent
|
|
if(pev.parent != "")
|
|
{
|
|
ent = findstring(null_entity, name, pev.parent);
|
|
|
|
if(ent == null_entity)
|
|
{
|
|
objerror("Item ", pev.parent, " not found !\n");
|
|
continue;
|
|
}
|
|
|
|
pev._parent = ent;
|
|
}
|
|
else
|
|
{
|
|
pev._parent = null_entity;
|
|
}
|
|
}
|
|
|
|
// now auto-set all ents with orderpos 0
|
|
pev = null_entity;
|
|
while((pev = findfloat(pev,orderpos, 0)) != null_entity)
|
|
{
|
|
if(pev.parent == "")
|
|
continue;
|
|
|
|
// now go through all orderpos' beginning from 1
|
|
opos = 1;
|
|
while((ent = findef(null_entity, _parent, pev._parent, orderpos, opos)) != null_entity)
|
|
{
|
|
opos = opos + 1;
|
|
}
|
|
|
|
pev.orderpos = opos;
|
|
}
|
|
|
|
pev = null_entity;
|
|
while((pev = nextent(pev)) != null_entity)
|
|
{
|
|
// find first child
|
|
// orderpos starts with 1
|
|
ent = findef(null_entity, _parent, pev, orderpos, 1);
|
|
|
|
if(ent == null_entity)
|
|
{
|
|
if(findentity(ent, _parent, pev) != null_entity)
|
|
{
|
|
objerror("Order pos 1 is missing in the child list of ", pev.name, " !\n");
|
|
continue;
|
|
}
|
|
//else doesnt have any chilren
|
|
}
|
|
else
|
|
pev._child = ent;
|
|
|
|
// add to next, previous list
|
|
// find orderpos - x (starting with x = 1)
|
|
x = pev.orderpos;
|
|
|
|
while(x > 1)
|
|
{
|
|
x = x - 1;
|
|
|
|
ent = findef(null_entity, _parent, pev._parent, orderpos, x);
|
|
if(ent != null_entity)
|
|
{
|
|
pev._prev = ent;
|
|
ent._next = pev;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// find orderpos + x (starting with x = 1 until x == pev.oderpos + 100)
|
|
x = pev.orderpos;
|
|
|
|
while(x < pev.orderpos + 100)
|
|
{
|
|
x = x + 1;
|
|
|
|
ent = findef(null_entity, _parent, pev._parent, orderpos, x);
|
|
if(ent != null_entity)
|
|
{
|
|
pev._next = ent;
|
|
ent._prev = pev;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// call the type functions (former classname functions)
|
|
ent = null_entity;
|
|
while((ent = nextent(ent)) != null_entity)
|
|
{
|
|
pev = ent;
|
|
callfunction(pev.type);
|
|
}
|
|
};
|
|
|
|
void(void) menu_toggle =
|
|
{
|
|
// only let the qc toggle the menu if we are ingame or a developer
|
|
if(gamestatus & GAME_CONNECTED || cvar("developer"))
|
|
{
|
|
// then allow toggling
|
|
m_toggle();
|
|
}// else do nothing
|
|
};
|
|
|
|
void(void) menu_performreinit =
|
|
{
|
|
// clear history
|
|
menu_clearhistory();
|
|
|
|
// and reinit all menu items
|
|
pev = null_entity;
|
|
while((pev = nextent(pev)) != null_entity)
|
|
{
|
|
if(pev.parent == "")
|
|
pev._parent = null_entity;
|
|
//else actually this shouldnt happen
|
|
else if(pev._parent.name != pev.parent)
|
|
objerror("Parent (should be ", pev.parent, ") of non-menu item ", pev.name, " changed to ", pev._parent.name, " !\n");
|
|
|
|
raise_reinit(pev); // always call reinit
|
|
}
|
|
|
|
// choose which menu to display
|
|
if(MENU_ALLOWINGAME && (gamestatus & GAME_CONNECTED))
|
|
menu_activewindow = findstring(null_entity, name, MENU_INGAME_NAME);
|
|
else menu_activewindow = findstring(null_entity, name, MENU_NORMAL_NAME);
|
|
|
|
// set the selected item
|
|
menu_selected = menu_activewindow;
|
|
// find first child that can be selected
|
|
menu_selectdown();
|
|
};
|
|
|
|
void(entity par, float selectalways) menu_processmouse =
|
|
{
|
|
// pev is parent
|
|
// loop through all childs
|
|
// and try to find an object whose click rect fits to the mouse coords
|
|
entity ent;
|
|
vector old_cursor, local_cursor;
|
|
|
|
ent = par._child;
|
|
if(ent == null_entity)
|
|
return;
|
|
|
|
menu_localorigin = menu_localorigin + par.origin;
|
|
|
|
old_cursor = menu_cursor;
|
|
local_cursor = gfx_congfxtomen(cursor);
|
|
|
|
do
|
|
{
|
|
// if not visible, continue to the next item
|
|
if(menu_isvisible(ent))
|
|
{
|
|
old_cursor = menu_cursor;
|
|
menu_cursor = local_cursor;
|
|
if(inrect(local_cursor, ent.click_pos, ent.click_size))
|
|
{
|
|
// call mouse_enter event ?
|
|
if(!(ent.flag & _FLAG_MOUSEINAREA) && menu_hasevents(ent))
|
|
{
|
|
raise_mouse_enter(ent);
|
|
|
|
ent.flag = ent.flag | _FLAG_MOUSEINAREA;
|
|
}
|
|
|
|
// select it ?
|
|
if(menu_selectable(ent))
|
|
{
|
|
menu_selected = ent;
|
|
}
|
|
else if(selectalways)
|
|
{
|
|
if(menu_hasevents(ent))
|
|
{
|
|
menu_selected = ent;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// call mouse_leave event ?
|
|
if((ent.flag & _FLAG_MOUSEINAREA) && menu_hasevents(ent))
|
|
{
|
|
raise_mouse_leave(ent);
|
|
|
|
// this only works if _FLAG_MOUSEINAREA is set
|
|
ent.flag = ent.flag - _FLAG_MOUSEINAREA;
|
|
}
|
|
}
|
|
|
|
if(menu_selected != ent)
|
|
menu_cursor = old_cursor;
|
|
|
|
|
|
// if ent has children recurse through them
|
|
if(ent._child != null_entity)
|
|
{
|
|
menu_processmouse(ent, selectalways);
|
|
}
|
|
}
|
|
} while((ent = ent._next) != null_entity);
|
|
|
|
menu_localorigin = menu_localorigin - par.origin;
|
|
};
|
|
|
|
void(void) menu_frame =
|
|
{
|
|
/*
|
|
// this is only for debugging purposes
|
|
// thus its unstable and *won't* work any more when Ive changed dp's behavior with
|
|
// the builtin list (the precache functions will only work for menu_init)
|
|
if(cvar("menu_reloadlist"))
|
|
{
|
|
cvar_set("menu_reloadlist","0");
|
|
menu_restart();
|
|
}*/
|
|
// if mouse moved, process it
|
|
if(cursor_rel != '0 0 0')
|
|
menu_processmouse(menu_activewindow, false);
|
|
|
|
}
|
|
|
|
void(entity menu) menu_drawwindow =
|
|
{
|
|
// loop through all children and draw them
|
|
entity ent;
|
|
vector old_c_pos, old_c_size, clipped_size;
|
|
|
|
// set the clipping area
|
|
// is this necessary at all ?
|
|
if(menu_clip_size != '0 0 0')
|
|
{
|
|
clipped_size = cliprectsize(gfx_conmentogfx(menu.clip_pos),menu.clip_size, menu_clip_pos, menu_clip_size);
|
|
}
|
|
else
|
|
{
|
|
clipped_size = menu.clip_size;
|
|
}
|
|
|
|
if(clipped_size != '0 0 0')
|
|
{
|
|
// do clip the clip area
|
|
// save the old
|
|
old_c_pos = menu_clip_pos;
|
|
old_c_size = menu_clip_size;
|
|
|
|
// clip the position
|
|
menu_clip_pos = cliprectpos( gfx_conmentogfx(menu.clip_pos) , menu.clip_size, menu_clip_pos, menu_clip_size);
|
|
menu_clip_size = clipped_size;
|
|
gfx_setcliparea(menu_clip_pos, menu_clip_size);
|
|
}
|
|
|
|
// set the localorigin (the clipping position wont be affected)
|
|
menu_localorigin = menu_localorigin + menu.origin;
|
|
|
|
ent = menu._child;
|
|
do
|
|
{
|
|
// if it's not visible continue
|
|
if(menu_isvisible(ent))
|
|
{
|
|
pev = ent;
|
|
if(menu_hasevents(ent))
|
|
{
|
|
raise_refresh(ent);
|
|
} else if(ent.flag & FLAG_DRAWREFRESHONLY)
|
|
{
|
|
raise_refresh(ent);
|
|
} else if(ent._parent)
|
|
{
|
|
if(ent._parent.flag & FLAG_CHILDDRAWREFRESHONLY)
|
|
raise_refresh(ent);
|
|
}
|
|
|
|
raise_draw(ent);
|
|
|
|
if(ent._child != null_entity)
|
|
{
|
|
menu_drawwindow(ent);
|
|
}
|
|
|
|
// reset the clip area to the current menu's
|
|
if(menu_clip_size != '0 0 0')
|
|
gfx_setcliparea(menu_clip_pos, menu_clip_size);
|
|
else
|
|
gfx_resetcliparea();
|
|
}
|
|
} while((ent = ent._next) != null_entity);
|
|
|
|
menu_localorigin = menu_localorigin - menu.origin;
|
|
|
|
// restore the old menu_clip vars if necessary
|
|
if(clipped_size != '0 0 0')
|
|
{
|
|
menu_clip_size = old_c_size;
|
|
menu_clip_pos = old_c_pos;
|
|
}
|
|
};
|
|
|
|
void(void) menu_draw =
|
|
{
|
|
// if menu_activewindow is visible loop though it
|
|
if(menu_isvisible(menu_activewindow))
|
|
{
|
|
menu_drawwindow(menu_activewindow);
|
|
menu_localorigin = '0 0 0';
|
|
menu_clip_pos = '0 0 0';
|
|
menu_clip_size = '0 0 0';
|
|
menu_resetcliparea();
|
|
}
|
|
}
|
|
|
|
float(entity e) menu_hasevents =
|
|
{
|
|
if(e.flag & FLAG_DRAWONLY)
|
|
return false;
|
|
if(e.flag & FLAG_DRAWREFRESHONLY)
|
|
return false;
|
|
if(e._parent)
|
|
{
|
|
if(e._parent.flag & FLAG_CHILDDRAWONLY)
|
|
return false;
|
|
if(e._parent.flag & FLAG_CHILDDRAWREFRESHONLY)
|
|
return false;
|
|
}
|
|
if(menu_isvisible(e))
|
|
return true;
|
|
return false;
|
|
};
|
|
|
|
float(entity e) menu_isvisible =
|
|
{
|
|
if(e.flag & FLAG_HIDDEN)
|
|
return false;
|
|
|
|
if((e.flag & FLAG_SERVERONLY) && !(gamestatus & GAME_ISSERVER))
|
|
return false;
|
|
|
|
if((e.flag & FLAG_DEVELOPERONLY) && !(gamestatus & GAME_DEVELOPER))
|
|
return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
float(entity e) menu_selectable =
|
|
{
|
|
if(!menu_hasevents(e))
|
|
return false;
|
|
if(e.flag & FLAG_NOSELECT)
|
|
return false;
|
|
|
|
//if(e == menu_getitem("quit"))
|
|
// crash();
|
|
|
|
return true;
|
|
};
|
|
|
|
void(void) menu_shutdown =
|
|
{
|
|
// call the terminate event for each object
|
|
pev = null_entity;
|
|
while((pev = nextent(pev)) != null_entity)
|
|
{
|
|
raise_destroy(pev);
|
|
}
|
|
};
|
|
|
|
void(float keynr, string ascii) menu_keydown =
|
|
{
|
|
// before calling the current keydown functions, process the mouse again
|
|
// so only the correct item is called
|
|
// (except mouse wheel up and down)
|
|
// if the mouse doesnt point to an item, there wont be a reaction on the clicking
|
|
if(K_MOUSE1 <= keynr && keynr <= K_MOUSE3)
|
|
{
|
|
entity key_selected;
|
|
key_selected = menu_selected;
|
|
menu_selected = null_entity;
|
|
menu_processmouse(menu_activewindow, true);
|
|
// if we find anything, we give it the key event, perhaps it can use it
|
|
if(menu_selected != key_selected)
|
|
{
|
|
// pass the keyevent
|
|
if(menu_selected != null_entity)
|
|
{
|
|
raise_key(menu_selected, keynr, ascii);
|
|
}
|
|
|
|
// if it is selectable the user perhaps wanted to reselect it
|
|
if(menu_selectable(menu_selected) == false || menu_selected == null_entity)
|
|
{
|
|
menu_selected = key_selected;
|
|
}
|
|
|
|
return;
|
|
}
|
|
// go on
|
|
}
|
|
|
|
// call current selected keydown function
|
|
// if nothing is selected -> window has no items -> call window key
|
|
if(menu_selected == null_entity)
|
|
{
|
|
// call window keydown
|
|
raise_key(menu_activewindow, keynr, ascii);
|
|
}
|
|
else
|
|
{
|
|
raise_key(menu_selected, keynr, ascii);
|
|
}
|
|
};
|
|
|
|
void(void) menu_selectprev =
|
|
{
|
|
entity temp;
|
|
|
|
temp = menu_selected;
|
|
// loop backward through the list until one item is selectable
|
|
while((temp = temp._prev) != null_entity)
|
|
if(menu_selectable(temp))
|
|
break;
|
|
|
|
if(temp != null_entity)
|
|
menu_selected = temp;
|
|
};
|
|
|
|
void(void) menu_selectnext =
|
|
{
|
|
entity temp;
|
|
|
|
temp = menu_selected;
|
|
// loop forward through the list until one item is selectable
|
|
while((temp = temp._next) != null_entity)
|
|
if(menu_selectable(temp))
|
|
break;
|
|
|
|
if(temp != null_entity)
|
|
menu_selected = temp;
|
|
};
|
|
|
|
void(void) menu_loopnext =
|
|
{
|
|
entity old;
|
|
old = menu_selected;
|
|
|
|
menu_selectnext();
|
|
if(menu_selected == old)
|
|
{
|
|
menu_selected = old._parent._child;
|
|
if(!menu_selectable(menu_selected))
|
|
menu_selectnext();
|
|
}
|
|
};
|
|
|
|
void(void) menu_loopprev =
|
|
{
|
|
entity old;
|
|
old = menu_selected;
|
|
menu_selectprev();
|
|
if(menu_selected == old)
|
|
{
|
|
while(old._next != null_entity)
|
|
{
|
|
old = old._next;
|
|
}
|
|
|
|
menu_selected = old;
|
|
if(!menu_selectable(old))
|
|
{
|
|
menu_selectprev();
|
|
}
|
|
}
|
|
}
|
|
|
|
void(void) menu_selectdown =
|
|
{
|
|
// move down a level, then search for a selectable child
|
|
// if none is found, then search for a sub-menu
|
|
// if one is found, recurse through it, else keep the old menu_selected
|
|
// (while recursing set the history)
|
|
|
|
entity ent, old_selected;
|
|
|
|
// if there is no child, return
|
|
if(menu_selected._child == null_entity)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// loop through the children till a selectable is found
|
|
ent = menu_selected._child;
|
|
do
|
|
{
|
|
if(menu_selectable(ent))
|
|
{
|
|
// found one -> break
|
|
menu_selected = ent;
|
|
return;
|
|
}
|
|
|
|
} while((ent = ent._next) != null_entity);
|
|
|
|
// we found no selectable child, thus we loop through the children once again
|
|
// and recurse
|
|
ent = menu_selected._child;
|
|
old_selected = menu_selected;
|
|
do
|
|
{
|
|
if(ent._child != null_entity)
|
|
{
|
|
// add the history item
|
|
menu_pushhistory(ent._child);
|
|
|
|
// give it a try
|
|
menu_selected = ent;
|
|
menu_selectdown();
|
|
|
|
// found one ?
|
|
if(menu_selected != ent)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// nothing found, then remove the history item
|
|
menu_pophistory();
|
|
}
|
|
} while((ent = ent._next) != null_entity);
|
|
|
|
// we didnt find anything
|
|
menu_selected = old_selected;
|
|
}
|
|
|
|
void(void) menu_selectup =
|
|
{
|
|
entity ent;
|
|
|
|
// move up till we find a selectable item
|
|
// if we reach the 'main' menu without having found such an item
|
|
// then toggle the menu (if possible) else select the first item available
|
|
// if we find the active_menu on our way up, reset it, so everything gets displayed
|
|
// correct
|
|
|
|
ent = menu_selected;
|
|
|
|
// reset menu_selected
|
|
menu_selected = null_entity;
|
|
|
|
print("Selectup called !\n");
|
|
|
|
while(1)
|
|
{
|
|
eprint(ent);
|
|
|
|
// does a history entry exist for the current object ?
|
|
if(menu_verifyhistory(ent))
|
|
{
|
|
menu_pophistory();
|
|
break;
|
|
}
|
|
|
|
// reset the active window if we reached it
|
|
if(ent == menu_activewindow) menu_activewindow = null_entity;
|
|
|
|
// move up
|
|
if(ent._parent != null_entity)
|
|
{
|
|
ent = ent._parent;
|
|
}
|
|
else
|
|
{
|
|
// nothing found -> break
|
|
break;
|
|
}
|
|
|
|
menu_selected = ent;
|
|
// is it selecteable ?
|
|
if(menu_selectable(ent))
|
|
{
|
|
// we found our item !
|
|
break;
|
|
}
|
|
|
|
// try selectnext
|
|
menu_selectnext();
|
|
if(menu_selected != ent)
|
|
{
|
|
// we found it !
|
|
break;
|
|
}
|
|
// try selectprev
|
|
menu_selectprev();
|
|
if(menu_selected != ent)
|
|
{
|
|
// we found it !
|
|
break;
|
|
}
|
|
}
|
|
|
|
// evalute our results:
|
|
if(menu_selected == null_entity)
|
|
{
|
|
// something must have been selected else -> error !
|
|
error("Couldnt select any item !\n");
|
|
// have we reached the 'main' menu ?
|
|
}
|
|
else if(menu_selected.name == MENU_NORMAL_NAME || menu_selected.name == MENU_INGAME_NAME)
|
|
{
|
|
menu_toggle();
|
|
// set the active window to the 'main' window
|
|
menu_activewindow = ent;
|
|
// if the menu isnt toggled then select an item now !
|
|
menu_selectdown();
|
|
return;
|
|
}
|
|
|
|
// does the active menu needs to be reset ?
|
|
if(menu_activewindow == null_entity)
|
|
{
|
|
if(menu_selected._parent)
|
|
menu_activewindow = ent._parent;
|
|
else menu_activewindow = ent;
|
|
}
|
|
};
|
|
|
|
void(void) menu_reselect =
|
|
{
|
|
menu_selected = menu_activewindow;
|
|
menu_selectdown();
|
|
};
|
|
|
|
void(entity menu, float setactive) menu_jumptowindow =
|
|
{
|
|
// only jump to windows
|
|
if(menu.type != "ITEM_WINDOW")
|
|
error("Cant jump to ", menu.name, " !\n");
|
|
|
|
// add a history point
|
|
menu_pushhistory(menu);
|
|
if(setactive)
|
|
menu_activewindow = menu;
|
|
|
|
// now set the selected to the first selectable child
|
|
menu_selected = menu;
|
|
menu_selectdown();
|
|
};
|
|
|
|
entity(string item_name) menu_getitem =
|
|
{
|
|
return findstring(null_entity, name, item_name);
|
|
};
|
|
|
|
void(entity ent) menu_removeitem =
|
|
{
|
|
// raise the destroy event
|
|
raise_destroy(ent);
|
|
remove(ent);
|
|
};
|
|
|
|
|
|
// history stuff
|
|
|
|
void(entity ent) menu_pushhistory =
|
|
{
|
|
entity his;
|
|
|
|
/*
|
|
// dont create multiple histories for the same 'trigger'
|
|
if(menu_history)
|
|
{
|
|
if(menu_history._next == ent)
|
|
return;
|
|
}*/
|
|
|
|
his = spawn();
|
|
|
|
his.type = "MMANAGER_HISTORY";
|
|
his._prev = menu_history;
|
|
his._child = menu_selected;
|
|
his._parent = menu_activewindow;
|
|
his._next = ent; // "used for"
|
|
|
|
menu_history = his;
|
|
};
|
|
|
|
void(void) menu_pophistory =
|
|
{
|
|
entity tmp;
|
|
|
|
if(menu_history == null_entity)
|
|
{
|
|
return;
|
|
}
|
|
|
|
menu_selected = menu_history._child;
|
|
menu_activewindow = menu_history._parent;
|
|
|
|
tmp = menu_history;
|
|
menu_history = menu_history._prev;
|
|
|
|
remove(tmp);
|
|
};
|
|
|
|
float(entity ent) menu_verifyhistory =
|
|
{
|
|
if(menu_history == null_entity)
|
|
return false;
|
|
|
|
if(menu_history._next == ent)
|
|
return true;
|
|
return false;
|
|
};
|
|
|
|
void(void) menu_clearhistory =
|
|
{
|
|
entity ent;
|
|
|
|
ent = null_entity;
|
|
while((ent = findstring(ent, type, "MMANAGER_HISTORY")) != null_entity)
|
|
{
|
|
remove(ent);
|
|
}
|
|
|
|
menu_history = null_entity;
|
|
};
|