summaryrefslogtreecommitdiff
path: root/indra/llui/llbutton.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llbutton.cpp')
-rw-r--r--indra/llui/llbutton.cpp649
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);
}