diff options
Diffstat (limited to 'indra/llui/llbutton.cpp')
-rw-r--r-- | indra/llui/llbutton.cpp | 964 |
1 files changed, 465 insertions, 499 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 2c2c1c25d8..98e8c9a988 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -45,183 +45,194 @@ #include "lluiconstants.h" #include "llresmgr.h" #include "llcriticaldamp.h" +#include "llfloater.h" +#include "llfloaterreg.h" #include "llfocusmgr.h" #include "llwindow.h" #include "llrender.h" +#include "lluictrlfactory.h" -static LLRegisterWidget<LLButton> r("button"); +static LLDefaultChildRegistry::Register<LLButton> r("button"); // globals loaded from settings.xml -S32 LLBUTTON_ORIG_H_PAD = 6; // Pre-zoomable UI S32 LLBUTTON_H_PAD = 0; S32 LLBUTTON_V_PAD = 0; S32 BTN_HEIGHT_SMALL= 0; S32 BTN_HEIGHT = 0; -S32 BTN_GRID = 12; -S32 BORDER_SIZE = 1; - -LLButton::LLButton( const std::string& name, const LLRect& rect, const std::string& control_name, void (*click_callback)(void*), void *callback_data) -: LLUICtrl(name, rect, TRUE, NULL, NULL), - mClickedCallback( click_callback ), - mMouseDownCallback( NULL ), - mMouseUpCallback( NULL ), - mHeldDownCallback( NULL ), - mGLFont( NULL ), - mMouseDownFrame( 0 ), - mHeldDownDelay( 0.5f ), // seconds until held-down callback is called - mHeldDownFrameDelay( 0 ), - mImageUnselected( NULL ), - mImageSelected( NULL ), - mImageHoverSelected( NULL ), - mImageHoverUnselected( NULL ), - mImageDisabled( NULL ), - mImageDisabledSelected( NULL ), - mToggleState( FALSE ), - mIsToggle( FALSE ), - mScaleImage( TRUE ), - mDropShadowedText( TRUE ), - mBorderEnabled( FALSE ), - mFlashing( FALSE ), - mHAlign( LLFontGL::HCENTER ), - mLeftHPad( LLBUTTON_H_PAD ), - mRightHPad( LLBUTTON_H_PAD ), - mHoverGlowStrength(0.15f), - mCurGlowStrength(0.f), - mNeedsHighlight(FALSE), - mCommitOnReturn(TRUE), - mImagep( NULL ) +LLButton::Params::Params() +: label_selected("label_selected"), // requires is_toggle 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")), + label_color("label_color"), + label_color_selected("label_color_selected"), // requires is_toggle true + label_color_disabled("label_color_disabled"), + label_color_disabled_selected("label_color_disabled_selected"), + highlight_color("highlight_color"), + image_color("image_color"), + image_color_disabled("image_color_disabled"), + image_overlay_color("image_overlay_color", LLColor4::white), + flash_color("flash_color"), + pad_right("pad_right", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")), + pad_left("pad_left", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")), + 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) { - mUnselectedLabel = name; - mSelectedLabel = name; - - setImageUnselected(std::string("button_enabled_32x128.tga")); - setImageSelected(std::string("button_enabled_selected_32x128.tga")); - setImageDisabled(std::string("button_disabled_32x128.tga")); - setImageDisabledSelected(std::string("button_disabled_32x128.tga")); - - mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" ); - mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" ); - - init(click_callback, callback_data, NULL, control_name); + addSynonym(is_toggle, "toggle"); + held_down_delay.seconds = 0.5f; + initial_value.set(LLSD(false), false); } -LLButton::LLButton(const std::string& name, const LLRect& rect, - const std::string &unselected_image_name, - const std::string &selected_image_name, - const std::string& control_name, - void (*click_callback)(void*), - void *callback_data, - const LLFontGL *font, - const std::string& unselected_label, - const std::string& selected_label ) -: LLUICtrl(name, rect, TRUE, NULL, NULL), - mClickedCallback( click_callback ), - mMouseDownCallback( NULL ), - mMouseUpCallback( NULL ), - mHeldDownCallback( NULL ), - mGLFont( NULL ), - mMouseDownFrame( 0 ), - mHeldDownDelay( 0.5f ), // seconds until held-down callback is called - mHeldDownFrameDelay( 0 ), - mImageUnselected( NULL ), - mImageSelected( NULL ), - mImageHoverSelected( NULL ), - mImageHoverUnselected( NULL ), - mImageDisabled( NULL ), - mImageDisabledSelected( NULL ), - mToggleState( FALSE ), - mIsToggle( FALSE ), - mScaleImage( TRUE ), - mDropShadowedText( TRUE ), +LLButton::LLButton(const LLButton::Params& p) +: LLUICtrl(p), + mMouseDownFrame(0), + mMouseHeldDownCount(0), mBorderEnabled( FALSE ), mFlashing( FALSE ), - mHAlign( LLFontGL::HCENTER ), - mLeftHPad( LLBUTTON_H_PAD ), - mRightHPad( LLBUTTON_H_PAD ), - mHoverGlowStrength(0.25f), mCurGlowStrength(0.f), mNeedsHighlight(FALSE), - mCommitOnReturn(TRUE), - mImagep( NULL ) + mUnselectedLabel(p.label()), + mSelectedLabel(p.label_selected()), + mGLFont(p.font), + mHeldDownDelay(p.held_down_delay.seconds), // seconds until held-down callback is called + mHeldDownFrameDelay(p.held_down_delay.frames), + mImageUnselected(p.image_unselected), + mImageSelected(p.image_selected), + mImageDisabled(p.image_disabled), + mImageDisabledSelected(p.image_disabled_selected), + mImagePressed(p.image_pressed), + mImagePressedSelected(p.image_pressed_selected), + mImageHoverSelected(p.image_hover_selected), + mImageHoverUnselected(p.image_hover_unselected), + mUnselectedLabelColor(p.label_color()), + mSelectedLabelColor(p.label_color_selected()), + mDisabledLabelColor(p.label_color_disabled()), + mDisabledSelectedLabelColor(p.label_color_disabled_selected()), + mHighlightColor(p.highlight_color()), + mImageColor(p.image_color()), + mFlashBgColor(p.flash_color()), + mDisabledImageColor(p.image_color_disabled()), + mImageOverlay(p.image_overlay()), + mImageOverlayColor(p.image_overlay_color()), + mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), + mIsToggle(p.is_toggle), + mScaleImage(p.scale_image), + mDropShadowedText(p.label_shadow), + mAutoResize(p.auto_resize), + mUseEllipses( p.use_ellipses ), + mHAlign(p.font_halign), + mLeftHPad(p.pad_left), + mRightHPad(p.pad_right), + mHoverGlowStrength(p.hover_glow_amount), + mCommitOnReturn(p.commit_on_return), + mFadeWhenDisabled(FALSE) { - mUnselectedLabel = unselected_label; - mSelectedLabel = selected_label; + static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0); + static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); - // by default, disabled color is same as enabled - mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" ); - mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" ); + //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.isProvided()) + { + mUnselectedLabel = p.name(); + } + if (!p.label_selected.isProvided()) + { + mSelectedLabel = mUnselectedLabel.getString(); + } + } - if( unselected_image_name != "" ) + // Hack to make sure there is space for at least one character + if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" "))) { - // user-specified image - don't use fixed borders unless requested - setImageUnselected(unselected_image_name); - setImageDisabled(unselected_image_name); - - mDisabledImageColor.mV[VALPHA] = 0.5f; - mScaleImage = FALSE; + // Use old defaults + mLeftHPad = llbutton_orig_h_pad; + mRightHPad = llbutton_orig_h_pad; } - else + + mMouseDownTimer.stop(); + + if (p.help_url.isProvided()) { - setImageUnselected(std::string("button_enabled_32x128.tga")); - setImageDisabled(std::string("button_disabled_32x128.tga")); + setHelpURLCallback(p.help_url); } - if( selected_image_name != "" ) + // if custom unselected button image provided... + if (p.image_unselected != default_params.image_unselected) { - // user-specified image - don't use fixed borders unless requested - setImageSelected(selected_image_name); - setImageDisabledSelected(selected_image_name); + //...fade it out for disabled image by default... + if (p.image_disabled() == default_params.image_disabled() ) + { + mImageDisabled = p.image_unselected; + mFadeWhenDisabled = TRUE; + } - mDisabledImageColor.mV[VALPHA] = 0.5f; - mScaleImage = FALSE; + if (p.image_pressed_selected == default_params.image_pressed_selected) + { + mImagePressedSelected = mImageUnselected; + } } - else + + // if custom selected button image provided... + if (p.image_selected != default_params.image_selected) { - setImageSelected(std::string("button_enabled_selected_32x128.tga")); - setImageDisabledSelected(std::string("button_disabled_32x128.tga")); - } + //...fade it out for disabled image by default... + if (p.image_disabled_selected() == default_params.image_disabled_selected()) + { + mImageDisabledSelected = p.image_selected; + mFadeWhenDisabled = TRUE; + } - init(click_callback, callback_data, font, control_name); -} + if (p.image_pressed == default_params.image_pressed) + { + mImagePressed = mImageSelected; + } + } -void LLButton::init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const std::string& control_name) -{ - mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); + if (!p.image_pressed.isProvided()) + { + mImagePressed = mImageSelected; + } - // Hack to make sure there is space for at least one character - if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" "))) + if (!p.image_pressed_selected.isProvided()) { - // Use old defaults - mLeftHPad = LLBUTTON_ORIG_H_PAD; - mRightHPad = LLBUTTON_ORIG_H_PAD; + mImagePressedSelected = mImageUnselected; } - mCallbackUserData = callback_data; - mMouseDownTimer.stop(); - - setControlName(control_name, NULL); - - mUnselectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelColor" ) ); - mSelectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelSelectedColor" ) ); - mDisabledLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelDisabledColor" ) ); - mDisabledSelectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelSelectedDisabledColor" ) ); - mHighlightColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) ); - mUnselectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) ); - mSelectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) ); - mFlashBgColor = ( LLUI::sColorsGroup->getColor( "ButtonFlashBgColor" ) ); - - mImageOverlayAlignment = LLFontGL::HCENTER; - mImageOverlayColor = LLColor4::white; -} - -LLButton::~LLButton() -{ - if( hasMouseCapture() ) + if (mImageUnselected.isNull()) { - gFocusMgr.setMouseCapture( NULL ); + llwarns << "Button: " << getName() << " with no image!" << llendl; } + + if (p.click_callback.isProvided()) + initCommitCallback(p.click_callback, mCommitSignal); // alias -> commit_callback + if (p.mouse_down_callback.isProvided()) + initCommitCallback(p.mouse_down_callback, mMouseDownSignal); + if (p.mouse_up_callback.isProvided()) + initCommitCallback(p.mouse_up_callback, mMouseUpSignal); + if (p.mouse_held_callback.isProvided()) + initCommitCallback(p.mouse_held_callback, mHeldDownSignal); } // HACK: Committing a button is the same as instantly clicking it. @@ -229,19 +240,12 @@ LLButton::~LLButton() void LLButton::onCommit() { // WARNING: Sometimes clicking a button destroys the floater or - // panel containing it. Therefore we need to call mClickedCallback + // panel containing it. Therefore we need to call LLUICtrl::onCommit() // LAST, otherwise this becomes deleted memory. - LLUICtrl::onCommit(); - if (mMouseDownCallback) - { - (*mMouseDownCallback)(mCallbackUserData); - } + mMouseDownSignal(this, LLSD()); - if (mMouseUpCallback) - { - (*mMouseUpCallback)(mCallbackUserData); - } + mMouseUpSignal(this, LLSD()); if (getSoundFlags() & MOUSE_DOWN) { @@ -259,14 +263,50 @@ void LLButton::onCommit() } // do this last, as it can result in destroying this button - if (mClickedCallback) - { - (*mClickedCallback)( mCallbackUserData ); - } + LLUICtrl::onCommit(); +} + +boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb ) +{ + return mCommitSignal.connect(cb); +} +boost::signals2::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb ) +{ + return mMouseDownSignal.connect(cb); +} +boost::signals2::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb ) +{ + return mMouseUpSignal.connect(cb); +} +boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb ) +{ + return mHeldDownSignal.connect(cb); } +// *TODO: Deprecate (for backwards compatability only) +boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data ) +{ + return setClickedCallback(boost::bind(cb, data)); +} +boost::signals2::connection LLButton::setMouseDownCallback( button_callback_t cb, void* data ) +{ + return setMouseDownCallback(boost::bind(cb, data)); +} +boost::signals2::connection LLButton::setMouseUpCallback( button_callback_t cb, void* data ) +{ + return setMouseUpCallback(boost::bind(cb, data)); +} +boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb, void* data ) +{ + return setHeldDownCallback(boost::bind(cb, data)); +} +BOOL LLButton::postBuild() +{ + autoResize(); + return TRUE; +} BOOL LLButton::handleUnicodeCharHere(llwchar uni_char) { BOOL handled = FALSE; @@ -278,10 +318,8 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char) toggleState(); } - if (mClickedCallback) - { - (*mClickedCallback)( mCallbackUserData ); - } + LLUICtrl::onCommit(); + handled = TRUE; } return handled; @@ -299,10 +337,7 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask ) handled = TRUE; - if (mClickedCallback) - { - (*mClickedCallback)( mCallbackUserData ); - } + LLUICtrl::onCommit(); } return handled; } @@ -310,27 +345,27 @@ 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 ); - if (mMouseDownCallback) - { - (*mMouseDownCallback)(mCallbackUserData); - } + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } - mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); - - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } + mMouseDownSignal(this, LLSD()); + mMouseDownTimer.start(); + mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseHeldDownCount = 0; + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } + } return TRUE; } @@ -344,13 +379,9 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) gFocusMgr.setMouseCapture( NULL ); // Regardless of where mouseup occurs, handle callback - if (mMouseUpCallback) - { - (*mMouseUpCallback)(mCallbackUserData); - } + mMouseUpSignal(this, LLSD()); - mMouseDownTimer.stop(); - mMouseDownTimer.reset(); + resetMouseDownTimer(); // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. // If mouseup in the widget, it's been clicked @@ -366,38 +397,97 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) toggleState(); } - if (mClickedCallback) - { - (*mClickedCallback)( mCallbackUserData ); - } + LLUICtrl::onCommit(); } } + else + { + childrenHandleMouseUp(x, y, mask); + } return TRUE; } - -BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) +BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLMouseHandler* other_captor = gFocusMgr.getMouseCapture(); - mNeedsHighlight = other_captor == NULL || - other_captor == this || - // this following bit is to support modal dialogs - (other_captor->isView() && hasAncestor((LLView*)other_captor)); - - if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback) + if (!childrenHandleRightMouseDown(x, y, mask)) { - F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + + if (hasTabStop() && !getIsChrome()) { - mHeldDownCallback( mCallbackUserData ); + 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; +} +BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ // 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; + if( hasMouseCapture() ) + { + // Always release the mouse + gFocusMgr.setMouseCapture( NULL ); +// 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 (isInEnabledChain()) + mNeedsHighlight = TRUE; +} + +void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mNeedsHighlight = FALSE; +} + +BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) +{ + if (!childrenHandleHover(x, y, mask)) + { + if (mMouseDownTimer.getStarted()) + { + F32 elapsed = getHeldDownTime(); + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + { + LLSD param; + param["count"] = mMouseHeldDownCount++; + 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; + } return TRUE; } @@ -405,16 +495,19 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) // virtual void LLButton::draw() { - BOOL flash = FALSE; + bool flash = FALSE; + static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0); + static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0); + if( mFlashing ) { F32 elapsed = mFlashingTimer.getElapsedTimeF32(); - S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f); + S32 flash_count = S32(elapsed * button_flash_rate * 2.f); // flash on or off? - flash = (flash_count % 2 == 0) || flash_count > S32((F32)LLUI::sConfigGroup->getS32("ButtonFlashCount") * 2.f); + 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)); @@ -425,24 +518,31 @@ void LLButton::draw() S32 local_mouse_y; LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); - BOOL pressed = pressed_by_keyboard - || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) - || mToggleState; + bool enabled = isInEnabledChain(); + + bool pressed = pressed_by_keyboard + || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)); + 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; } } @@ -450,32 +550,18 @@ void LLButton::draw() { if (mImageHoverUnselected) { - mImagep = mImageHoverUnselected; + imagep = mImageHoverUnselected; } else { - mImagep = mImageUnselected; + imagep = mImageUnselected; use_glow_effect = TRUE; } } } - else if ( pressed ) + else { - mImagep = mImageSelected; - } - else - { - mImagep = mImageUnselected; - } - - if (mFlashing) - { - use_glow_effect = TRUE; - glow_type = LLRender::BT_ALPHA; // blend the glow - if (mNeedsHighlight) // highlighted AND flashing - glow_color = (glow_color*0.5f + mFlashBgColor*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity - else - glow_color = mFlashBgColor; + imagep = selected ? mImageSelected : mImageUnselected; } // Override if more data is available @@ -485,19 +571,31 @@ 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) { - mImagep = mImageDisabled; + imagep = mImageDisabled; } - if (mNeedsHighlight && !mImagep) + if (mFlashing) + { + 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 && !imagep) { use_glow_effect = TRUE; } @@ -506,60 +604,46 @@ void LLButton::draw() LLColor4 label_color; // label changes when button state changes, not when pressed - if ( getEnabled() ) + if ( enabled ) { - if ( mToggleState ) + if ( getToggleState() ) { - label_color = mSelectedLabelColor; + label_color = mSelectedLabelColor.get(); } else { - label_color = mUnselectedLabelColor; + label_color = mUnselectedLabelColor.get(); } } else { - if ( mToggleState ) + if ( getToggleState() ) { - label_color = mDisabledSelectedLabelColor; + label_color = mDisabledSelectedLabelColor.get(); } else { - label_color = mDisabledLabelColor; + label_color = mDisabledLabelColor.get(); } } // Unselected label assignments LLWString label; - if( mToggleState ) + 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(), llround(lerp(1.f, 3.f, lerp_amt))); } if (use_glow_effect) @@ -576,25 +660,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 : mDisabledImageColor ); + imagep->draw(getLocalRect(), enabled ? mImageColor.get() : disabled_color ); 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); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } else { - mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor ); + imagep->draw(0, 0, enabled ? mImageColor.get() : disabled_color ); if (mCurGlowStrength > 0.01f) { gGL.setSceneBlendType(glow_type); - mImagep->drawSolid(0, 0, glow_color % mCurGlowStrength); + imagep->drawSolid(0, 0, glow_color % mCurGlowStrength); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } @@ -602,7 +688,7 @@ void LLButton::draw() else { // no image - llwarns << "No image for button " << getName() << llendl; + 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); } @@ -634,8 +720,8 @@ void LLButton::draw() } // fade out overlay images on disabled buttons - LLColor4 overlay_color = mImageOverlayColor; - if (!getEnabled()) + LLColor4 overlay_color = mImageOverlayColor.get(); + if (!enabled) { overlay_color.mV[VALPHA] = 0.5f; } @@ -704,52 +790,49 @@ void LLButton::draw() x++; } + // *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. mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), label_color, mHAlign, LLFontGL::BOTTOM, - mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL, - U32_MAX, text_width, - NULL, FALSE, FALSE); - } - - if (sDebugRects - || (LLView::sEditingUI && this == LLView::sEditingUIView)) - { - drawDebugRect(); + LLFontGL::NORMAL, + mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW, + S32_MAX, text_width, + NULL, mUseEllipses); } - // reset hover status for next frame - mNeedsHighlight = FALSE; + LLUICtrl::draw(); } -void LLButton::drawBorder(const LLColor4& color, S32 size) +void LLButton::drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size) { + 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); } } -void LLButton::setClickedCallback(void (*cb)(void*), void* userdata) +BOOL LLButton::getToggleState() const { - mClickedCallback = cb; - if (userdata) - { - mCallbackUserData = userdata; - } + return getValue().asBoolean(); } - void LLButton::setToggleState(BOOL b) { - if( b != mToggleState ) + if( b != getToggleState() ) { setControlValue(b); // will fire LLControlVariable callbacks (if any) - mToggleState = b; // may or may not be redundant + setValue(b); // may or may not be redundant + // Unselected label assignments + autoResize(); } } @@ -764,19 +847,11 @@ void LLButton::setFlashing( BOOL b ) BOOL LLButton::toggleState() -{ - setToggleState( !mToggleState ); - return mToggleState; -} - -void LLButton::setValue(const LLSD& value ) { - mToggleState = value.asBoolean(); -} + bool flipped = ! getToggleState(); + setToggleState(flipped); -LLSD LLButton::getValue() const -{ - return mToggleState == TRUE; + return flipped; } void LLButton::setLabel( const LLStringExplicit& label ) @@ -803,26 +878,48 @@ void LLButton::setLabelSelected( const LLStringExplicit& label ) mSelectedLabel = label; } -void LLButton::setDisabledLabel( const LLStringExplicit& label ) +void LLButton::setImageUnselected(LLPointer<LLUIImage> image) { - mDisabledLabel = label; + mImageUnselected = image; + if (mImageUnselected.isNull()) + { + llwarns << "Setting default button image for: " << getName() << " to NULL" << llendl; + } } -void LLButton::setDisabledSelectedLabel( const LLStringExplicit& label ) +void LLButton::autoResize() { - mDisabledSelectedLabel = label; + LLUIString label; + if(getToggleState()) + { + label = mSelectedLabel; + } + else + { + label = mUnselectedLabel; + } + resize(label); } -void LLButton::setImageUnselected(LLPointer<LLUIImage> image) +void LLButton::resize(LLUIString label) { - mImageUnselected = image; + // get label length + S32 label_width = mGLFont->getWidth(label.getString()); + // get current btn length + S32 btn_width =getRect().getWidth(); + // check if it need resize + if (mAutoResize == TRUE) + { + if (btn_width - (mRightHPad + mLeftHPad) < label_width) + { + setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom)); + } + } } - 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) @@ -840,26 +937,29 @@ void LLButton::setColor(const LLColor4& color) setImageColor(color); } +void LLButton::setAlpha(F32 alpha) +{ + LLColor4 temp = mImageColor.get(); + temp.setAlpha(alpha); + mImageColor.set(temp); + + temp = mDisabledImageColor.get(); + temp.setAlpha(alpha * 0.5f); + mDisabledImageColor.set(temp); +} void LLButton::setImageDisabled(LLPointer<LLUIImage> image) { mImageDisabled = image; mDisabledImageColor = mImageColor; - mDisabledImageColor.mV[VALPHA] *= 0.5f; + mFadeWhenDisabled = TRUE; } void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image) { mImageDisabledSelected = image; mDisabledImageColor = mImageColor; - mDisabledImageColor.mV[VALPHA] *= 0.5f; -} - -void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name, const LLColor4& c ) -{ - setImageDisabled(image_name); - setImageDisabledSelected(selected_name); - mDisabledImageColor = c; + mFadeWhenDisabled = TRUE; } void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image) @@ -867,24 +967,11 @@ void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image) mImageHoverSelected = image; } -void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name) -{ - LLColor4 clr = mImageColor; - clr.mV[VALPHA] *= .5f; - setDisabledImages( image_name, selected_name, clr ); -} - void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image) { mImageHoverUnselected = image; } -void LLButton::setHoverImages( const std::string& image_name, const std::string& selected_name ) -{ - setImageHoverUnselected(image_name); - setImageHoverSelected(selected_name); -} - void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color) { if (image_name.empty()) @@ -899,11 +986,9 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a } } - void LLButton::onMouseCaptureLost() { - mMouseDownTimer.stop(); - mMouseDownTimer.reset(); + resetMouseDownTimer(); } //------------------------------------------------------------------------- @@ -924,42 +1009,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, @@ -975,28 +1024,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node, } } -// virtual -LLXMLNodePtr LLButton::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLUICtrl::getXML(); - - node->createChild("label", TRUE)->setStringValue(getLabelUnselected()); - node->createChild("label_selected", TRUE)->setStringValue(getLabelSelected()); - node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); - node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); - - addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,std::string("image_unselected")); - addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,std::string("image_selected")); - addImageAttributeToXML(node,mImageHoverSelectedName,mImageHoverSelectedID,std::string("image_hover_selected")); - addImageAttributeToXML(node,mImageHoverUnselectedName,mImageHoverUnselectedID,std::string("image_hover_unselected")); - addImageAttributeToXML(node,mImageDisabledName,mImageDisabledID,std::string("image_disabled")); - addImageAttributeToXML(node,mImageDisabledSelectedName,mImageDisabledSelectedID,std::string("image_disabled_selected")); - - node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage); - - return node; -} - void clicked_help(void* data) { LLButton* self = (LLButton*)data; @@ -1010,114 +1037,53 @@ void clicked_help(void* data) LLUI::sHtmlHelp->show(self->getHelpURL()); } -// static -LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +void LLButton::setHelpURLCallback(const std::string &help_url) { - std::string name("button"); - node->getAttributeString("name", name); - - std::string label = name; - node->getAttributeString("label", label); - - std::string label_selected = label; - node->getAttributeString("label_selected", label_selected); - - LLFontGL* font = selectFont(node); - - std::string image_unselected; - if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected); - - std::string image_selected; - if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected); - - std::string image_hover_selected; - if (node->hasAttribute("image_hover_selected")) node->getAttributeString("image_hover_selected",image_hover_selected); - - std::string image_hover_unselected; - if (node->hasAttribute("image_hover_unselected")) node->getAttributeString("image_hover_unselected",image_hover_unselected); - - std::string image_disabled_selected; - if (node->hasAttribute("image_disabled_selected")) node->getAttributeString("image_disabled_selected",image_disabled_selected); - - std::string image_disabled; - if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled); - - std::string image_overlay; - node->getAttributeString("image_overlay", image_overlay); - - LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER; - std::string image_overlay_alignment_string; - if (node->hasAttribute("image_overlay_alignment")) - { - node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string); - image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string); - } - - - LLButton *button = new LLButton(name, - LLRect(), - image_unselected, - image_selected, - LLStringUtil::null, - NULL, - parent, - font, - label, - label_selected); - - node->getAttributeS32("pad_right", button->mRightHPad); - node->getAttributeS32("pad_left", button->mLeftHPad); + mHelpURL = help_url; + setClickedCallback(clicked_help,this); +} - BOOL is_toggle = button->getIsToggle(); - node->getAttributeBOOL("toggle", is_toggle); - button->setIsToggle(is_toggle); +// static +void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname) +{ + bool floater_vis = LLFloaterReg::toggleInstance(sdname.asString()); + LLButton* button = dynamic_cast<LLButton*>(ctrl); + if (button) + button->setToggleState(floater_vis); +} - if(image_hover_selected != LLStringUtil::null) button->setImageHoverSelected(image_hover_selected); - - if(image_hover_unselected != LLStringUtil::null) button->setImageHoverUnselected(image_hover_unselected); - - if(image_disabled_selected != LLStringUtil::null) button->setImageDisabledSelected(image_disabled_selected ); - - if(image_disabled != LLStringUtil::null) button->setImageDisabled(image_disabled); - - if(image_overlay != LLStringUtil::null) button->setImageOverlay(image_overlay, image_overlay_alignment); +// static +// Gets called once +void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) +{ + 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(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + // Set the clicked callback to toggle the floater + button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname)); +} - if (node->hasAttribute("halign")) - { - LLFontGL::HAlign halign = selectFontHAlign(node); - button->setHAlign(halign); - } +void LLButton::resetMouseDownTimer() +{ + mMouseDownTimer.stop(); + mMouseDownTimer.reset(); +} - if (node->hasAttribute("scale_image")) - { - BOOL needsScale = FALSE; - node->getAttributeBOOL("scale_image",needsScale); - button->setScaleImage( needsScale ); - } - if(label.empty()) - { - button->setLabelUnselected(node->getTextContents()); - } - if (label_selected.empty()) - { - button->setLabelSelected(node->getTextContents()); - } - - if (node->hasAttribute("help_url")) +// *TODO: Remove this function after the initial XUI XML re-export pass. +// static +void LLButton::setupParamsForExport(Params& p, LLView* parent) +{ + std::string label = p.label; + if (label.empty()) { - std::string help_url; - node->getAttributeString("help_url",help_url); - button->setHelpURLCallback(help_url); + //if our label is empty this is a picture style button + p.picture_style = true; } - button->initFromXML(node, parent); - - return button; -} - -void LLButton::setHelpURLCallback(const std::string &help_url) -{ - mHelpURL = help_url; - setClickedCallback(clicked_help,this); + LLUICtrl::setupParamsForExport(p, parent); } |