/* =========================================================================== 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& src, Container& bottom, Container& normal, Container& 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& dst, Container& bottom, Container& normal, Container& top ) { Container *lists[3]; int list; int i; dst.ClearObjectList(); lists[0] = ⊥ lists[1] = &normal; lists[2] = ⊤ for (list = 0; list < 3; list++) { for (i = 1; i <= lists[list]->NumObjects(); i++) { dst.AddObject(lists[list]->ObjectAt(i)); } } } void UIWidget::ArrangeWidgetList(Container& list) { Container bottom; Container normal; Container 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); }