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.cpp1139
1 files changed, 598 insertions, 541 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 4fa2a3de92..d51276bf26 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -1,36 +1,33 @@
+
/**
* @file llbutton.cpp
* @brief LLButton base class
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, 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://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * 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.
*
- * 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.
+ * 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.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
+#define LLBUTTON_CPP
#include "llbutton.h"
// Linden library includes
@@ -43,182 +40,216 @@
#include "lluiconstants.h"
#include "llresmgr.h"
#include "llcriticaldamp.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
-#include "llglimmediate.h"
+#include "llnotificationsutil.h"
+#include "llrender.h"
+#include "lluictrlfactory.h"
+#include "llhelp.h"
+#include "lldockablefloater.h"
+
+static LLDefaultChildRegistry::Register<LLButton> r("button");
-static LLRegisterWidget<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_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 LLString& name, const LLRect& rect, const LLString& 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")),
+ 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"),
+ 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")),
+ 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),
+ hover_glow_amount("hover_glow_amount"),
+ commit_on_return("commit_on_return", true)
{
- mUnselectedLabel = name;
- mSelectedLabel = name;
-
- setImageUnselected("button_enabled_32x128.tga");
- setImageSelected("button_enabled_selected_32x128.tga");
- setImageDisabled("button_disabled_32x128.tga");
- setImageDisabledSelected("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 LLString& name, const LLRect& rect,
- const LLString &unselected_image_name,
- const LLString &selected_image_name,
- const LLString& control_name,
- void (*click_callback)(void*),
- void *callback_data,
- const LLFontGL *font,
- const LLString& unselected_label,
- const LLString& 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 = unselected_label;
- mSelectedLabel = selected_label;
+ mMouseOver(false),
+ 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),
+ 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()),
+ 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)),
+ 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_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),
+ mForcePressedState(false),
+ mLastDrawCharsCount(0),
+ mMouseDownSignal(NULL),
+ mMouseUpSignal(NULL),
+ mHeldDownSignal(NULL)
- // by default, disabled color is same as enabled
- mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
- mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
+{
+ static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
+ static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
- if( unselected_image_name != "" )
+ if (!p.label_selected.isProvided())
{
- // 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;
+ mSelectedLabel = mUnselectedLabel;
}
- else
+
+ // Hack to make sure there is space for at least one character
+ if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))
{
- setImageUnselected("button_enabled_32x128.tga");
- setImageDisabled("button_disabled_32x128.tga");
+ // Use old defaults
+ mLeftHPad = llbutton_orig_h_pad;
+ mRightHPad = llbutton_orig_h_pad;
}
+
+ mMouseDownTimer.stop();
- 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("button_enabled_selected_32x128.tga");
- setImageDisabledSelected("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 LLString& control_name)
-{
- mGLFont = ( font ? font : LLFontGL::sSansSerif);
+ 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(" "))
+ 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" ) );
-
- mImageOverlayAlignment = LLFontGL::HCENTER;
- mImageOverlayColor = LLColor4::white;
+ if (mImageUnselected.isNull())
+ {
+ llwarns << "Button: " << getName() << " with no image!" << llendl;
+ }
+
+ if (p.click_callback.isProvided())
+ {
+ setCommitCallback(initCommitCallback(p.click_callback)); // alias -> commit_callback
+ }
+ if (p.mouse_down_callback.isProvided())
+ {
+ setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
+ }
+ if (p.mouse_up_callback.isProvided())
+ {
+ setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
+ }
+ if (p.mouse_held_callback.isProvided())
+ {
+ setHeldDownCallback(initCommitCallback(p.mouse_held_callback));
+ }
}
LLButton::~LLButton()
{
- if( hasMouseCapture() )
- {
- gFocusMgr.setMouseCapture( NULL );
- }
+ delete mMouseDownSignal;
+ delete mMouseUpSignal;
+ delete mHeldDownSignal;
}
// HACK: Committing a button is the same as instantly clicking it.
@@ -226,19 +257,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);
- }
+ if (mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
- if (mMouseUpCallback)
- {
- (*mMouseUpCallback)(mCallbackUserData);
- }
+ if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
if (getSoundFlags() & MOUSE_DOWN)
{
@@ -256,14 +280,54 @@ 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 )
+{
+ if (!mCommitSignal) mCommitSignal = new commit_signal_t();
+ return mCommitSignal->connect(cb);
+}
+boost::signals2::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
+ return mMouseDownSignal->connect(cb);
+}
+boost::signals2::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
+ return mMouseUpSignal->connect(cb);
+}
+boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mHeldDownSignal) mHeldDownSignal = new commit_signal_t();
+ 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;
@@ -275,10 +339,8 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
toggleState();
}
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
+
handled = TRUE;
}
return handled;
@@ -296,10 +358,7 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask )
handled = TRUE;
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
}
return handled;
}
@@ -307,27 +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 );
- if (mMouseDownCallback)
- {
- (*mMouseDownCallback)(mCallbackUserData);
- }
+ if (hasTabStop() && !getIsChrome())
+ {
+ setFocus(TRUE);
+ }
- mMouseDownTimer.start();
- mMouseDownFrame = LLFrameTimer::getFrameCount();
-
- 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;
}
@@ -340,14 +407,17 @@ 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
- if (mMouseUpCallback)
- {
- (*mMouseUpCallback)(mCallbackUserData);
- }
+ if(mMouseUpSignal) (*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
@@ -363,38 +433,111 @@ 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 <= 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)
+{
+ 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 (!childrenHandleHover(x, y, mask))
+ {
+ if (mMouseDownTimer.getStarted())
+ {
+ 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;
+ }
return TRUE;
}
@@ -402,48 +545,52 @@ 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);
+
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));
}
// Unselected image assignments
- S32 local_mouse_x;
- S32 local_mouse_y;
- LLCoordWindow cursor_pos_window;
- getWindow()->getCursorPosition(&cursor_pos_window);
- LLCoordGL cursor_pos_gl;
- getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
- cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
- cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
- screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &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() && mMouseOver)
+ || mForcePressedState;
+ bool selected = getToggleState();
- BOOL use_glow_effect = FALSE;
- if ( mNeedsHighlight || flash )
+ bool use_glow_effect = FALSE;
+ LLColor4 glow_color = LLColor4::white;
+ LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
+ 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;
}
}
@@ -451,22 +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
+ else
{
- mImagep = mImageUnselected;
+ imagep = selected ? mImageSelected : mImageUnselected;
}
// Override if more data is available
@@ -476,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)
{
- mImagep = mImageDisabled;
+ imagep = mImageDisabled;
+ }
+
+ if (mFlashing)
+ {
+ // 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;
}
@@ -497,65 +662,54 @@ 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() % alpha, llround(lerp(1.f, 3.f, lerp_amt)));
}
if (use_glow_effect)
{
- mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
+ mCurGlowStrength = lerp(mCurGlowStrength,
+ mFlashing ? (flash? 1.0 : 0.0)
+ : mHoverGlowStrength,
+ LLCriticalDamp::getInterpolant(0.05f));
}
else
{
@@ -564,35 +718,37 @@ 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) % alpha );
if (mCurGlowStrength > 0.01f)
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gGL.setSceneBlendType(glow_type);
+ imagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % (mCurGlowStrength * alpha));
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
else
{
- mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
+ imagep->draw(0, 0, (enabled ? mImageColor.get() : disabled_color) % alpha );
if (mCurGlowStrength > 0.01f)
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gGL.setSceneBlendType(glow_type);
+ imagep->drawSolid(0, 0, glow_color % (mCurGlowStrength * alpha));
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
}
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);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1 % alpha, FALSE);
}
// let overlay image and text play well together
@@ -621,20 +777,21 @@ void LLButton::draw()
center_x++;
}
+ center_y += (mImageOverlayBottomPad - mImageOverlayTopPad);
// 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;
}
+ 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,
@@ -649,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,
@@ -667,7 +823,7 @@ void LLButton::draw()
// Draw label
if( !label.empty() )
{
- LLWString::trim(label);
+ LLWStringUtil::trim(label);
S32 x;
switch( mHAlign )
@@ -676,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:
@@ -692,52 +848,51 @@ 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,
- mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
- U32_MAX, text_width,
- NULL, FALSE, FALSE);
+ LLFontGL::NORMAL,
+ mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
+ S32_MAX, text_width,
+ NULL, mUseEllipses);
}
- if (sDebugRects
- || (LLView::sEditingUI && this == LLView::sEditingUIView))
- {
- drawDebugRect();
- }
-
- // 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();
}
}
@@ -752,19 +907,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 )
@@ -774,7 +921,7 @@ void LLButton::setLabel( const LLStringExplicit& label )
}
//virtual
-BOOL LLButton::setLabelArg( const LLString& key, const LLStringExplicit& text )
+BOOL LLButton::setLabelArg( const std::string& key, const LLStringExplicit& text )
{
mUnselectedLabel.setArg(key, text);
mSelectedLabel.setArg(key, text);
@@ -791,26 +938,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 LLString &image_name, const LLString &selected_name )
+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)
@@ -828,26 +997,23 @@ void LLButton::setColor(const LLColor4& color)
setImageColor(color);
}
-
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;
+ mFadeWhenDisabled = TRUE;
}
-void LLButton::setDisabledImages( const LLString &image_name, const LLString &selected_name, const LLColor4& c )
+void LLButton::setImagePressed(LLPointer<LLUIImage> image)
{
- setImageDisabled(image_name);
- setImageDisabledSelected(selected_name);
- mDisabledImageColor = c;
+ mImagePressed = image;
}
void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image)
@@ -855,25 +1021,17 @@ void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image)
mImageHoverSelected = image;
}
-void LLButton::setDisabledImages( const LLString &image_name, const LLString &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 LLString& image_name, const LLString& selected_name )
+void LLButton::setImageFlash(LLPointer<LLUIImage> image)
{
- setImageHoverUnselected(image_name);
- setImageHoverSelected(selected_name);
+ mImageFlash = image;
}
-void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment, const LLColor4& color)
+void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color)
{
if (image_name.empty())
{
@@ -887,11 +1045,23 @@ void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alig
}
}
+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()
{
- mMouseDownTimer.stop();
- mMouseDownTimer.reset();
+ resetMouseDownTimer();
}
//-------------------------------------------------------------------------
@@ -912,200 +1082,87 @@ S32 round_up(S32 grid, S32 value)
}
}
-void LLButton::setImageUnselected(const LLString &image_name)
-{
- setImageUnselected(LLUI::getUIImage(image_name));
- mImageUnselectedName = image_name;
-}
-
-void LLButton::setImageSelected(const LLString &image_name)
-{
- setImageSelected(LLUI::getUIImage(image_name));
- mImageSelectedName = image_name;
-}
-
-void LLButton::setImageHoverSelected(const LLString &image_name)
-{
- setImageHoverSelected(LLUI::getUIImage(image_name));
- mImageHoverSelectedName = image_name;
-}
-
-void LLButton::setImageHoverUnselected(const LLString &image_name)
-{
- setImageHoverUnselected(LLUI::getUIImage(image_name));
- mImageHoverUnselectedName = image_name;
-}
-
-void LLButton::setImageDisabled(const LLString &image_name)
-{
- setImageDisabled(LLUI::getUIImage(image_name));
- mImageDisabledName = image_name;
-}
-
-void LLButton::setImageDisabledSelected(const LLString &image_name)
-{
- setImageDisabledSelected(LLUI::getUIImage(image_name));
- mImageDisabledSelectedName = image_name;
-}
-
void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
- const LLString& image_name,
+ const std::string& image_name,
const LLUUID& image_id,
- const LLString& xml_tag_name) const
+ const std::string& xml_tag_name) const
{
if( !image_name.empty() )
{
- node->createChild(xml_tag_name, TRUE)->setStringValue(image_name);
+ node->createChild(xml_tag_name.c_str(), TRUE)->setStringValue(image_name);
}
else if( image_id != LLUUID::null )
{
- node->createChild(xml_tag_name + "_id", TRUE)->setUUIDValue(image_id);
+ node->createChild((xml_tag_name + "_id").c_str(), TRUE)->setUUIDValue(image_id);
}
}
-// 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,"image_unselected");
- addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected");
- addImageAttributeToXML(node,mImageHoverSelectedName,mImageHoverSelectedID,"image_hover_selected");
- addImageAttributeToXML(node,mImageHoverUnselectedName,mImageHoverUnselectedID,"image_hover_unselected");
- addImageAttributeToXML(node,mImageDisabledName,mImageDisabledID,"image_disabled");
- addImageAttributeToXML(node,mImageDisabledSelectedName,mImageDisabledSelectedID,"image_disabled_selected");
- node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage);
-
- return node;
+// 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);
}
-void clicked_help(void* data)
+// static
+// Gets called once
+void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
{
- LLButton* self = (LLButton*)data;
- if (!self) return;
-
- if (!LLUI::sHtmlHelp)
- {
+ LLButton* button = dynamic_cast<LLButton*>(ctrl);
+ if (!button)
return;
- }
-
- LLUI::sHtmlHelp->show(self->getHelpURL());
+ // 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(&LLFloaterReg::toggleFloaterInstance, sdname));
}
// static
-LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+void LLButton::setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
{
- LLString name("button");
- node->getAttributeString("name", name);
-
- LLString label = name;
- node->getAttributeString("label", label);
-
- LLString label_selected = label;
- node->getAttributeString("label_selected", label_selected);
-
- LLFontGL* font = selectFont(node);
-
- LLString image_unselected;
- if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
-
- LLString image_selected;
- if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
-
- LLString image_hover_selected;
- if (node->hasAttribute("image_hover_selected")) node->getAttributeString("image_hover_selected",image_hover_selected);
-
- LLString image_hover_unselected;
- if (node->hasAttribute("image_hover_unselected")) node->getAttributeString("image_hover_unselected",image_hover_unselected);
-
- LLString image_disabled_selected;
- if (node->hasAttribute("image_disabled_selected")) node->getAttributeString("image_disabled_selected",image_disabled_selected);
-
- LLString image_disabled;
- if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled);
-
- LLString image_overlay;
- node->getAttributeString("image_overlay", image_overlay);
-
- LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER;
- LLString 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,
- "",
- NULL,
- parent,
- font,
- label,
- label_selected);
-
- node->getAttributeS32("pad_right", button->mRightHPad);
- node->getAttributeS32("pad_left", button->mLeftHPad);
-
- BOOL is_toggle = button->getIsToggle();
- node->getAttributeBOOL("toggle", is_toggle);
- button->setIsToggle(is_toggle);
-
- if(image_hover_selected != LLString::null) button->setImageHoverSelected(image_hover_selected);
-
- if(image_hover_unselected != LLString::null) button->setImageHoverUnselected(image_hover_unselected);
-
- if(image_disabled_selected != LLString::null) button->setImageDisabledSelected(image_disabled_selected );
-
- if(image_disabled != LLString::null) button->setImageDisabled(image_disabled);
-
- if(image_overlay != LLString::null) button->setImageOverlay(image_overlay, image_overlay_alignment);
-
- if (node->hasAttribute("halign"))
- {
- LLFontGL::HAlign halign = selectFontHAlign(node);
- button->setHAlign(halign);
- }
+ 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));
+}
- if (node->hasAttribute("scale_image"))
+// static
+void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ // 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))
{
- BOOL needsScale = FALSE;
- node->getAttributeBOOL("scale_image",needsScale);
- button->setScaleImage( needsScale );
+ LLUI::sHelpImpl->showTopic(help_topic);
+ return; // success
}
- if(label.empty())
- {
- button->setLabelUnselected(node->getTextContents());
- }
- if (label_selected.empty())
- {
- button->setLabelSelected(node->getTextContents());
- }
-
- if (node->hasAttribute("help_url"))
- {
- LLString help_url;
- node->getAttributeString("help_url",help_url);
- button->setHelpURLCallback(help_url);
- }
+ // 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");
+}
- button->initFromXML(node, parent);
-
- return button;
+void LLButton::resetMouseDownTimer()
+{
+ mMouseDownTimer.stop();
+ mMouseDownTimer.reset();
}
-void LLButton::setHelpURLCallback(const LLString &help_url)
+
+BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask)
{
- mHelpURL = help_url;
- setClickedCallback(clicked_help,this);
+ // just treat a double click as a second click
+ return handleMouseDown(x, y, mask);
}