298 lines
8.4 KiB
Plaintext
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;
|
|
};
|
|
|