Files

2661 lines
62 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "ui_local.h"
#include "../qcommon/localization.h"
Event W_Destroyed
(
"widget_destroyed",
EV_DEFAULT,
NULL,
NULL,
"Specifies that the widget has been destroyed."
);
Event W_SizeChanged
(
"size_changed",
EV_DEFAULT,
NULL,
NULL,
"Specifies that the size of the widget has changed."
);
Event W_FrameChanged
(
"frame_changed",
EV_DEFAULT,
NULL,
NULL,
"Specifies that the frame has changed."
);
Event W_OriginChanged
(
"origin_changed",
EV_DEFAULT,
NULL,
NULL,
"Specifies that the origin f the widget has changed."
);
Event W_Activated
(
"activated",
EV_DEFAULT,
NULL,
NULL,
"Signals that the widget has been activated."
);
Event EV_Widget_Activate
(
"activate",
EV_DEFAULT,
NULL,
NULL,
"Activate this widget."
);
Event W_Deactivated
(
"deactivated",
EV_DEFAULT,
NULL,
NULL,
"Signals that the widget has been deactivated."
);
Event EV_Widget_Hide
(
"hide",
EV_DEFAULT,
NULL,
NULL,
"Hides the widget."
);
Event EV_Widget_Enable
(
"enable",
EV_DEFAULT,
NULL,
NULL,
"enable the widget."
);
Event EV_Widget_Disable
(
"disable",
EV_DEFAULT,
NULL,
NULL,
"enable the widget."
);
Event W_RealignWidget
(
"realign_widget",
EV_DEFAULT,
NULL,
NULL,
"Specifies that the widget has been realigned."
);
Event W_Draw
(
"draw_widget",
EV_DEFAULT,
NULL,
NULL,
"Draw the widget."
);
Event EV_Layout_Size
(
"size",
EV_DEFAULT,
"ffff",
"x y width height",
"Set the size of the widget"
);
Event EV_Layout_Rect
(
"rect",
EV_DEFAULT,
"ffff",
"x y width height",
"Set the rect of the widget"
);
Event EV_Layout_Name
(
"name",
EV_DEFAULT,
"s",
"name",
"Set the name of the widget"
);
Event EV_Layout_Title
(
"title",
EV_DEFAULT,
"s",
"title",
"Set the title of the widget to be displayed in the center of it"
);
Event EV_Layout_Font
(
"font",
EV_DEFAULT,
"s",
"title",
"Set the font of the widget"
);
Event EV_Layout_BGColor
(
"bgcolor",
EV_DEFAULT,
"ffff",
"red green blue alpha",
"Set the background color of the widget"
);
Event EV_Layout_FGColor
(
"fgcolor",
EV_DEFAULT,
"ffff",
"red green blue alpha",
"Set the foreground color of the widget"
);
Event EV_Layout_Borderstyle
(
"borderstyle",
EV_DEFAULT,
"s",
"style",
"Set the borderstyle of the widget(NONE, 3D_BORDER, INDENT_BORDER) "
);
Event EV_Layout_BorderColor
(
"bordercolor",
EV_DEFAULT,
"ffff",
"red green blue alpha",
"Set the border color of the widget"
);
Event EV_Layout_Shader
(
"shader",
EV_DEFAULT,
"s",
"shaderName",
"Set the shader to draw on the background of the widget"
);
Event EV_Layout_TileShader
(
"tileshader",
EV_DEFAULT,
"s",
"shaderName",
"Set the shader to draw tiled on the background of the widget"
);
Event EV_Layout_HoverShader
(
"hovershader",
EV_DEFAULT,
"s",
"shaderName",
"Set the shader to on the background of the widget when the mouse is over the widget"
);
Event EV_Layout_PressedShader
(
"pressedshader",
EV_DEFAULT,
"s",
"shaderName",
"Set the shader to on the background of the widget when it is pressed in"
);
Event EV_Layout_FadeIn
(
"fadein",
EV_DEFAULT,
"f",
"fadetime",
"Set the amount of time it takes for the widget to fade in"
);
Event EV_Layout_StopSound
(
"stopsound",
EV_DEFAULT,
"s",
"soundName",
"Set the sound to be played when the widget stops moving"
);
Event EV_Layout_ClickSound
(
"clicksound",
EV_DEFAULT,
"s",
"soundName",
"Set the sound to be played when the widget is clicked"
);
Event EV_Layout_Stretch
(
"stretch",
EV_DEFAULT,
"s",
"stretchdir",
"Set the widget to be stretched horizontally or vertically across the screen"
);
Event EV_Layout_VirtualRes
(
"virtualres",
EV_DEFAULT,
"i",
"usevirtualres",
"Set the widget to be modified horizontally or vertically across the screen to account for resolutions != 640x480"
);
Event EV_Layout_InitData
(
"initdata",
EV_DEFAULT,
"s",
"datastring",
"Set the linkcvar to be initialized to this value"
);
Event EV_Layout_Direction
(
"direction",
EV_DEFAULT,
"sF",
"direction time",
"Set the direction the widget will appear from on the screen\n(from_top, from_bottom, from_left, or from_right)\nTime is specified to determine how fast the widget will scroll in\n"
);
Event EV_Layout_Align
(
"align",
EV_DEFAULT,
"s",
"alignment",
"Set the side of the screen to align the widget(left right top bottom centerx centery)"
);
Event EV_Layout_StuffCommand
(
"stuffcommand",
EV_DEFAULT,
"s",
"command",
"Set the command to be stuffed when the widget is clicked"
);
Event EV_Layout_LinkCvar
(
"linkcvar",
EV_DEFAULT,
"s",
"cvarname",
"Set the cvar that will be updated when the widget is changed"
);
Event EV_Layout_NoParentClipping
(
"noparentclip",
EV_DEFAULT,
NULL,
NULL,
"Set the widget to not be clipped by the parent widget"
);
Event EV_Layout_NoParentAdjustment
(
"noparentadjust",
EV_DEFAULT,
NULL,
NULL,
"Set the widget to not be adjusted by the parent widget"
);
Event EV_Widget_HideCommand
(
"hidecommand",
EV_DEFAULT,
"s",
"command",
"Set a command to be executed when the widget is hidden"
);
Event EV_Widget_ShowCommand
(
"showcommand",
EV_DEFAULT,
"s",
"command",
"Set a command to be executed when the widget is shown"
);
Event EV_Widget_OrderNumber
(
"ordernumber",
EV_DEFAULT,
"d",
"num",
"Set the order the widget should be activated in"
);
Event EV_Widget_TextAlignment
(
"textalign",
EV_DEFAULT,
"s",
"alignment",
"Sets the alignment of text for this widget"
);
Event EV_Widget_EnabledCvar
(
"enabledcvar",
EV_DEFAULT,
"s",
"cvar_name",
"Set the cvar to check to see if this button is enabled or not"
);
Event EV_Widget_ScaleCvar
(
"scalecvar",
EV_DEFAULT,
"s",
"cvar_name",
"Set the cvar to check to scale this component"
);
Event EV_Layout_AliasCache
(
"aliascache",
EV_DEFAULT,
"ssSSSSSS",
"alias realPath arg1 arg2 arg3 arg4 arg5 arg6",
"Create an alias to the specified path and cache the resource"
);
Event EV_Layout_DontLocalize
(
"dontlocalize",
EV_DEFAULT,
NULL,
NULL,
"Disables localization for this widget"
);
// Added in 2.0
Event EV_Layout_FadeSequence
(
"fadesequence",
EV_DEFAULT,
"ffff",
"delay fadein hold fadeout",
"Set up for a delay/fadein/hold/fadeout"
);
Event EV_Layout_BGFill
(
"bgfill",
EV_DEFAULT,
"ffff",
"red green blue alpha",
"Set a color to fill the entire background"
);
Event EV_Layout_Fullscreen
(
"fullscreen",
EV_DEFAULT,
"b",
"fullscreen",
"Set container to be fullscreen. This will disable the game rendering if it's active"
);
Event EV_Layout_VidMode
(
"vidmode",
EV_DEFAULT,
"i",
"vidmode",
"Set container's vidmode to change to when it's active"
);
CLASS_DECLARATION(USignal, UIWidget, NULL) {
{&EV_Widget_Hide, &UIWidget::Hide },
{&EV_Widget_Activate, &UIWidget::Activate },
{&EV_Layout_Size, &UIWidget::LayoutSize },
{&EV_Layout_Rect, &UIWidget::LayoutRect },
{&EV_Layout_Name, &UIWidget::LayoutName },
{&EV_Layout_Title, &UIWidget::LayoutTitle },
{&EV_Layout_Font, &UIWidget::LayoutFont },
{&EV_Layout_BGColor, &UIWidget::LayoutBgColor },
{&EV_Layout_FGColor, &UIWidget::LayoutFgColor },
{&EV_Layout_Borderstyle, &UIWidget::LayoutBorderStyle },
{&EV_Layout_BorderColor, &UIWidget::LayoutBorderColor },
{&EV_Layout_Shader, &UIWidget::LayoutShader },
{&EV_Layout_TileShader, &UIWidget::LayoutTileShader },
{&EV_Layout_HoverShader, &UIWidget::LayoutHoverShader },
{&EV_Layout_PressedShader, &UIWidget::LayoutPressedShader },
{&EV_Layout_FadeIn, &UIWidget::LayoutFadeIn },
{&EV_Layout_StopSound, &UIWidget::LayoutStopSound },
{&EV_Layout_ClickSound, &UIWidget::LayoutClickSound },
{&EV_Layout_Stretch, &UIWidget::LayoutStretch },
{&EV_Layout_VirtualRes, &UIWidget::LayoutVirtualRes },
{&EV_Layout_InitData, &UIWidget::LayoutInitData },
{&EV_Layout_Direction, &UIWidget::LayoutDirection },
{&EV_Layout_Align, &UIWidget::LayoutAlign },
{&EV_Layout_NoParentClipping, &UIWidget::LayoutNoParentClipping },
{&EV_Layout_NoParentAdjustment, &UIWidget::LayoutNoParentAdjustment},
{&EV_Layout_StuffCommand, &UIWidget::LayoutStuffCommand },
{&EV_Layout_LinkCvar, &UIWidget::LayoutLinkCvar },
{&EV_Layout_AliasCache, &UIWidget::LayoutAliasCache },
{&EV_Widget_ShowCommand, &UIWidget::ShowCommand },
{&EV_Widget_HideCommand, &UIWidget::HideCommand },
{&EV_Widget_OrderNumber, &UIWidget::LayoutOrderNumber },
{&EV_Widget_TextAlignment, &UIWidget::TextAlignment },
{&EV_Widget_Enable, &UIWidget::EnableEvent },
{&EV_Widget_Disable, &UIWidget::DisableEvent },
{&EV_Widget_EnabledCvar, &UIWidget::SetEnabledCvar },
{&EV_Widget_ScaleCvar, &UIWidget::SetScaleCvar },
//
// Added in 2.0
//
{&EV_Layout_DontLocalize, &UIWidget::SetDontLocalize },
{&EV_Layout_FadeSequence, &UIWidget::EventFadeSequence },
{NULL, NULL }
};
void SetColor(const UColor& color, float alpha)
{
const vec4_t col = {color.r, color.g, color.b, color.a * alpha};
uii.Rend_SetColor(col);
}
void DrawBox(const UIRect2D& rect, const UColor& color, float alpha)
{
DrawBox(rect.pos.x, rect.pos.y, rect.size.width, rect.size.height, color, alpha);
}
void Draw3DBox(const UIRect2D& rect, bool indent, const UBorderColor& color, float alpha)
{
Draw3DBox(rect.pos.x, rect.pos.y, rect.size.width, rect.size.height, indent, color, alpha);
}
void DrawBox(float x, float y, float width, float height, const UColor& color, float alpha)
{
SetColor(color, alpha);
uii.Rend_DrawBox(x, y, width, height);
}
void Draw3DBox(float x, float y, float width, float height, bool indent, const UBorderColor& color, float alpha)
{
if (indent) {
DrawBox(x, y, 1.0, height - 1.0, color.dark, alpha);
DrawBox(x + 1.0, y + 1.0, 1.0, height - 3.0, color.reallydark, alpha);
DrawBox(x, y, width - 1.0, 1.0, color.dark, alpha);
DrawBox(x + 1.0, y + 1.0, width - 1.0, 1.0, color.reallydark, alpha);
DrawBox(x + width - 1.0, y, 1.0, height, color.light, alpha);
DrawBox(x, y + height - 1.0, width, 1.0, color.light, alpha);
} else {
DrawBox(x + width - 2.0, y + 1.0, 1.0, height - 2.0, color.dark, alpha);
DrawBox(x + width - 1.0, y, 1.0, height, color.reallydark, alpha);
DrawBox(x + 1.0, y + height - 2.0, width - 2.0, 1.0, color.dark, alpha);
DrawBox(x, y + height - 1.0, width, 1.0, color.reallydark, alpha);
DrawBox(x, y, 1.0, height - 1.0, color.light, alpha);
DrawBox(x, y, width - 1.0, 1.0, color.light, alpha);
}
}
void DrawMac3DBox(const UIRect2D& rect, bool indent, const UBorderColor& color, int inset, float alpha)
{
float x, y;
float width, height;
x = rect.pos.x + inset;
y = rect.pos.y + inset;
width = rect.size.width - inset * 2;
height = rect.size.height - inset * 2;
if (indent) {
DrawBox(x + 1.0, y + 1.0, width - 2.0, height - 2.0, color.dark, alpha);
DrawBox(x, y, width, 1.0, color.reallydark, alpha);
DrawBox(x, y + 1.0, 1.0, width - 2.0, color.reallydark, alpha);
DrawBox(x + width - 1.0, y + 1.0, 1.0, height - 1.0, color.light, alpha);
DrawBox(x, y + height - 1.0, width - 1.0, 1.0, color.light, alpha);
} else {
DrawBox(x, y, width, 1.0, color.light, alpha);
DrawBox(x, y + 1.0, 1.0, height - 2.0, color.light, alpha);
DrawBox(x + width - 1.0, y + 1.0, 1.0, height - 1.0, color.dark, alpha);
DrawBox(x, y + height - 1.0, width - 1.0, 1.0, color.dark, alpha);
}
}
void DrawBoxWithSolidBorder(
const UIRect2D& rect, const UColor& inside, const UColor& outside, int size, int flags, float alpha
)
{
if (flags & 1) {
DrawBox(
rect.pos.x + size, rect.pos.y + size, rect.size.width - size * 2, rect.size.height - size * 2, inside, alpha
);
}
if (size && flags & 2) {
DrawBox(rect.pos.x, rect.pos.y, size, rect.size.height - size, outside, alpha);
DrawBox(rect.pos.x + size, rect.pos.y, rect.size.width - size, size, outside, alpha);
DrawBox(rect.pos.x + rect.size.width - size, rect.pos.y + size, size, rect.size.height - size, outside, alpha);
DrawBox(rect.pos.x, rect.pos.y + rect.size.height - size, rect.size.width - size, size, outside, alpha);
}
}
static bool scaleFrameVirtualRes(UIRect2D& frame, vec3_t outScale, const vec3_t newScale)
{
if (!VectorCompare2D(outScale, newScale)) {
frame.pos.x = frame.pos.x / outScale[0] * newScale[0];
frame.pos.y = frame.pos.y / outScale[1] * newScale[1];
frame.size.width = frame.size.width / outScale[0] * newScale[0];
frame.size.height = frame.size.height / outScale[1] * newScale[1];
outScale[0] = newScale[0];
outScale[1] = newScale[1];
return true;
}
return false;
}
UIReggedMaterial::UIReggedMaterial()
{
hMat = 0;
isSet = true;
isGot = false;
}
uihandle_t UIReggedMaterial::GetMaterial()
{
if (!isGot) {
isGot = true;
this->hMat = uii.Rend_RegisterMaterial(name.c_str());
}
return hMat;
}
void UIReggedMaterial::ReregisterMaterial(void)
{
if (isGot) {
this->hMat = uii.Rend_RegisterMaterial(name.c_str());
}
}
void UIReggedMaterial::CleanupMaterial(void)
{
isGot = false;
}
void UIReggedMaterial::SetMaterial(const str& name)
{
this->name = name;
}
void UIReggedMaterial::RefreshMaterial(void)
{
if (isGot) {
this->hMat = uii.Rend_RefreshMaterial(name.c_str());
}
}
str UIReggedMaterial::GetName(void)
{
return name;
}
UIWidget::UIWidget()
{
VectorSet2D(m_vVirtualScale, 1, 1);
m_parent = NULL;
m_background_color.set(0.075f, 0.097f, 0.139f, 1.0f);
m_foreground_color = UColor(UHudColor);
m_border_color = UColor(0.15f, 0.195f, 0.278f, 1.0f);
m_indent = 10.0f;
m_bottomindent = 5.0f;
m_borderStyle = border_indent;
m_visible = true;
m_enabled = true;
m_canactivate = false;
m_commandhandler = NULL;
m_font = NULL;
m_material = NULL;
m_hovermaterial = NULL;
m_pressedmaterial = NULL;
m_hovermaterial_active = false;
m_pressedmaterial_active = false;
m_direction = D_NONE;
m_fadetime = 0.0f;
m_alpha = 1.0f;
m_motiontime = 0.0f;
m_starttime = 0.0f;
m_direction_orig = D_NONE;
m_motiontype = MOTION_IN;
m_align = 0;
m_flags = 0;
m_dying = false;
m_ordernum = 0;
m_configstring_index = -1;
m_iFontAlignmentHorizontal = FONT_JUSTHORZ_CENTER;
m_iFontAlignmentVertical = FONT_JUSTVERT_CENTER;
m_bVirtual = false;
m_scaleCvar = NULL;
m_enabledCvar = "";
m_fadeSequenceDelay = 0;
m_fadeSequenceFadeIn = 0;
m_fadeSequenceHold = 0;
m_fadeSequenceFadeOut = 0;
m_fadeSequenceState = fadesequence_t::SEQUENCE_NONE;
m_fadeSequenceLastTime = 0;
UIRect2D frame(6.0f, 6.0f, 100.0f, 13.0f);
setFrame(frame);
lastShowTime = -1;
}
UIWidget::~UIWidget()
{
//int i;
m_dying = true;
if (IsActive()) {
uWinMan.DeactivateCurrentSmart();
}
//for( i = m_children.NumObjects(); i > 0; i-- ) {
//
//}
// remove this child from our parent
if (m_parent) {
m_parent->removeChild(this);
}
// delete font
if (m_font) {
delete m_font;
m_font = NULL;
}
SendSignal(W_Destroyed);
}
bool UIWidget::addChild(UIWidget *widget)
{
if (m_children.ObjectInList(widget)) {
return false;
}
m_children.AddObject(widget);
if (m_children.NumObjects() != 1) {
UIWidget *child = m_children.ObjectAt(m_children.NumObjects() - 1);
if ((child->m_flags & (WF_ALWAYS_TOP | WF_ALWAYS_BOTTOM))
!= (widget->m_flags & (WF_ALWAYS_TOP | WF_ALWAYS_BOTTOM))) {
ArrangeWidgetList(m_children);
}
}
return true;
}
bool UIWidget::removeChild(UIWidget *widget)
{
if (m_children.ObjectInList(widget)) {
m_children.RemoveObject(widget);
return true;
}
return false;
}
void UIWidget::PropogateCoordinateSystem(void)
{
int i;
int n;
UIWidget *subview;
if (m_parent) {
if (m_parent->m_scaleCvar) {
m_scaleCvar = m_parent->m_scaleCvar;
}
}
if (!m_parent || (m_flags & WF_NOPARENTADJUST)) {
m_screenorigin = m_origin;
m_clippedorigin = m_origin;
m_screenframe = m_frame;
m_clippedframe = m_frame;
} else {
m_screenframe.pos.x = m_frame.pos.x + m_parent->m_screenorigin.x;
m_screenframe.pos.y = m_frame.pos.y + m_parent->m_screenorigin.y;
m_screenframe.size = m_frame.size;
m_screenorigin.x = m_screenframe.pos.x - m_origin.x;
m_screenorigin.y = m_screenframe.pos.y - m_origin.y;
m_clippedframe = m_screenframe;
m_clippedorigin.x = -m_origin.x;
m_clippedorigin.y = -m_origin.y;
}
if (m_parent && !(m_flags & WF_DIRECTED)) {
if (m_parent->m_clippedframe.pos.x > m_clippedframe.pos.x) {
m_clippedframe.size.width -= (m_parent->m_clippedframe.pos.x - m_clippedframe.pos.x);
if (m_clippedframe.size.width < 0.0) {
m_clippedframe.size.width = 0.0;
}
m_clippedframe.pos.x = m_parent->m_clippedframe.pos.x;
}
if (m_parent->m_clippedframe.pos.y > m_clippedframe.pos.y) {
m_clippedframe.size.height -= (m_parent->m_clippedframe.pos.y - m_clippedframe.pos.y);
if (m_clippedframe.size.height < 0.0) {
m_clippedframe.size.height = 0.0;
}
m_clippedframe.pos.y = m_parent->m_clippedframe.pos.y;
}
if (m_parent->m_clippedframe.getMaxX() < m_clippedframe.getMaxX()) {
m_clippedframe.size.width = m_parent->m_clippedframe.getMaxX() - m_clippedframe.pos.x;
if (m_clippedframe.size.width < 0.0) {
m_clippedframe.size.width = 0.0;
}
}
if (m_parent->m_clippedframe.getMaxY() < m_clippedframe.getMaxY()) {
m_clippedframe.size.height = m_parent->m_clippedframe.getMaxY() - m_clippedframe.pos.y;
if (m_clippedframe.size.height < 0.0) {
m_clippedframe.size.height = 0.0;
}
}
}
n = m_children.NumObjects();
for (i = 1; i <= n; i++) {
subview = m_children.ObjectAt(i);
subview->PropogateCoordinateSystem();
}
}
void UIWidget::set2D(void)
{
uii.Rend_Set2D(
m_screenframe.pos.x,
uid.vidHeight - (int)(m_screenframe.size.height + m_screenframe.pos.y),
m_screenframe.size.width,
m_screenframe.size.height,
m_clippedorigin.x,
m_clippedorigin.x + m_screenframe.size.width,
m_clippedorigin.y + m_screenframe.size.height,
m_clippedorigin.y,
-1.0,
1.0
);
uii.Rend_Scissor(
m_clippedframe.pos.x,
uid.vidHeight - (int)(m_clippedframe.size.height + m_clippedframe.pos.y),
m_clippedframe.size.width,
m_clippedframe.size.height
);
//
// Added in OPM
//
if (lastShowTime == -1) {
lastShowTime = uii.Sys_Milliseconds() / 1000.0;
}
uii.Rend_Set2DStartTime(lastShowTime);
}
void UIWidget::Draw(void) {}
void UIWidget::FrameInitialized(void)
{
if (m_fadeSequenceDelay || m_fadeSequenceFadeIn || m_fadeSequenceHold || m_fadeSequenceFadeOut) {
m_fadeSequenceRemainingTime = m_fadeSequenceDelay;
m_fadeSequenceState = fadesequence_t::SEQUENCE_STARTING;
}
}
void UIWidget::DrawTitle(float x, float y)
{
m_font->setColor(m_foreground_color);
m_font->Print(x, y, Sys_LV_CL_ConvertString(m_title), -1, getVirtualScale());
}
void UIWidget::Motion(void)
{
float t;
float frac;
int i;
float nx, ny;
t = uid.time / 1000.0;
if (m_fadeSequenceState != fadesequence_t::SEQUENCE_NONE) {
// Added in 2.0
// Process fade sequence
if (!paused->integer) {
switch (m_fadeSequenceState) {
case fadesequence_t::SEQUENCE_STARTING:
m_alpha = 0.0;
m_fadeSequenceRemainingTime -= t - m_fadeSequenceLastTime;
if (m_fadeSequenceRemainingTime < 0) {
m_fadeSequenceState = fadesequence_t::SEQUENCE_FADEIN;
m_fadeSequenceRemainingTime = m_fadeSequenceFadeIn;
}
break;
case fadesequence_t::SEQUENCE_FADEIN:
m_alpha = 1.0 - m_fadeSequenceRemainingTime / m_fadeSequenceFadeIn;
m_fadeSequenceRemainingTime -= t - m_fadeSequenceLastTime;
if (m_fadeSequenceRemainingTime < 0) {
m_fadeSequenceState = fadesequence_t::SEQUENCE_HOLD;
m_fadeSequenceRemainingTime = m_fadeSequenceHold;
}
break;
case fadesequence_t::SEQUENCE_HOLD:
m_alpha = 1.0;
m_fadeSequenceRemainingTime -= t - m_fadeSequenceLastTime;
if (m_fadeSequenceRemainingTime < 0) {
m_fadeSequenceState = fadesequence_t::SEQUENCE_FADEOUT;
m_fadeSequenceRemainingTime = m_fadeSequenceFadeOut;
}
break;
case fadesequence_t::SEQUENCE_FADEOUT:
m_alpha = m_fadeSequenceRemainingTime / m_fadeSequenceFadeOut;
m_fadeSequenceRemainingTime -= (t - m_fadeSequenceLastTime);
if (m_fadeSequenceRemainingTime < 0) {
// Fade sequence has finished fading
m_alpha = 0;
m_fadeSequenceState = fadesequence_t::SEQUENCE_NONE;
}
break;
default:
break;
}
}
m_fadeSequenceLastTime = t;
} else if (m_fadetime >= 0.0) {
frac = (t - m_starttime) / m_fadetime;
m_alpha = frac;
if (m_alpha > 1.0) {
m_alpha = 1.0;
}
if (m_motiontype == MOTION_OUT) {
m_alpha = 1.0 - m_alpha;
}
}
if (m_direction) {
frac = (t - m_starttime) / m_motiontime;
if (m_motiontype == MOTION_OUT) {
frac = 1.0 - frac;
if (frac <= 0.0) {
switch (m_direction) {
case D_FROM_BOTTOM:
setFrame(UIRect2D(m_frame.pos.x, uid.vidHeight, m_frame.size.width, m_frame.size.height));
break;
case D_FROM_TOP:
setFrame(UIRect2D(
m_frame.pos.x,
-m_frame.size.height - m_parent->m_screenorigin.y,
m_frame.size.width,
m_frame.size.height
));
break;
case D_FROM_LEFT:
setFrame(UIRect2D(
-m_frame.size.width - m_parent->m_screenorigin.x,
m_frame.pos.y,
m_frame.size.width,
m_frame.size.height
));
break;
case D_FROM_RIGHT:
setFrame(UIRect2D(uid.vidWidth, m_frame.pos.y, m_frame.size.width, m_frame.size.height));
break;
default:
setFrame(UIRect2D(m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height));
break;
}
m_direction = D_NONE;
}
} else {
if (frac >= 1.0) {
// done moving
setFrame(UIRect2D(m_startingpos, m_frame.size));
FrameInitialized();
for (i = 1; i <= m_children.NumObjects(); i++) {
m_children.ObjectAt(i)->FrameInitialized();
}
m_direction = D_NONE;
}
}
}
switch (m_direction) {
case D_FROM_LEFT:
nx = 0;
if (m_parent) {
nx = m_frame.size.width + m_parent->m_screenorigin.x;
}
nx = (m_startingpos.x + nx) * frac - nx;
ny = m_frame.pos.y;
setFrame(UIRect2D(nx, ny, m_frame.size.width, m_frame.size.height));
break;
case D_FROM_RIGHT:
nx = uid.vidWidth - (uid.vidWidth - m_startingpos.x) * frac;
ny = m_frame.pos.y;
setFrame(UIRect2D(nx, ny, m_frame.size.width, m_frame.size.height));
break;
case D_FROM_BOTTOM:
nx = m_frame.pos.x;
ny = uid.vidHeight - (uid.vidHeight - m_startingpos.y) * frac;
setFrame(UIRect2D(nx, ny, m_frame.size.width, m_frame.size.height));
break;
case D_FROM_TOP:
nx = m_frame.pos.y;
ny = 0;
if (m_parent) {
ny = m_frame.size.height + m_parent->m_screenorigin.y;
}
ny = (m_startingpos.y + ny) * frac - ny;
setFrame(UIRect2D(nx, ny, m_frame.size.width, m_frame.size.height));
break;
default:
break;
}
if (m_direction == D_NONE) {
//
// play a sound to indicate the motion has finished
if (m_stopsound.length()) {
uii.Snd_PlaySound(m_stopsound);
}
}
}
void UIWidget::AlignPosition(void)
{
if (m_bVirtual) {
vec2_t vNewVirtualScale;
SetVirtualScale(vNewVirtualScale);
scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
} else if (uid.bHighResScaling) {
scaleFrameVirtualRes(m_frame, m_vVirtualScale, uid.scaleRes);
} else {
vec2_t vNewVirtualScale = {1.0, 1.0};
scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
}
if (m_flags & WF_STRETCH_VERTICAL) {
m_frame.pos.y = 0;
m_frame.size.height = uid.vidHeight;
}
if (m_flags & WF_STRETCH_HORIZONTAL) {
m_frame.pos.x = 0;
m_frame.size.width = uid.vidWidth;
}
if (m_align & WA_CENTERX) {
m_frame.pos.x = uid.vidWidth * 0.5 - m_frame.size.width * 0.5;
}
if (m_align & WA_RIGHT) {
m_frame.pos.x = uid.vidWidth - m_frame.size.width;
} else if (m_align & WA_LEFT) {
m_frame.pos.x = 0;
}
if (m_align & WA_CENTERY) {
m_frame.pos.y = uid.vidHeight * 0.5 - m_frame.size.height * 0.5;
}
if (m_align & WA_BOTTOM) {
m_frame.pos.y = uid.vidHeight - m_frame.size.height;
} else if (m_align & WA_TOP) {
m_frame.pos.y = 0;
}
setFrame(m_frame);
}
void UIWidget::Hide(Event *ev)
{
setShow(false);
}
void UIWidget::Activate(Event *ev)
{
uWinMan.ActivateControl(this);
}
void UIWidget::BringToFront(void)
{
UIWidget *me;
if (m_parent->m_children.NumObjects() > 1) {
me = m_parent->m_children.ObjectAt(m_parent->m_children.NumObjects());
if (me != this) {
m_parent->m_children.RemoveObject(this);
m_parent->m_children.AddObject(this);
if ((m_parent->m_children.ObjectAt(m_parent->m_children.NumObjects() - 1)->m_flags & 0x30)
!= (m_flags & 0x30)) {
ArrangeWidgetList(m_parent->m_children);
}
}
}
}
void UIWidget::SplitWidgets(
Container<UIWidget *>& src, Container<UIWidget *>& bottom, Container<UIWidget *>& normal, Container<UIWidget *>& top
)
{
int i;
bottom.FreeObjectList();
normal.FreeObjectList();
top.FreeObjectList();
for (i = 1; i <= src.NumObjects(); i++) {
UIWidget *wid = src.ObjectAt(i);
if (wid->m_flags & 0x10) {
bottom.AddObject(wid);
} else if (wid->m_flags & 0x20) {
top.AddObject(wid);
} else {
normal.AddObject(wid);
}
}
}
void UIWidget::CombineWidgets(
Container<UIWidget *>& dst, Container<UIWidget *>& bottom, Container<UIWidget *>& normal, Container<UIWidget *>& top
)
{
Container<UIWidget *> *lists[3];
int list;
int i;
dst.ClearObjectList();
lists[0] = &bottom;
lists[1] = &normal;
lists[2] = &top;
for (list = 0; list < 3; list++) {
for (i = 1; i <= lists[list]->NumObjects(); i++) {
dst.AddObject(lists[list]->ObjectAt(i));
}
}
}
void UIWidget::ArrangeWidgetList(Container<UIWidget *>& list)
{
Container<UIWidget *> bottom;
Container<UIWidget *> normal;
Container<UIWidget *> top;
SplitWidgets(list, bottom, normal, top);
CombineWidgets(list, bottom, normal, top);
}
void UIWidget::Shutdown(void)
{
int i;
if (IsActive()) {
uWinMan.DeactivateCurrentSmart();
}
// notify childs
for (i = m_children.NumObjects(); i > 0; i--) {
UIWidget *wid = m_children.ObjectAt(i);
wid->Shutdown();
delete wid;
}
if (m_font) {
delete m_font;
m_font = NULL;
}
}
void UIWidget::InitFrame(
UIWidget *parentview, float x, float y, float width, float height, int border, const char *fontname
)
{
if (border != -1) {
setBorderStyle((borderstyle_t)border);
}
setFrame(UIRect2D(x, y, width, height));
if (parentview) {
setParent(parentview);
} else if (this != &uWinMan) {
setParent(&uWinMan);
}
m_startingpos = m_frame.pos;
setFont(fontname);
FrameInitialized();
}
void UIWidget::InitFrame(UIWidget *parentview, const UIRect2D& r, int border, const char *fontname)
{
InitFrame(parentview, r.pos.x, r.pos.y, r.size.width, r.size.height, border, fontname);
}
void UIWidget::LayoutSize(Event *ev)
{
LayoutRect(ev);
}
void UIWidget::LayoutRect(Event *ev)
{
UIPoint2D pos;
UISize2D size;
if (ev->NumArgs() == 4) {
pos.x = ev->GetFloat(1);
pos.y = ev->GetFloat(2);
size.width = ev->GetFloat(3);
size.height = ev->GetFloat(4);
setFrame(UIRect2D(pos, size));
m_startingpos = pos;
}
}
void UIWidget::LayoutName(Event *ev)
{
setName(ev->GetString(1));
}
void UIWidget::LayoutTitle(Event *ev)
{
setTitle(ev->GetString(1));
}
void UIWidget::LayoutFont(Event *ev)
{
setFont(ev->GetString(1));
}
void UIWidget::LayoutBgColor(Event *ev)
{
setBackgroundColor(UColor(ev->GetFloat(1), ev->GetFloat(2), ev->GetFloat(3), ev->GetFloat(4)), true);
}
void UIWidget::LayoutFgColor(Event *ev)
{
setForegroundColor(UColor(ev->GetFloat(1), ev->GetFloat(2), ev->GetFloat(3), ev->GetFloat(4)));
}
void UIWidget::LayoutBorderStyle(Event *ev)
{
str style = ev->GetString(1);
if (!stricmp(style, "NONE")) {
setBorderStyle(border_none);
} else if (!stricmp(style, "3D_BORDER")) {
setBorderStyle(border_3D);
} else if (!stricmp(style, "INDENT_BORDER")) {
setBorderStyle(border_indent);
}
}
void UIWidget::LayoutBorderColor(Event *ev)
{
setBorderColor(UColor(ev->GetFloat(1), ev->GetFloat(2), ev->GetFloat(3), ev->GetFloat(4)));
}
void UIWidget::LayoutShader(Event *ev)
{
setMaterial(uWinMan.RegisterShader(ev->GetString(1)));
m_flags &= ~WF_TILESHADER;
}
void UIWidget::LayoutTileShader(Event *ev)
{
setMaterial(uWinMan.RegisterShader(ev->GetString(1)));
m_flags |= WF_TILESHADER;
}
void UIWidget::LayoutHoverShader(Event *ev)
{
setHoverMaterial(uWinMan.RegisterShader(ev->GetString(1)));
}
void UIWidget::LayoutPressedShader(Event *ev)
{
setPressedMaterial(uWinMan.RegisterShader(ev->GetString(1)));
}
void UIWidget::LayoutFadeIn(Event *ev)
{
m_fadetime = ev->GetFloat(1);
if (m_motiontime != 0.0) {
setMotionTime(m_fadetime);
}
}
void UIWidget::LayoutStopSound(Event *ev)
{
m_stopsound = ev->GetString(1);
uii.Snd_RegisterSound(m_stopsound, false);
}
void UIWidget::LayoutClickSound(Event *ev)
{
m_clicksound = ev->GetString(1);
uii.Snd_RegisterSound(m_clicksound, false);
}
void UIWidget::LayoutStretch(Event *ev)
{
str stretch = ev->GetString(1);
if (!stricmp(stretch, "vertical")) {
m_flags |= WF_STRETCH_VERTICAL;
} else if (!stricmp(stretch, "horizontal")) {
m_flags |= WF_STRETCH_HORIZONTAL;
} else if (!stricmp(stretch, "both")) {
m_flags |= WF_STRETCH_VERTICAL | WF_STRETCH_HORIZONTAL;
}
m_flags |= WF_NOPARENTADJUST | WF_DIRECTED;
}
void UIWidget::LayoutVirtualRes(Event *ev)
{
if (ev->GetInteger(1)) {
m_bVirtual = true;
}
}
void UIWidget::LayoutInitData(Event *ev)
{
if (m_cvarname.length()) {
uii.Cvar_Set(m_cvarname, ev->GetString(1));
}
}
void UIWidget::LayoutDirection(Event *ev)
{
str direction = ev->GetString(1);
if (!stricmp(direction, "from_bottom")) {
setDirection(D_FROM_BOTTOM);
} else if (!stricmp(direction, "from_top")) {
setDirection(D_FROM_TOP);
} else if (!stricmp(direction, "from_left")) {
setDirection(D_FROM_LEFT);
} else if (!stricmp(direction, "from_right")) {
setDirection(D_FROM_RIGHT);
} else {
setDirection(D_NONE);
}
if (ev->NumArgs() > 1) {
setMotionTime(ev->GetFloat(2));
}
m_flags |= WF_DIRECTED;
}
void UIWidget::LayoutAlign(Event *ev)
{
for (int i = 1; i <= ev->NumArgs(); i++) {
str align = ev->GetString(i);
if (!stricmp(align, "left")) {
m_align |= WA_LEFT;
} else if (!stricmp(align, "right")) {
m_align |= WA_RIGHT;
} else if (!stricmp(align, "top")) {
m_align |= WA_TOP;
} else if (!stricmp(align, "bottom")) {
m_align |= WA_BOTTOM;
} else if (!stricmp(align, "centerx")) {
m_align |= WA_CENTERX;
} else if (!stricmp(align, "centery")) {
m_align |= WA_CENTERY;
}
}
if (!isSubclassOf(UIWidgetContainer)) {
m_flags |= WF_NOPARENTADJUST | WF_DIRECTED;
}
}
void UIWidget::LayoutStuffCommand(Event *ev)
{
LinkCommand(ev->GetString(1));
}
void UIWidget::LayoutLinkCvar(Event *ev)
{
LinkCvar(ev->GetString(1));
}
void UIWidget::LayoutNoParentClipping(Event *ev)
{
m_flags |= WF_DIRECTED;
}
void UIWidget::LayoutNoParentAdjustment(Event *ev)
{
m_flags |= WF_NOPARENTADJUST;
}
void UIWidget::LayoutOrderNumber(Event *ev)
{
m_ordernum = ev->GetInteger(1);
}
void UIWidget::TextAlignment(Event *ev)
{
for (int i = 1; i <= ev->NumArgs(); i++) {
str align = ev->GetString(1);
if (!stricmp(align, "left")) {
setFontHorizontalAlignment(FONT_JUSTHORZ_LEFT);
} else if (!stricmp(align, "right")) {
setFontHorizontalAlignment(FONT_JUSTHORZ_RIGHT);
} else if (!stricmp(align, "top")) {
setFontVerticalAlignment(FONT_JUSTVERT_TOP);
} else if (!stricmp(align, "bottom")) {
setFontVerticalAlignment(FONT_JUSTVERT_BOTTOM);
} else if (!stricmp(align, "centerx")) {
setFontHorizontalAlignment(FONT_JUSTHORZ_CENTER);
} else if (!stricmp(align, "centery")) {
setFontVerticalAlignment(FONT_JUSTVERT_CENTER);
}
}
}
void UIWidget::LayoutAliasCache(Event *ev)
{
int i;
str parms;
str realSound;
if (ev->NumArgs() <= 1) {
return;
}
for (i = 3; i <= ev->NumArgs(); i++) {
parms += ev->GetToken(i);
parms += " ";
}
realSound = ev->GetString(2);
uii.Alias_Add(parms, realSound, parms);
if (strstr(realSound, ".wav") || strstr(realSound, ".mp3")) {
uii.Snd_RegisterSound(realSound, false);
}
}
void UIWidget::setParent(UIWidget *parent)
{
if (m_parent) {
m_parent->removeChild(this);
}
m_parent = parent;
if (m_parent) {
m_parent->addChild(this);
}
PropogateCoordinateSystem();
}
UIWidget *UIWidget::getParent(void)
{
return m_parent;
}
UIWidget *UIWidget::getFirstChild(void)
{
if (m_children.NumObjects() > 0) {
return m_children.ObjectAt(1);
}
return NULL;
}
UIWidget *UIWidget::getNextSibling(void)
{
if (m_parent) {
return m_parent->getNextChild(this);
}
return NULL;
}
UIWidget *UIWidget::getNextChild(UIWidget *child)
{
int index = m_children.IndexOfObject(child);
if (index && m_children.NumObjects() != index) {
return m_children.ObjectAt(index + 1);
}
return NULL;
}
UIWidget *UIWidget::getPrevChild(UIWidget *child)
{
int index;
if (child) {
index = m_children.IndexOfObject(child);
} else {
index = m_children.NumObjects();
}
if (index > 1) {
return m_children.ObjectAt(index - 1);
}
return NULL;
}
UIWidget *UIWidget::getPrevSibling(void)
{
if (m_parent) {
return m_parent->getPrevChild(this);
}
return NULL;
}
UIWidget *UIWidget::getPrevSibling(UIWidget *curr)
{
if (m_parent) {
return m_parent->getPrevChild(curr);
}
return NULL;
}
UIWidget *UIWidget::getLastSibling(void)
{
if (m_parent && m_children.NumObjects()) {
UIWidget *wid = m_parent->m_children.ObjectAt(m_parent->m_children.NumObjects());
if (wid == this) {
return getPrevSibling();
} else {
return wid;
}
} else {
return NULL;
}
}
UIWidget *UIWidget::findSibling(str name)
{
UIWidget *wid;
for (wid = getLastSibling(); wid != NULL; wid = getPrevSibling(wid)) {
if (wid->getName() == name) {
return wid;
}
}
return NULL;
}
void UIWidget::Enable(void)
{
int n;
int i;
setShow(true);
m_enabled = true;
n = m_children.NumObjects();
for (i = 1; i <= n; i++) {
m_children.ObjectAt(i)->Enable();
}
}
void UIWidget::Disable(void)
{
int n;
int i;
PostEvent(EV_Widget_Hide, 0);
m_enabled = false;
n = m_children.NumObjects();
for (i = 1; i <= n; i++) {
m_children.ObjectAt(i)->Disable();
}
// Added in OPM
lastShowTime = -1;
}
bool UIWidget::isEnabled(void)
{
if (!strcmp(m_enabledCvar.c_str(), "")) {
return m_enabled;
}
if (m_enabledCvar[0] == '!') {
//
// Added in 2.30
// True if the cvar is 0
if (m_enabled) {
return !UI_GetCvarInt(m_enabledCvar.c_str() + 1, 0);
}
} else {
if (m_enabled) {
return UI_GetCvarInt(m_enabledCvar.c_str(), 0) != 0;
}
}
return false;
}
bool UIWidget::IsDying(void)
{
return m_dying;
}
UIWidget *UIWidget::FindResponder(const UIPoint2D& pos)
{
UIWidget *subview;
UIWidget *responder;
int i;
if (!m_visible || !m_clippedframe.contains(pos)) {
return NULL;
}
for (i = m_children.NumObjects(); i >= 1; i--) {
subview = m_children.ObjectAt(i);
responder = subview->FindResponder(pos);
if (responder) {
return responder;
}
}
return this;
}
void UIWidget::setFont(const char *name)
{
if (m_font) {
delete m_font;
}
m_font = new UIFont(name);
}
void UIWidget::setFontHorizontalAlignment(fonthorzjustify_t alignment)
{
m_iFontAlignmentHorizontal = alignment;
}
void UIWidget::setFontVerticalAlignment(fontvertjustify_t alignment)
{
m_iFontAlignmentVertical = alignment;
}
void UIWidget::setShow(bool visible)
{
m_visible = visible;
if (!visible) {
if (IsThisOrChildActive()) {
uWinMan.DeactivateCurrentSmart();
}
// Added in OPM
lastShowTime = -1;
}
}
bool UIWidget::getShow(void)
{
return m_visible;
}
UColor UIWidget::getBackgroundColor(void)
{
return m_background_color;
}
void UIWidget::setBackgroundColor(const UColor& color, bool setbordercolor)
{
m_background_color = color;
if (setbordercolor) {
setBorderColor(color);
}
}
UBorderColor UIWidget::getBorderColor(void)
{
return m_border_color;
}
void UIWidget::setBorderColor(const UBorderColor& color)
{
m_border_color = color;
}
UColor UIWidget::getForegroundColor(void)
{
return m_foreground_color;
}
void UIWidget::setForegroundColor(const UColor& color)
{
m_foreground_color = color;
}
borderstyle_t UIWidget::getBorderStyle(void)
{
return m_borderStyle;
}
void UIWidget::setBorderStyle(borderstyle_t style)
{
m_borderStyle = style;
}
UISize2D UIWidget::getSize(void)
{
return m_frame.size;
}
void UIWidget::setSize(const UISize2D& newsize)
{
if (newsize.width != m_frame.size.width || newsize.height != m_frame.size.height) {
m_frame.size = newsize;
PropogateCoordinateSystem();
SendSignal(W_SizeChanged);
}
}
UIRect2D UIWidget::getFrame(void)
{
return m_frame;
}
void UIWidget::setFrame(const UIRect2D& newframe)
{
bool bNewSize;
bNewSize = newframe.size != m_frame.size;
m_frame = newframe;
PropogateCoordinateSystem();
SendSignal(W_FrameChanged);
if (bNewSize) {
SendSignal(W_SizeChanged);
}
}
UIPoint2D UIWidget::getOrigin(void)
{
return m_origin;
}
void UIWidget::setOrigin(const UIPoint2D& neworigin)
{
if (neworigin != m_origin) {
m_origin = neworigin;
PropogateCoordinateSystem();
}
}
void UIWidget::setName(str name)
{
m_name = name;
}
const char *UIWidget::getName(void)
{
return m_name;
}
void UIWidget::setTitle(str title)
{
m_title = title;
}
const char *UIWidget::getTitle(void)
{
return m_title;
}
void UIWidget::setDirection(direction_t dir)
{
m_direction = dir;
m_direction_orig = dir;
}
direction_t UIWidget::getDirection(void)
{
return m_direction;
}
void UIWidget::setMotionType(motion_t type)
{
m_motiontype = type;
}
motion_t UIWidget::getMotionType(void)
{
return m_motiontype;
}
void UIWidget::setMotionTime(float time)
{
m_motiontime = time;
}
float UIWidget::getMotionTime(void)
{
return m_motiontime;
}
void UIWidget::setAlign(int align)
{
m_align = align;
}
int UIWidget::getAlign(void)
{
return m_align;
}
void UIWidget::setMaterial(UIReggedMaterial *mat)
{
m_material = mat;
}
void UIWidget::setHoverMaterial(UIReggedMaterial *mat)
{
m_hovermaterial = mat;
}
void UIWidget::setPressedMaterial(UIReggedMaterial *mat)
{
m_pressedmaterial = mat;
}
UIPoint2D UIWidget::getLocalPoint(const UIPoint2D& pos)
{
if (m_parent) {
return UIPoint2D(pos.x - m_screenframe.pos.x, pos.y - m_screenframe.pos.y);
} else {
return pos;
}
}
UIPoint2D UIWidget::getGlobalPoint(const UIPoint2D& pos)
{
if (m_parent) {
return UIPoint2D(pos.x + m_screenframe.pos.x, pos.y + m_screenframe.pos.y);
} else {
return pos;
}
}
void UIWidget::setBackgroundAlpha(float f)
{
m_alpha = f;
}
float UIWidget::getBackgroundAlpha(void)
{
return m_alpha;
}
void UIWidget::Display(const UIRect2D& drawframe, float parent_alpha)
{
int i;
int n;
vec4_t col = {1, 1, 1, 1};
if (!isEnabled()) {
lastShowTime = -1;
return;
}
if (!m_enabledCvar.length() && !IsVisible()) {
return;
}
if (m_direction || m_fadetime || m_fadeSequenceState != fadesequence_t::SEQUENCE_NONE) {
Motion();
}
m_local_alpha = m_alpha * parent_alpha;
set2D();
col[3] = m_local_alpha;
uii.Rend_SetColor(col);
if (m_background_color.a != 0.0) {
DrawBox(
0, 0, m_frame.size.width, m_frame.size.height, m_background_color, m_background_color.a * m_local_alpha
);
}
if (m_borderStyle == border_outline) {
DrawBoxWithSolidBorder(
UIRect2D(0, 0, m_frame.size.width, m_frame.size.height),
UWhite,
m_border_color.original,
2,
2,
m_local_alpha
);
} else if (m_borderStyle) {
Draw3DBox(
0, 0, m_frame.size.width, m_frame.size.height, m_borderStyle == border_indent, m_border_color, m_local_alpha
);
}
if (m_material) {
col[0] = m_foreground_color.r;
col[1] = m_foreground_color.g;
col[2] = m_foreground_color.b;
col[3] = m_foreground_color.a * m_local_alpha;
uii.Rend_SetColor(col);
if (m_flags & WF_TILESHADER) {
if (m_bVirtual) {
float fvWidth =
m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_material->GetMaterial());
float fvHeight =
m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_material->GetMaterial());
uii.Rend_DrawPicStretched(
0, 0, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_material->GetMaterial()
);
} else {
uii.Rend_DrawPicTiled(0, 0, m_frame.size.width, m_frame.size.height, m_material->GetMaterial());
}
} else {
uii.Rend_DrawPicStretched(
0, 0, m_frame.size.width, m_frame.size.height, 0, 0, 1, 1, m_material->GetMaterial()
);
}
}
if (m_pressedmaterial_active && m_pressedmaterial != NULL) {
uii.Rend_DrawPicStretched(
0, 0, m_frame.size.width, m_frame.size.height, 0, 0, 1, 1, m_pressedmaterial->GetMaterial()
);
} else if (m_hovermaterial_active && m_hovermaterial != NULL) {
uii.Rend_DrawPicStretched(
0, 0, m_frame.size.width, m_frame.size.height, 0, 0, 1, 1, m_hovermaterial->GetMaterial()
);
}
Draw();
n = m_children.NumObjects();
for (i = 1; i <= m_children.NumObjects(); i++) {
m_children.ObjectAt(i)->Display(m_frame, m_local_alpha);
}
}
qboolean UIWidget::KeyEvent(int key, unsigned int time)
{
return qfalse;
}
void UIWidget::CharEvent(int ch) {}
void UIWidget::UpdateData(void) {}
void UIWidget::UpdateUIElement(void) {}
float UIWidget::getTitleWidth(void)
{
return m_font->getWidth(getTitle(), -1);
}
float UIWidget::getTitleHeight(void)
{
return m_font->getHeight(getVirtualScale());
}
bool UIWidget::CanActivate(void)
{
if (!m_canactivate || m_dying) {
return false;
}
for (UIWidget *wid = this; wid != NULL; wid = wid->getParent()) {
if (!wid->getShow()) {
return false;
}
}
return true;
}
void UIWidget::AllowActivate(bool canactivate)
{
m_canactivate = canactivate;
}
bool UIWidget::IsActive(void)
{
return uWinMan.ActiveControl() == this;
}
bool UIWidget::IsVisible(void)
{
return m_visible;
}
void UIWidget::LinkCvar(str cvarname)
{
m_cvarname = cvarname;
}
void UIWidget::LinkCommand(str cmd)
{
m_command = cmd;
}
void UIWidget::ExecuteShowCommands(void)
{
for (int i = 1; i <= m_showcommands.NumObjects(); i++) {
//uii.Cmd_Stuff( m_showcommands.ObjectAt( i )->c_str() );
// Fixed in 2.0
Event event(m_showcommands.ObjectAt(i)->c_str());
ProcessEvent(event);
}
}
void UIWidget::ExecuteHideCommands(void)
{
for (int i = 1; i <= m_hidecommands.NumObjects(); i++) {
//uii.Cmd_Stuff( m_hidecommands.ObjectAt( i )->c_str() );
// Fixed in 2.0
Event event(m_hidecommands.ObjectAt(i)->c_str());
ProcessEvent(event);
}
}
void UIWidget::InitializeCommandHandler(void (*fcn)(const char *, void *))
{
m_commandhandler = fcn;
}
UIWidget *UIWidget::FindWidget(str name)
{
int i;
int n;
n = m_children.NumObjects();
for (i = 1; i <= n; i++) {
UIWidget *wid = m_children.ObjectAt(i);
if (wid->getName() == name) {
return wid;
}
UIWidget *w = wid->FindWidget(name);
if (w) {
return w;
}
}
return NULL;
}
void UIWidget::ResetMotion(motion_t type)
{
AlignPosition();
m_direction = m_direction_orig;
m_motiontype = type;
if (type == MOTION_IN) {
if (m_direction == D_FROM_BOTTOM) {
UIPoint2D point(m_frame.pos.x, uid.vidHeight);
setFrame(UIRect2D(point, m_frame.size));
} else if (m_direction == D_FROM_TOP) {
UIPoint2D point(m_frame.pos.x, -m_frame.size.height - m_parent->m_screenorigin.y);
setFrame(UIRect2D(point, m_frame.size));
} else if (m_direction == D_FROM_LEFT) {
UIPoint2D point(-m_frame.size.width - m_parent->m_screenorigin.x, m_frame.pos.y);
setFrame(UIRect2D(point, m_frame.size));
} else if (m_direction == D_FROM_RIGHT) {
UIPoint2D point(uid.vidWidth, m_frame.pos.y);
setFrame(UIRect2D(point, m_frame.size));
} else {
setFrame(m_frame);
FrameInitialized();
}
}
m_starttime = uid.time / 1000.0;
// Added in 2.0
m_fadeSequenceLastTime = uid.time / 1000.0;
}
void UIWidget::Realign(void)
{
bool bScaled = false;
if (m_bVirtual) {
vec2_t vNewVirtualScale;
SetVirtualScale(vNewVirtualScale);
scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
bScaled = true;
} else if (uid.bHighResScaling) {
scaleFrameVirtualRes(m_frame, m_vVirtualScale, uid.scaleRes);
bScaled = true;
} else {
vec2_t vNewVirtualScale = {1.0, 1.0};
bScaled = scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
}
if (m_flags & WF_STRETCH_VERTICAL) {
m_frame.pos.y = 0;
m_frame.size.height = uid.vidHeight;
}
if (m_flags & WF_STRETCH_HORIZONTAL) {
m_frame.pos.x = 0;
m_frame.size.width = uid.vidWidth;
}
if (m_align & WA_CENTERX) {
m_frame.pos.x = uid.vidWidth * 0.5 - m_frame.size.width * 0.5;
}
if (m_align & WA_RIGHT) {
m_frame.pos.x = uid.vidWidth - m_frame.size.width;
} else if (m_align & WA_LEFT) {
m_frame.pos.x = 0;
}
if (m_align & WA_CENTERY) {
m_frame.pos.y = uid.vidHeight * 0.5 - m_frame.size.height * 0.5;
}
if (m_align & WA_BOTTOM) {
m_frame.pos.y = uid.vidHeight - m_frame.size.height;
} else if (m_align & WA_TOP) {
m_frame.pos.y = 0;
}
if ((m_align & WA_FULL) || (m_flags & (WF_STRETCH_HORIZONTAL | WF_STRETCH_VERTICAL)) || bScaled) {
setFrame(m_frame);
m_startingpos = m_frame.pos;
}
}
void UIWidget::BringToFrontPropogated(void)
{
for (UIWidget *at = this; at->getParent() != NULL; at = at->getParent()) {
at->BringToFront();
}
}
UIWidget *UIWidget::IsThisOrChildActive(void)
{
UIWidget *child = this;
if (child->IsActive()) {
return child;
}
for (int i = 1; i <= m_children.NumObjects(); i++) {
child = m_children.ObjectAt(i);
if (child->IsThisOrChildActive()) {
return child;
}
}
return NULL;
}
UIPoint2D UIWidget::MouseEventToClientPoint(Event *ev)
{
UIPoint2D p;
p.x = ev->GetFloat(1) - m_screenframe.pos.x;
p.y = ev->GetFloat(2) - m_screenframe.pos.y;
return p;
}
UIRect2D UIWidget::getClientFrame(void)
{
// don't return the position
return UIRect2D(UIPoint2D(0, 0), m_frame.size);
}
void UIWidget::setAlwaysOnBottom(bool b)
{
if (getAlwaysOnBottom() != b) {
if (b) {
m_flags &= ~WF_ALWAYS_TOP;
m_flags |= WF_ALWAYS_BOTTOM;
} else {
m_flags &= ~WF_ALWAYS_BOTTOM;
}
if (m_parent) {
ArrangeWidgetList(m_parent->m_children);
}
}
}
void UIWidget::setAlwaysOnTop(bool b)
{
if (getAlwaysOnTop() != b) {
if (b) {
m_flags &= ~WF_ALWAYS_BOTTOM;
m_flags |= WF_ALWAYS_TOP;
} else {
m_flags &= ~WF_ALWAYS_TOP;
}
if (m_parent) {
ArrangeWidgetList(m_parent->m_children);
}
}
}
bool UIWidget::getAlwaysOnBottom(void)
{
return (m_flags & WF_ALWAYS_BOTTOM) ? true : false;
}
bool UIWidget::getAlwaysOnTop(void)
{
return (m_flags & WF_ALWAYS_TOP) ? true : false;
}
bool UIWidget::SendSignal(Event& event)
{
if (uWinMan.IsDead()) {
return false;
} else {
return USignal::SendSignal(event);
}
}
void UIWidget::ShowCommand(Event *ev)
{
int i;
str *command = new str;
for (i = 1; i <= ev->NumArgs(); i++) {
*command += ev->GetToken(i);
}
m_showcommands.AddObject(command);
}
void UIWidget::HideCommand(Event *ev)
{
int i;
str *command = new str;
for (i = 1; i <= ev->NumArgs(); i++) {
*command += ev->GetToken(i);
}
m_hidecommands.AddObject(command);
}
void UIWidget::AddFlag(int flag)
{
m_flags |= flag;
}
void UIWidget::SetHovermaterialActive(bool a)
{
m_hovermaterial_active = a;
}
void UIWidget::SetPressedmaterialActive(bool a)
{
m_pressedmaterial_active = a;
}
int UIWidget::getOrderNum(void)
{
return m_ordernum;
}
str UIWidget::getCommand(void)
{
return m_command;
}
void UIWidget::ActivateOrder(void)
{
UIWidget *selwidget;
for (selwidget = this; selwidget != NULL; selwidget = selwidget->getParent()) {
if (selwidget->getParent() == &uWinMan) {
if (selwidget->isSubclassOf(UIWidgetContainer)) {
UIWidgetContainer *widcon = (UIWidgetContainer *)selwidget;
widcon->SetActiveWidgetOrderNum(this);
}
return;
}
}
}
void UIWidget::EnableEvent(Event *ev)
{
Enable();
}
void UIWidget::DisableEvent(Event *ev)
{
Disable();
}
void UIWidget::setConfigstringIndex(int cs)
{
m_configstring_index = cs;
}
int UIWidget::getConfigstringIndex(void)
{
return m_configstring_index;
}
bool UIWidget::PassEventToWidget(str name, Event *ev)
{
int i;
int n;
if (!isEnabled()) {
return false;
}
if (!str::cmp(name, m_name)) {
ProcessEvent(ev);
return true;
}
n = m_children.NumObjects();
for (i = 1; i <= n; i++) {
if (m_children.ObjectAt(i)->PassEventToWidget(name, ev)) {
return true;
}
}
return false;
}
UIFont *UIWidget::getFont() const
{
return m_font;
}
bool UIWidget::isVirtual() const
{
return m_bVirtual;
}
const vec2_t& UIWidget::getVirtualScale() const
{
if (m_bVirtual) {
return m_vVirtualScale;
} else {
return uid.scaleRes;
}
}
const vec2_t& UIWidget::getHighResScale() const
{
return uid.scaleRes;
}
void UIWidget::SetEnabledCvar(Event *ev)
{
m_enabledCvar = ev->GetString(1);
}
void UIWidget::SetScaleCvar(Event *ev)
{
m_scaleCvar = uii.Cvar_Find(ev->GetString(1).c_str());
}
void UIWidget::SetVirtualScale(vec2_t out)
{
if (m_scaleCvar) {
const float vidRatio = (float)uid.vidWidth / (float)uid.vidHeight;
const float minHeight = 480;
const float minWidth = minHeight * vidRatio;
out[0] = uid.vidWidth / minWidth * m_scaleCvar->value;
out[1] = uid.vidHeight / minHeight * m_scaleCvar->value;
} else {
out[0] = uid.vidWidth / 640.0;
out[1] = uid.vidHeight / 480.0;
}
}
void UIWidget::SetDontLocalize(Event *ev)
{
SetDontLocalize();
}
void UIWidget::EventFadeSequence(Event *ev)
{
m_fadeSequenceDelay = ev->GetFloat(1);
m_fadeSequenceFadeIn = ev->GetFloat(2);
m_fadeSequenceHold = ev->GetFloat(3);
m_fadeSequenceFadeOut = ev->GetFloat(4);
m_fadeSequenceRemainingTime = m_fadeSequenceDelay;
m_fadeSequenceState = fadesequence_t::SEQUENCE_STARTING;
}
void UIWidget::SetDontLocalize()
{
m_flags |= WF_DONTLOCALIZE;
}
CLASS_DECLARATION(UIWidget, UIWidgetContainer, NULL) {
{&EV_Layout_BGFill, &UIWidgetContainer::SetBGFill },
{&EV_Layout_Fullscreen, &UIWidgetContainer::SetFullscreen},
{&EV_Layout_VidMode, &UIWidgetContainer::SetVidMode },
{NULL, NULL }
};
UIWidgetContainer::UIWidgetContainer()
{
m_bgfill = UColor(0, 0, 0, 0);
m_fullscreen = false;
m_vidmode = -1;
m_currentwidnum = 0;
m_maxordernum = 0;
m_layout = NULL;
AllowActivate(false);
}
void UIWidgetContainer::AlignPosition(void)
{
if (m_bVirtual) {
vec2_t vNewVirtualScale;
SetVirtualScale(vNewVirtualScale);
scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
} else if (uid.bHighResScaling) {
scaleFrameVirtualRes(m_frame, m_vVirtualScale, uid.scaleRes);
} else {
vec2_t vNewVirtualScale = {1.0, 1.0};
scaleFrameVirtualRes(m_frame, m_vVirtualScale, vNewVirtualScale);
}
if (m_align & WA_LEFT) {
m_frame.pos.x = 0;
} else if (m_align & WA_RIGHT) {
m_frame.pos.x = uid.vidWidth - m_frame.size.width;
} else {
// default to center
m_frame.pos.x = (uid.vidWidth - m_frame.size.width) * 0.5;
}
if (m_align & WA_BOTTOM) {
m_frame.pos.y = uid.vidHeight - m_frame.size.height;
} else if (m_align & WA_TOP) {
m_frame.pos.y = 0;
} else {
// default to center
m_frame.pos.y = (uid.vidHeight - m_frame.size.height) * 0.5;
}
setFrame(m_frame);
m_startingpos = m_frame.pos;
}
void UIWidgetContainer::Draw(void)
{
uii.Rend_Set2D(0, 0, uid.vidWidth, uid.vidHeight, 0, uid.vidWidth, uid.vidHeight, 0, -1.0, 1.0);
uii.Rend_Scissor(0, 0, uid.vidWidth, uid.vidHeight);
if (m_bgfill.a != 0.0) {
DrawBox(0, 0, uid.vidWidth, uid.vidHeight, m_bgfill, m_local_alpha);
}
set2D();
}
void UIWidgetContainer::Realign(void)
{
AlignPosition();
}
void UIWidgetContainer::SetBGFill(Event *ev)
{
m_bgfill.r = ev->GetFloat(1);
m_bgfill.b = ev->GetFloat(2);
m_bgfill.g = ev->GetFloat(3);
m_bgfill.a = ev->GetFloat(4);
}
void UIWidgetContainer::SetFullscreen(Event *ev)
{
m_fullscreen = ev->GetBoolean(1);
}
void UIWidgetContainer::SetVidMode(Event *ev)
{
m_vidmode = ev->GetInteger(1);
}
int UIWidgetContainer::getVidMode(void)
{
return m_vidmode;
}
qboolean UIWidgetContainer::isFullscreen(void)
{
return m_fullscreen;
}
UIWidget *UIWidgetContainer::GetNextWidgetInOrder(void)
{
int i;
if (!m_maxordernum) {
for (i = 1; i <= m_children.NumObjects(); i++) {
if (m_children.ObjectAt(i)->getOrderNum()) {
m_maxordernum++;
}
}
}
m_currentwidnum++;
if (m_currentwidnum > m_maxordernum) {
m_currentwidnum = m_maxordernum;
}
for (i = 1; i <= m_children.NumObjects(); i++) {
UIWidget *wid = m_children.ObjectAt(i);
if (wid->getOrderNum() == m_currentwidnum) {
return wid;
}
}
return NULL;
}
UIWidget *UIWidgetContainer::GetPrevWidgetInOrder(void)
{
int i;
if (!m_maxordernum) {
for (i = 1; i <= m_children.NumObjects(); i++) {
if (m_children.ObjectAt(i)->getOrderNum()) {
m_maxordernum++;
}
}
}
m_currentwidnum--;
if (m_currentwidnum <= 0) {
m_currentwidnum = m_maxordernum;
}
for (i = 1; i <= m_children.NumObjects(); i++) {
UIWidget *wid = m_children.ObjectAt(i);
if (wid->getOrderNum() == m_currentwidnum) {
return wid;
}
}
return NULL;
}
void UIWidgetContainer::SetActiveWidgetOrderNum(UIWidget *wid)
{
int i;
for (i = 1; i <= m_children.NumObjects(); i++) {
if (wid == m_children.ObjectAt(i)) {
m_currentwidnum = wid->getOrderNum();
}
}
}
void UIWidgetContainer::SetActiveWidgetOrderNum(int num)
{
UIWidget *wid;
int i;
for (i = 1; i <= m_children.NumObjects(); i++) {
wid = m_children.ObjectAt(i);
if (wid->getOrderNum() == num) {
uWinMan.ActivateControl(wid);
} else {
wid->SetHovermaterialActive(false);
wid->SetPressedmaterialActive(false);
}
}
}
void UIWidgetContainer::SetLastActiveWidgetOrderNum(void)
{
if (!m_currentwidnum) {
m_currentwidnum = 1;
}
SetActiveWidgetOrderNum(m_currentwidnum);
}