diff options
Diffstat (limited to 'indra/llui/llui.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llui/llui.cpp | 1898 |
1 files changed, 277 insertions, 1621 deletions
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index d0ed3b6fca..aabc7ed2e4 100644..100755 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -2,31 +2,25 @@ * @file llui.cpp * @brief UI implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library 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 + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,13 +33,16 @@ // Linden library includes #include "v2math.h" +#include "m3math.h" #include "v4color.h" #include "llrender.h" #include "llrect.h" #include "lldir.h" #include "llgl.h" +#include "llsd.h" // Project includes +#include "llcommandmanager.h" #include "llcontrol.h" #include "llui.h" #include "lluicolortable.h" @@ -55,29 +52,31 @@ #include "llfloaterreg.h" #include "llmenugl.h" #include "llmenubutton.h" +#include "llloadingindicator.h" #include "llwindow.h" // for registration #include "llfiltereditor.h" #include "llflyoutbutton.h" #include "llsearcheditor.h" +#include "lltoolbar.h" // for XUIParse #include "llquaternion.h" #include <boost/tokenizer.hpp> +#include <boost/algorithm/string/find_iterator.hpp> +#include <boost/algorithm/string/finder.hpp> // // Globals // -const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); // Language for UI construction std::map<std::string, std::string> gTranslation; std::list<std::string> gUntranslated; /*static*/ LLUI::settings_map_t LLUI::sSettingGroups; -/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL; /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL; -/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); +/*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL; /*static*/ LLWindow* LLUI::sWindow = NULL; /*static*/ LLView* LLUI::sRootView = NULL; /*static*/ BOOL LLUI::sDirty = FALSE; @@ -85,1492 +84,138 @@ std::list<std::string> gUntranslated; /*static*/ LLHelp* LLUI::sHelpImpl = NULL; /*static*/ std::vector<std::string> LLUI::sXUIPaths; /*static*/ LLFrameTimer LLUI::sMouseIdleTimer; +/*static*/ LLUI::add_popup_t LLUI::sAddPopupFunc; +/*static*/ LLUI::remove_popup_t LLUI::sRemovePopupFunc; +/*static*/ LLUI::clear_popups_t LLUI::sClearPopupsFunc; -// register filtereditor here +// register filter editor here static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor"); static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button"); static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor"); -static LLDefaultChildRegistry::Register<LLMenuButton> register_menu_button("menu_button"); +// register other widgets which otherwise may not be linked in +static LLDefaultChildRegistry::Register<LLLoadingIndicator> register_loading_indicator("loading_indicator"); +static LLDefaultChildRegistry::Register<LLToolBar> register_toolbar("toolbar"); // // Functions // -void make_ui_sound(const char* namep) + +LLUUID find_ui_sound(const char * namep) { std::string name = ll_safe_string(namep); + LLUUID uuid = LLUUID(NULL); if (!LLUI::sSettingGroups["config"]->controlExists(name)) { - llwarns << "tried to make ui sound for unknown sound name: " << name << llendl; + LL_WARNS() << "tried to make UI sound for unknown sound name: " << name << LL_ENDL; } else { - LLUUID uuid(LLUI::sSettingGroups["config"]->getString(name)); + uuid = LLUUID(LLUI::sSettingGroups["config"]->getString(name)); if (uuid.isNull()) { if (LLUI::sSettingGroups["config"]->getString(name) == LLUUID::null.asString()) { if (LLUI::sSettingGroups["config"]->getBOOL("UISndDebugSpamToggle")) { - llinfos << "ui sound name: " << name << " triggered but silent (null uuid)" << llendl; + LL_INFOS() << "UI sound name: " << name << " triggered but silent (null uuid)" << LL_ENDL; } } else { - llwarns << "ui sound named: " << name << " does not translate to a valid uuid" << llendl; + LL_WARNS() << "UI sound named: " << name << " does not translate to a valid uuid" << LL_ENDL; } - } else if (LLUI::sAudioCallback != NULL) { if (LLUI::sSettingGroups["config"]->getBOOL("UISndDebugSpamToggle")) { - llinfos << "ui sound name: " << name << llendl; + LL_INFOS() << "UI sound name: " << name << LL_ENDL; } - LLUI::sAudioCallback(uuid); - } - } -} - -BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom) -{ - if (x < left || right < x) return FALSE; - if (y < bottom || top < y) return FALSE; - return TRUE; -} - - -// Puts GL into 2D drawing mode by turning off lighting, setting to an -// orthographic projection, etc. -void gl_state_for_2d(S32 width, S32 height) -{ - stop_glerror(); - F32 window_width = (F32) width;//gViewerWindow->getWindowWidth(); - F32 window_height = (F32) height;//gViewerWindow->getWindowHeight(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - stop_glerror(); -} - - -void gl_draw_x(const LLRect& rect, const LLColor4& color) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv( color.mV ); - - gGL.begin( LLRender::LINES ); - gGL.vertex2i( rect.mLeft, rect.mTop ); - gGL.vertex2i( rect.mRight, rect.mBottom ); - gGL.vertex2i( rect.mLeft, rect.mBottom ); - gGL.vertex2i( rect.mRight, rect.mTop ); - gGL.end(); -} - - -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled) -{ - gGL.color4fv(color.mV); - gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled); -} - -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled) -{ - gGL.pushMatrix(); - left += LLFontGL::sCurOrigin.mX; - right += LLFontGL::sCurOrigin.mX; - bottom += LLFontGL::sCurOrigin.mY; - top += LLFontGL::sCurOrigin.mY; - - glLoadIdentity(); - gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset, - llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset, - llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset, - llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset, - filled); - gGL.popMatrix(); -} - - -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) -{ - stop_glerror(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Counterclockwise quad will face the viewer - if( filled ) - { - gGL.begin( LLRender::QUADS ); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.end(); - } - else - { - if( gGLManager.mATIOffsetVerticalLines ) - { - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - gGL.begin( LLRender::LINES ); - - // Verticals - gGL.vertex2i(left + 1, top); - gGL.vertex2i(left + 1, bottom); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - - // Horizontals - top--; - right--; - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - - gGL.vertex2i(left, top); - gGL.vertex2i(right, top); - gGL.end(); - } - else - { - top--; - right--; - gGL.begin( LLRender::LINE_STRIP ); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.vertex2i(left, top); - gGL.end(); } } - stop_glerror(); -} -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled ) -{ - gGL.color4fv( color.mV ); - gl_rect_2d( left, top, right, bottom, filled ); + return uuid; } - -void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled ) -{ - gGL.color4fv( color.mV ); - gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); -} - -// Given a rectangle on the screen, draws a drop shadow _outside_ -// the right and bottom edges of it. Along the right it has width "lines" -// and along the bottom it has height "lines". -void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines) -{ - stop_glerror(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // HACK: Overlap with the rectangle by a single pixel. - right--; - bottom++; - lines++; - - LLColor4 end_color = start_color; - end_color.mV[VALPHA] = 0.f; - - gGL.begin(LLRender::QUADS); - - // Right edge, CCW faces screen - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, top-lines); - gGL.vertex2i(right, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(right+lines, bottom); - gGL.vertex2i(right+lines, top-lines); - - // Bottom edge, CCW faces screen - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); - gGL.vertex2i(left+lines, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(left+lines, bottom-lines); - gGL.vertex2i(right, bottom-lines); - - // bottom left Corner - gGL.color4fv(start_color.mV); - gGL.vertex2i(left+lines, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(left, bottom); - // make the bottom left corner not sharp - gGL.vertex2i(left+1, bottom-lines+1); - gGL.vertex2i(left+lines, bottom-lines); - - // bottom right corner - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(right, bottom-lines); - // make the rightmost corner not sharp - gGL.vertex2i(right+lines-1, bottom-lines+1); - gGL.vertex2i(right+lines, bottom); - - // top right corner - gGL.color4fv(start_color.mV); - gGL.vertex2i( right, top-lines ); - gGL.color4fv(end_color.mV); - gGL.vertex2i( right+lines, top-lines ); - // make the corner not sharp - gGL.vertex2i( right+lines-1, top-1 ); - gGL.vertex2i( right, top ); - - gGL.end(); - stop_glerror(); -} - -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) -{ - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin(LLRender::LINES); - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.end(); -} - -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) -{ - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv( color.mV ); - - gGL.begin(LLRender::LINES); - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.end(); -} - -void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv(color.mV); - - if (filled) - { - gGL.begin(LLRender::TRIANGLES); - } - else - { - gGL.begin(LLRender::LINE_LOOP); - } - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.vertex2i(x3, y3); - gGL.end(); -} - -void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - length = llmin((S32)(max_frac*(right - left)), length); - length = llmin((S32)(max_frac*(top - bottom)), length); - gGL.begin(LLRender::LINES); - gGL.vertex2i(left, top); - gGL.vertex2i(left + length, top); - - gGL.vertex2i(left, top); - gGL.vertex2i(left, top - length); - - gGL.vertex2i(left, bottom); - gGL.vertex2i(left + length, bottom); - - gGL.vertex2i(left, bottom); - gGL.vertex2i(left, bottom + length); - - gGL.vertex2i(right, top); - gGL.vertex2i(right - length, top); - - gGL.vertex2i(right, top); - gGL.vertex2i(right, top - length); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right - length, bottom); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, bottom + length); - gGL.end(); -} - - -void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); -} - -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); -} - -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - // scale screen size of borders down - F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0); - F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0); - - LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction); - gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); -} - -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) -{ - stop_glerror(); - - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - // shrink scaling region to be proportional to clipped image region - LLRectf scale_rect_uv( - uv_rect.mLeft + (scale_rect.mLeft * uv_rect.getWidth()), - uv_rect.mBottom + (scale_rect.mTop * uv_rect.getHeight()), - uv_rect.mLeft + (scale_rect.mRight * uv_rect.getWidth()), - uv_rect.mBottom + (scale_rect.mBottom * uv_rect.getHeight())); - - S32 image_natural_width = llround((F32)image->getWidth(0) * uv_rect.getWidth()); - S32 image_natural_height = llround((F32)image->getHeight(0) * uv_rect.getHeight()); - - LLRect draw_rect(0, height, width, 0); - LLRect draw_scale_rect(llround(scale_rect_uv.mLeft * (F32)image->getWidth(0)), - llround(scale_rect_uv.mTop * (F32)image->getHeight(0)), - llround(scale_rect_uv.mRight * (F32)image->getWidth(0)), - llround(scale_rect_uv.mBottom * (F32)image->getHeight(0))); - // scale fixed region of image to drawn region - draw_scale_rect.mRight += width - image_natural_width; - draw_scale_rect.mTop += height - image_natural_height; - - S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight); - S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop); - - F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - scale_rect.getWidth())); - F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - scale_rect.getHeight())); - - F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); - draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale); - draw_scale_rect.mTop = llround(lerp((F32)height, (F32)draw_scale_rect.mTop, shrink_scale)); - draw_scale_rect.mRight = llround(lerp((F32)width, (F32)draw_scale_rect.mRight, shrink_scale)); - draw_scale_rect.mBottom = llround((F32)draw_scale_rect.mBottom * shrink_scale); - - LLGLSUIDefault gls_ui; - - if (solid_color) - { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); - } - - gGL.pushMatrix(); - { - gGL.translatef((F32)x, (F32)y, 0.f); - - gGL.getTexUnit(0)->bind(image); - - gGL.color4fv(color.mV); - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2i(0, 0); - - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, 0); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(0, draw_scale_rect.mBottom); - - // draw bottom middle - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, 0); - - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, 0); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - - // draw bottom right - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, 0); - - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2i(width, 0); - - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(width, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - - // draw left - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(0, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(0, draw_scale_rect.mTop); - - // draw middle - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - - // draw right - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mBottom); - gGL.vertex2i(width, draw_scale_rect.mBottom); - - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); - gGL.vertex2i(width, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - - // draw top left - gGL.texCoord2f(uv_rect.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(0, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, height); - - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2i(0, height); - - // draw top middle - gGL.texCoord2f(scale_rect_uv.mLeft, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mRight, height); - - gGL.texCoord2f(scale_rect_uv.mLeft, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mLeft, height); - - // draw top right - gGL.texCoord2f(scale_rect_uv.mRight, scale_rect_uv.mTop); - gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - - gGL.texCoord2f(uv_rect.mRight, scale_rect_uv.mTop); - gGL.vertex2i(width, draw_scale_rect.mTop); - - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2i(width, height); - - gGL.texCoord2f(scale_rect_uv.mRight, uv_rect.mTop); - gGL.vertex2i(draw_scale_rect.mRight, height); - } - gGL.end(); - } - gGL.popMatrix(); - - if (solid_color) - { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } -} - -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); -} - -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - LLGLSUIDefault gls_ui; - - gGL.pushMatrix(); - { - gGL.translatef((F32)x, (F32)y, 0.f); - if( degrees ) - { - F32 offset_x = F32(width/2); - F32 offset_y = F32(height/2); - gGL.translatef( offset_x, offset_y, 0.f); - glRotatef( degrees, 0.f, 0.f, 1.f ); - gGL.translatef( -offset_x, -offset_y, 0.f ); - } - - gGL.getTexUnit(0)->bind(image); - - gGL.color4fv(color.mV); - - gGL.begin(LLRender::QUADS); - { - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2i(width, height ); - - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2i(0, height ); - - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2i(0, 0); - - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2i(width, 0); - } - gGL.end(); - } - gGL.popMatrix(); -} - - -void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) -{ - phase = fmod(phase, 1.f); - - S32 shift = S32(phase * 4.f) % 4; - - // Stippled line - LLGLEnable stipple(GL_LINE_STIPPLE); - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); - - gGL.flush(); - glLineWidth(2.5f); - glLineStipple(2, 0x3333 << shift); - - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv( start.mV ); - gGL.vertex3fv( end.mV ); - } - gGL.end(); - - LLUI::setLineWidth(1.f); -} - - -void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom) -{ - gGL.color4fv( LLColor4::white.mV ); - glLogicOp( GL_XOR ); - stop_glerror(); - - gGL.begin(LLRender::QUADS); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.end(); - - glLogicOp( GL_COPY ); - stop_glerror(); -} - - -void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) -{ - if (end_angle < start_angle) - { - end_angle += F_TWO_PI; - } - - gGL.pushMatrix(); - { - gGL.translatef(center_x, center_y, 0.f); - - // Inexact, but reasonably fast. - F32 delta = (end_angle - start_angle) / steps; - F32 sin_delta = sin( delta ); - F32 cos_delta = cos( delta ); - F32 x = cosf(start_angle) * radius; - F32 y = sinf(start_angle) * radius; - - if (filled) - { - gGL.begin(LLRender::TRIANGLE_FAN); - gGL.vertex2f(0.f, 0.f); - // make sure circle is complete - steps += 1; - } - else - { - gGL.begin(LLRender::LINE_STRIP); - } - - while( steps-- ) - { - // Successive rotations - gGL.vertex2f( x, y ); - F32 x_new = x * cos_delta - y * sin_delta; - y = x * sin_delta + y * cos_delta; - x = x_new; - } - gGL.end(); - } - gGL.popMatrix(); -} - -void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) -{ - gGL.pushMatrix(); - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.translatef(center_x, center_y, 0.f); - - // Inexact, but reasonably fast. - F32 delta = F_TWO_PI / steps; - F32 sin_delta = sin( delta ); - F32 cos_delta = cos( delta ); - F32 x = radius; - F32 y = 0.f; - - if (filled) - { - gGL.begin(LLRender::TRIANGLE_FAN); - gGL.vertex2f(0.f, 0.f); - // make sure circle is complete - steps += 1; - } - else - { - gGL.begin(LLRender::LINE_LOOP); - } - - while( steps-- ) - { - // Successive rotations - gGL.vertex2f( x, y ); - F32 x_new = x * cos_delta - y * sin_delta; - y = x * sin_delta + y * cos_delta; - x = x_new; - } - gGL.end(); - } - gGL.popMatrix(); -} - -// Renders a ring with sides (tube shape) -void gl_deep_circle( F32 radius, F32 depth, S32 steps ) -{ - F32 x = radius; - F32 y = 0.f; - F32 angle_delta = F_TWO_PI / (F32)steps; - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - S32 step = steps + 1; // An extra step to close the circle. - while( step-- ) - { - gGL.vertex3f( x, y, depth ); - gGL.vertex3f( x, y, 0.f ); - - F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta); - y = x * sinf(angle_delta) + y * cosf(angle_delta); - x = x_new; - } - } - gGL.end(); -} - -void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ) -{ - gGL.pushMatrix(); - { - gGL.translatef(0.f, 0.f, -width / 2); - if( render_center ) - { - gGL.color4fv(center_color.mV); - gl_deep_circle( radius, width, steps ); - } - else - { - gl_washer_2d(radius, radius - width, steps, side_color, side_color); - gGL.translatef(0.f, 0.f, width); - gl_washer_2d(radius - width, radius, steps, side_color, side_color); - } - } - gGL.popMatrix(); -} - -// Draw gray and white checkerboard with black border -void gl_rect_2d_checkerboard(const LLRect& rect) -{ - // Initialize the first time this is called. - const S32 PIXELS = 32; - static GLubyte checkerboard[PIXELS * PIXELS]; - static BOOL first = TRUE; - if( first ) - { - for( S32 i = 0; i < PIXELS; i++ ) - { - for( S32 j = 0; j < PIXELS; j++ ) - { - checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; - } - } - first = FALSE; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // ...white squares - gGL.color3f( 1.f, 1.f, 1.f ); - gl_rect_2d(rect); - - // ...gray squares - gGL.color3f( .7f, .7f, .7f ); - gGL.flush(); - glPolygonStipple( checkerboard ); - - LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); - gl_rect_2d(rect); - gGL.flush(); -} - - -// Draws the area between two concentric circles, like -// a doughnut or washer. -void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = F_TWO_PI / steps; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius; - F32 y1 = 0.f; - F32 x2 = inner_radius; - F32 y2 = 0.f; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - steps += 1; // An extra step to close the circle. - while( steps-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -// Draws the area between two concentric circles, like -// a doughnut or washer. -void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = (end_radians - start_radians) / steps; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius * cos( start_radians ); - F32 y1 = outer_radius * sin( start_radians ); - F32 x2 = inner_radius * cos( start_radians ); - F32 y2 = inner_radius * sin( start_radians ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - steps += 1; // An extra step to close the circle. - while( steps-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -// Draws spokes around a circle. -void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = F_TWO_PI / count; - const F32 HALF_DELTA = DELTA * 0.5f; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius * cos( HALF_DELTA ); - F32 y1 = outer_radius * sin( HALF_DELTA ); - F32 x2 = inner_radius * cos( HALF_DELTA ); - F32 y2 = inner_radius * sin( HALF_DELTA ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin( LLRender::LINES ); - { - while( count-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -void gl_rect_2d_simple_tex( S32 width, S32 height ) -{ - gGL.begin( LLRender::QUADS ); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(width, height); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(0, height); - - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(0, 0); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(width, 0); - - gGL.end(); -} - -void gl_rect_2d_simple( S32 width, S32 height ) -{ - gGL.begin( LLRender::QUADS ); - gGL.vertex2i(width, height); - gGL.vertex2i(0, height); - gGL.vertex2i(0, 0); - gGL.vertex2i(width, 0); - gGL.end(); -} - -void gl_segmented_rect_2d_tex(const S32 left, - const S32 top, - const S32 right, - const S32 bottom, - const S32 texture_width, - const S32 texture_height, - const S32 border_size, - const U32 edges) -{ - S32 width = llabs(right - left); - S32 height = llabs(top - bottom); - - gGL.pushMatrix(); - - gGL.translatef((F32)left, (F32)bottom, 0.f); - LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); - - if (border_uv_scale.mV[VX] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; - } - if (border_uv_scale.mV[VY] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; - } - - F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); - LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 width_vec((F32)width, 0.f); - LLVector2 height_vec(0.f, (F32)height); - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2f(0.f, 0.f); - - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(border_width_left.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); - gGL.vertex2fv(border_height_bottom.mV); - - // draw bottom middle - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(border_width_left.mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((width_vec - border_width_right).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - // draw bottom right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((width_vec - border_width_right).mV); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2fv(width_vec.mV); - - gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - // draw left - gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); - gGL.vertex2fv(border_height_bottom.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((height_vec - border_height_top).mV); - - // draw middle - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - // draw right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + border_height_bottom).mV); - - gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - // draw top left - gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((border_width_left + height_vec).mV); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2fv((height_vec).mV); - - // draw top middle - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((border_width_left + height_vec).mV); - - // draw top right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2fv((width_vec + height_vec).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); - } - gGL.end(); - - gGL.popMatrix(); -} - -void gl_segmented_rect_2d_fragment_tex(const S32 left, - const S32 top, - const S32 right, - const S32 bottom, - const S32 texture_width, - const S32 texture_height, - const S32 border_size, - const F32 start_fragment, - const F32 end_fragment, - const U32 edges) +void make_ui_sound(const char* namep) { - S32 width = llabs(right - left); - S32 height = llabs(top - bottom); - - gGL.pushMatrix(); - - gGL.translatef((F32)left, (F32)bottom, 0.f); - LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); - - if (border_uv_scale.mV[VX] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; - } - if (border_uv_scale.mV[VY] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; - } - - F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); - LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 width_vec((F32)width, 0.f); - LLVector2 height_vec(0.f, (F32)height); - - F32 middle_start = border_scale / (F32)width; - F32 middle_end = 1.f - middle_start; - - F32 u_min; - F32 u_max; - LLVector2 x_min; - LLVector2 x_max; - - gGL.begin(LLRender::QUADS); + LLUUID soundUUID = find_ui_sound(namep); + if(soundUUID.notNull()) { - if (start_fragment < middle_start) - { - u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; - u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; - x_min = (start_fragment / middle_start) * border_width_left; - x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left; - - // draw bottom left - gGL.texCoord2f(u_min, 0.f); - gGL.vertex2fv(x_min.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(x_max.mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw left - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top left - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(u_min, 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } - - if (end_fragment > middle_start || start_fragment < middle_end) - { - x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec; - x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; - - // draw bottom middle - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(x_min.mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((x_max).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw middle - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top middle - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } - - if (end_fragment > middle_end) - { - u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; - u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; - x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); - x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); - - // draw bottom right - gGL.texCoord2f(u_min, 0.f); - gGL.vertex2fv((x_min).mV); - - gGL.texCoord2f(u_max, 0.f); - gGL.vertex2fv(x_max.mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw right - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top right - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(u_min, 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } + LLUI::sAudioCallback(soundUUID); } - gGL.end(); - - gGL.popMatrix(); } -void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, - const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, - const U32 edges) +void make_ui_sound_deferred(const char* namep) { - LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero; - LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; - - LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; - LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; - - - gGL.begin(LLRender::QUADS); + LLUUID soundUUID = find_ui_sound(namep); + if(soundUUID.notNull()) { - // draw bottom left - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(0.f, 0.f, 0.f); - - gGL.texCoord2f(border_scale.mV[VX], 0.f); - gGL.vertex3fv(left_border_width.mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(0.f, border_scale.mV[VY]); - gGL.vertex3fv(bottom_border_height.mV); - - // draw bottom middle - gGL.texCoord2f(border_scale.mV[VX], 0.f); - gGL.vertex3fv(left_border_width.mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); - gGL.vertex3fv((width_vec - right_border_width).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - // draw bottom right - gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); - gGL.vertex3fv((width_vec - right_border_width).mV); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3fv(width_vec.mV); - - gGL.texCoord2f(1.f, border_scale.mV[VY]); - gGL.vertex3fv((width_vec + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - // draw left - gGL.texCoord2f(0.f, border_scale.mV[VY]); - gGL.vertex3fv(bottom_border_height.mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((height_vec - top_border_height).mV); - - // draw middle - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - // draw right - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f, border_scale.mV[VY]); - gGL.vertex3fv((width_vec + bottom_border_height).mV); - - gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - // draw top left - gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f); - gGL.vertex3fv((left_border_width + height_vec).mV); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3fv((height_vec).mV); - - // draw top middle - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); - gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f); - gGL.vertex3fv((left_border_width + height_vec).mV); - - // draw top right - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3fv((width_vec + height_vec).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); - gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); + LLUI::sDeferredAudioCallback(soundUUID); } - gGL.end(); - -} - -void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) -{ - gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); } void LLUI::initClass(const settings_map_t& settings, LLImageProviderInterface* image_provider, LLUIAudioCallback audio_callback, + LLUIAudioCallback deferred_audio_callback, const LLVector2* scale_factor, const std::string& language) { + LLRender2D::initClass(image_provider,scale_factor); sSettingGroups = settings; if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("floater")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("ignores")) == NULL)) { - llerrs << "Failure to initialize configuration groups" << llendl; + LL_ERRS() << "Failure to initialize configuration groups" << LL_ENDL; } - sImageProvider = image_provider; sAudioCallback = audio_callback; - sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; + sDeferredAudioCallback = deferred_audio_callback; sWindow = NULL; // set later in startup LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow"); - // Callbacks for associating controls with floater visibilty: - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2)); + LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar(); + + // Callbacks for associating controls with floater visibility: + reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD())); + reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD())); + reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE)); + reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD())); // Button initialization callback for toggle buttons - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); + reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); - // Button initialization callback for toggle buttons on dockale floaters - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2)); + // Button initialization callback for toggle buttons on dockable floaters + reg.add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2)); // Display the help topic for the current context - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); + reg.add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); // Currently unused, but kept for reference: - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2)); + reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2)); - // Used by menus along with Floater.Toggle to display visibility as a checkmark - LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::floaterInstanceVisible, _2)); + // Used by menus along with Floater.Toggle to display visibility as a check-mark + LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD())); + LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD())); + + // Parse the master list of commands + LLCommandManager::load(); } void LLUI::cleanupClass() { - sImageProvider->cleanUp(); + LLRender2D::cleanupClass(); +} + +void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) +{ + sAddPopupFunc = add_popup; + sRemovePopupFunc = remove_popup; + sClearPopupsFunc = clear_popups; } //static @@ -1587,64 +232,14 @@ void LLUI::dirtyRect(LLRect rect) } } - -//static -void LLUI::translate(F32 x, F32 y, F32 z) -{ - gGL.translatef(x,y,z); - LLFontGL::sCurOrigin.mX += (S32) x; - LLFontGL::sCurOrigin.mY += (S32) y; - LLFontGL::sCurOrigin.mZ += z; -} - -//static -void LLUI::pushMatrix() -{ - gGL.pushMatrix(); - LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin); -} - -//static -void LLUI::popMatrix() -{ - gGL.popMatrix(); - LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin(); - LLFontGL::sOriginStack.pop_back(); -} - -//static -void LLUI::loadIdentity() -{ - glLoadIdentity(); - LLFontGL::sCurOrigin.mX = 0; - LLFontGL::sCurOrigin.mY = 0; - LLFontGL::sCurOrigin.mZ = 0; -} - -//static -void LLUI::setScaleFactor(const LLVector2 &scale_factor) -{ - sGLScaleFactor = scale_factor; -} - -//static -void LLUI::setLineWidth(F32 width) -{ - gGL.flush(); - glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); -} - //static void LLUI::setMousePositionScreen(S32 x, S32 y) { S32 screen_x, screen_y; - screen_x = llround((F32)x * sGLScaleFactor.mV[VX]); - screen_y = llround((F32)y * sGLScaleFactor.mV[VY]); + screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); + screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); - LLCoordWindow window_point; - LLView::getWindow()->convertCoords(LLCoordGL(screen_x, screen_y), &window_point); - - LLView::getWindow()->setCursorPosition(window_point); + LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert()); } //static @@ -1652,10 +247,9 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y) { LLCoordWindow cursor_pos_window; getWindow()->getCursorPosition(&cursor_pos_window); - LLCoordGL cursor_pos_gl; - getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); - *x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]); - *y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]); + LLCoordGL cursor_pos_gl(cursor_pos_window.convert()); + *x = ll_round((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]); + *y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]); } //static @@ -1704,69 +298,64 @@ std::string LLUI::getLanguage() return language; } -//static -void LLUI::setupPaths() +struct SubDir : public LLInitParam::Block<SubDir> { - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml"); + Mandatory<std::string> value; - LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(filename, root, NULL); - sXUIPaths.clear(); - - if (success) - { - LLStringUtil::format_map_t path_args; - path_args["[LANGUAGE]"] = LLUI::getLanguage(); - - for (LLXMLNodePtr path = root->getFirstChild(); path.notNull(); path = path->getNextSibling()) - { - std::string path_val_ui(path->getValue()); - LLStringUtil::format(path_val_ui, path_args); - if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui) == sXUIPaths.end()) - { - sXUIPaths.push_back(path_val_ui); - } - } - } - else // parsing failed - { - std::string slash = gDirUtilp->getDirDelimiter(); - std::string dir = "xui" + slash + "en"; - llwarns << "XUI::config file unable to open: " << filename << llendl; - sXUIPaths.push_back(dir); - } -} + SubDir() + : value("value") + {} +}; + +struct Directory : public LLInitParam::Block<Directory> +{ + Multiple<SubDir, AtLeast<1> > subdirs; + + Directory() + : subdirs("subdir") + {} +}; + +struct Paths : public LLInitParam::Block<Paths> +{ + Multiple<Directory, AtLeast<1> > directories; + + Paths() + : directories("directory") + {} +}; //static std::string LLUI::locateSkin(const std::string& filename) { - std::string slash = gDirUtilp->getDirDelimiter(); std::string found_file = filename; - if (!gDirUtilp->fileExists(found_file)) + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + return found_file; } - if (sSettingGroups["config"] && sSettingGroups["config"]->controlExists("Language")) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + if (gDirUtilp->fileExists(found_file)) { - if (!gDirUtilp->fileExists(found_file)) - { - std::string localization = getLanguage(); - std::string local_skin = "xui" + slash + localization + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); - } + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->findSkinnedFilename(LLDir::XUI, filename); + if (! found_file.empty()) { - std::string local_skin = "xui" + slash + "en" + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + return found_file; } - return found_file; -} + LL_WARNS("LLUI") << "Can't find '" << filename + << "' in user settings, any skin directory or app_settings" << LL_ENDL; + return ""; +} //static LLVector2 LLUI::getWindowSize() @@ -1774,21 +363,21 @@ LLVector2 LLUI::getWindowSize() LLCoordWindow window_rect; sWindow->getSize(&window_rect); - return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]); + return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]); } //static void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y) { - *gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]); - *gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]); + *gl_x = ll_round((F32)screen_x * getScaleFactor().mV[VX]); + *gl_y = ll_round((F32)screen_y * getScaleFactor().mV[VY]); } //static void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y) { - *screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]); - *screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]); + *screen_x = ll_round((F32)gl_x / getScaleFactor().mV[VX]); + *screen_y = ll_round((F32)gl_y / getScaleFactor().mV[VY]); } //static @@ -1805,27 +394,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen) glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom); } -//static -LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority) -{ - if (sImageProvider) - { - return sImageProvider->getUIImageByID(image_id, priority); - } - else - { - return NULL; - } -} - -//static -LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority) -{ - if (!name.empty() && sImageProvider) - return sImageProvider->getUIImage(name, priority); - else - return NULL; -} LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) { @@ -1843,6 +411,39 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) return *sSettingGroups["config"]; // default group } +//static +void LLUI::addPopup(LLView* viewp) +{ + if (sAddPopupFunc) + { + sAddPopupFunc(viewp); + } +} + +//static +void LLUI::removePopup(LLView* viewp) +{ + if (sRemovePopupFunc) + { + sRemovePopupFunc(viewp); + } +} + +//static +void LLUI::clearPopups() +{ + if (sClearPopupsFunc) + { + sClearPopupsFunc(); + } +} + +//static +void LLUI::reportBadKeystroke() +{ + make_ui_sound("UISndBadKeystroke"); +} + //static // spawn_x and spawn_y are top left corner of view in screen GL coordinates void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) @@ -1873,13 +474,60 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2); S32 local_x, local_y; - // convert screen coordinates to tooltipview-local coordinates + // convert screen coordinates to tooltip view-local coordinates parent->screenPointToLocal(spawn_x, spawn_y, &local_x, &local_y); // Start at spawn position (using left/top) view->setOrigin( local_x, local_y - view->getRect().getHeight()); - // Make sure we're onscreen and not overlapping the mouse - view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect, FALSE ); + // Make sure we're on-screen and not overlapping the mouse + view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect ); +} + +LLView* LLUI::resolvePath(LLView* context, const std::string& path) +{ + // Nothing about resolvePath() should require non-const LLView*. If caller + // wants non-const, call the const flavor and then cast away const-ness. + return const_cast<LLView*>(resolvePath(const_cast<const LLView*>(context), path)); +} + +const LLView* LLUI::resolvePath(const LLView* context, const std::string& path) +{ + // Create an iterator over slash-separated parts of 'path'. Dereferencing + // this iterator returns an iterator_range over the substring. Unlike + // LLStringUtil::getTokens(), this split_iterator doesn't combine adjacent + // delimiters: leading/trailing slash produces an empty substring, double + // slash produces an empty substring. That's what we need. + boost::split_iterator<std::string::const_iterator> ti(path, boost::first_finder("/")), tend; + + if (ti == tend) + { + // 'path' is completely empty, no navigation + return context; + } + + // leading / means "start at root" + if (ti->empty()) + { + context = getRootView(); + ++ti; + } + + bool recurse = false; + for (; ti != tend && context; ++ti) + { + if (ti->empty()) + { + recurse = true; + } + else + { + std::string part(ti->begin(), ti->end()); + context = context->findChildView(part, recurse); + recurse = false; + } + } + + return context; } @@ -1887,44 +535,37 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) namespace LLInitParam { - TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) - : super_t(descriptor, name, value, func, min_count, max_count), + ParamValue<LLUIColor>::ParamValue(const LLUIColor& color) + : super_t(color), red("red"), green("green"), blue("blue"), alpha("alpha"), control("") - {} + { + updateBlockFromValue(false); + } - void TypedParam<LLUIColor>::setValueFromBlock() const + void ParamValue<LLUIColor>::updateValueFromBlock() { - if (control.isProvided()) + if (control.isProvided() && !control().empty()) { - mData.mValue = LLUIColorTable::instance().getColor(control); + updateValue(LLUIColorTable::instance().getColor(control)); } else { - mData.mValue = LLColor4(red, green, blue, alpha); + updateValue(LLColor4(red, green, blue, alpha)); } } - void TypedParam<LLUIColor>::setBlockFromValue() + void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative) { - LLColor4 color = mData.mValue.get(); - red = color.mV[VRED]; - green = color.mV[VGREEN]; - blue = color.mV[VBLUE]; - alpha = color.mV[VALPHA]; - control.set("", false); - } - - void TypeValues<LLUIColor>::declareValues() - { - declare("white", LLColor4::white); - declare("black", LLColor4::black); - declare("red", LLColor4::red); - declare("green", LLColor4::green); - declare("blue", LLColor4::blue); + LLColor4 color = getValue(); + red.set(color.mV[VRED], make_block_authoritative); + green.set(color.mV[VGREEN], make_block_authoritative); + blue.set(color.mV[VBLUE], make_block_authoritative); + alpha.set(color.mV[VALPHA], make_block_authoritative); + control.set("", make_block_authoritative); } bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -1933,21 +574,26 @@ namespace LLInitParam && !(b->getFontDesc() < a->getFontDesc()); } - TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) - : super_t(descriptor, _name, value, func, min_count, max_count), + ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp) + : super_t(fontp), name("name"), size("size"), style("style") { + if (!fontp) + { + updateValue(LLFontGL::getFontDefault()); + } addSynonym(name, ""); + updateBlockFromValue(false); } - void TypedParam<const LLFontGL*>::setValueFromBlock() const + void ParamValue<const LLFontGL*>::updateValueFromBlock() { const LLFontGL* res_fontp = LLFontGL::getFontByName(name); if (res_fontp) { - mData.mValue = res_fontp; + updateValue(res_fontp); return; } @@ -1957,31 +603,37 @@ namespace LLInitParam const LLFontGL* fontp = LLFontGL::getFont(desc); if (fontp) { - mData.mValue = fontp; - } + updateValue(fontp); + } + else + { + updateValue(LLFontGL::getFontDefault()); + } } - void TypedParam<const LLFontGL*>::setBlockFromValue() + void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative) { - if (mData.mValue) + if (getValue()) { - name = LLFontGL::nameFromFont(mData.mValue); - size = LLFontGL::sizeFromFont(mData.mValue); - style = LLFontGL::getStringFromStyle(mData.mValue->getFontDesc().getStyle()); + name.set(LLFontGL::nameFromFont(getValue()), make_block_authoritative); + size.set(LLFontGL::sizeFromFont(getValue()), make_block_authoritative); + style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), make_block_authoritative); } } - TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) - : super_t(descriptor, name, value, func, min_count, max_count), + ParamValue<LLRect>::ParamValue(const LLRect& rect) + : super_t(rect), left("left"), top("top"), right("right"), bottom("bottom"), width("width"), height("height") - {} + { + updateBlockFromValue(false); + } - void TypedParam<LLRect>::setValueFromBlock() const + void ParamValue<LLRect>::updateValueFromBlock() { LLRect rect; @@ -2042,39 +694,43 @@ namespace LLInitParam rect.mBottom = bottom; rect.mTop = top; } - mData.mValue = rect; + updateValue(rect); } - void TypedParam<LLRect>::setBlockFromValue() + void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative) { // because of the ambiguity in specifying a rect by position and/or dimensions - // we clear the "provided" flag so that values from xui/etc have priority - // over those calculated from the rect object - - left.set(mData.mValue.mLeft, false); - right.set(mData.mValue.mRight, false); - bottom.set(mData.mValue.mBottom, false); - top.set(mData.mValue.mTop, false); - width.set(mData.mValue.getWidth(), false); - height.set(mData.mValue.getHeight(), false); + // we use the lowest priority pairing so that any valid pairing in xui + // will override those calculated from the rect object + // in this case, that is left+width and bottom+height + LLRect& value = getValue(); + + right.set(value.mRight, false); + left.set(value.mLeft, make_block_authoritative); + width.set(value.getWidth(), make_block_authoritative); + + top.set(value.mTop, false); + bottom.set(value.mBottom, make_block_authoritative); + height.set(value.getHeight(), make_block_authoritative); } - TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) - : super_t(descriptor, name, value, func, min_count, max_count), + ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord) + : super_t(coord), x("x"), y("y") { + updateBlockFromValue(false); } - void TypedParam<LLCoordGL>::setValueFromBlock() const + void ParamValue<LLCoordGL>::updateValueFromBlock() { - mData.mValue.set(x, y); + updateValue(LLCoordGL(x, y)); } - void TypedParam<LLCoordGL>::setBlockFromValue() + void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative) { - x = mData.mValue.mX; - y = mData.mValue.mY; + x.set(getValue().mX, make_block_authoritative); + y.set(getValue().mY, make_block_authoritative); } |