/** * @file llviewborder.cpp * @brief LLViewBorder base class * * Copyright (c) 2001-2007, Linden Research, Inc. * * 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://secondlife.com/developers/opensource/gplv2 * * 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://secondlife.com/developers/opensource/flossexception * * 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. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. */ // A customizable decorative border. Does not interact with mouse events. #include "linden_common.h" #include "llviewborder.h" #include "llgl.h" #include "llui.h" #include "llimagegl.h" //#include "llviewerimagelist.h" #include "llcontrol.h" #include "llglheaders.h" #include "v2math.h" #include "llfocusmgr.h" LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width ) : LLView( name, rect, FALSE ), mBevel( bevel ), mStyle( style ), mHighlightLight( LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ), mHighlightDark( LLUI::sColorsGroup->getColor( "DefaultHighlightDark" ) ), mShadowLight( LLUI::sColorsGroup->getColor( "DefaultShadowLight" ) ), mShadowDark( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ), // mKeyboardFocusColor(LLUI::sColorsGroup->getColor( "FocusColor" ) ), mBorderWidth( width ), mTexture( NULL ), mHasKeyboardFocus( FALSE ) { setFollowsAll(); } // virtual BOOL LLViewBorder::isCtrl() const { return FALSE; } void LLViewBorder::setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light ) { mShadowDark = shadow_dark; mHighlightLight = highlight_light; } void LLViewBorder::setColorsExtended( const LLColor4& shadow_light, const LLColor4& shadow_dark, const LLColor4& highlight_light, const LLColor4& highlight_dark ) { mShadowDark = shadow_dark; mShadowLight = shadow_light; mHighlightLight = highlight_light; mHighlightDark = highlight_dark; } void LLViewBorder::setTexture( const LLUUID &image_id ) { mTexture = LLUI::sImageProvider->getUIImageByID(image_id); } void LLViewBorder::draw() { if( getVisible() ) { if( STYLE_LINE == mStyle ) { if( 0 == mBorderWidth ) { // no visible border } else if( 1 == mBorderWidth ) { drawOnePixelLines(); } else if( 2 == mBorderWidth ) { drawTwoPixelLines(); } else { llassert( FALSE ); // not implemented } } else if( STYLE_TEXTURE == mStyle ) { if( mTexture ) { drawTextures(); } } // draw the children LLView::draw(); } } void LLViewBorder::drawOnePixelLines() { LLGLSNoTexture uiNoTexture; LLColor4 top_color = mHighlightLight; LLColor4 bottom_color = mHighlightLight; switch( mBevel ) { case BEVEL_OUT: top_color = mHighlightLight; bottom_color = mShadowDark; break; case BEVEL_IN: top_color = mShadowDark; bottom_color = mHighlightLight; break; case BEVEL_NONE: // use defaults break; default: llassert(0); } if( mHasKeyboardFocus ) { F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); top_color = gFocusMgr.getFocusColor(); bottom_color = top_color; LLUI::setLineWidth(lerp(1.f, 3.f, lerp_amt)); } S32 left = 0; S32 top = mRect.getHeight(); S32 right = mRect.getWidth(); S32 bottom = 0; glColor4fv( top_color.mV ); gl_line_2d(left, bottom, left, top); gl_line_2d(left, top, right, top); glColor4fv( bottom_color.mV ); gl_line_2d(right, top, right, bottom); gl_line_2d(left, bottom, right, bottom); LLUI::setLineWidth(1.f); } void LLViewBorder::drawTwoPixelLines() { LLGLSNoTexture no_texture; LLColor4 focus_color = gFocusMgr.getFocusColor(); F32* top_in_color = mShadowDark.mV; F32* top_out_color = mShadowDark.mV; F32* bottom_in_color = mShadowDark.mV; F32* bottom_out_color = mShadowDark.mV; switch( mBevel ) { case BEVEL_OUT: top_in_color = mHighlightLight.mV; top_out_color = mHighlightDark.mV; bottom_in_color = mShadowLight.mV; bottom_out_color = mShadowDark.mV; break; case BEVEL_IN: top_in_color = mShadowDark.mV; top_out_color = mShadowLight.mV; bottom_in_color = mHighlightDark.mV; bottom_out_color = mHighlightLight.mV; break; case BEVEL_BRIGHT: top_in_color = mHighlightLight.mV; top_out_color = mHighlightLight.mV; bottom_in_color = mHighlightLight.mV; bottom_out_color = mHighlightLight.mV; break; case BEVEL_NONE: // use defaults break; default: llassert(0); } if( mHasKeyboardFocus ) { top_out_color = focus_color.mV; bottom_out_color = focus_color.mV; } S32 left = 0; S32 top = mRect.getHeight(); S32 right = mRect.getWidth(); S32 bottom = 0; // draw borders glColor3fv( top_out_color ); gl_line_2d(left, bottom, left, top-1); gl_line_2d(left, top-1, right, top-1); glColor3fv( top_in_color ); gl_line_2d(left+1, bottom+1, left+1, top-2); gl_line_2d(left+1, top-2, right-1, top-2); glColor3fv( bottom_out_color ); gl_line_2d(right-1, top-1, right-1, bottom); gl_line_2d(left, bottom, right, bottom); glColor3fv( bottom_in_color ); gl_line_2d(right-2, top-2, right-2, bottom+1); gl_line_2d(left+1, bottom+1, right-1, bottom+1); } void LLViewBorder::drawTextures() { LLGLSUIDefault gls_ui; llassert( FALSE ); // TODO: finish implementing glColor4fv(UI_VERTEX_COLOR.mV); mTexture->bind(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); drawTextureTrapezoid( 0.f, mBorderWidth, mRect.getWidth(), 0, 0 ); drawTextureTrapezoid( 90.f, mBorderWidth, mRect.getHeight(), (F32)mRect.getWidth(),0 ); drawTextureTrapezoid( 180.f, mBorderWidth, mRect.getWidth(), (F32)mRect.getWidth(),(F32)mRect.getHeight() ); drawTextureTrapezoid( 270.f, mBorderWidth, mRect.getHeight(), 0, (F32)mRect.getHeight() ); } void LLViewBorder::drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 start_x, F32 start_y ) { glPushMatrix(); { glTranslatef(start_x, start_y, 0.f); glRotatef( degrees, 0, 0, 1 ); glBegin(GL_QUADS); { // width, width /---------\ length-width, width // // / \ // // / \ // // /---------------\ // // 0,0 length, 0 // glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); glTexCoord2f( (GLfloat)length, 0 ); glVertex2i( length, 0 ); glTexCoord2f( (GLfloat)(length - width), (GLfloat)width ); glVertex2i( length - width, width ); glTexCoord2f( (GLfloat)width, (GLfloat)width ); glVertex2i( width, width ); } glEnd(); } glPopMatrix(); } bool LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style) { if (node->hasAttribute("bevel_style")) { LLString bevel_string; node->getAttributeString("bevel_style", bevel_string); LLString::toLower(bevel_string); if (bevel_string == "none") { bevel_style = LLViewBorder::BEVEL_NONE; } else if (bevel_string == "in") { bevel_style = LLViewBorder::BEVEL_IN; } else if (bevel_string == "out") { bevel_style = LLViewBorder::BEVEL_OUT; } else if (bevel_string == "bright") { bevel_style = LLViewBorder::BEVEL_BRIGHT; } return true; } return false; } void LLViewBorder::setValue(const LLSD& val) { setRect(LLRect(val)); } EWidgetType LLViewBorder::getWidgetType() const { return WIDGET_TYPE_VIEW_BORDER; } LLString LLViewBorder::getWidgetTag() const { return LL_VIEW_BORDER_TAG; } // static LLView* LLViewBorder::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) { LLString name("view_border"); node->getAttributeString("name", name); LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_IN; getBevelFromAttribute(node, bevel_style); S32 border_thickness = 1; node->getAttributeS32("border_thickness", border_thickness); LLViewBorder* border = new LLViewBorder(name, LLRect(), bevel_style, LLViewBorder::STYLE_LINE, border_thickness); border->initFromXML(node, parent); return border; }