engine/quakec/menusys/menusys/mitems_common.qc

298 lines
8.4 KiB
Plaintext

/***************************************************************************
simple block-fill item
non-interactable.
*/
class mitem_fill : mitem
{
virtual void(vector pos) item_draw =
{
ui.drawfill(pos, this.item_size, this.item_rgb, this.item_alpha, 0);
};
};
#define menuitemfill_spawn(sz,rgb,alph) spawn(mitem_fill, item_size:sz, item_rgb:rgb, item_alpha:alph)
/***************************************************************************
basic picture item.
non-interactable.
item_text: the normal image to use
item_text_mactive: the image to use when the mouse is over it.
item_size: if not set, will be set to the size of the image named by item_text. if only y is set, x will be sized to match aspect with y.
*/
class mitem_pic : mitem
{
string item_text_mactive;
virtual void(vector pos) item_draw =
{
if (item_text_mactive != "" && (item_flags & IF_MFOCUSED))
ui.drawpic(pos, item_text_mactive, item_size, item_rgb, item_alpha, 0);
else
ui.drawpic(pos, item_text, item_size, item_rgb, item_alpha, 0);
};
void() mitem_pic =
{
if (dp_workarounds)
{
if (substring(item_text, -4, 4) == ".lmp")
item_text = substring(item_text, 0, -5);
if (substring(item_text_mactive , -4, 5) == ".lmp")
item_text_mactive = substring(item_text_mactive, 0, -4);
}
item_text = strzone(item_text);
precache_pic(item_text);
if (item_text_mactive)
{
item_text_mactive = strzone(item_text_mactive);
precache_pic(item_text_mactive);
}
if (!item_size[0])
{
float y = item_size[1];
item_size = drawgetimagesize(item_text);
if (y) //rescale x to ma
{
if (!item_size[1]) //bad image? don't glitch out too much.
item_size = item_size[0] * '1 1 0';
else
item_size = [item_size[0] * (y / item_size[1]), y, 0];
}
}
};
virtual void() item_remove =
{
strunzone(item_text);
if (item_text_mactive)
strunzone(item_text_mactive);
super::item_remove();
};
};
#define menuitempic_spawn(img,sz) spawn(mitem_pic, item_text:img, item_size:sz)
/***************************************************************************
basic text item.
interactable - executes a given console command.
*/
class mitem_text : mitem
{
virtual void(vector pos) item_draw =
{
vector rgb = menuitem_textcolour(this);
float w;
if (item_flags & IF_CENTERALIGN)
{
w = stringwidth(item_text, TRUE, '1 1 0'*item_scale);
ui.drawstring(pos + [(item_size_x-w)/2, 0], item_text, '1 1 0' * item_scale, rgb, item_alpha, 0);
}
else if (item_flags & IF_RIGHTALIGN)
{
w = stringwidth(item_text, TRUE, '1 1 0'*item_scale);
ui.drawstring(pos + [(item_size_x-w), 0], item_text, '1 1 0' * item_scale, rgb, item_alpha, 0);
}
else
ui.drawstring(pos, item_text, '1 1 0' * item_scale, rgb, item_alpha, 0);
};
virtual float(vector pos, float scan, float char, float down) item_keypress =
{
if (this.item_command)
{
if (!down)
return FALSE;
if (scan == K_ENTER || (scan == K_MOUSE1 && mouseinbox(pos, this.item_size)))
{
item_parent.item_execcommand(this, this.item_command);
// localcmd(strcat(this.item_command, "\n"));
return TRUE;
}
}
return FALSE;
};
//zone+unzone input strings as needed
virtual void() item_remove =
{
strunzone(item_text);
if (item_command)
strunzone(item_command);
super::item_remove();
};
void() mitem_text =
{
item_text = strzone(item_text);
if (item_command != "")
{
item_command = strzone(item_command);
item_flags |= IF_SELECTABLE;
}
};
};
mitem(string text, string command, float height) menuitemtext_spawn =
{
return spawn(mitem_text, item_scale:height, item_text:text, item_command:command, item_size:[stringwidth(text, TRUE, '1 1 0'*height), height, 0]);
};
class mitem_label : mitem
{ //class that queries its frame to find the text to show.
mitem_vslider vslider;
virtual void(vector pos) item_draw =
{
vector rgb = menuitem_textcolour(this);
string text = get(item_text);
float fl = 2; //top-align
vector textpos = pos;
vector clientsize = item_size;
if (item_flags & IF_CENTERALIGN)
fl |= 0; //default is to center align
else if (item_flags & IF_RIGHTALIGN)
fl |= 4; //right align.
else
fl |= 1; //left align.
if (vslider)
{
textpos[1] -= vslider.val;
clientsize[1] += vslider.val;
clientsize[0] -= vslider.item_size[0];
}
local vector omin = ui.drawrectmin, omax = ui.drawrectmax;
//clip the draw rect to our area, so text doesn't appear outside it. don't draw if its inverted.
if (pos_x > ui.drawrectmin[0])
ui.drawrectmin[0] = pos_x;
if (pos_y > ui.drawrectmin[1])
ui.drawrectmin[1] = pos_y;
if (pos_x+clientsize_x < ui.drawrectmax[0])
ui.drawrectmax[0] = pos_x+clientsize_x;
if (pos_y+clientsize_y < ui.drawrectmax[1])
ui.drawrectmax[1] = pos_y+clientsize[1];
if (ui.drawrectmax[0] > ui.drawrectmin[0] && ui.drawrectmax[1] > ui.drawrectmin[1])
{
ui.setcliparea(ui.drawrectmin[0], ui.drawrectmin[1], ui.drawrectmax[0] - ui.drawrectmin[0], ui.drawrectmax[1] - ui.drawrectmin[1]);
clientsize[1] = drawtextfield(textpos, clientsize, fl, text) * item_scale;
ui.setcliparea(omin_x, omin_y, omax_x - omin_x, omax_y - omin_y);
if (vslider)
{
vslider.item_size[1] = item_size[1];
if (ui.mousepos != ui.oldmousepos)
{
if (mouseinbox(pos + [clientsize[0], 0], vslider.item_size))
this.item_focuschange(vslider, IF_MFOCUSED);
}
vslider.item_draw(pos + [clientsize[0], 0]);
}
}
ui.drawrectmin = omin;
ui.drawrectmax = omax;
if (clientsize[1] > item_size[1])
{ //enough text that we need a scrollbar.
if (!vslider)
vslider = spawn(mitem_vslider, val:0, stride:8);
vslider.maxv = clientsize[1] - item_size[1];
item_flags |= IF_SELECTABLE;
}
else if (vslider)
{ //the text got shorter...
vslider.item_remove();
vslider = (mitem_vslider)__NULL__;
if (item_command == "")
item_flags &~= IF_SELECTABLE;
}
};
virtual float(vector pos, float scan, float char, float down) item_keypress =
{
if (vslider)
if (vslider.item_keypress(pos, scan, char, down))
return TRUE;
if (this.item_command)
{
if (!down)
return FALSE;
if (scan == K_ENTER || (scan == K_MOUSE1 && mouseinbox(pos, this.item_size)))
{
item_parent.item_execcommand(this, this.item_command);
// localcmd(strcat(this.item_command, "\n"));
return TRUE;
}
}
return FALSE;
};
//zone+unzone input strings as needed
virtual void() item_remove =
{
if (item_command)
strunzone(item_command);
if (vslider)
{
vslider.item_remove();
vslider = (mitem_vslider)__NULL__;
}
super::item_remove();
};
void() mitem_label =
{
if (item_command != "")
{
item_command = strzone(item_command);
item_flags |= IF_SELECTABLE;
}
};
};
/***************************************************************************
basic text item.
identical to text, but includes a 3dish border.
*/
class mitem_button : mitem
{
virtual void(vector pos) item_draw =
{
ui.drawfill(pos, [this.item_size[0], 1], TD_TOP, this.item_alpha, 0);
ui.drawfill(pos, [1, this.item_size[1] - 1], TD_LFT, this.item_alpha, 0);
ui.drawfill(pos + [this.item_size[0]-1, 1], [1, this.item_size[1] - 1], TD_RGT, this.item_alpha, 0);
ui.drawfill(pos + [0, this.item_size[1]-1], [this.item_size[0], 1], TD_BOT, this.item_alpha, 0);
pos_x += (this.item_size[0] - stringwidth(this.item_text, TRUE, '1 1 0'*this.item_scale)) * 0.5;
pos_y += (this.item_size[1] - this.item_scale)*0.5;
ui.drawstring(pos, this.item_text, '1 1 0' * this.item_scale, menuitem_textcolour(this), this.item_alpha, 0);
};
virtual float(vector pos, float scan, float char, float down) item_keypress =
{
if (!down)
return FALSE;
if (scan == K_ENTER || (scan == K_MOUSE1 && mouseinbox(pos, this.item_size)))
item_parent.item_execcommand(this, item_command);
else
return FALSE;
return TRUE;
};
virtual void() item_remove =
{
strunzone(item_text);
if (item_command)
strunzone(item_command);
super::item_remove();
};
};
mitem_button(string text, string command, vector sz) menuitembutton_spawn =
{
mitem_button n = spawn(mitem_button);
n.item_scale = sz_y - 4;
n.item_text = strzone(text);
n.item_size = sz;
if (command != "")
{
n.item_command = strzone(command);
n.item_flags |= IF_SELECTABLE;
}
return n;
};