diff options
Diffstat (limited to 'indra/llui/llbutton.cpp')
-rw-r--r-- | indra/llui/llbutton.cpp | 649 |
1 files changed, 348 insertions, 301 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 110ad82763..d51276bf26 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -1,38 +1,33 @@ + /** * @file llbutton.cpp * @brief LLButton base class * - * $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$ */ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_BUTTON +#define LLBUTTON_CPP #include "llbutton.h" // Linden library includes @@ -40,7 +35,6 @@ #include "llstring.h" // Project includes -#include "llhtmlhelp.h" #include "llkeyboard.h" #include "llui.h" #include "lluiconstants.h" @@ -50,31 +44,41 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llwindow.h" +#include "llnotificationsutil.h" #include "llrender.h" #include "lluictrlfactory.h" +#include "llhelp.h" +#include "lldockablefloater.h" -static LLDefaultWidgetRegistry::Register<LLButton> r("button"); +static LLDefaultChildRegistry::Register<LLButton> r("button"); + +// Compiler optimization, generate extern template +template class LLButton* LLView::getChild<class LLButton>( + const std::string& name, BOOL recurse) const; // globals loaded from settings.xml S32 LLBUTTON_H_PAD = 0; -S32 LLBUTTON_V_PAD = 0; S32 BTN_HEIGHT_SMALL= 0; S32 BTN_HEIGHT = 0; -template LLButton* LLView::getChild<LLButton>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - LLButton::Params::Params() : label_selected("label_selected"), // requires is_toggle true - label_dropshadow("label_shadow", true), + label_shadow("label_shadow", true), auto_resize("auto_resize", false), + use_ellipses("use_ellipses", false), image_unselected("image_unselected"), image_selected("image_selected"), image_hover_selected("image_hover_selected"), image_hover_unselected("image_hover_unselected"), image_disabled_selected("image_disabled_selected"), image_disabled("image_disabled"), + image_pressed("image_pressed"), + image_pressed_selected("image_pressed_selected"), image_overlay("image_overlay"), image_overlay_alignment("image_overlay_alignment", std::string("center")), + image_top_pad("image_top_pad"), + image_bottom_pad("image_bottom_pad"), + imgoverlay_label_space("imgoverlay_label_space", 1), label_color("label_color"), label_color_selected("label_color_selected"), // requires is_toggle true label_color_disabled("label_color_disabled"), @@ -86,16 +90,15 @@ LLButton::Params::Params() flash_color("flash_color"), pad_right("pad_right", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")), pad_left("pad_left", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")), + pad_bottom("pad_bottom"), click_callback("click_callback"), mouse_down_callback("mouse_down_callback"), mouse_up_callback("mouse_up_callback"), mouse_held_callback("mouse_held_callback"), is_toggle("is_toggle", false), scale_image("scale_image", true), - help_url("help_url"), hover_glow_amount("hover_glow_amount"), - commit_on_return("commit_on_return", true), - picture_style("picture_style", false) + commit_on_return("commit_on_return", true) { addSynonym(is_toggle, "toggle"); held_down_delay.seconds = 0.5f; @@ -111,7 +114,7 @@ LLButton::LLButton(const LLButton::Params& p) mFlashing( FALSE ), mCurGlowStrength(0.f), mNeedsHighlight(FALSE), - mImagep( NULL ), + mMouseOver(false), mUnselectedLabel(p.label()), mSelectedLabel(p.label_selected()), mGLFont(p.font), @@ -121,6 +124,9 @@ LLButton::LLButton(const LLButton::Params& p) mImageSelected(p.image_selected), mImageDisabled(p.image_disabled), mImageDisabledSelected(p.image_disabled_selected), + mImageFlash(p.image_flash), + mImagePressed(p.image_pressed), + mImagePressedSelected(p.image_pressed_selected), mImageHoverSelected(p.image_hover_selected), mImageHoverUnselected(p.image_hover_unselected), mUnselectedLabelColor(p.label_color()), @@ -134,31 +140,34 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlay(p.image_overlay()), mImageOverlayColor(p.image_overlay_color()), mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), + mImageOverlayTopPad(p.image_top_pad), + mImageOverlayBottomPad(p.image_bottom_pad), + mImgOverlayLabelSpace(p.imgoverlay_label_space), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), - mDropShadowedText(p.label_dropshadow), + mDropShadowedText(p.label_shadow), mAutoResize(p.auto_resize), + mUseEllipses( p.use_ellipses ), mHAlign(p.font_halign), mLeftHPad(p.pad_left), mRightHPad(p.pad_right), + mBottomVPad(p.pad_bottom), mHoverGlowStrength(p.hover_glow_amount), mCommitOnReturn(p.commit_on_return), - mFadeWhenDisabled(FALSE) + mFadeWhenDisabled(FALSE), + mForcePressedState(false), + mLastDrawCharsCount(0), + mMouseDownSignal(NULL), + mMouseUpSignal(NULL), + mHeldDownSignal(NULL) + { static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0); - static LLButton::Params default_params(LLUICtrlFactory::getDefaultParams<LLButton::Params>()); + static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); - //if we aren't a picture_style button set label as name if not provided - if (!p.picture_style.isProvided() || !p.picture_style) + if (!p.label_selected.isProvided()) { - if (!p.label.isProvided()) - { - mUnselectedLabel = p.name(); - } - if (!p.label_selected.isProvided()) - { - mSelectedLabel = mUnselectedLabel.getString(); - } + mSelectedLabel = mUnselectedLabel; } // Hack to make sure there is space for at least one character @@ -171,11 +180,6 @@ LLButton::LLButton(const LLButton::Params& p) mMouseDownTimer.stop(); - if (p.help_url.isProvided()) - { - setHelpURLCallback(p.help_url); - } - // if custom unselected button image provided... if (p.image_unselected != default_params.image_unselected) { @@ -185,6 +189,11 @@ LLButton::LLButton(const LLButton::Params& p) mImageDisabled = p.image_unselected; mFadeWhenDisabled = TRUE; } + + if (p.image_pressed_selected == default_params.image_pressed_selected) + { + mImagePressedSelected = mImageUnselected; + } } // if custom selected button image provided... @@ -196,6 +205,21 @@ LLButton::LLButton(const LLButton::Params& p) mImageDisabledSelected = p.image_selected; mFadeWhenDisabled = TRUE; } + + if (p.image_pressed == default_params.image_pressed) + { + mImagePressed = mImageSelected; + } + } + + if (!p.image_pressed.isProvided()) + { + mImagePressed = mImageSelected; + } + + if (!p.image_pressed_selected.isProvided()) + { + mImagePressedSelected = mImageUnselected; } if (mImageUnselected.isNull()) @@ -204,13 +228,28 @@ LLButton::LLButton(const LLButton::Params& p) } if (p.click_callback.isProvided()) - initCommitCallback(p.click_callback, mCommitSignal); // alias -> commit_callback + { + setCommitCallback(initCommitCallback(p.click_callback)); // alias -> commit_callback + } if (p.mouse_down_callback.isProvided()) - initCommitCallback(p.mouse_down_callback, mMouseDownSignal); + { + setMouseDownCallback(initCommitCallback(p.mouse_down_callback)); + } if (p.mouse_up_callback.isProvided()) - initCommitCallback(p.mouse_up_callback, mMouseUpSignal); + { + setMouseUpCallback(initCommitCallback(p.mouse_up_callback)); + } if (p.mouse_held_callback.isProvided()) - initCommitCallback(p.mouse_held_callback, mHeldDownSignal); + { + setHeldDownCallback(initCommitCallback(p.mouse_held_callback)); + } +} + +LLButton::~LLButton() +{ + delete mMouseDownSignal; + delete mMouseUpSignal; + delete mHeldDownSignal; } // HACK: Committing a button is the same as instantly clicking it. @@ -221,9 +260,9 @@ void LLButton::onCommit() // panel containing it. Therefore we need to call LLUICtrl::onCommit() // LAST, otherwise this becomes deleted memory. - mMouseDownSignal(this, LLSD()); + if (mMouseDownSignal) (*mMouseDownSignal)(this, LLSD()); - mMouseUpSignal(this, LLSD()); + if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD()); if (getSoundFlags() & MOUSE_DOWN) { @@ -244,43 +283,42 @@ void LLButton::onCommit() LLUICtrl::onCommit(); } -boost::signals::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb ) +boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb ) { - return mCommitSignal.connect(cb); + if (!mCommitSignal) mCommitSignal = new commit_signal_t(); + return mCommitSignal->connect(cb); } -boost::signals::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb ) +boost::signals2::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb ) { - return mMouseDownSignal.connect(cb); + if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t(); + return mMouseDownSignal->connect(cb); } -boost::signals::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb ) +boost::signals2::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb ) { - return mMouseUpSignal.connect(cb); + if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t(); + return mMouseUpSignal->connect(cb); } -boost::signals::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb ) +boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb ) { - return mHeldDownSignal.connect(cb); -} - -boost::signals::connection LLButton::setRightClickedCallback( const commit_signal_t::slot_type& cb ) -{ - return mRightClickSignal.connect(cb); + if (!mHeldDownSignal) mHeldDownSignal = new commit_signal_t(); + return mHeldDownSignal->connect(cb); } // *TODO: Deprecate (for backwards compatability only) -boost::signals::connection LLButton::setClickedCallback( button_callback_t cb, void* data ) +boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data ) { return setClickedCallback(boost::bind(cb, data)); } -boost::signals::connection LLButton::setMouseDownCallback( button_callback_t cb, void* data ) +boost::signals2::connection LLButton::setMouseDownCallback( button_callback_t cb, void* data ) { return setMouseDownCallback(boost::bind(cb, data)); } -boost::signals::connection LLButton::setMouseUpCallback( button_callback_t cb, void* data ) +boost::signals2::connection LLButton::setMouseUpCallback( button_callback_t cb, void* data ) { return setMouseUpCallback(boost::bind(cb, data)); } -boost::signals::connection LLButton::setHeldDownCallback( button_callback_t cb, void* data ) +boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb, void* data ) { return setHeldDownCallback(boost::bind(cb, data)); } @@ -328,25 +366,35 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask ) BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); - mMouseDownSignal(this, LLSD()); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } - mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); - mMouseHeldDownCount = 0; - - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } + /* + * ATTENTION! This call fires another mouse down callback. + * If you wish to remove this call emit that signal directly + * by calling LLUICtrl::mMouseDownSignal(x, y, mask); + */ + LLUICtrl::handleMouseDown(x, y, mask); + + if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD()); + + mMouseDownTimer.start(); + mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseHeldDownCount = 0; + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } + } return TRUE; } @@ -359,8 +407,15 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) // Always release the mouse gFocusMgr.setMouseCapture( NULL ); + /* + * ATTENTION! This call fires another mouse up callback. + * If you wish to remove this call emit that signal directly + * by calling LLUICtrl::mMouseUpSignal(x, y, mask); + */ + LLUICtrl::handleMouseUp(x, y, mask); + // Regardless of where mouseup occurs, handle callback - mMouseUpSignal(this, LLSD()); + if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD()); resetMouseDownTimer(); @@ -381,21 +436,35 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) LLUICtrl::onCommit(); } } + else + { + childrenHandleMouseUp(x, y, mask); + } return TRUE; } BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleRightMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } +// if (pointInView(x, y)) +// { +// } + } + // send the mouse down signal + LLUICtrl::handleRightMouseDown(x,y,mask); + // *TODO: Return result of LLUICtrl call above? Should defer to base class + // but this might change the mouse handling of existing buttons in a bad way + // if they are not mouse opaque. return TRUE; } @@ -407,43 +476,68 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) // Always release the mouse gFocusMgr.setMouseCapture( NULL ); - if (pointInView(x, y)) - { - mRightClickSignal(this, getValue()); - } +// if (pointInView(x, y)) +// { +// mRightMouseUpSignal(this, x,y,mask); +// } } + else + { + childrenHandleRightMouseUp(x, y, mask); + } + // send the mouse up signal + LLUICtrl::handleRightMouseUp(x,y,mask); + // *TODO: Return result of LLUICtrl call above? Should defer to base class + // but this might change the mouse handling of existing buttons in a bad way. + // if they are not mouse opaque. return TRUE; } void LLButton::onMouseEnter(S32 x, S32 y, MASK mask) { - if (getEnabled()) + LLUICtrl::onMouseEnter(x, y, mask); + + if (isInEnabledChain()) + { mNeedsHighlight = TRUE; + } + + mMouseOver = true; } void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) { + LLUICtrl::onMouseLeave(x, y, mask); + mNeedsHighlight = FALSE; + mMouseOver = true; +} + +void LLButton::setHighlight(bool b) +{ + mNeedsHighlight = b; } BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) { - if (mMouseDownTimer.getStarted()) + if (!childrenHandleHover(x, y, mask)) { - F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + if (mMouseDownTimer.getStarted()) { - LLSD param; - param["count"] = mMouseHeldDownCount++; - mHeldDownSignal(this, param); + F32 elapsed = getHeldDownTime(); + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + { + LLSD param; + param["count"] = mMouseHeldDownCount++; + if (mHeldDownSignal) (*mHeldDownSignal)(this, param); + } } - } - - // We only handle the click if the click both started and ended within us - getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + // We only handle the click if the click both started and ended within us + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + } return TRUE; } @@ -451,7 +545,8 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) // virtual void LLButton::draw() { - BOOL flash = FALSE; + F32 alpha = getDrawContext().mAlpha; + bool flash = FALSE; static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0); static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0); @@ -463,35 +558,39 @@ void LLButton::draw() flash = (flash_count % 2 == 0) || flash_count > S32((F32)button_flash_count * 2.f); } - BOOL pressed_by_keyboard = FALSE; + bool pressed_by_keyboard = FALSE; if (hasFocus()) { pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN)); } // Unselected image assignments - S32 local_mouse_x; - S32 local_mouse_y; - LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); + bool enabled = isInEnabledChain(); - BOOL pressed = pressed_by_keyboard - || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) - || getToggleState(); + bool pressed = pressed_by_keyboard + || (hasMouseCapture() && mMouseOver) + || mForcePressedState; + bool selected = getToggleState(); - BOOL use_glow_effect = FALSE; + bool use_glow_effect = FALSE; LLColor4 glow_color = LLColor4::white; LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA; - if ( mNeedsHighlight ) + LLUIImage* imagep = NULL; + if (pressed) { - if (pressed) + imagep = selected ? mImagePressedSelected : mImagePressed; + } + else if ( mNeedsHighlight ) + { + if (selected) { if (mImageHoverSelected) { - mImagep = mImageHoverSelected; + imagep = mImageHoverSelected; } else { - mImagep = mImageSelected; + imagep = mImageSelected; use_glow_effect = TRUE; } } @@ -499,34 +598,18 @@ void LLButton::draw() { if (mImageHoverUnselected) { - mImagep = mImageHoverUnselected; + imagep = mImageHoverUnselected; } else { - mImagep = mImageUnselected; + imagep = mImageUnselected; use_glow_effect = TRUE; } } } - else if ( pressed ) - { - mImagep = mImageSelected; - } - else - { - mImagep = mImageUnselected; - } - - if (mFlashing) + else { - LLColor4 flash_color = mFlashBgColor.get(); - use_glow_effect = TRUE; - glow_type = LLRender::BT_ALPHA; // blend the glow - - if (mNeedsHighlight) // highlighted AND flashing - glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity - else - glow_color = flash_color; + imagep = selected ? mImageSelected : mImageUnselected; } // Override if more data is available @@ -536,19 +619,41 @@ void LLButton::draw() // disabled but checked if (!mImageDisabledSelected.isNull() && - ( (getEnabled() && getTentative()) - || (!getEnabled() && pressed ) ) ) + ( (enabled && getTentative()) + || (!enabled && selected ) ) ) { - mImagep = mImageDisabledSelected; + imagep = mImageDisabledSelected; } else if (!mImageDisabled.isNull() - && !getEnabled() - && !pressed) + && !enabled + && !selected) + { + imagep = mImageDisabled; + } + + if (mFlashing) { - mImagep = mImageDisabled; + // if button should flash and we have icon for flashing, use it as image for button + if(flash && mImageFlash) + { + // setting flash to false to avoid its further influence on glow + flash = false; + imagep = mImageFlash; + } + // else use usual flashing via flash_color + else + { + LLColor4 flash_color = mFlashBgColor.get(); + use_glow_effect = TRUE; + glow_type = LLRender::BT_ALPHA; // blend the glow + if (mNeedsHighlight) // highlighted AND flashing + glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity + else + glow_color = flash_color; + } } - if (mNeedsHighlight && !mImagep) + if (mNeedsHighlight && !imagep) { use_glow_effect = TRUE; } @@ -557,7 +662,7 @@ void LLButton::draw() LLColor4 label_color; // label changes when button state changes, not when pressed - if ( getEnabled() ) + if ( enabled ) { if ( getToggleState() ) { @@ -585,32 +690,18 @@ void LLButton::draw() if( getToggleState() ) { - if( getEnabled() || mDisabledSelectedLabel.empty() ) - { - label = mSelectedLabel; - } - else - { - label = mDisabledSelectedLabel; - } + label = mSelectedLabel; } else { - if( getEnabled() || mDisabledLabel.empty() ) - { - label = mUnselectedLabel; - } - else - { - label = mDisabledLabel; - } + label = mUnselectedLabel; } // overlay with keyboard focus border if (hasFocus()) { F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); - drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt))); + drawBorder(imagep, gFocusMgr.getFocusColor() % alpha, llround(lerp(1.f, 3.f, lerp_amt))); } if (use_glow_effect) @@ -627,27 +718,27 @@ void LLButton::draw() // Draw button image, if available. // Otherwise draw basic rectangular button. - if (mImagep.notNull()) + if (imagep != NULL) { // apply automatic 50% alpha fade to disabled image LLColor4 disabled_color = mFadeWhenDisabled ? mDisabledImageColor.get() % 0.5f : mDisabledImageColor.get(); if ( mScaleImage) { - mImagep->draw(getLocalRect(), getEnabled() ? mImageColor.get() : disabled_color ); + imagep->draw(getLocalRect(), (enabled ? mImageColor.get() : disabled_color) % alpha ); if (mCurGlowStrength > 0.01f) { gGL.setSceneBlendType(glow_type); - mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength); + imagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % (mCurGlowStrength * alpha)); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } else { - mImagep->draw(0, 0, getEnabled() ? mImageColor.get() : disabled_color ); + imagep->draw(0, 0, (enabled ? mImageColor.get() : disabled_color) % alpha ); if (mCurGlowStrength > 0.01f) { gGL.setSceneBlendType(glow_type); - mImagep->drawSolid(0, 0, glow_color % mCurGlowStrength); + imagep->drawSolid(0, 0, glow_color % (mCurGlowStrength * alpha)); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } @@ -657,7 +748,7 @@ void LLButton::draw() // no image lldebugs << "No image for button " << getName() << llendl; // draw it in pink so we can find it - gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1 % alpha, FALSE); } // let overlay image and text play well together @@ -686,20 +777,21 @@ void LLButton::draw() center_x++; } + center_y += (mImageOverlayBottomPad - mImageOverlayTopPad); // fade out overlay images on disabled buttons LLColor4 overlay_color = mImageOverlayColor.get(); - if (!getEnabled()) + if (!enabled) { overlay_color.mV[VALPHA] = 0.5f; } + overlay_color.mV[VALPHA] *= alpha; switch(mImageOverlayAlignment) { case LLFontGL::LEFT: - text_left += overlay_width + 1; - text_width -= overlay_width + 1; + text_left += overlay_width + mImgOverlayLabelSpace; mImageOverlay->draw( - mLeftHPad, + mLeftHPad, center_y - (overlay_height / 2), overlay_width, overlay_height, @@ -714,10 +806,9 @@ void LLButton::draw() overlay_color); break; case LLFontGL::RIGHT: - text_right -= overlay_width + 1; - text_width -= overlay_width + 1; + text_right -= overlay_width + mImgOverlayLabelSpace; mImageOverlay->draw( - getRect().getWidth() - mRightHPad - overlay_width, + getRect().getWidth() - mRightHPad - overlay_width, center_y - (overlay_height / 2), overlay_width, overlay_height, @@ -741,7 +832,7 @@ void LLButton::draw() x = text_right; break; case LLFontGL::HCENTER: - x = getRect().getWidth() / 2; + x = text_left + (text_width / 2); break; case LLFontGL::LEFT: default: @@ -757,28 +848,35 @@ void LLButton::draw() x++; } - mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), - label_color, + // *NOTE: mantipov: before mUseEllipses is implemented in EXT-279 U32_MAX has been passed as + // max_chars. + // LLFontGL::render expects S32 max_chars variable but process in a separate way -1 value. + // Due to U32_MAX is equal to S32 -1 value I have rest this value for non-ellipses mode. + // Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars. + mLastDrawCharsCount = mGLFont->render(label, 0, + (F32)x, + (F32)(mBottomVPad + y_offset), + label_color % alpha, mHAlign, LLFontGL::BOTTOM, LLFontGL::NORMAL, mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW, - U32_MAX, text_width, - NULL, FALSE, FALSE); + S32_MAX, text_width, + NULL, mUseEllipses); } - LLView::draw(); + LLUICtrl::draw(); } -void LLButton::drawBorder(const LLColor4& color, S32 size) +void LLButton::drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size) { - if (mImagep.isNull()) return; + if (imagep == NULL) return; if (mScaleImage) { - mImagep->drawBorder(getLocalRect(), color, size); + imagep->drawBorder(getLocalRect(), color, size); } else { - mImagep->drawBorder(0, 0, color, size); + imagep->drawBorder(0, 0, color, size); } } @@ -840,16 +938,6 @@ void LLButton::setLabelSelected( const LLStringExplicit& label ) mSelectedLabel = label; } -void LLButton::setDisabledLabel( const LLStringExplicit& label ) -{ - mDisabledLabel = label; -} - -void LLButton::setDisabledSelectedLabel( const LLStringExplicit& label ) -{ - mDisabledSelectedLabel = label; -} - void LLButton::setImageUnselected(LLPointer<LLUIImage> image) { mImageUnselected = image; @@ -864,25 +952,11 @@ void LLButton::autoResize() LLUIString label; if(getToggleState()) { - if( getEnabled() || mDisabledSelectedLabel.empty() ) - { - label = mSelectedLabel; - } - else - { - label = mDisabledSelectedLabel; - } + label = mSelectedLabel; } else { - if( getEnabled() || mDisabledLabel.empty() ) - { - label = mUnselectedLabel; - } - else - { - label = mDisabledLabel; - } + label = mUnselectedLabel; } resize(label); } @@ -904,9 +978,8 @@ void LLButton::resize(LLUIString label) } void LLButton::setImages( const std::string &image_name, const std::string &selected_name ) { - setImageUnselected(image_name); - setImageSelected(selected_name); - + setImageUnselected(LLUI::getUIImage(image_name)); + setImageSelected(LLUI::getUIImage(selected_name)); } void LLButton::setImageSelected(LLPointer<LLUIImage> image) @@ -924,7 +997,6 @@ void LLButton::setColor(const LLColor4& color) setImageColor(color); } - void LLButton::setImageDisabled(LLPointer<LLUIImage> image) { mImageDisabled = image; @@ -939,17 +1011,9 @@ void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image) mFadeWhenDisabled = TRUE; } -void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name) +void LLButton::setImagePressed(LLPointer<LLUIImage> image) { - setDisabledImages( image_name, selected_name, mImageColor.get()); - mFadeWhenDisabled = TRUE; -} - -void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name, const LLColor4& c ) -{ - setImageDisabled(image_name); - setImageDisabledSelected(selected_name); - mDisabledImageColor = c; + mImagePressed = image; } void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image) @@ -962,10 +1026,9 @@ void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image) mImageHoverUnselected = image; } -void LLButton::setHoverImages( const std::string& image_name, const std::string& selected_name ) +void LLButton::setImageFlash(LLPointer<LLUIImage> image) { - setImageHoverUnselected(image_name); - setImageHoverSelected(selected_name); + mImageFlash = image; } void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color) @@ -982,6 +1045,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a } } +void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color) +{ + if (image_id.isNull()) + { + mImageOverlay = NULL; + } + else + { + mImageOverlay = LLUI::getUIImageByID(image_id); + mImageOverlayAlignment = alignment; + mImageOverlayColor = color; + } +} + void LLButton::onMouseCaptureLost() { resetMouseDownTimer(); @@ -1005,42 +1082,6 @@ S32 round_up(S32 grid, S32 value) } } -void LLButton::setImageUnselected(const std::string &image_name) -{ - setImageUnselected(LLUI::getUIImage(image_name)); - mImageUnselectedName = image_name; -} - -void LLButton::setImageSelected(const std::string &image_name) -{ - setImageSelected(LLUI::getUIImage(image_name)); - mImageSelectedName = image_name; -} - -void LLButton::setImageHoverSelected(const std::string &image_name) -{ - setImageHoverSelected(LLUI::getUIImage(image_name)); - mImageHoverSelectedName = image_name; -} - -void LLButton::setImageHoverUnselected(const std::string &image_name) -{ - setImageHoverUnselected(LLUI::getUIImage(image_name)); - mImageHoverUnselectedName = image_name; -} - -void LLButton::setImageDisabled(const std::string &image_name) -{ - setImageDisabled(LLUI::getUIImage(image_name)); - mImageDisabledName = image_name; -} - -void LLButton::setImageDisabledSelected(const std::string &image_name) -{ - setImageDisabledSelected(LLUI::getUIImage(image_name)); - mImageDisabledSelectedName = image_name; -} - void LLButton::addImageAttributeToXML(LLXMLNodePtr node, const std::string& image_name, const LLUUID& image_id, @@ -1056,24 +1097,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node, } } -void clicked_help(void* data) -{ - LLButton* self = (LLButton*)data; - if (!self) return; - - if (!LLUI::sHtmlHelp) - { - return; - } - - LLUI::sHtmlHelp->show(self->getHelpURL()); -} - -void LLButton::setHelpURLCallback(const std::string &help_url) -{ - mHelpURL = help_url; - setClickedCallback(clicked_help,this); -} // static void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname) @@ -1094,28 +1117,52 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) // Get the visibility control name for the floater std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) - button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); // Set the clicked callback to toggle the floater button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname)); } -void LLButton::resetMouseDownTimer() +// static +void LLButton::setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) { - mMouseDownTimer.stop(); - mMouseDownTimer.reset(); + LLButton* button = dynamic_cast<LLButton*>(ctrl); + if (!button) + return; + // Get the visibility control name for the floater + std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); + // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) + button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); + // Set the clicked callback to toggle the floater + button->setClickedCallback(boost::bind(&LLDockableFloater::toggleInstance, sdname)); } - -// *TODO: Remove this function after the initial XUI XML re-export pass. // static -void LLButton::setupParamsForExport(Params& p, LLView* parent) +void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname) { - std::string label = p.label; - if (label.empty()) + // search back through the button's parents for a panel + // with a help_topic string defined + std::string help_topic; + if (LLUI::sHelpImpl && + ctrl->findHelpTopic(help_topic)) { - //if our label is empty this is a picture style button - p.picture_style = true; + LLUI::sHelpImpl->showTopic(help_topic); + return; // success } - LLUICtrl::setupParamsForExport(p, parent); + // display an error if we can't find a help_topic string. + // fix this by adding a help_topic attribute to the xui file + LLNotificationsUtil::add("UnableToFindHelpTopic"); +} + +void LLButton::resetMouseDownTimer() +{ + mMouseDownTimer.stop(); + mMouseDownTimer.reset(); +} + + +BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + // just treat a double click as a second click + return handleMouseDown(x, y, mask); } |