openmohaa/code/uilib/uiwidget.cpp
smallmodel 6fe1e86b31
Automatically scale UI elements for high resolutions
This fixes UI elements being tiny on high resolutions like 4K. Now most UI elements will scale automatically with resolutions above 1920x1080.
2024-11-30 22:40:00 +01:00

3475 lines
55 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 );
}
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 );
}
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();
}
}
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();
}
}
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() ) {
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 - m_frame.size.height;
}
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;
}
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 );
}