From 5c4ae5b11a44ab4711f0148cb721f35be9f18100 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Thu, 23 Feb 2017 17:50:36 -0500 Subject: STORM-2145 Camera Presets -- some initial work --- indra/llui/llfloater.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 4f664a1ccc..8b0e19e4f6 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1839,7 +1839,7 @@ void LLFloater::onClickCloseBtn(bool app_quitting) // virtual void LLFloater::draw() { - const F32 alpha = getCurrentTransparency(); + F32 alpha = getCurrentTransparency(); // draw background if( isBackgroundVisible() ) @@ -1854,6 +1854,16 @@ void LLFloater::draw() LLUIImage* image = NULL; LLColor4 color; LLColor4 overlay_color; + std::string help_topic; + if (this->findHelpTopic(help_topic)) + { + if("camera_floater" == help_topic) + { + alpha = llmin(LLCachedControl(gSavedSettings, "CameraOpacity"), + LLCachedControl(gSavedSettings, "ActiveFloaterTransparency")); + } + } + if (isBackgroundOpaque()) { // NOTE: image may not be set -- cgit v1.2.3 From 527388694a8bb3f3c3bf1510e1e79562dd426385 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Sat, 13 Jan 2018 12:18:40 -0500 Subject: STORM-2145 Added a small floater --- indra/llui/llfloater.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e5fe6967d1..663d96bdd4 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -64,6 +64,8 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; +extern LLControlGroup gSavedSettings; + namespace LLInitParam { void TypeValues::declareValues() -- cgit v1.2.3 From 149d4ce795a9bcfe8d0a9d83521b94d25ca8deab Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 30 Jan 2018 09:22:23 -0500 Subject: remove cross-library reference (needs to be moved to newview) --- indra/llui/llfloater.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 663d96bdd4..2dcc62ce79 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1,5 +1,4 @@ /** - * @file llfloater.cpp * @brief LLFloater base class * @@ -64,8 +63,6 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; -extern LLControlGroup gSavedSettings; - namespace LLInitParam { void TypeValues::declareValues() @@ -1833,7 +1830,7 @@ void LLFloater::onClickCloseBtn(bool app_quitting) // virtual void LLFloater::draw() { - F32 alpha = getCurrentTransparency(); + const F32 alpha = getCurrentTransparency(); // draw background if( isBackgroundVisible() ) @@ -1848,16 +1845,6 @@ void LLFloater::draw() LLUIImage* image = NULL; LLColor4 color; LLColor4 overlay_color; - std::string help_topic; - if (this->findHelpTopic(help_topic)) - { - if("camera_floater" == help_topic) - { - alpha = llmin(LLCachedControl(gSavedSettings, "CameraOpacity"), - LLCachedControl(gSavedSettings, "ActiveFloaterTransparency")); - } - } - if (isBackgroundOpaque()) { // NOTE: image may not be set -- cgit v1.2.3 From bff875d25f03501ddad9a2be7cc45d1c949d83e0 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Fri, 2 Feb 2018 10:39:59 -0500 Subject: STORM-2145 Camera controls opacity is now working --- indra/llui/lluictrl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 550bee5c70..e53ecd30c2 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -212,7 +212,8 @@ public: virtual void setColor(const LLColor4& color); - F32 getCurrentTransparency(); + // Ansariel: Changed to virtual. We might want to change the transparency ourself! + virtual F32 getCurrentTransparency(); void setTransparencyType(ETypeTransparency type); ETypeTransparency getTransparencyType() const {return mTransparencyType;} -- cgit v1.2.3 From cf460b13bee894684d0ca1bcb5bbc9eb38df719c Mon Sep 17 00:00:00 2001 From: "Graham Linden graham@lindenlab.com" Date: Mon, 12 Mar 2018 16:24:16 +0100 Subject: De-duplicate sRGB conversion funcs from many shaders and unify on using the version that works on OSX. Add more logging to shader loading about fallbacks and loading succcess. Add frag shaders for sharing sRGB and normal encode/decode via GL shader linkage. --- indra/llui/llui.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llui.h b/indra/llui/llui.h index d7151dbee9..111f6472cd 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -33,7 +33,6 @@ #include "llcontrol.h" #include "llcoord.h" #include "llcontrol.h" -#include "llglslshader.h" #include "llinitparam.h" #include "llregistry.h" #include "llrender2dutils.h" @@ -49,7 +48,6 @@ // for initparam specialization #include "llfontgl.h" - class LLUUID; class LLWindow; class LLView; -- cgit v1.2.3 From 7a0a580eddf4fb7608d1bd84b7eccd2653075184 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 17 May 2018 15:50:27 +0300 Subject: MAINT-8344 Prevent multislider from locking in infinit cycle --- indra/llui/llmultislider.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 0aa3e17075..aab77c2bd8 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -334,10 +334,15 @@ void LLMultiSlider::deleteSlider(const std::string& name) void LLMultiSlider::clear() { - while(mThumbRects.size() > 0) { + while(mThumbRects.size() > 0 && mValue.size() > 0) { deleteCurSlider(); } + if (mThumbRects.size() > 0 || mValue.size() > 0) + { + LL_WARNS() << "Failed to fully clear Multi slider" << LL_ENDL; + } + LLF32UICtrl::clear(); } -- cgit v1.2.3 From e4973e0f92b524e7f9c2d10745f4c5e3a8557284 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 18 May 2018 21:09:42 +0300 Subject: MAINT-8344 Day Cycle Editor (part 3) --- indra/llui/llmultislider.cpp | 42 ++++++++++++++++++++++++++-------------- indra/llui/llmultislider.h | 1 + indra/llui/llmultisliderctrl.cpp | 5 +++++ indra/llui/llmultisliderctrl.h | 1 + 4 files changed, 34 insertions(+), 15 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index aab77c2bd8..93045a6578 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -196,7 +196,11 @@ void LLMultiSlider::setValue(const LLSD& value) F32 LLMultiSlider::getSliderValue(const std::string& name) const { - return (F32)mValue[name].asReal(); + if (mValue.has(name)) + { + return (F32)mValue[name].asReal(); + } + return 0; } void LLMultiSlider::setCurSlider(const std::string& name) @@ -206,6 +210,11 @@ void LLMultiSlider::setCurSlider(const std::string& name) } } +void LLMultiSlider::resetCurSlider() +{ + mCurSlider = LLStringUtil::null; +} + const std::string& LLMultiSlider::addSlider() { return addSlider(mInitialValue); @@ -421,20 +430,23 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask) } } - // Find the offset of the actual mouse location from the center of the thumb. - if (mThumbRects[mCurSlider].pointInRect(x,y)) + if (!mCurSlider.empty()) { - mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x; - } - else - { - mMouseOffset = 0; - } + // Find the offset of the actual mouse location from the center of the thumb. + if (mThumbRects[mCurSlider].pointInRect(x,y)) + { + mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x; + } + else + { + mMouseOffset = 0; + } - // Start dragging the thumb - // No handler needed for focus lost since this class has no state that depends on it. - gFocusMgr.setMouseCapture( this ); - mDragStartThumbRect = mThumbRects[mCurSlider]; + // Start dragging the thumb + // No handler needed for focus lost since this class has no state that depends on it. + gFocusMgr.setMouseCapture( this ); + mDragStartThumbRect = mThumbRects[mCurSlider]; + } } make_ui_sound("UISndClick"); @@ -551,7 +563,7 @@ void LLMultiSlider::draw() thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); // draw the highlight - if (hasFocus()) + if (hasFocus() && !mCurSlider.empty()) { thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); } @@ -583,7 +595,7 @@ void LLMultiSlider::draw() else { // draw highlight - if (hasFocus()) + if (hasFocus() && !mCurSlider.empty()) { thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); } diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 2b422e89c9..927063a5fd 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -76,6 +76,7 @@ public: const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } void setCurSlider(const std::string& name); + void resetCurSlider(); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); } /*virtual*/ void setValue(const LLSD& value); diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index c460a08afc..a982d431b3 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -213,6 +213,11 @@ void LLMultiSliderCtrl::setCurSlider(const std::string& name) mCurValue = mMultiSlider->getCurSliderValue(); } +void LLMultiSliderCtrl::resetCurSlider() +{ + mMultiSlider->resetCurSlider(); +} + BOOL LLMultiSliderCtrl::setLabelArg( const std::string& key, const LLStringExplicit& text ) { BOOL res = FALSE; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index b6a3542376..84378ff7b2 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -84,6 +84,7 @@ public: const std::string& getCurSlider() const { return mMultiSlider->getCurSlider(); } F32 getCurSliderValue() const { return mCurValue; } void setCurSlider(const std::string& name); + void resetCurSlider(); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); } virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } -- cgit v1.2.3 From 2ddad24c4d5e64711cdbffd98e290d3da8e9714a Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 30 May 2018 17:08:28 -0700 Subject: Timeline behavior in day cycle edit. --- indra/llui/llmultislider.cpp | 30 ++++++++++++++++++++++-------- indra/llui/llmultislider.h | 1 + indra/llui/llmultisliderctrl.h | 4 +++- 3 files changed, 26 insertions(+), 9 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 93045a6578..5cfe79267f 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -210,6 +210,19 @@ void LLMultiSlider::setCurSlider(const std::string& name) } } +F32 LLMultiSlider::getSliderValueFromX(S32 xpos) const +{ + S32 left_edge = mThumbWidth / 2; + S32 right_edge = getRect().getWidth() - (mThumbWidth / 2); + + xpos += mMouseOffset; + xpos = llclamp(xpos, left_edge, right_edge); + + F32 t = F32(xpos - left_edge) / (right_edge - left_edge); + + return((t * (mMaxValue - mMinValue)) + mMinValue); +} + void LLMultiSlider::resetCurSlider() { mCurSlider = LLStringUtil::null; @@ -359,14 +372,15 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) { if( gFocusMgr.getMouseCapture() == this ) { - S32 left_edge = mThumbWidth/2; - S32 right_edge = getRect().getWidth() - (mThumbWidth/2); - - x += mMouseOffset; - x = llclamp( x, left_edge, right_edge ); - - F32 t = F32(x - left_edge) / (right_edge - left_edge); - setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); +// S32 left_edge = mThumbWidth/2; +// S32 right_edge = getRect().getWidth() - (mThumbWidth/2); +// +// x += mMouseOffset; +// x = llclamp( x, left_edge, right_edge ); +// +// F32 t = F32(x - left_edge) / (right_edge - left_edge); +// setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); + setCurSliderValue(getSliderValueFromX(x)); onCommit(); getWindow()->setCursor(UI_CURSOR_ARROW); diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 927063a5fd..0177597da2 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -72,6 +72,7 @@ public: virtual ~LLMultiSlider(); void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE); F32 getSliderValue(const std::string& name) const; + F32 getSliderValueFromX(S32 xpos) const; const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 84378ff7b2..5c4777ebd0 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -74,7 +74,7 @@ protected: public: virtual ~LLMultiSliderCtrl(); - F32 getSliderValue(const std::string& name) const; + F32 getSliderValue(const std::string& name) const { return mMultiSlider->getSliderValue(name); } void setSliderValue(const std::string& name, F32 v, BOOL from_event = FALSE); virtual void setValue(const LLSD& value ); @@ -99,6 +99,8 @@ public: void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} + F32 getSliderValueFromX(S32 x) const { return mMultiSlider->getSliderValueFromX(x); } + /// for adding and deleting sliders const std::string& addSlider(); const std::string& addSlider(F32 val); -- cgit v1.2.3 From 442bbfed348b0c60f4d8a8da87aa15d3185bde7c Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 20 Jun 2018 12:37:17 -0700 Subject: Adding settings DAD type --- indra/llui/llui.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 111f6472cd..59fc1ddcef 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -75,7 +75,8 @@ enum EDragAndDropType DAD_MESH = 15, DAD_WIDGET = 16, DAD_PERSON = 17, - DAD_COUNT = 18, // number of types in this enum + DAD_SETTINGS = 18, + DAD_COUNT = 19, // number of types in this enum }; // Reasons for drags to be denied. -- cgit v1.2.3 From 8b3957b310afa23e543c3eb33aca9131dba52b31 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Thu, 7 Jun 2018 20:22:20 +0300 Subject: MAINT-8331 EEP UI control: XYVector --- indra/llui/CMakeLists.txt | 2 + indra/llui/llxyvector.cpp | 306 ++++++++++++++++++++++++++++++++++++++++++++++ indra/llui/llxyvector.h | 118 ++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 indra/llui/llxyvector.cpp create mode 100644 indra/llui/llxyvector.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 8054eb3619..04cd8b3f21 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -135,6 +135,7 @@ set(llui_SOURCE_FILES llviewereventrecorder.cpp llwindowshade.cpp llxuiparser.cpp + llxyvector.cpp ) set(llui_HEADER_FILES @@ -251,6 +252,7 @@ set(llui_HEADER_FILES llviewquery.h llwindowshade.h llxuiparser.h + llxyvector.h ) set_source_files_properties(${llui_HEADER_FILES} diff --git a/indra/llui/llxyvector.cpp b/indra/llui/llxyvector.cpp new file mode 100644 index 0000000000..48f38b8a92 --- /dev/null +++ b/indra/llui/llxyvector.cpp @@ -0,0 +1,306 @@ +/** +* @file llxyvector.cpp +* @author Andrey Lihatskiy +* @brief Implementation for LLXYVector +* +* $LicenseInfo:firstyear=2001&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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. +* +* 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. +* +* 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$ +*/ + +// A control that allows to set two related vector magnitudes by manipulating a single vector on a plane. + +#include "linden_common.h" + +#include "llxyvector.h" + +#include "llstring.h" +#include "llrect.h" + +#include "lluictrlfactory.h" +#include "llrender.h" + +// Globals +static LLDefaultChildRegistry::Register register_xy_vector("xy_vector"); + + +const F32 CENTER_CIRCLE_RADIUS = 2; +const S32 ARROW_ANGLE = 30; +const S32 ARROW_LENGTH_LONG = 10; +const S32 ARROW_LENGTH_SHORT = 6; + +LLXYVector::Params::Params() + : x_entry("x_entry"), + y_entry("y_entry"), + touch_area("touch_area"), + border("border"), + edit_bar_height("edit_bar_height", 18), + padding("padding", 4), + min_val_x("min_val_x", -1.0f), + max_val_x("max_val_x", 1.0f), + increment_x("increment_x", 0.05f), + min_val_y("min_val_y", -1.0f), + max_val_y("max_val_y", 1.0f), + increment_y("increment_y", 0.05f), + label_width("label_width", 16), + arrow_color("arrow_color", LLColor4::white), + ghost_color("ghost_color"), + area_color("area_color", LLColor4::grey4), + grid_color("grid_color", LLColor4::grey % 0.25f) +{ +} + +LLXYVector::LLXYVector(const LLXYVector::Params& p) + : LLUICtrl(p), + mArrowColor(p.arrow_color()), + mAreaColor(p.area_color), + mGridColor(p.grid_color), + mMinValueX(p.min_val_x), + mMaxValueX(p.max_val_x), + mIncrementX(p.increment_x), + mMinValueY(p.min_val_y), + mMaxValueY(p.max_val_y), + mIncrementY(p.increment_y) +{ + mGhostColor = p.ghost_color.isProvided() ? p.ghost_color() % 0.3f : p.arrow_color() % 0.3f; + + LLRect border_rect = getLocalRect(); + LLViewBorder::Params params = p.border; + params.rect(border_rect); + mBorder = LLUICtrlFactory::create(params); + addChild(mBorder); + + LLTextBox::Params x_label_params; + x_label_params.initial_value(p.x_entry.label()); + x_label_params.rect = LLRect(p.padding, + border_rect.mTop - p.padding, + p.label_width, + border_rect.getHeight() - p.edit_bar_height); + mXLabel = LLUICtrlFactory::create(x_label_params); + addChild(mXLabel); + LLLineEditor::Params x_params = p.x_entry; + x_params.rect = LLRect(p.padding + p.label_width, + border_rect.mTop - p.padding, + border_rect.getCenterX(), + border_rect.getHeight() - p.edit_bar_height); + x_params.commit_callback.function(boost::bind(&LLXYVector::onEditChange, this)); + mXEntry = LLUICtrlFactory::create(x_params); + mXEntry->setPrevalidateInput(LLTextValidate::validateFloat); + addChild(mXEntry); + + LLTextBox::Params y_label_params; + y_label_params.initial_value(p.y_entry.label()); + y_label_params.rect = LLRect(border_rect.getCenterX() + p.padding, + border_rect.mTop - p.padding, + border_rect.getCenterX() + p.label_width, + border_rect.getHeight() - p.edit_bar_height); + mYLabel = LLUICtrlFactory::create(y_label_params); + addChild(mYLabel); + LLLineEditor::Params y_params = p.y_entry; + y_params.rect = LLRect(border_rect.getCenterX() + p.padding + p.label_width, + border_rect.getHeight() - p.padding, + border_rect.getWidth() - p.padding, + border_rect.getHeight() - p.edit_bar_height); + y_params.commit_callback.function(boost::bind(&LLXYVector::onEditChange, this)); + mYEntry = LLUICtrlFactory::create(y_params); + mYEntry->setPrevalidateInput(LLTextValidate::validateFloat); + addChild(mYEntry); + + LLPanel::Params touch_area = p.touch_area; + touch_area.rect = LLRect(p.padding, + border_rect.mTop - p.edit_bar_height - p.padding, + border_rect.getWidth() - p.padding, + p.padding); + mTouchArea = LLUICtrlFactory::create(touch_area); + addChild(mTouchArea); +} + +LLXYVector::~LLXYVector() +{ +} + +BOOL LLXYVector::postBuild() +{ + return TRUE; +} + +void drawArrow(S32 tailX, S32 tailY, S32 tipX, S32 tipY, LLColor4 color) +{ + gl_line_2d(tailX, tailY, tipX, tipY, color); + + S32 dx = tipX - tailX; + S32 dy = tipY - tailY; + + S32 arrowLength = (abs(dx) < ARROW_LENGTH_LONG && abs(dy) < ARROW_LENGTH_LONG) ? ARROW_LENGTH_SHORT : ARROW_LENGTH_LONG; + + F32 theta = std::atan2(dy, dx); + + F32 rad = ARROW_ANGLE * std::atan(1) * 4 / 180; + F32 x = tipX - arrowLength * cos(theta + rad); + F32 y = tipY - arrowLength * sin(theta + rad); + F32 rad2 = -1 * ARROW_ANGLE * std::atan(1) * 4 / 180; + F32 x2 = tipX - arrowLength * cos(theta + rad2); + F32 y2 = tipY - arrowLength * sin(theta + rad2); + gl_triangle_2d(tipX, tipY, x, y, x2, y2, color, true); +} + +void LLXYVector::draw() +{ + S32 centerX = mTouchArea->getRect().getCenterX(); + S32 centerY = mTouchArea->getRect().getCenterY(); + + S32 pointX = centerX + (mValueX * mTouchArea->getRect().getWidth() / (2 * mMaxValueX)); + S32 pointY = centerY + (mValueY * mTouchArea->getRect().getHeight() / (2 * mMaxValueY)); + + // fill + gl_rect_2d(mTouchArea->getRect(), mAreaColor, true); + + // draw grid + gl_line_2d(centerX, mTouchArea->getRect().mTop, centerX, mTouchArea->getRect().mBottom, mGridColor); + gl_line_2d(mTouchArea->getRect().mLeft, centerY, mTouchArea->getRect().mRight, centerY, mGridColor); + + // draw ghost + if (hasMouseCapture()) + { + drawArrow(centerX, centerY, mGhostX, mGhostY, mGhostColor); + } + else + { + mGhostX = pointX; + mGhostY = pointY; + } + + if (abs(mValueX) >= mIncrementX || abs(mValueY) >= mIncrementY) + { + // draw the vector arrow + drawArrow(centerX, centerY, pointX, pointY, mArrowColor); + } + else + { + // skip the arrow, set color for center circle + gGL.color4fv(mArrowColor.get().mV); + } + + // draw center circle + gl_circle_2d(centerX, centerY, CENTER_CIRCLE_RADIUS, 12, true); + + LLView::draw(); +} + +void LLXYVector::onEditChange() +{ + if (getEnabled()) + { + setValueAndCommit(mXEntry->getValue().asReal(), mYEntry->getValue().asReal()); + } +} + +void LLXYVector::setValue(const LLSD& value) +{ + if (value.isArray()) + { + setValue(value[0].asReal(), value[1].asReal()); + } +} + +void LLXYVector::setValue(F32 x, F32 y) +{ + x = llclamp(x, mMinValueX, mMaxValueX); + y = llclamp(y, mMinValueY, mMaxValueY); + + // Round the values to nearest increments + x -= mMinValueX; + x += mIncrementX / 2.0001f; + x -= fmod(x, mIncrementX); + x += mMinValueX; + + y -= mMinValueY; + y += mIncrementY / 2.0001f; + y -= fmod(y, mIncrementY); + y += mMinValueY; + + mValueX = x; + mValueY = y; + + update(); +} + +void LLXYVector::setValueAndCommit(F32 x, F32 y) +{ + if (mValueX != x || mValueY != y) + { + setValue(x, y); + onCommit(); + } +} + +LLSD LLXYVector::getValue() const +{ + LLSD value; + value.append(mValueX); + value.append(mValueY); + return value; +} + +void LLXYVector::update() +{ + mXEntry->setValue(mValueX); + mYEntry->setValue(mValueY); +} + +BOOL LLXYVector::handleHover(S32 x, S32 y, MASK mask) +{ + if (hasMouseCapture()) + { + F32 valueX = F32(x - mTouchArea->getRect().getCenterX()) / mTouchArea->getRect().getWidth(); + F32 valueY = F32(y - mTouchArea->getRect().getCenterY()) / mTouchArea->getRect().getHeight(); + + valueX *= 2 * mMaxValueX; + valueY *= 2 * mMaxValueY; + + setValueAndCommit(valueX, valueY); + } + + return TRUE; +} + +BOOL LLXYVector::handleMouseUp(S32 x, S32 y, MASK mask) +{ + if (hasMouseCapture()) + { + gFocusMgr.setMouseCapture(NULL); + make_ui_sound("UISndClickRelease"); + } + + return TRUE; +} + +BOOL LLXYVector::handleMouseDown(S32 x, S32 y, MASK mask) +{ + + if (mTouchArea->getRect().pointInRect(x, y)) + { + gFocusMgr.setMouseCapture(this); + make_ui_sound("UISndClick"); + } + + return TRUE; +} + diff --git a/indra/llui/llxyvector.h b/indra/llui/llxyvector.h new file mode 100644 index 0000000000..4d67db3251 --- /dev/null +++ b/indra/llui/llxyvector.h @@ -0,0 +1,118 @@ +/** +* @file llxyvector.h +* @author Andrey Lihatskiy +* @brief Header file for LLXYVector +* +* $LicenseInfo:firstyear=2001&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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. +* +* 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. +* +* 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$ +*/ + +// A control that allows to set two related vector magnitudes by manipulating a single vector on a plane. + +#ifndef LL_LLXYVECTOR_H +#define LL_LLXYVECTOR_H + +#include "lluictrl.h" +#include "llpanel.h" +#include "lltextbox.h" +#include "lllineeditor.h" + +class LLXYVector + : public LLUICtrl +{ +public: + struct Params + : public LLInitParam::Block + { + Optional x_entry; + Optional y_entry; + Optional touch_area; + Optional border; + Optional edit_bar_height; + Optional padding; + Optional label_width; + Optional min_val_x; + Optional max_val_x; + Optional increment_x; + Optional min_val_y; + Optional max_val_y; + Optional increment_y; + Optional arrow_color; + Optional ghost_color; + Optional area_color; + Optional grid_color; + + Params(); + }; + + + virtual ~LLXYVector(); + /*virtual*/ BOOL postBuild(); + + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + + virtual void draw(); + + virtual void setValue(const LLSD& value); + void setValue(F32 x, F32 y); + virtual LLSD getValue() const; + +protected: + friend class LLUICtrlFactory; + LLXYVector(const Params&); + void onEditChange(); + +protected: + LLTextBox* mXLabel; + LLTextBox* mYLabel; + LLLineEditor* mXEntry; + LLLineEditor* mYEntry; + LLPanel* mTouchArea; + LLViewBorder* mBorder; + +private: + void update(); + void setValueAndCommit(F32 x, F32 y); + + F32 mValueX; + F32 mValueY; + + F32 mMinValueX; + F32 mMaxValueX; + F32 mIncrementX; + F32 mMinValueY; + F32 mMaxValueY; + F32 mIncrementY; + + U32 mGhostX; + U32 mGhostY; + + LLUIColor mArrowColor; + LLUIColor mGhostColor; + LLUIColor mAreaColor; + LLUIColor mGridColor; + +}; + +#endif + -- cgit v1.2.3 From e61d7ac0098d89cc6b124dda2e040120c01d2bee Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 10 Jul 2018 17:09:47 +0300 Subject: MAINT-8833 EEP UI should be either responsive or indicate that it is disabled. --- indra/llui/llslider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index ebbb951ee6..6925c0a130 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -331,8 +331,9 @@ void LLSlider::draw() highlight_rect.set(track_rect.mLeft, track_rect.mTop, track_rect.mRight, track_rect.mBottom); } - trackImage->draw(track_rect, LLColor4::white % alpha); - trackHighlightImage->draw(highlight_rect, LLColor4::white % alpha); + LLColor4 color = isInEnabledChain() ? LLColor4::white % alpha : LLColor4::white % (0.6f * alpha); + trackImage->draw(track_rect, color); + trackHighlightImage->draw(highlight_rect, color); // Thumb if (hasFocus()) -- cgit v1.2.3 From 1abea33b7012b6b00502620dab92cc39eacb1d50 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Wed, 18 Jul 2018 14:13:29 +0300 Subject: MAINT-8334 EEP UI control: Virtual Trackball --- indra/llui/CMakeLists.txt | 2 + indra/llui/llvirtualtrackball.cpp | 411 ++++++++++++++++++++++++++++++++++++++ indra/llui/llvirtualtrackball.h | 149 ++++++++++++++ 3 files changed, 562 insertions(+) create mode 100644 indra/llui/llvirtualtrackball.cpp create mode 100644 indra/llui/llvirtualtrackball.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 04cd8b3f21..54e4d296ab 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -133,6 +133,7 @@ set(llui_SOURCE_FILES llview.cpp llviewquery.cpp llviewereventrecorder.cpp + llvirtualtrackball.cpp llwindowshade.cpp llxuiparser.cpp llxyvector.cpp @@ -250,6 +251,7 @@ set(llui_HEADER_FILES llview.h llviewereventrecorder.h llviewquery.h + llvirtualtrackball.h llwindowshade.h llxuiparser.h llxyvector.h diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp new file mode 100644 index 0000000000..0ddbe8b9c2 --- /dev/null +++ b/indra/llui/llvirtualtrackball.cpp @@ -0,0 +1,411 @@ +/** +* @file LLVirtualTrackball.cpp +* @author Andrey Lihatskiy +* @brief Implementation for LLVirtualTrackball +* +* $LicenseInfo:firstyear=2001&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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. +* +* 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. +* +* 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$ +*/ + +// A control for positioning the sun and the moon in the celestial sphere. + +#include "linden_common.h" +#include "llvirtualtrackball.h" +#include "llstring.h" +#include "llrect.h" +#include "lluictrlfactory.h" +#include "llrender.h" + +// Globals +static LLDefaultChildRegistry::Register register_virtual_trackball("sun_moon_trackball"); + +const LLVector3 VectorZero(1.0f, 0.0f, 0.0f); + +LLVirtualTrackball::Params::Params() + : border("border"), + image_moon_back("image_moon_back"), + image_moon_front("image_moon_front"), + image_sphere("image_sphere"), + image_sun_back("image_sun_back"), + image_sun_front("image_sun_front"), + btn_rotate_top("button_rotate_top"), + btn_rotate_bottom("button_rotate_bottom"), + btn_rotate_left("button_rotate_left"), + btn_rotate_right("button_rotate_right"), + thumb_mode("thumb_mode"), + lbl_N("labelN"), + lbl_S("labelS"), + lbl_W("labelW"), + lbl_E("labelE"), + increment_angle_mouse("increment_angle_mouse", 0.5f), + increment_angle_btn("increment_angle_btn", 3.0f) +{ +} + +LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p) + : LLUICtrl(p), + mImgMoonBack(p.image_moon_back), + mImgMoonFront(p.image_moon_front), + mImgSunBack(p.image_sun_back), + mImgSunFront(p.image_sun_front), + mImgSphere(p.image_sphere), + mThumbMode(p.thumb_mode() == "moon" ? ThumbMode::MOON : ThumbMode::SUN), + mIncrementMouse(DEG_TO_RAD * p.increment_angle_mouse()), + mIncrementBtn(DEG_TO_RAD * p.increment_angle_btn()) +{ + LLRect border_rect = getLocalRect(); + S32 centerX = border_rect.getCenterX(); + S32 centerY = border_rect.getCenterY(); + U32 btn_size = 32; // width & height + U32 axis_offset_lt = 16; // offset from the axis for left/top sides + U32 axis_offset_rb = btn_size - axis_offset_lt; // and for right/bottom + + LLViewBorder::Params border = p.border; + border.rect(border_rect); + mBorder = LLUICtrlFactory::create(border); + addChild(mBorder); + + + LLButton::Params btn_rt = p.btn_rotate_top; + btn_rt.rect(LLRect(centerX - axis_offset_lt, border_rect.mTop, centerX + axis_offset_rb, border_rect.mTop - btn_size)); + btn_rt.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this)); + btn_rt.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this)); + mBtnRotateTop = LLUICtrlFactory::create(btn_rt); + addChild(mBtnRotateTop); + + LLTextBox::Params lbl_N = p.lbl_N; + LLRect rect_N = btn_rt.rect; + //rect_N.translate(btn_rt.rect().getWidth(), 0); + lbl_N.rect = rect_N; + lbl_N.initial_value(lbl_N.label()); + mLabelN = LLUICtrlFactory::create(lbl_N); + addChild(mLabelN); + + + LLButton::Params btn_rr = p.btn_rotate_right; + btn_rr.rect(LLRect(border_rect.mRight - btn_size, centerY + axis_offset_lt, border_rect.mRight, centerY - axis_offset_rb)); + btn_rr.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this)); + btn_rr.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this)); + mBtnRotateRight = LLUICtrlFactory::create(btn_rr); + addChild(mBtnRotateRight); + + LLTextBox::Params lbl_E = p.lbl_E; + LLRect rect_E = btn_rr.rect; + //rect_E.translate(0, -1 * btn_rr.rect().getHeight()); + lbl_E.rect = rect_E; + lbl_E.initial_value(lbl_E.label()); + mLabelE = LLUICtrlFactory::create(lbl_E); + addChild(mLabelE); + + + LLButton::Params btn_rb = p.btn_rotate_bottom; + btn_rb.rect(LLRect(centerX - axis_offset_lt, border_rect.mBottom + btn_size, centerX + axis_offset_rb, border_rect.mBottom)); + btn_rb.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this)); + btn_rb.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this)); + mBtnRotateBottom = LLUICtrlFactory::create(btn_rb); + addChild(mBtnRotateBottom); + + LLTextBox::Params lbl_S = p.lbl_S; + LLRect rect_S = btn_rb.rect; + //rect_S.translate(btn_rb.rect().getWidth(), 0); + lbl_S.rect = rect_S; + lbl_S.initial_value(lbl_S.label()); + mLabelS = LLUICtrlFactory::create(lbl_S); + addChild(mLabelS); + + + LLButton::Params btn_rl = p.btn_rotate_left; + btn_rl.rect(LLRect(border_rect.mLeft, centerY + axis_offset_lt, border_rect.mLeft + btn_size, centerY - axis_offset_rb)); + btn_rl.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this)); + btn_rl.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this)); + mBtnRotateLeft = LLUICtrlFactory::create(btn_rl); + addChild(mBtnRotateLeft); + + LLTextBox::Params lbl_W = p.lbl_W; + LLRect rect_W = btn_rl.rect; + //rect_W.translate(0, -1* btn_rl.rect().getHeight()); + lbl_W.rect = rect_W; + lbl_W.initial_value(lbl_W.label()); + mLabelW = LLUICtrlFactory::create(lbl_W); + addChild(mLabelW); + + + LLPanel::Params touch_area; + touch_area.rect = LLRect(centerX - mImgSphere->getWidth() / 2, + centerY + mImgSphere->getHeight() / 2, + centerX + mImgSphere->getWidth() / 2, + centerY - mImgSphere->getHeight() / 2); + mTouchArea = LLUICtrlFactory::create(touch_area); + addChild(mTouchArea); +} + +LLVirtualTrackball::~LLVirtualTrackball() +{ +} + +BOOL LLVirtualTrackball::postBuild() +{ + return TRUE; +} + + +void LLVirtualTrackball::drawThumb(S32 x, S32 y, ThumbMode mode, bool upperHemi) +{ + LLUIImage* thumb; + if (mode == ThumbMode::SUN) + { + if (upperHemi) + { + thumb = mImgSunFront; + } + else + { + thumb = mImgSunBack; + } + } + else + { + if (upperHemi) + { + thumb = mImgMoonFront; + } + else + { + thumb = mImgMoonBack; + } + } + thumb->draw(LLRect(x - thumb->getWidth() / 2, + y + thumb->getHeight() / 2, + x + thumb->getWidth() / 2, + y - thumb->getHeight() / 2)); +} + +bool LLVirtualTrackball::pointInTouchCircle(S32 x, S32 y) const +{ + S32 centerX = mTouchArea->getRect().getCenterX(); + S32 centerY = mTouchArea->getRect().getCenterY(); + + bool in_circle = pow(x - centerX, 2) + pow(y - centerY, 2) <= pow(mTouchArea->getRect().getWidth() / 2, 2); + return in_circle; +} + +void LLVirtualTrackball::draw() +{ + LLVector3 draw_point = VectorZero * mValue; + + S32 halfwidth = mTouchArea->getRect().getWidth() / 2; + S32 halfheight = mTouchArea->getRect().getHeight() / 2; + draw_point.mV[VX] = (draw_point.mV[VX] + 1.0) * halfwidth + mTouchArea->getRect().mLeft; + draw_point.mV[VY] = (draw_point.mV[VY] + 1.0) * halfheight + mTouchArea->getRect().mBottom; + bool upper_hemisphere = (draw_point.mV[VZ] >= 0.f); + + mImgSphere->draw(mTouchArea->getRect(), upper_hemisphere ? UI_VERTEX_COLOR : UI_VERTEX_COLOR % 0.5f); + drawThumb(draw_point.mV[VX], draw_point.mV[VY], mThumbMode, upper_hemisphere); + + + if (LLView::sDebugRects) + { + gGL.color4fv(LLColor4::red.mV); + gl_circle_2d(mTouchArea->getRect().getCenterX(), mTouchArea->getRect().getCenterY(), mImgSphere->getWidth() / 2, 60, false); + gl_circle_2d(draw_point.mV[VX], draw_point.mV[VY], mImgSunFront->getWidth() / 2, 12, false); + } + + LLView::draw(); +} + +void LLVirtualTrackball::onRotateTopClick() +{ + if (getEnabled()) + { + LLQuaternion delta; + delta.setAngleAxis(mIncrementBtn, 1, 0, 0); + mValue *= delta; + setValueAndCommit(mValue); + + make_ui_sound("UISndClick"); + } +} + +void LLVirtualTrackball::onRotateBottomClick() +{ + if (getEnabled()) + { + LLQuaternion delta; + delta.setAngleAxis(mIncrementBtn, -1, 0, 0); + mValue *= delta; + setValueAndCommit(mValue); + + make_ui_sound("UISndClick"); + } +} + +void LLVirtualTrackball::onRotateLeftClick() +{ + if (getEnabled()) + { + LLQuaternion delta; + delta.setAngleAxis(mIncrementBtn, 0, 1, 0); + mValue *= delta; + setValueAndCommit(mValue); + + make_ui_sound("UISndClick"); + } +} + +void LLVirtualTrackball::onRotateRightClick() +{ + if (getEnabled()) + { + LLQuaternion delta; + delta.setAngleAxis(mIncrementBtn, 0, -1, 0); + mValue *= delta; + setValueAndCommit(mValue); + + make_ui_sound("UISndClick"); + } +} + +void LLVirtualTrackball::setValue(const LLSD& value) +{ + if (value.isArray() && value.size() == 4) + { + mValue.setValue(value); + } +} + +void LLVirtualTrackball::setRotation(const LLQuaternion &value) +{ + mValue = value; +} + +void LLVirtualTrackball::setValue(F32 x, F32 y, F32 z, F32 w) +{ + mValue.set(x, y, z, w); +} + +void LLVirtualTrackball::setValueAndCommit(const LLQuaternion &value) +{ + mValue = value; + onCommit(); +} + +LLSD LLVirtualTrackball::getValue() const +{ + return mValue.getValue(); +} + +LLQuaternion LLVirtualTrackball::getRotation() const +{ + return mValue; +} + +BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask) +{ + if (hasMouseCapture()) + { + LLQuaternion delta; + + F32 rotX = x - mPrevX; + F32 rotY = y - mPrevY; + + if (abs(rotX) > 1) + { + F32 direction = (rotX < 0) ? -1 : 1; + delta.setAngleAxis(mIncrementMouse * abs(rotX), 0, direction, 0); // changing X - rotate around Y axis + mValue *= delta; + } + + if (abs(rotY) > 1) + { + F32 direction = (rotY < 0) ? 1 : -1; // reverse for Y (value increases from bottom to top) + delta.setAngleAxis(mIncrementMouse * abs(rotY), direction, 0, 0); // changing Y - rotate around X axis + mValue *= delta; + } + + onCommit(); + + mPrevX = x; + mPrevY = y; + } + return TRUE; +} + +BOOL LLVirtualTrackball::handleMouseUp(S32 x, S32 y, MASK mask) +{ + if (hasMouseCapture()) + { + mPrevX = 0; + mPrevY = 0; + gFocusMgr.setMouseCapture(NULL); + make_ui_sound("UISndClickRelease"); + } + return TRUE; +} + +BOOL LLVirtualTrackball::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if (pointInTouchCircle(x, y)) + { + mPrevX = x; + mPrevY = y; + gFocusMgr.setMouseCapture(this); + make_ui_sound("UISndClick"); + } + return TRUE; +} + +BOOL LLVirtualTrackball::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if (pointInTouchCircle(x, y)) + { + + //make_ui_sound("UISndClick"); + } + return TRUE; +} + +BOOL LLVirtualTrackball::handleKeyHere(KEY key, MASK mask) +{ + BOOL handled = FALSE; + switch (key) + { + case KEY_DOWN: + onRotateTopClick(); + handled = TRUE; + break; + case KEY_LEFT: + onRotateRightClick(); + handled = TRUE; + break; + case KEY_UP: + onRotateBottomClick(); + handled = TRUE; + break; + case KEY_RIGHT: + onRotateLeftClick(); + handled = TRUE; + break; + default: + break; + } + return handled; +} + diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h new file mode 100644 index 0000000000..c1b66550bb --- /dev/null +++ b/indra/llui/llvirtualtrackball.h @@ -0,0 +1,149 @@ +/** +* @file virtualtrackball.h +* @author Andrey Lihatskiy +* @brief Header file for LLVirtualTrackball +* +* $LicenseInfo:firstyear=2001&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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. +* +* 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. +* +* 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$ +*/ + +// A control for positioning the sun and the moon in the celestial sphere. + +#ifndef LL_LLVIRTUALTRACKBALL_H +#define LL_LLVIRTUALTRACKBALL_H + +#include "lluictrl.h" +#include "llpanel.h" +#include "lltextbox.h" +#include "llbutton.h" + +class LLVirtualTrackball + : public LLUICtrl +{ +public: + enum ThumbMode + { + SUN, + MOON + }; + + struct Params + : public LLInitParam::Block + { + Optional border; + Optional image_moon_back, + image_moon_front, + image_sphere, + image_sun_back, + image_sun_front; + + Optional thumb_mode; + Optional increment_angle_mouse, + increment_angle_btn; + + Optional lbl_N, + lbl_S, + lbl_W, + lbl_E; + + Optional btn_rotate_top, + btn_rotate_bottom, + btn_rotate_left, + btn_rotate_right; + + Params(); + }; + + + virtual ~LLVirtualTrackball(); + /*virtual*/ BOOL postBuild(); + + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleKeyHere(KEY key, MASK mask); + + virtual void draw(); + + virtual void setValue(const LLSD& value); + void setValue(F32 x, F32 y, F32 z, F32 w); + virtual LLSD getValue() const; + + void setRotation(const LLQuaternion &value); + LLQuaternion getRotation() const; + +protected: + friend class LLUICtrlFactory; + LLVirtualTrackball(const Params&); + void onEditChange(); + +protected: + LLTextBox* mNLabel; + LLTextBox* mELabel; + LLTextBox* mSLabel; + LLTextBox* mWLabel; + + LLButton* mBtnRotateTop; + LLButton* mBtnRotateBottom; + LLButton* mBtnRotateLeft; + LLButton* mBtnRotateRight; + + LLTextBox* mLabelN; + LLTextBox* mLabelS; + LLTextBox* mLabelW; + LLTextBox* mLabelE; + + LLPanel* mTouchArea; + LLViewBorder* mBorder; + +private: + void setValueAndCommit(const LLQuaternion &value); + void drawThumb(S32 x, S32 y, ThumbMode mode, bool upperHemi = true); + bool pointInTouchCircle(S32 x, S32 y) const; + + void onRotateTopClick(); + void onRotateBottomClick(); + void onRotateLeftClick(); + void onRotateRightClick(); + + S32 mPrevX; + S32 mPrevY; + + LLUIImage* mImgMoonBack; + LLUIImage* mImgMoonFront; + LLUIImage* mImgSunBack; + LLUIImage* mImgSunFront; + LLUIImage* mImgBtnRotTop; + LLUIImage* mImgBtnRotLeft; + LLUIImage* mImgBtnRotRight; + LLUIImage* mImgBtnRotBottom; + LLUIImage* mImgSphere; + + LLQuaternion mValue; + ThumbMode mThumbMode; + + F32 mIncrementMouse; + F32 mIncrementBtn; +}; + +#endif + -- cgit v1.2.3 From 31aa86b7039b025b23b5b02455e65be103e2ea0b Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Thu, 19 Jul 2018 21:11:23 +0100 Subject: Compile fixes for latest Xcode on OSX. --- indra/llui/llscrolllistctrl.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 212e27477b..ed65b1e45f 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2784,7 +2784,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata) } // if this column is the primary sort key, reverse the direction - sort_column_t cur_sort_column; if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index) { ascending = !parent->mSortColumns.back().second; -- cgit v1.2.3 From c822d8af16428cf245ae57305a4f39d3fccd672b Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 20 Jul 2018 19:10:22 +0300 Subject: MAINT-8344 implement slider support for an overlap threshold and reenable shift-copy --- indra/llui/llmultislider.cpp | 23 ++++++++++++++++++----- indra/llui/llmultislider.h | 3 +++ indra/llui/llmultisliderctrl.cpp | 5 +++++ indra/llui/llmultisliderctrl.h | 2 ++ 4 files changed, 28 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 5cfe79267f..cd9c77585a 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -41,8 +41,6 @@ static LLDefaultChildRegistry::Register r("multi_slider_bar"); -const F32 FLOAT_THRESHOLD = 0.00001f; - S32 LLMultiSlider::mNameCounter = 0; LLMultiSlider::SliderParams::SliderParams() @@ -54,6 +52,7 @@ LLMultiSlider::SliderParams::SliderParams() LLMultiSlider::Params::Params() : max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), + overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), track_color("track_color"), @@ -98,6 +97,15 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) setMouseUpCallback(initCommitCallback(p.mouse_up_callback)); } + if (p.overlap_threshold.isProvided()) + { + mOverlapThreshold = p.overlap_threshold; + } + else + { + mOverlapThreshold = 0; + } + for (LLInitParam::ParamIterator::const_iterator it = p.sliders.begin(); it != p.sliders.end(); ++it) @@ -143,11 +151,14 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from // look at the current spot // and see if anything is there LLSD::map_iterator mIt = mValue.beginMap(); + F32 threshold = mOverlapThreshold + (mIncrement / 4); // increment is our distance between points, use to eliminate round error for(;mIt != mValue.endMap(); mIt++) { F32 testVal = (F32)mIt->second.asReal() - newValue; - if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD && - mIt->first != name) { + if (testVal > -threshold + && testVal < threshold + && mIt->first != name) + { hit = true; break; } @@ -300,11 +311,13 @@ bool LLMultiSlider::findUnusedValue(F32& initVal) // look at the current spot // and see if anything is there + F32 threshold = mOverlapThreshold + (mIncrement / 4); LLSD::map_iterator mIt = mValue.beginMap(); for(;mIt != mValue.endMap(); mIt++) { F32 testVal = (F32)mIt->second.asReal() - initVal; - if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD) { + if(testVal > -threshold && testVal < threshold) + { hit = true; break; } diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 0177597da2..9281b68406 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -50,6 +50,8 @@ public: draw_track, use_triangle; + Optional overlap_threshold; + Optional track_color, thumb_disabled_color, thumb_outline_color, @@ -107,6 +109,7 @@ protected: S32 mMaxNumSliders; BOOL mAllowOverlap; + F32 mOverlapThreshold; BOOL mDrawTrack; BOOL mUseTriangle; /// hacked in toggle to use a triangle diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index a982d431b3..d2afca19b7 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -53,6 +53,7 @@ LLMultiSliderCtrl::Params::Params() can_edit_text("can_edit_text", false), max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), + overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), decimal_digits("decimal_digits", 3), @@ -167,6 +168,10 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.increment(p.increment); params.max_sliders(p.max_sliders); params.allow_overlap(p.allow_overlap); + if (p.overlap_threshold.isProvided()) + { + params.overlap_threshold = p.overlap_threshold; + } params.draw_track(p.draw_track); params.use_triangle(p.use_triangle); params.control_name(p.control_name); diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 5c4777ebd0..507115f5e1 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -57,6 +57,8 @@ public: draw_track, use_triangle; + Optional overlap_threshold; + Optional text_color, text_disabled_color; -- cgit v1.2.3 From 6a54e0948d651963399da82cfc5672125b9442e7 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Wed, 8 Aug 2018 03:28:37 +0300 Subject: MAINT-8900 LLVirtualTrackball improvement: added click-to-set mode --- indra/llui/llvirtualtrackball.cpp | 73 +++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 18 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index 0ddbe8b9c2..a24c5a420d 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -321,29 +321,66 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask) { if (hasMouseCapture()) { - LLQuaternion delta; - - F32 rotX = x - mPrevX; - F32 rotY = y - mPrevY; - - if (abs(rotX) > 1) - { - F32 direction = (rotX < 0) ? -1 : 1; - delta.setAngleAxis(mIncrementMouse * abs(rotX), 0, direction, 0); // changing X - rotate around Y axis - mValue *= delta; + if (mask == MASK_CONTROL) + { // trackball (move to roll) mode + LLQuaternion delta; + + F32 rotX = x - mPrevX; + F32 rotY = y - mPrevY; + + if (abs(rotX) > 1) + { + F32 direction = (rotX < 0) ? -1 : 1; + delta.setAngleAxis(mIncrementMouse * abs(rotX), 0, direction, 0); // changing X - rotate around Y axis + mValue *= delta; + } + + if (abs(rotY) > 1) + { + F32 direction = (rotY < 0) ? 1 : -1; // reverse for Y (value increases from bottom to top) + delta.setAngleAxis(mIncrementMouse * abs(rotY), direction, 0, 0); // changing Y - rotate around X axis + mValue *= delta; + } } - - if (abs(rotY) > 1) - { - F32 direction = (rotY < 0) ? 1 : -1; // reverse for Y (value increases from bottom to top) - delta.setAngleAxis(mIncrementMouse * abs(rotY), direction, 0, 0); // changing Y - rotate around X axis - mValue *= delta; + else + { // set on click mode + if (!pointInTouchCircle(x, y)) + { + return TRUE; // don't drag outside the circle + } + + F32 radius = mTouchArea->getRect().getWidth() / 2; + F32 xx = x - mTouchArea->getRect().getCenterX(); + F32 yy = y - mTouchArea->getRect().getCenterY(); + F32 dist = sqrt(pow(xx, 2) + pow(yy, 2)); + + F32 azimuth = llclamp(acosf(xx / dist), 0.0f, F_PI); + F32 altitude = llclamp(acosf(dist / radius), 0.0f, F_PI_BY_TWO); + + if (yy < 0) + { + azimuth = F_TWO_PI - azimuth; + } + + LLVector3 draw_point = VectorZero * mValue; + if (draw_point.mV[VZ] >= 0.f) + { + if (is_approx_zero(altitude)) // don't change the hemisphere + { + altitude = F_APPROXIMATELY_ZERO; + } + altitude *= -1; + } + + mValue.setAngleAxis(altitude, 0, 1, 0); + LLQuaternion az_quat; + az_quat.setAngleAxis(azimuth, 0, 0, 1); + mValue *= az_quat; } - - onCommit(); mPrevX = x; mPrevY = y; + onCommit(); } return TRUE; } -- cgit v1.2.3 From 51abc168c03f80d63c85d4bb48624f440b585390 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 3 Aug 2018 21:01:43 +0300 Subject: MAINT-8902 fix encroaching 'legacy' issues --- indra/llui/llmultislider.cpp | 27 +++++++++++++++++++++++++-- indra/llui/llmultislider.h | 2 ++ indra/llui/llmultisliderctrl.cpp | 2 ++ indra/llui/llmultisliderctrl.h | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index cd9c77585a..725f1e8f65 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -41,6 +41,8 @@ static LLDefaultChildRegistry::Register r("multi_slider_bar"); +const F32 FLOAT_THRESHOLD = 0.00001f; + S32 LLMultiSlider::mNameCounter = 0; LLMultiSlider::SliderParams::SliderParams() @@ -52,6 +54,7 @@ LLMultiSlider::SliderParams::SliderParams() LLMultiSlider::Params::Params() : max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), + loop_overlap("loop_overlap", false), overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), @@ -73,6 +76,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mDragStartThumbRect( 0, getRect().getHeight(), p.thumb_width, 0 ), mMaxNumSliders(p.max_sliders), mAllowOverlap(p.allow_overlap), + mLoopOverlap(p.loop_overlap), mDrawTrack(p.draw_track), mUseTriangle(p.use_triangle), mTrackColor(p.track_color()), @@ -151,7 +155,14 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from // look at the current spot // and see if anything is there LLSD::map_iterator mIt = mValue.beginMap(); - F32 threshold = mOverlapThreshold + (mIncrement / 4); // increment is our distance between points, use to eliminate round error + + // increment is our distance between points, use to eliminate round error + F32 threshold = mOverlapThreshold + (mIncrement / 4); + // If loop overlap is enabled, check if we overlap with points 'after' max value (project to lower) + F32 loop_up_check = (mLoopOverlap && (value + threshold) > mMaxValue) ? (value + threshold - mMaxValue + mMinValue) : 0.0f; + // If loop overlap is enabled, check if we overlap with points 'before' min value (project to upper) + F32 loop_down_check = (mLoopOverlap && (value - threshold) < mMinValue) ? (value - threshold - mMinValue + mMaxValue) : 0.0f; + for(;mIt != mValue.endMap(); mIt++) { F32 testVal = (F32)mIt->second.asReal() - newValue; @@ -162,6 +173,18 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from hit = true; break; } + if (loop_up_check != 0 + && testVal < loop_up_check) + { + hit = true; + break; + } + if (loop_down_check != 0 + && testVal > loop_down_check) + { + hit = true; + break; + } } // if none found, stop @@ -311,7 +334,7 @@ bool LLMultiSlider::findUnusedValue(F32& initVal) // look at the current spot // and see if anything is there - F32 threshold = mOverlapThreshold + (mIncrement / 4); + F32 threshold = mAllowOverlap ? FLOAT_THRESHOLD : mOverlapThreshold + (mIncrement / 4); LLSD::map_iterator mIt = mValue.beginMap(); for(;mIt != mValue.endMap(); mIt++) { diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 9281b68406..eff0c7d2d7 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -47,6 +47,7 @@ public: Optional max_sliders; Optional allow_overlap, + loop_overlap, draw_track, use_triangle; @@ -109,6 +110,7 @@ protected: S32 mMaxNumSliders; BOOL mAllowOverlap; + BOOL mLoopOverlap; F32 mOverlapThreshold; BOOL mDrawTrack; BOOL mUseTriangle; /// hacked in toggle to use a triangle diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index d2afca19b7..4c2936eb69 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -53,6 +53,7 @@ LLMultiSliderCtrl::Params::Params() can_edit_text("can_edit_text", false), max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), + loop_overlap("loop_overlap", false), overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), @@ -168,6 +169,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.increment(p.increment); params.max_sliders(p.max_sliders); params.allow_overlap(p.allow_overlap); + params.loop_overlap(p.loop_overlap); if (p.overlap_threshold.isProvided()) { params.overlap_threshold = p.overlap_threshold; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 507115f5e1..0ce21c0612 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -54,6 +54,7 @@ public: Optional decimal_digits; Optional max_sliders; Optional allow_overlap, + loop_overlap, draw_track, use_triangle; -- cgit v1.2.3 From 3dfd3be98e19c239949eb7d59ef3fb84274322d1 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Thu, 9 Aug 2018 13:09:22 +0300 Subject: MAINT-8900 LLVirtualTrackball improvements: buttons behavior and mode select --- indra/llui/llvirtualtrackball.cpp | 9 +++++---- indra/llui/llvirtualtrackball.h | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index a24c5a420d..e73bba57bb 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -321,7 +321,7 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask) { if (hasMouseCapture()) { - if (mask == MASK_CONTROL) + if (mDragMode == DRAG_SCROLL) { // trackball (move to roll) mode LLQuaternion delta; @@ -394,7 +394,7 @@ BOOL LLVirtualTrackball::handleMouseUp(S32 x, S32 y, MASK mask) gFocusMgr.setMouseCapture(NULL); make_ui_sound("UISndClickRelease"); } - return TRUE; + return LLView::handleMouseUp(x, y, mask); } BOOL LLVirtualTrackball::handleMouseDown(S32 x, S32 y, MASK mask) @@ -404,9 +404,10 @@ BOOL LLVirtualTrackball::handleMouseDown(S32 x, S32 y, MASK mask) mPrevX = x; mPrevY = y; gFocusMgr.setMouseCapture(this); + mDragMode = (mask == MASK_CONTROL) ? DRAG_SCROLL : DRAG_SET; make_ui_sound("UISndClick"); } - return TRUE; + return LLView::handleMouseDown(x, y, mask); } BOOL LLVirtualTrackball::handleRightMouseDown(S32 x, S32 y, MASK mask) @@ -416,7 +417,7 @@ BOOL LLVirtualTrackball::handleRightMouseDown(S32 x, S32 y, MASK mask) //make_ui_sound("UISndClick"); } - return TRUE; + return LLView::handleRightMouseDown(x, y, mask); } BOOL LLVirtualTrackball::handleKeyHere(KEY key, MASK mask) diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index c1b66550bb..48ddb7f4d9 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -44,6 +44,11 @@ public: SUN, MOON }; + enum DragMode + { + DRAG_SET, + DRAG_SCROLL + }; struct Params : public LLInitParam::Block @@ -140,6 +145,7 @@ private: LLQuaternion mValue; ThumbMode mThumbMode; + DragMode mDragMode; F32 mIncrementMouse; F32 mIncrementBtn; -- cgit v1.2.3 From d965af2b0cbf62e2e1601f504e0d548da40aa742 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Fri, 24 Aug 2018 02:40:12 +0300 Subject: MAINT-9032 Virtual Track Ball improvements --- indra/llui/llvirtualtrackball.cpp | 31 +++++++++++++++++++++++++++++++ indra/llui/llvirtualtrackball.h | 5 +++++ 2 files changed, 36 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index e73bba57bb..723643dd25 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -88,6 +88,7 @@ LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p) btn_rt.rect(LLRect(centerX - axis_offset_lt, border_rect.mTop, centerX + axis_offset_rb, border_rect.mTop - btn_size)); btn_rt.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this)); btn_rt.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopClick, this)); + btn_rt.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateTopMouseEnter, this)); mBtnRotateTop = LLUICtrlFactory::create(btn_rt); addChild(mBtnRotateTop); @@ -104,6 +105,7 @@ LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p) btn_rr.rect(LLRect(border_rect.mRight - btn_size, centerY + axis_offset_lt, border_rect.mRight, centerY - axis_offset_rb)); btn_rr.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this)); btn_rr.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightClick, this)); + btn_rr.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateRightMouseEnter, this)); mBtnRotateRight = LLUICtrlFactory::create(btn_rr); addChild(mBtnRotateRight); @@ -120,6 +122,7 @@ LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p) btn_rb.rect(LLRect(centerX - axis_offset_lt, border_rect.mBottom + btn_size, centerX + axis_offset_rb, border_rect.mBottom)); btn_rb.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this)); btn_rb.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomClick, this)); + btn_rb.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateBottomMouseEnter, this)); mBtnRotateBottom = LLUICtrlFactory::create(btn_rb); addChild(mBtnRotateBottom); @@ -136,6 +139,7 @@ LLVirtualTrackball::LLVirtualTrackball(const LLVirtualTrackball::Params& p) btn_rl.rect(LLRect(border_rect.mLeft, centerY + axis_offset_lt, border_rect.mLeft + btn_size, centerY - axis_offset_rb)); btn_rl.click_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this)); btn_rl.mouse_held_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftClick, this)); + btn_rl.mouseenter_callback.function(boost::bind(&LLVirtualTrackball::onRotateLeftMouseEnter, this)); mBtnRotateLeft = LLUICtrlFactory::create(btn_rl); addChild(mBtnRotateLeft); @@ -228,6 +232,13 @@ void LLVirtualTrackball::draw() gl_circle_2d(draw_point.mV[VX], draw_point.mV[VY], mImgSunFront->getWidth() / 2, 12, false); } + // hide the direction labels when disabled + BOOL enabled = isInEnabledChain(); + mLabelN->setVisible(enabled); + mLabelE->setVisible(enabled); + mLabelS->setVisible(enabled); + mLabelW->setVisible(enabled); + LLView::draw(); } @@ -283,6 +294,26 @@ void LLVirtualTrackball::onRotateRightClick() } } +void LLVirtualTrackball::onRotateTopMouseEnter() +{ + mBtnRotateTop->setHighlight(true); +} + +void LLVirtualTrackball::onRotateBottomMouseEnter() +{ + mBtnRotateBottom->setHighlight(true); +} + +void LLVirtualTrackball::onRotateLeftMouseEnter() +{ + mBtnRotateLeft->setHighlight(true); +} + +void LLVirtualTrackball::onRotateRightMouseEnter() +{ + mBtnRotateRight->setHighlight(true); +} + void LLVirtualTrackball::setValue(const LLSD& value) { if (value.isArray() && value.size() == 4) diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index 48ddb7f4d9..2d4b1ece17 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -130,6 +130,11 @@ private: void onRotateLeftClick(); void onRotateRightClick(); + void onRotateTopMouseEnter(); + void onRotateBottomMouseEnter(); + void onRotateLeftMouseEnter(); + void onRotateRightMouseEnter(); + S32 mPrevX; S32 mPrevY; -- cgit v1.2.3 From e539236a75a163b1c6748617bd1e4d2b84aaa3d6 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 6 Sep 2018 21:29:28 +0300 Subject: MAINT-9099 Implementation of vertical orientation support for multislider --- indra/llui/llmultislider.cpp | 95 ++++++++++++++++++++++++++++++++-------- indra/llui/llmultislider.h | 8 +++- indra/llui/llmultisliderctrl.cpp | 2 + indra/llui/llmultisliderctrl.h | 4 +- 4 files changed, 88 insertions(+), 21 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 725f1e8f65..6d6b6c4e90 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -55,6 +55,7 @@ LLMultiSlider::Params::Params() : max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), loop_overlap("loop_overlap", false), + orientation("orientation"), overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), @@ -86,6 +87,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mDisabledThumbColor(p.thumb_disabled_color()), mTriangleColor(p.triangle_color()), mThumbWidth(p.thumb_width), + mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL), mMouseDownSignal(NULL), mMouseUpSignal(NULL) { @@ -204,13 +206,26 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from } F32 t = (newValue - mMinValue) / (mMaxValue - mMinValue); + if (mOrientation == HORIZONTAL) + { + S32 left_edge = mThumbWidth/2; + S32 right_edge = getRect().getWidth() - (mThumbWidth/2); + + S32 x = left_edge + S32( t * (right_edge - left_edge) ); + + mThumbRects[name].mLeft = x - (mThumbWidth / 2); + mThumbRects[name].mRight = x + (mThumbWidth / 2); + } + else + { + S32 bottom_edge = mThumbWidth/2; + S32 top_edge = getRect().getHeight() - (mThumbWidth/2); - S32 left_edge = mThumbWidth/2; - S32 right_edge = getRect().getWidth() - (mThumbWidth/2); + S32 x = bottom_edge + S32( t * (top_edge - bottom_edge) ); - S32 x = left_edge + S32( t * (right_edge - left_edge) ); - mThumbRects[name].mLeft = x - (mThumbWidth/2); - mThumbRects[name].mRight = x + (mThumbWidth/2); + mThumbRects[name].mTop = x + (mThumbWidth / 2); + mThumbRects[name].mBottom = x - (mThumbWidth / 2); + } } void LLMultiSlider::setValue(const LLSD& value) @@ -244,15 +259,29 @@ void LLMultiSlider::setCurSlider(const std::string& name) } } -F32 LLMultiSlider::getSliderValueFromX(S32 xpos) const +F32 LLMultiSlider::getSliderValueFromPos(S32 xpos, S32 ypos) const { - S32 left_edge = mThumbWidth / 2; - S32 right_edge = getRect().getWidth() - (mThumbWidth / 2); + F32 t = 0; + if (mOrientation == HORIZONTAL) + { + S32 left_edge = mThumbWidth / 2; + S32 right_edge = getRect().getWidth() - (mThumbWidth / 2); - xpos += mMouseOffset; - xpos = llclamp(xpos, left_edge, right_edge); + xpos += mMouseOffset; + xpos = llclamp(xpos, left_edge, right_edge); - F32 t = F32(xpos - left_edge) / (right_edge - left_edge); + t = F32(xpos - left_edge) / (right_edge - left_edge); + } + else + { + S32 bottom_edge = mThumbWidth / 2; + S32 top_edge = getRect().getHeight() - (mThumbWidth / 2); + + ypos += mMouseOffset; + ypos = llclamp(ypos, bottom_edge, top_edge); + + t = F32(ypos - bottom_edge) / (top_edge - bottom_edge); + } return((t * (mMaxValue - mMinValue)) + mMinValue); } @@ -286,7 +315,14 @@ const std::string& LLMultiSlider::addSlider(F32 val) } // add a new thumb rect - mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 ); + if (mOrientation == HORIZONTAL) + { + mThumbRects[newName.str()] = LLRect(0, getRect().getHeight(), mThumbWidth, 0); + } + else + { + mThumbRects[newName.str()] = LLRect(0, mThumbWidth, getRect().getWidth(), 0); + } // add the value and set the current slider to this one mValue.insert(newName.str(), initVal); @@ -312,7 +348,14 @@ void LLMultiSlider::addSlider(F32 val, const std::string& name) } // add a new thumb rect - mThumbRects[name] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 ); + if (mOrientation == HORIZONTAL) + { + mThumbRects[name] = LLRect(0, getRect().getHeight(), mThumbWidth, 0); + } + else + { + mThumbRects[name] = LLRect(0, mThumbWidth, getRect().getWidth(), 0); + } // add the value and set the current slider to this one mValue.insert(name, initVal); @@ -416,7 +459,7 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) // // F32 t = F32(x - left_edge) / (right_edge - left_edge); // setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); - setCurSliderValue(getSliderValueFromX(x)); + setCurSliderValue(getSliderValueFromPos(x, y)); onCommit(); getWindow()->setCursor(UI_CURSOR_ARROW); @@ -485,7 +528,14 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask) // Find the offset of the actual mouse location from the center of the thumb. if (mThumbRects[mCurSlider].pointInRect(x,y)) { - mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x; + if (mOrientation == HORIZONTAL) + { + mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth / 2) - x; + } + else + { + mMouseOffset = (mThumbRects[mCurSlider].mBottom + mThumbWidth / 2) - y; + } } else { @@ -550,9 +600,18 @@ void LLMultiSlider::draw() // Track LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square"); - static LLUICachedControl multi_track_height ("UIMultiTrackHeight", 0); - S32 height_offset = (getRect().getHeight() - multi_track_height) / 2; - LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset ); + static LLUICachedControl multi_track_height_width ("UIMultiTrackHeight", 0); + S32 height_offset = 0; + S32 width_offset = 0; + if (mOrientation == HORIZONTAL) + { + height_offset = (getRect().getHeight() - multi_track_height_width) / 2; + } + else + { + width_offset = (getRect().getWidth() - multi_track_height_width) / 2; + } + LLRect track_rect(width_offset, getRect().getHeight() - height_offset, getRect().getWidth() - width_offset, height_offset); if(mDrawTrack) diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index eff0c7d2d7..3884b0a2a0 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -60,6 +60,8 @@ public: thumb_center_selected_color, triangle_color; + Optional orientation; + Optional mouse_down_callback, mouse_up_callback; Optional thumb_width; @@ -75,7 +77,7 @@ public: virtual ~LLMultiSlider(); void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE); F32 getSliderValue(const std::string& name) const; - F32 getSliderValueFromX(S32 xpos) const; + F32 getSliderValueFromPos(S32 xpos, S32 ypos) const; const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } @@ -127,7 +129,9 @@ protected: LLUIColor mThumbCenterSelectedColor; LLUIColor mDisabledThumbColor; LLUIColor mTriangleColor; - + + const EOrientation mOrientation; + commit_signal_t* mMouseDownSignal; commit_signal_t* mMouseUpSignal; }; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 4c2936eb69..73792206a6 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -54,6 +54,7 @@ LLMultiSliderCtrl::Params::Params() max_sliders("max_sliders", 1), allow_overlap("allow_overlap", false), loop_overlap("loop_overlap", false), + orientation("orientation"), overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), @@ -170,6 +171,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.max_sliders(p.max_sliders); params.allow_overlap(p.allow_overlap); params.loop_overlap(p.loop_overlap); + params.orientation(p.orientation()); if (p.overlap_threshold.isProvided()) { params.overlap_threshold = p.overlap_threshold; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 0ce21c0612..a1593c28e0 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -58,6 +58,8 @@ public: draw_track, use_triangle; + Optional orientation; + Optional overlap_threshold; Optional text_color, @@ -102,7 +104,7 @@ public: void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} - F32 getSliderValueFromX(S32 x) const { return mMultiSlider->getSliderValueFromX(x); } + F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); } /// for adding and deleting sliders const std::string& addSlider(); -- cgit v1.2.3 From 43c8f5959f8afaf2f67fbbf49e78965802859b55 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 10 Sep 2018 16:44:56 +0300 Subject: MAINT-9099 Adjustable region altitudes. --- indra/llui/llmultislider.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 6d6b6c4e90..b5e3032626 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -74,7 +74,6 @@ LLMultiSlider::Params::Params() LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) : LLF32UICtrl(p), mMouseOffset( 0 ), - mDragStartThumbRect( 0, getRect().getHeight(), p.thumb_width, 0 ), mMaxNumSliders(p.max_sliders), mAllowOverlap(p.allow_overlap), mLoopOverlap(p.loop_overlap), @@ -93,7 +92,16 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) { mValue.emptyMap(); mCurSlider = LLStringUtil::null; - + + if (mOrientation == HORIZONTAL) + { + mDragStartThumbRect = LLRect(0, getRect().getHeight(), p.thumb_width, 0); + } + else + { + mDragStartThumbRect = LLRect(0, p.thumb_width, getRect().getWidth(), 0); + } + if (p.mouse_down_callback.isProvided()) { setMouseDownCallback(initCommitCallback(p.mouse_down_callback)); -- cgit v1.2.3 From c5936bbba031272b1deb78ce8ea52663d033695b Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 12 Sep 2018 21:02:58 +0300 Subject: SL-1961 Icon support for multislider and icons on altitudes slider --- indra/llui/llmultislider.cpp | 91 ++++++++++++++++++++++++---------------- indra/llui/llmultislider.h | 6 ++- indra/llui/llmultisliderctrl.cpp | 12 +++++- indra/llui/llmultisliderctrl.h | 9 ++-- 4 files changed, 76 insertions(+), 42 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index b5e3032626..caf9f06074 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -61,9 +61,11 @@ LLMultiSlider::Params::Params() use_triangle("use_triangle", false), track_color("track_color"), thumb_disabled_color("thumb_disabled_color"), + thumb_highlight_color("thumb_highlight_color"), thumb_outline_color("thumb_outline_color"), thumb_center_color("thumb_center_color"), thumb_center_selected_color("thumb_center_selected_color"), + thumb_image("thumb_image"), triangle_color("triangle_color"), mouse_down_callback("mouse_down_callback"), mouse_up_callback("mouse_up_callback"), @@ -133,6 +135,12 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) addSlider(it->value); } } + + if (p.thumb_image.isProvided()) + { + mThumbImagep = LLUI::getUIImage(p.thumb_image()); + } + mThumbHighlightColor = p.thumb_highlight_color.isProvided() ? p.thumb_highlight_color() : gFocusMgr.getFocusColor(); } LLMultiSlider::~LLMultiSlider() @@ -644,7 +652,7 @@ void LLMultiSlider::draw() mTriangleColor.get() % opacity, TRUE); } } - else if (!thumb_imagep) + else if (!thumb_imagep && !mThumbImagep) { // draw all the thumbs curSldrIt = mThumbRects.end(); @@ -674,15 +682,33 @@ void LLMultiSlider::draw() gl_rect_2d(mDragStartThumbRect, mThumbCenterColor.get() % opacity, FALSE); } } - else if( gFocusMgr.getMouseCapture() == this ) + else { - // draw drag start - thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); + LLMouseHandler* capture = gFocusMgr.getMouseCapture(); + if (capture == this) + { + // draw drag start (ghost) + if (mThumbImagep) + { + mThumbImagep->draw(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); + } + else + { + thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); + } + } // draw the highlight if (hasFocus() && !mCurSlider.empty()) { - thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + if (mThumbImagep) + { + mThumbImagep->drawBorder(mThumbRects[mCurSlider], mThumbHighlightColor, gFocusMgr.getFocusFlashWidth()); + } + else + { + thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + } } // draw the thumbs @@ -699,44 +725,35 @@ void LLMultiSlider::draw() } // the draw command - thumb_imagep->drawSolid(mIt->second, curThumbColor); + if (mThumbImagep) + { + mThumbImagep->draw(mIt->second); + } + else if (capture == this) + { + thumb_imagep->drawSolid(mIt->second, curThumbColor); + } + else + { + thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity); + } } // draw cur slider last if(curSldrIt != mThumbRects.end()) { - thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get()); - } - - } - else - { - // draw highlight - if (hasFocus() && !mCurSlider.empty()) - { - thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); - } - - // draw thumbs - curSldrIt = mThumbRects.end(); - for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) - { - - // choose the color - curThumbColor = mThumbCenterColor.get(); - if(mIt->first == mCurSlider) + if (mThumbImagep) { - curSldrIt = mIt; - continue; - //curThumbColor = mThumbCenterSelectedColor; - } - - thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity); - } - - if(curSldrIt != mThumbRects.end()) - { - thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity); + mThumbImagep->draw(curSldrIt->second); + } + else if (capture == this) + { + thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get()); + } + else + { + thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity); + } } } diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 3884b0a2a0..a068b461e0 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -55,12 +55,14 @@ public: Optional track_color, thumb_disabled_color, + thumb_highlight_color, thumb_outline_color, thumb_center_color, thumb_center_selected_color, triangle_color; - Optional orientation; + Optional orientation, + thumb_image; Optional mouse_down_callback, mouse_up_callback; @@ -125,10 +127,12 @@ protected: mThumbRects; LLUIColor mTrackColor; LLUIColor mThumbOutlineColor; + LLUIColor mThumbHighlightColor; LLUIColor mThumbCenterColor; LLUIColor mThumbCenterSelectedColor; LLUIColor mDisabledThumbColor; LLUIColor mTriangleColor; + LLUIImagePtr mThumbImagep; //blimps on the slider, for now no 'disabled' support const EOrientation mOrientation; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 73792206a6..972567ef9b 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -55,6 +55,9 @@ LLMultiSliderCtrl::Params::Params() allow_overlap("allow_overlap", false), loop_overlap("loop_overlap", false), orientation("orientation"), + thumb_image("thumb_image"), + thumb_width("thumb_width"), + thumb_highlight_color("thumb_highlight_color"), overlap_threshold("overlap_threshold", 0), draw_track("draw_track", true), use_triangle("use_triangle", false), @@ -171,11 +174,18 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.max_sliders(p.max_sliders); params.allow_overlap(p.allow_overlap); params.loop_overlap(p.loop_overlap); - params.orientation(p.orientation()); if (p.overlap_threshold.isProvided()) { params.overlap_threshold = p.overlap_threshold; } + params.orientation(p.orientation); + params.thumb_image(p.thumb_image); + params.thumb_highlight_color(p.thumb_highlight_color); + if (p.thumb_width.isProvided()) + { + // otherwise should be provided by template + params.thumb_width(p.thumb_width); + } params.draw_track(p.draw_track); params.use_triangle(p.use_triangle); params.control_name(p.control_name); diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index a1593c28e0..74eaf69987 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -51,19 +51,22 @@ public: text_width; Optional show_text, can_edit_text; - Optional decimal_digits; + Optional decimal_digits, + thumb_width; Optional max_sliders; Optional allow_overlap, loop_overlap, draw_track, use_triangle; - Optional orientation; + Optional orientation, + thumb_image; Optional overlap_threshold; Optional text_color, - text_disabled_color; + text_disabled_color, + thumb_highlight_color; Optional mouse_down_callback, mouse_up_callback; -- cgit v1.2.3 From ceb336c5f340c260ac5c1923723dbc8204b98157 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 13 Sep 2018 16:32:41 +0300 Subject: SL-1168 EEP Shouldn't be possible to create more than 20 keframes --- indra/llui/llmultislider.h | 4 ++++ indra/llui/llmultisliderctrl.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 3884b0a2a0..9a997de16a 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -105,6 +105,10 @@ public: /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ void draw(); + S32 getMaxNumSliders() { return mMaxNumSliders; } + S32 getCurNumSliders() { return mValue.size(); } + bool canAddSliders() { return mValue.size() < mMaxNumSliders; } + protected: LLSD mValue; std::string mCurSlider; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index a1593c28e0..ad2dc94779 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -115,6 +115,10 @@ public: F32 getMinValue() const { return mMultiSlider->getMinValue(); } F32 getMaxValue() const { return mMultiSlider->getMaxValue(); } + S32 getMaxNumSliders() { return mMultiSlider->getMaxNumSliders(); } + S32 getCurNumSliders() { return mMultiSlider->getCurNumSliders(); } + bool canAddSliders() { return mMultiSlider->canAddSliders(); } + void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; } -- cgit v1.2.3 From 53de3916a16e316543cd12491556999a4c84f545 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Thu, 13 Sep 2018 10:48:55 -0700 Subject: Explicit cast for LLUIColor --- indra/llui/llmultislider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index caf9f06074..ef907e620e 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -140,7 +140,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) { mThumbImagep = LLUI::getUIImage(p.thumb_image()); } - mThumbHighlightColor = p.thumb_highlight_color.isProvided() ? p.thumb_highlight_color() : gFocusMgr.getFocusColor(); + mThumbHighlightColor = p.thumb_highlight_color.isProvided() ? p.thumb_highlight_color() : static_cast(gFocusMgr.getFocusColor()); } LLMultiSlider::~LLMultiSlider() -- cgit v1.2.3 From 8290206887972bcd3d3acac0a02d9df37a82e637 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 14 Sep 2018 17:52:08 +0300 Subject: SL-9653 Multy slider edge overlap cases --- indra/llui/llmultislider.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index ef907e620e..c35b7c5496 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -177,13 +177,15 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from // increment is our distance between points, use to eliminate round error F32 threshold = mOverlapThreshold + (mIncrement / 4); // If loop overlap is enabled, check if we overlap with points 'after' max value (project to lower) - F32 loop_up_check = (mLoopOverlap && (value + threshold) > mMaxValue) ? (value + threshold - mMaxValue + mMinValue) : 0.0f; + F32 loop_up_check = (mLoopOverlap && (value + threshold) > mMaxValue) ? (value + threshold - mMaxValue + mMinValue) : mMinValue - 1.0f; // If loop overlap is enabled, check if we overlap with points 'before' min value (project to upper) - F32 loop_down_check = (mLoopOverlap && (value - threshold) < mMinValue) ? (value - threshold - mMinValue + mMaxValue) : 0.0f; + F32 loop_down_check = (mLoopOverlap && (value - threshold) < mMinValue) ? (value - threshold - mMinValue + mMaxValue) : mMaxValue + 1.0f; - for(;mIt != mValue.endMap(); mIt++) { - - F32 testVal = (F32)mIt->second.asReal() - newValue; + for(;mIt != mValue.endMap(); mIt++) + { + F32 locationVal = (F32)mIt->second.asReal(); + // Check nearby values + F32 testVal = locationVal - newValue; if (testVal > -threshold && testVal < threshold && mIt->first != name) @@ -191,17 +193,19 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from hit = true; break; } - if (loop_up_check != 0 - && testVal < loop_up_check) - { - hit = true; - break; - } - if (loop_down_check != 0 - && testVal > loop_down_check) + if (mLoopOverlap) { - hit = true; - break; + // Check edge overlap values + if (locationVal < loop_up_check) + { + hit = true; + break; + } + if (locationVal > loop_down_check) + { + hit = true; + break; + } } } -- cgit v1.2.3 From 92dc9ceb834dd31aa6fe1c67b9ea896a62cd7c7c Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 24 Sep 2018 16:36:01 +0300 Subject: SL-9676 EEP Pick:SELECT SETTINGS limit folder operations options --- indra/llui/llfolderview.cpp | 25 ++++++++++++++++++++++--- indra/llui/llfolderview.h | 8 ++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 895753aeae..9d0f4b6db1 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -149,6 +149,7 @@ LLFolderView::Params::Params() use_label_suffix("use_label_suffix"), allow_multiselect("allow_multiselect", true), show_empty_message("show_empty_message", true), + suppress_folder_menu("suppress_folder_menu", false), use_ellipses("use_ellipses", false), options_menu("options_menu", "") { @@ -167,6 +168,7 @@ LLFolderView::LLFolderView(const Params& p) mRenameItem( NULL ), mNeedsScroll( FALSE ), mUseLabelSuffix(p.use_label_suffix), + mSuppressFolderMenu(p.suppress_folder_menu), mPinningSelectedItem(FALSE), mNeedsAutoSelect( FALSE ), mAutoSelectOverride(FALSE), @@ -1432,10 +1434,13 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - if ( handled + bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); + if ((handled && ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible - && menu ) + && menu ) && + !hide_folder_menu) { if (mCallbackRegistrar) { @@ -1449,7 +1454,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) if (mCallbackRegistrar) { mCallbackRegistrar->popScope(); - } + } } else { @@ -1862,6 +1867,20 @@ void LLFolderView::updateMenu() } } +bool LLFolderView::isFolderSelected() +{ + selected_items_t::iterator item_iter; + for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) + { + LLFolderViewFolder* folder = dynamic_cast(*item_iter); + if (folder != NULL) + { + return true; + } + } + return false; +} + bool LLFolderView::selectFirstItem() { for (folders_t::iterator iter = mFolders.begin(); diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 2926e160d0..69824992c1 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -92,7 +92,8 @@ public: allow_multiselect, show_empty_message, use_ellipses, - show_item_link_overlays; + show_item_link_overlays, + suppress_folder_menu; Mandatory view_model; Optional grouped_item_model; Mandatory options_menu; @@ -259,6 +260,8 @@ protected: void closeRenamer( void ); + bool isFolderSelected(); + bool selectFirstItem(); bool selectLastItem(); @@ -282,7 +285,8 @@ protected: mDragAndDropThisFrame, mShowItemLinkOverlays, mShowSelectionContext, - mShowSingleSelection; + mShowSingleSelection, + mSuppressFolderMenu; // Renaming variables and methods LLFolderViewItem* mRenameItem; // The item currently being renamed -- cgit v1.2.3 From 6fff70222b60674f0e3cc531e402afb9e7c184e3 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 5 Oct 2018 18:05:36 +0300 Subject: SL-9818 [EEP] Single click on Cloud Scroll number input field doesn't select it --- indra/llui/llxyvector.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llxyvector.cpp b/indra/llui/llxyvector.cpp index 48f38b8a92..9d5823e368 100644 --- a/indra/llui/llxyvector.cpp +++ b/indra/llui/llxyvector.cpp @@ -289,7 +289,14 @@ BOOL LLXYVector::handleMouseUp(S32 x, S32 y, MASK mask) make_ui_sound("UISndClickRelease"); } - return TRUE; + if (mTouchArea->getRect().pointInRect(x, y)) + { + return TRUE; + } + else + { + return LLUICtrl::handleMouseUp(x, y, mask); + } } BOOL LLXYVector::handleMouseDown(S32 x, S32 y, MASK mask) @@ -299,8 +306,12 @@ BOOL LLXYVector::handleMouseDown(S32 x, S32 y, MASK mask) { gFocusMgr.setMouseCapture(this); make_ui_sound("UISndClick"); - } - return TRUE; + return TRUE; + } + else + { + return LLUICtrl::handleMouseDown(x, y, mask); + } } -- cgit v1.2.3 From b030d7036f87d30babb4a8df8d256113f46182e9 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 5 Oct 2018 19:31:35 +0300 Subject: SL-1961 EEP correct disabling of altitude multislider and cleanup --- indra/llui/llmultislider.cpp | 18 ++++++++++++++++-- indra/llui/llslider.cpp | 2 -- indra/llui/llslider.h | 4 +--- 3 files changed, 17 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index c35b7c5496..ece6edd285 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -731,7 +731,14 @@ void LLMultiSlider::draw() // the draw command if (mThumbImagep) { - mThumbImagep->draw(mIt->second); + if (getEnabled()) + { + mThumbImagep->draw(mIt->second); + } + else + { + mThumbImagep->draw(mIt->second, LLColor4::grey % 0.8f); + } } else if (capture == this) { @@ -748,7 +755,14 @@ void LLMultiSlider::draw() { if (mThumbImagep) { - mThumbImagep->draw(curSldrIt->second); + if (getEnabled()) + { + mThumbImagep->draw(curSldrIt->second); + } + else + { + mThumbImagep->draw(curSldrIt->second, LLColor4::grey % 0.8f); + } } else if (capture == this) { diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index 6925c0a130..62df5a2c38 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -42,7 +42,6 @@ static LLDefaultChildRegistry::Register r1("slider_bar"); LLSlider::Params::Params() : orientation ("orientation", std::string ("horizontal")), - track_color("track_color"), thumb_outline_color("thumb_outline_color"), thumb_center_color("thumb_center_color"), thumb_image("thumb_image"), @@ -60,7 +59,6 @@ LLSlider::LLSlider(const LLSlider::Params& p) : LLF32UICtrl(p), mMouseOffset( 0 ), mOrientation ((p.orientation() == "horizontal") ? HORIZONTAL : VERTICAL), - mTrackColor(p.track_color()), mThumbOutlineColor(p.thumb_outline_color()), mThumbCenterColor(p.thumb_center_color()), mThumbImage(p.thumb_image), diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index 3b492d8182..484a5373b3 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -38,8 +38,7 @@ public: { Optional orientation; - Optional track_color, - thumb_outline_color, + Optional thumb_outline_color, thumb_center_color; Optional thumb_image, @@ -99,7 +98,6 @@ private: const EOrientation mOrientation; LLRect mThumbRect; - LLUIColor mTrackColor; LLUIColor mThumbOutlineColor; LLUIColor mThumbCenterColor; -- cgit v1.2.3 From 49f4b68b31a8299fc1b796102bea6da6de8b6115 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 23 Oct 2018 10:15:04 +0300 Subject: SL-9941 EEP XY_Vector improvement - logarithmic scale mode --- indra/llui/llxyvector.cpp | 72 +++++++++++++++++++++++++++++------------------ indra/llui/llxyvector.h | 4 +++ 2 files changed, 49 insertions(+), 27 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llxyvector.cpp b/indra/llui/llxyvector.cpp index 9d5823e368..08dedc157b 100644 --- a/indra/llui/llxyvector.cpp +++ b/indra/llui/llxyvector.cpp @@ -37,6 +37,8 @@ #include "lluictrlfactory.h" #include "llrender.h" +#include "llmath.h" + // Globals static LLDefaultChildRegistry::Register register_xy_vector("xy_vector"); @@ -63,7 +65,8 @@ LLXYVector::Params::Params() arrow_color("arrow_color", LLColor4::white), ghost_color("ghost_color"), area_color("area_color", LLColor4::grey4), - grid_color("grid_color", LLColor4::grey % 0.25f) + grid_color("grid_color", LLColor4::grey % 0.25f), + logarithmic("logarithmic", FALSE) { } @@ -77,7 +80,8 @@ LLXYVector::LLXYVector(const LLXYVector::Params& p) mIncrementX(p.increment_x), mMinValueY(p.min_val_y), mMaxValueY(p.max_val_y), - mIncrementY(p.increment_y) + mIncrementY(p.increment_y), + mLogarithmic(p.logarithmic) { mGhostColor = p.ghost_color.isProvided() ? p.ghost_color() % 0.3f : p.arrow_color() % 0.3f; @@ -138,6 +142,9 @@ LLXYVector::~LLXYVector() BOOL LLXYVector::postBuild() { + mLogScaleX = (2 * log(mMaxValueX)) / mTouchArea->getRect().getWidth(); + mLogScaleY = (2 * log(mMaxValueY)) / mTouchArea->getRect().getHeight(); + return TRUE; } @@ -165,9 +172,24 @@ void LLXYVector::draw() { S32 centerX = mTouchArea->getRect().getCenterX(); S32 centerY = mTouchArea->getRect().getCenterY(); + S32 pointX; + S32 pointY; + + if (mLogarithmic) + { + pointX = (log(llabs(mValueX) + 1)) / mLogScaleX; + pointX *= (mValueX < 0) ? -1 : 1; + pointX += centerX; - S32 pointX = centerX + (mValueX * mTouchArea->getRect().getWidth() / (2 * mMaxValueX)); - S32 pointY = centerY + (mValueY * mTouchArea->getRect().getHeight() / (2 * mMaxValueY)); + pointY = (log(llabs(mValueY) + 1)) / mLogScaleY; + pointY *= (mValueY < 0) ? -1 : 1; + pointY += centerY; + } + else // linear + { + pointX = centerX + (mValueX * mTouchArea->getRect().getWidth() / (2 * mMaxValueX)); + pointY = centerY + (mValueY * mTouchArea->getRect().getHeight() / (2 * mMaxValueY)); + } // fill gl_rect_2d(mTouchArea->getRect(), mAreaColor, true); @@ -222,22 +244,8 @@ void LLXYVector::setValue(const LLSD& value) void LLXYVector::setValue(F32 x, F32 y) { - x = llclamp(x, mMinValueX, mMaxValueX); - y = llclamp(y, mMinValueY, mMaxValueY); - - // Round the values to nearest increments - x -= mMinValueX; - x += mIncrementX / 2.0001f; - x -= fmod(x, mIncrementX); - x += mMinValueX; - - y -= mMinValueY; - y += mIncrementY / 2.0001f; - y -= fmod(y, mIncrementY); - y += mMinValueY; - - mValueX = x; - mValueY = y; + mValueX = ll_round(llclamp(x, mMinValueX, mMaxValueX), mIncrementX); + mValueY = ll_round(llclamp(y, mMinValueY, mMaxValueY), mIncrementY); update(); } @@ -269,13 +277,23 @@ BOOL LLXYVector::handleHover(S32 x, S32 y, MASK mask) { if (hasMouseCapture()) { - F32 valueX = F32(x - mTouchArea->getRect().getCenterX()) / mTouchArea->getRect().getWidth(); - F32 valueY = F32(y - mTouchArea->getRect().getCenterY()) / mTouchArea->getRect().getHeight(); - - valueX *= 2 * mMaxValueX; - valueY *= 2 * mMaxValueY; - - setValueAndCommit(valueX, valueY); + if (mLogarithmic) + { + F32 valueX = llfastpow(F_E, mLogScaleX*(llabs(x - mTouchArea->getRect().getCenterX()))) - 1; + valueX *= (x < mTouchArea->getRect().getCenterX()) ? -1 : 1; + + F32 valueY = llfastpow(F_E, mLogScaleY*(llabs(y - mTouchArea->getRect().getCenterY()))) - 1; + valueY *= (y < mTouchArea->getRect().getCenterY()) ? -1 : 1; + + setValueAndCommit(valueX, valueY); + } + else //linear + { + F32 valueX = 2 * mMaxValueX * F32(x - mTouchArea->getRect().getCenterX()) / mTouchArea->getRect().getWidth(); + F32 valueY = 2 * mMaxValueY * F32(y - mTouchArea->getRect().getCenterY()) / mTouchArea->getRect().getHeight(); + + setValueAndCommit(valueX, valueY); + } } return TRUE; diff --git a/indra/llui/llxyvector.h b/indra/llui/llxyvector.h index 4d67db3251..bb3822dd26 100644 --- a/indra/llui/llxyvector.h +++ b/indra/llui/llxyvector.h @@ -59,6 +59,7 @@ public: Optional ghost_color; Optional area_color; Optional grid_color; + Optional logarithmic; Params(); }; @@ -112,6 +113,9 @@ private: LLUIColor mAreaColor; LLUIColor mGridColor; + BOOL mLogarithmic; + F32 mLogScaleX; + F32 mLogScaleY; }; #endif -- cgit v1.2.3 From 58ffb2e4b11d7aaf1fb66531f4925bd359f551cb Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Thu, 29 Nov 2018 17:55:23 +0200 Subject: SL-10141 FIXED [EEP] Neighboring sky levels may be closer than 100 meters to each other in edit mode --- indra/llui/llmultislider.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index ece6edd285..9a7b6f9f6b 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -113,9 +113,9 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) setMouseUpCallback(initCommitCallback(p.mouse_up_callback)); } - if (p.overlap_threshold.isProvided()) + if (p.overlap_threshold.isProvided() && p.overlap_threshold > mIncrement) { - mOverlapThreshold = p.overlap_threshold; + mOverlapThreshold = p.overlap_threshold - mIncrement; } else { -- cgit v1.2.3 From 6762c4515a9b0f98164d6efd191abec5ca4dd211 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 7 Dec 2018 17:10:05 +0200 Subject: SL-1894 When crossing regions altitude slider could misbehave --- indra/llui/llmultislider.cpp | 8 +++++--- indra/llui/llmultislider.h | 3 ++- indra/llui/llmultisliderctrl.cpp | 11 +++++++++++ indra/llui/llmultisliderctrl.h | 2 ++ 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 9a7b6f9f6b..ed93b3d44c 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -354,17 +354,17 @@ const std::string& LLMultiSlider::addSlider(F32 val) return mCurSlider; } -void LLMultiSlider::addSlider(F32 val, const std::string& name) +bool LLMultiSlider::addSlider(F32 val, const std::string& name) { F32 initVal = val; if(mValue.size() >= mMaxNumSliders) { - return; + return false; } bool foundOne = findUnusedValue(initVal); if(!foundOne) { - return; + return false; } // add a new thumb rect @@ -383,6 +383,8 @@ void LLMultiSlider::addSlider(F32 val, const std::string& name) // move the slider setSliderValue(mCurSlider, initVal, TRUE); + + return true; } bool LLMultiSlider::findUnusedValue(F32& initVal) diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 52c6d1ddef..50cf62e9c5 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -96,7 +96,7 @@ public: bool findUnusedValue(F32& initVal); const std::string& addSlider(); const std::string& addSlider(F32 val); - void addSlider(F32 val, const std::string& name); + bool addSlider(F32 val, const std::string& name); void deleteSlider(const std::string& name); void deleteCurSlider() { deleteSlider(mCurSlider); } void clear(); @@ -109,6 +109,7 @@ public: S32 getMaxNumSliders() { return mMaxNumSliders; } S32 getCurNumSliders() { return mValue.size(); } + F32 getOverlapThreshold() { return mOverlapThreshold; } bool canAddSliders() { return mValue.size() < mMaxNumSliders; } protected: diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 972567ef9b..20e2b569f1 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -293,6 +293,17 @@ const std::string& LLMultiSliderCtrl::addSlider(F32 val) return name; } +bool LLMultiSliderCtrl::addSlider(F32 val, const std::string& name) +{ + bool res = mMultiSlider->addSlider(val, name); + if (res) + { + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); + } + return res; +} + void LLMultiSliderCtrl::deleteSlider(const std::string& name) { mMultiSlider->deleteSlider(name); diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index c370ebf505..75715d6043 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -112,6 +112,7 @@ public: /// for adding and deleting sliders const std::string& addSlider(); const std::string& addSlider(F32 val); + bool addSlider(F32 val, const std::string& name); void deleteSlider(const std::string& name); void deleteCurSlider() { deleteSlider(mMultiSlider->getCurSlider()); } @@ -120,6 +121,7 @@ public: S32 getMaxNumSliders() { return mMultiSlider->getMaxNumSliders(); } S32 getCurNumSliders() { return mMultiSlider->getCurNumSliders(); } + F32 getOverlapThreshold() { return mMultiSlider->getOverlapThreshold(); } bool canAddSliders() { return mMultiSlider->canAddSliders(); } void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); } -- cgit v1.2.3 From 8227a0b270f6e7cc521adeb7b97ad2d5fb646973 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 21 Dec 2018 15:30:57 -0800 Subject: SL-10279: Rework the environment pannel. Still in progress. --- indra/llui/llmultislider.cpp | 9 +++++++++ indra/llui/llmultislider.h | 1 + indra/llui/llmultisliderctrl.h | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index ed93b3d44c..f30ce28b9d 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -306,6 +306,15 @@ F32 LLMultiSlider::getSliderValueFromPos(S32 xpos, S32 ypos) const return((t * (mMaxValue - mMinValue)) + mMinValue); } + +LLRect LLMultiSlider::getSliderThumbRect(const std::string& name) const +{ + auto it = mThumbRects.find(name); + if (it != mThumbRects.end()) + return (*it).second; + return LLRect(); +} + void LLMultiSlider::resetCurSlider() { mCurSlider = LLStringUtil::null; diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 50cf62e9c5..b4331e11c0 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -80,6 +80,7 @@ public: void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE); F32 getSliderValue(const std::string& name) const; F32 getSliderValueFromPos(S32 xpos, S32 ypos) const; + LLRect getSliderThumbRect(const std::string& name) const; const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 75715d6043..20d204a6dc 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -107,7 +107,8 @@ public: void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} - F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); } + F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); } + LLRect getSliderThumbRect(const std::string &name) const { return mMultiSlider->getSliderThumbRect(name); } /// for adding and deleting sliders const std::string& addSlider(); -- cgit v1.2.3 From d607d81dba25dfe7dd1ecdf123af656ca939924f Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 2 Jan 2019 17:10:15 -0800 Subject: SL-10279: Temp fix for stale estate info when editing parcel environment. --- indra/llui/llmultislider.cpp | 15 +++++++++++++++ indra/llui/llmultislider.h | 5 +++++ indra/llui/llmultisliderctrl.h | 3 +++ 3 files changed, 23 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index f30ce28b9d..61e8bdd38c 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -315,6 +315,21 @@ LLRect LLMultiSlider::getSliderThumbRect(const std::string& name) const return LLRect(); } +void LLMultiSlider::setSliderThumbImage(const std::string &name) +{ + if (!name.empty()) + { + mThumbImagep = LLUI::getUIImage(name); + } + else + clearSliderThumbImage(); +} + +void LLMultiSlider::clearSliderThumbImage() +{ + mThumbImagep = NULL; +} + void LLMultiSlider::resetCurSlider() { mCurSlider = LLStringUtil::null; diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index b4331e11c0..b0fca2597d 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -82,6 +82,10 @@ public: F32 getSliderValueFromPos(S32 xpos, S32 ypos) const; LLRect getSliderThumbRect(const std::string& name) const; + void setSliderThumbImage(const std::string &name); + void clearSliderThumbImage(); + + const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } void setCurSlider(const std::string& name); @@ -113,6 +117,7 @@ public: F32 getOverlapThreshold() { return mOverlapThreshold; } bool canAddSliders() { return mValue.size() < mMaxNumSliders; } + protected: LLSD mValue; std::string mCurSlider; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 20d204a6dc..e16737b3c7 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -110,6 +110,9 @@ public: F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); } LLRect getSliderThumbRect(const std::string &name) const { return mMultiSlider->getSliderThumbRect(name); } + void setSliderThumbImage(const std::string &name) { mMultiSlider->setSliderThumbImage(name); } + void clearSliderThumbImage() { mMultiSlider->clearSliderThumbImage(); } + /// for adding and deleting sliders const std::string& addSlider(); const std::string& addSlider(F32 val); -- cgit v1.2.3 From 64e45b5b6ef8ded7bbea1b376e5bf2cbb0d6f5a4 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 4 Jan 2019 17:10:28 -0800 Subject: SL-10041, SL-9758: Environment tab is disabled(shows can't do this) when EM does not allow parcel override. "Commit" button now reads "Apply to Parcel" or "Apply to Region" as needed. --- indra/llui/llmenugl.cpp | 22 ++++++++++++++++++++++ indra/llui/llmenugl.h | 3 +++ 2 files changed, 25 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 0d42f726fa..ddcce61123 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2713,6 +2713,15 @@ void LLMenuGL::setItemVisible( const std::string& name, BOOL visible ) } } + +void LLMenuGL::setItemLabel(const std::string &name, const std::string &label) +{ + LLMenuItemGL *item = getItem(name); + + if (item) + item->setLabel(label); +} + void LLMenuGL::setItemLastSelected(LLMenuItemGL* item) { if (getVisible()) @@ -2757,6 +2766,19 @@ LLMenuItemGL* LLMenuGL::getItem(S32 number) return NULL; } +LLMenuItemGL* LLMenuGL::getItem(std::string name) +{ + item_list_t::iterator item_iter; + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + { + if ((*item_iter)->getName() == name) + { + return (*item_iter); + } + } + return NULL; +} + LLMenuItemGL* LLMenuGL::getHighlightedItem() { item_list_t::iterator item_iter; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 69f7d21513..6ca581fa86 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -463,6 +463,8 @@ public: void setEnabledSubMenus(BOOL enable); void setItemVisible( const std::string& name, BOOL visible); + + void setItemLabel(const std::string &name, const std::string &label); // sets the left,bottom corner of menu, useful for popups void setLeftAndBottom(S32 left, S32 bottom); @@ -493,6 +495,7 @@ public: void setItemLastSelected(LLMenuItemGL* item); // must be in menu U32 getItemCount(); // number of menu items LLMenuItemGL* getItem(S32 number); // 0 = first item + LLMenuItemGL* getItem(std::string name); LLMenuItemGL* getHighlightedItem(); LLMenuItemGL* highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disabled = TRUE); -- cgit v1.2.3 From 13c537e9a0f05857f89085b91ac098921c317fb1 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 9 Jan 2019 21:57:12 +0200 Subject: SL-10279 Readjusting altitude slider --- indra/llui/llsliderctrl.cpp | 37 +++++++++++++++++++++++++++++++++++++ indra/llui/llsliderctrl.h | 4 ++++ 2 files changed, 41 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 0056cb6dc4..c3c3ce04f9 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -283,6 +283,31 @@ void LLSliderCtrl::updateText() } } +void LLSliderCtrl::updateSliderRect() +{ + S32 right = getRect().getWidth(); + S32 top = getRect().getHeight(); + S32 bottom = 0; + S32 left = 0; + static LLUICachedControl sliderctrl_spacing("UISliderctrlSpacing", 0); + if (mEditor) + { + LLRect editor_rect = mEditor->getRect(); + S32 editor_width = editor_rect.getWidth(); + editor_rect.mRight = right; + editor_rect.mLeft = right - editor_width; + mEditor->setRect(editor_rect); + + right -= editor_width + sliderctrl_spacing; + } + if (mLabelBox) + { + left += mLabelBox->getRect().getWidth() + sliderctrl_spacing; + } + + mSlider->setRect(LLRect(left, top,right,bottom)); +} + // static void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata ) { @@ -404,6 +429,18 @@ void LLSliderCtrl::onCommit() LLF32UICtrl::onCommit(); } +void LLSliderCtrl::setRect(const LLRect& rect) +{ + LLF32UICtrl::setRect(rect); + updateSliderRect(); +} + +//virtual +void LLSliderCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLF32UICtrl::reshape(width, height, called_from_parent); + updateSliderRect(); +} void LLSliderCtrl::setPrecision(S32 precision) { diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index 67cca9ef04..75fcdc4b71 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -125,6 +125,9 @@ public: mSlider->setControlName(control_name, context); } + /*virtual*/ void setRect(const LLRect& rect); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + static void onSliderCommit(LLUICtrl* caller, const LLSD& userdata); static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata); @@ -133,6 +136,7 @@ public: private: void updateText(); + void updateSliderRect(); void reportInvalidData(); const LLFontGL* mFont; -- cgit v1.2.3 From ac865de287b2e740acd9f6a8724301146df73ccf Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 25 Jan 2019 22:02:16 +0200 Subject: SL-1945 Day Cycle Editor Copy Track --- indra/llui/llfloater.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ indra/llui/llfloater.h | 13 +++++++++ 2 files changed, 82 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a245dd8f78..d6c2c7bc55 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -37,6 +37,7 @@ #include "lluictrlfactory.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llcriticaldamp.h" // LLSmoothInterpolation #include "lldir.h" #include "lldraghandle.h" #include "llfloaterreg.h" @@ -64,6 +65,10 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; +const F32 LLFloater::CONTEXT_CONE_IN_ALPHA = 0.0f; +const F32 LLFloater::CONTEXT_CONE_OUT_ALPHA = 1.f; +const F32 LLFloater::CONTEXT_CONE_FADE_TIME = 0.08f; + namespace LLInitParam { void TypeValues::declareValues() @@ -2116,6 +2121,70 @@ void LLFloater::updateTitleButtons() } } +void LLFloater::drawConeToOwner(F32 &context_cone_opacity, + F32 max_cone_opacity, + LLView *owner_view, + F32 fade_time, + F32 contex_cone_in_alpha, + F32 contex_cone_out_alpha) +{ + if (owner_view + && owner_view->isInVisibleChain() + && hasFocus() + && context_cone_opacity > 0.001f + && gFocusMgr.childHasKeyboardFocus(this)) + { + // draw cone of context pointing back to owner (e.x. texture swatch) + LLRect owner_rect; + owner_view->localRectToOtherView(owner_view->getLocalRect(), &owner_rect, this); + LLRect local_rect = getLocalRect(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLEnable(GL_CULL_FACE); + gGL.begin(LLRender::QUADS); + { + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + } + gGL.end(); + } + + if (gFocusMgr.childHasMouseCapture(getDragHandle())) + { + context_cone_opacity = lerp(context_cone_opacity, max_cone_opacity, LLSmoothInterpolation::getInterpolant(fade_time)); + } + else + { + context_cone_opacity = lerp(context_cone_opacity, 0.f, LLSmoothInterpolation::getInterpolant(fade_time)); + } +} + void LLFloater::buildButtons(const Params& floater_params) { static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 165f67499b..f8c04e8a2f 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -395,6 +395,15 @@ protected: virtual void updateTitleButtons(); + // Draws a cone from this floater to parent floater or view (owner) + // Modifies context_cone_opacity (interpolates according to fade time and returns new value) + void drawConeToOwner(F32 &context_cone_opacity, + F32 max_cone_opacity, + LLView *owner_view, + F32 context_fade_time = CONTEXT_CONE_FADE_TIME, + F32 contex_cone_in_alpha = CONTEXT_CONE_IN_ALPHA, + F32 contex_cone_out_alpha = CONTEXT_CONE_OUT_ALPHA); + private: void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters @@ -424,6 +433,10 @@ private: void updateTransparency(LLView* view, ETypeTransparency transparency_type); public: + static const F32 CONTEXT_CONE_IN_ALPHA; + static const F32 CONTEXT_CONE_OUT_ALPHA; + static const F32 CONTEXT_CONE_FADE_TIME; + // Called when floater is opened, passes mKey // Public so external views or floaters can watch for this floater opening commit_signal_t mOpenSignal; -- cgit v1.2.3 From 347ae7a38bb2535bac4d3c497e216e3178c6e966 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Tue, 29 Jan 2019 16:49:16 +0200 Subject: SL-10430 FIXED Slider control rendering broken --- indra/llui/llsliderctrl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index c3c3ce04f9..3b89a8ca63 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -300,6 +300,10 @@ void LLSliderCtrl::updateSliderRect() right -= editor_width + sliderctrl_spacing; } + if (mTextBox) + { + right -= mTextBox->getRect().getWidth() + sliderctrl_spacing; + } if (mLabelBox) { left += mLabelBox->getRect().getWidth() + sliderctrl_spacing; -- cgit v1.2.3 From 531ad5b3ec1b6785bf6cde04c1d7203233b552a2 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 31 Jan 2019 18:45:01 +0200 Subject: SL-1531 EEP Visual feedback on the timeline --- indra/llui/llmultislider.cpp | 102 +++++++++++++++++++++++++++++++++++-------- indra/llui/llmultislider.h | 2 + 2 files changed, 85 insertions(+), 19 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 61e8bdd38c..b8f0a01b86 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -497,14 +497,6 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) { if( gFocusMgr.getMouseCapture() == this ) { -// S32 left_edge = mThumbWidth/2; -// S32 right_edge = getRect().getWidth() - (mThumbWidth/2); -// -// x += mMouseOffset; -// x = llclamp( x, left_edge, right_edge ); -// -// F32 t = F32(x - left_edge) / (right_edge - left_edge); -// setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); setCurSliderValue(getSliderValueFromPos(x, y)); onCommit(); @@ -513,6 +505,27 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) } else { + if (getEnabled()) + { + if (mHoverSlider.empty() || !getSliderThumbRect(mHoverSlider).pointInRect(x, y)) + { + mHoverSlider.clear(); + std::map::iterator mIt = mThumbRects.begin(); + for (; mIt != mThumbRects.end(); mIt++) + { + if (mIt->second.pointInRect(x, y)) + { + mHoverSlider = mIt->first; + break; + } + } + } + } + else + { + mHoverSlider.clear(); + } + getWindow()->setCursor(UI_CURSOR_ARROW); LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL; } @@ -625,6 +638,13 @@ BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask) return handled; } +/*virtual*/ +void LLMultiSlider::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mHoverSlider.clear(); + LLF32UICtrl::onMouseLeave(x, y, mask); +} + void LLMultiSlider::draw() { static LLUICachedControl extra_triangle_height ("UIExtraTriangleHeight", 0); @@ -633,6 +653,7 @@ void LLMultiSlider::draw() std::map::iterator mIt; std::map::iterator curSldrIt; + std::map::iterator hoverSldrIt; // Draw background and thumb. @@ -686,6 +707,7 @@ void LLMultiSlider::draw() { // draw all the thumbs curSldrIt = mThumbRects.end(); + hoverSldrIt = mThumbRects.end(); for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { // choose the color @@ -694,15 +716,21 @@ void LLMultiSlider::draw() curSldrIt = mIt; continue; - //curThumbColor = mThumbCenterSelectedColor; + } + if (mIt->first == mHoverSlider && getEnabled() && gFocusMgr.getMouseCapture() != this) + { + // draw last, after current one + hoverSldrIt = mIt; + continue; } // the draw command gl_rect_2d(mIt->second, curThumbColor, TRUE); } - // now draw the current slider - if(curSldrIt != mThumbRects.end()) { + // now draw the current and hover sliders + if(curSldrIt != mThumbRects.end()) + { gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor.get(), TRUE); } @@ -711,6 +739,10 @@ void LLMultiSlider::draw() { gl_rect_2d(mDragStartThumbRect, mThumbCenterColor.get() % opacity, FALSE); } + else if (hoverSldrIt != mThumbRects.end()) + { + gl_rect_2d(hoverSldrIt->second, mThumbCenterSelectedColor.get(), TRUE); + } } else { @@ -729,20 +761,35 @@ void LLMultiSlider::draw() } // draw the highlight - if (hasFocus() && !mCurSlider.empty()) + if (hasFocus()) { - if (mThumbImagep) + if (!mCurSlider.empty()) { - mThumbImagep->drawBorder(mThumbRects[mCurSlider], mThumbHighlightColor, gFocusMgr.getFocusFlashWidth()); - } - else - { - thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + if (mThumbImagep) + { + mThumbImagep->drawBorder(mThumbRects[mCurSlider], mThumbHighlightColor, gFocusMgr.getFocusFlashWidth()); + } + else + { + thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + } } } + if (!mHoverSlider.empty()) + { + if (mThumbImagep) + { + mThumbImagep->drawBorder(mThumbRects[mHoverSlider], mThumbHighlightColor, gFocusMgr.getFocusFlashWidth()); + } + else + { + thumb_imagep->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); + } + } // draw the thumbs curSldrIt = mThumbRects.end(); + hoverSldrIt = mThumbRects.end(); for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { // choose the color @@ -753,6 +800,12 @@ void LLMultiSlider::draw() curSldrIt = mIt; continue; } + if (mIt->first == mHoverSlider && getEnabled() && gFocusMgr.getMouseCapture() != this) + { + // don't draw now, draw last, after current one + hoverSldrIt = mIt; + continue; + } // the draw command if (mThumbImagep) @@ -776,7 +829,7 @@ void LLMultiSlider::draw() } } - // draw cur slider last + // draw cur and hover slider last if(curSldrIt != mThumbRects.end()) { if (mThumbImagep) @@ -799,6 +852,17 @@ void LLMultiSlider::draw() thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity); } } + if(hoverSldrIt != mThumbRects.end()) + { + if (mThumbImagep) + { + mThumbImagep->draw(hoverSldrIt->second); + } + else + { + thumb_imagep->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get()); + } + } } LLF32UICtrl::draw(); diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index b0fca2597d..b85eec1e61 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -110,6 +110,7 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override; /*virtual*/ void draw(); S32 getMaxNumSliders() { return mMaxNumSliders; } @@ -121,6 +122,7 @@ public: protected: LLSD mValue; std::string mCurSlider; + std::string mHoverSlider; static S32 mNameCounter; S32 mMaxNumSliders; -- cgit v1.2.3 From 7469fdba800e9a5d282ddc16f034aca71a2e8764 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 31 Jan 2019 20:25:56 +0200 Subject: SL-1531 Mac build fix --- indra/llui/llmultislider.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index b85eec1e61..20c3437ec4 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -92,8 +92,8 @@ public: void resetCurSlider(); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); } - /*virtual*/ void setValue(const LLSD& value); - /*virtual*/ LLSD getValue() const { return mValue; } + /*virtual*/ void setValue(const LLSD& value) override; + /*virtual*/ LLSD getValue() const override { return mValue; } boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ); boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); @@ -104,14 +104,14 @@ public: bool addSlider(F32 val, const std::string& name); void deleteSlider(const std::string& name); void deleteCurSlider() { deleteSlider(mCurSlider); } - void clear(); + /*virtual*/ void clear() override; - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask) override; /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override; - /*virtual*/ void draw(); + /*virtual*/ void draw() override; S32 getMaxNumSliders() { return mMaxNumSliders; } S32 getCurNumSliders() { return mValue.size(); } -- cgit v1.2.3 From b7a1b499fd03bd6bfaef37dbdaa9db734dc293b5 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 1 Feb 2019 15:03:02 +0200 Subject: SL-1531 Hover highlight should be consistent with mouse selection --- indra/llui/llmultislider.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index b8f0a01b86..fbe0d3f065 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -507,17 +507,14 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) { if (getEnabled()) { - if (mHoverSlider.empty() || !getSliderThumbRect(mHoverSlider).pointInRect(x, y)) + mHoverSlider.clear(); + std::map::iterator mIt = mThumbRects.begin(); + for (; mIt != mThumbRects.end(); mIt++) { - mHoverSlider.clear(); - std::map::iterator mIt = mThumbRects.begin(); - for (; mIt != mThumbRects.end(); mIt++) + if (mIt->second.pointInRect(x, y)) { - if (mIt->second.pointInRect(x, y)) - { - mHoverSlider = mIt->first; - break; - } + mHoverSlider = mIt->first; + break; } } } -- cgit v1.2.3 From c8d8414b3b2e83fbaffd6e48f55ca14a3cb27ca4 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 8 Feb 2019 19:06:20 +0200 Subject: SL-10509 EEP Settings Picker gets closed by drag&drop --- indra/llui/llfolderview.cpp | 2 ++ indra/llui/llfolderview.h | 3 +++ indra/llui/llfolderviewitem.cpp | 1 + 3 files changed, 6 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 9d0f4b6db1..e38c5c1ef3 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -148,6 +148,7 @@ LLFolderView::Params::Params() : title("title"), use_label_suffix("use_label_suffix"), allow_multiselect("allow_multiselect", true), + allow_drag("allow_drag", true), show_empty_message("show_empty_message", true), suppress_folder_menu("suppress_folder_menu", false), use_ellipses("use_ellipses", false), @@ -163,6 +164,7 @@ LLFolderView::LLFolderView(const Params& p) mScrollContainer( NULL ), mPopupMenuHandle(), mAllowMultiSelect(p.allow_multiselect), + mAllowDrag(p.allow_drag), mShowEmptyMessage(p.show_empty_message), mShowFolderHierarchy(FALSE), mRenameItem( NULL ), diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 69824992c1..6bb5e6c02e 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -90,6 +90,7 @@ public: Optional title; Optional use_label_suffix, allow_multiselect, + allow_drag, show_empty_message, use_ellipses, show_item_link_overlays, @@ -124,6 +125,7 @@ public: void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } bool getAllowMultiSelect() { return mAllowMultiSelect; } + bool getAllowDrag() { return mAllowDrag; } // Close all folders in the view void closeAllFolders(); @@ -274,6 +276,7 @@ protected: selected_items_t mSelectedItems; bool mKeyboardSelection, mAllowMultiSelect, + mAllowDrag, mShowEmptyMessage, mShowFolderHierarchy, mNeedsScroll, diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 0510e472c5..341399e980 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -557,6 +557,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) LLFolderView* root = getRoot(); if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold() + && root->getAllowDrag() && root->getCurSelectedItem() && root->startDrag()) { -- cgit v1.2.3 From 3e560022459bf3534b873a7f6499dfb5eb75a7d9 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 11 Mar 2019 08:11:09 -0700 Subject: Tabs -> spaces. --- indra/llui/llfloater.cpp | 5446 +++++++++++++++++----------------- indra/llui/lluictrl.h | 518 ++-- indra/llui/tests/llurlentry_stub.cpp | 128 +- 3 files changed, 3046 insertions(+), 3046 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 2dcc62ce79..6b325f6232 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -43,7 +43,7 @@ #include "llresizebar.h" #include "llresizehandle.h" #include "llkeyboard.h" -#include "llmenugl.h" // MENU_BAR_HEIGHT +#include "llmenugl.h" // MENU_BAR_HEIGHT #include "llmodaldialog.h" #include "lltextbox.h" #include "llresmgr.h" @@ -65,23 +65,23 @@ const S32 TABBED_FLOATER_OFFSET = 0; namespace LLInitParam { - void TypeValues::declareValues() - { - declare("relative", LLFloaterEnums::POSITIONING_RELATIVE); - declare("cascading", LLFloaterEnums::POSITIONING_CASCADING); - declare("centered", LLFloaterEnums::POSITIONING_CENTERED); - declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED); - } + void TypeValues::declareValues() + { + declare("relative", LLFloaterEnums::POSITIONING_RELATIVE); + declare("cascading", LLFloaterEnums::POSITIONING_CASCADING); + declare("centered", LLFloaterEnums::POSITIONING_CENTERED); + declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED); + } } -std::string LLFloater::sButtonNames[BUTTON_COUNT] = +std::string LLFloater::sButtonNames[BUTTON_COUNT] = { - "llfloater_close_btn", //BUTTON_CLOSE - "llfloater_restore_btn", //BUTTON_RESTORE - "llfloater_minimize_btn", //BUTTON_MINIMIZE - "llfloater_tear_off_btn", //BUTTON_TEAR_OFF - "llfloater_dock_btn", //BUTTON_DOCK - "llfloater_help_btn" //BUTTON_HELP + "llfloater_close_btn", //BUTTON_CLOSE + "llfloater_restore_btn", //BUTTON_RESTORE + "llfloater_minimize_btn", //BUTTON_MINIMIZE + "llfloater_tear_off_btn", //BUTTON_TEAR_OFF + "llfloater_dock_btn", //BUTTON_DOCK + "llfloater_help_btn" //BUTTON_HELP }; std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; @@ -89,29 +89,29 @@ std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= { #ifdef LL_DARWIN - "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE #else - "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE #endif - "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE - "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE - "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF - "BUTTON_DOCK", - "BUTTON_HELP" + "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE + "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE + "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF + "BUTTON_DOCK", + "BUTTON_HELP" }; LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = { - LLFloater::onClickClose, //BUTTON_CLOSE - LLFloater::onClickMinimize, //BUTTON_RESTORE - LLFloater::onClickMinimize, //BUTTON_MINIMIZE - LLFloater::onClickTearOff, //BUTTON_TEAR_OFF - LLFloater::onClickDock, //BUTTON_DOCK - LLFloater::onClickHelp //BUTTON_HELP + LLFloater::onClickClose, //BUTTON_CLOSE + LLFloater::onClickMinimize, //BUTTON_RESTORE + LLFloater::onClickMinimize, //BUTTON_MINIMIZE + LLFloater::onClickTearOff, //BUTTON_TEAR_OFF + LLFloater::onClickDock, //BUTTON_DOCK + LLFloater::onClickHelp //BUTTON_HELP }; LLMultiFloater* LLFloater::sHostp = NULL; -BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting +BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting LLFloaterView* gFloaterView = NULL; @@ -128,105 +128,105 @@ LLFloaterView* gFloaterView = NULL; //static bool LLFloater::KeyCompare::compare(const LLSD& a, const LLSD& b) { - if (a.type() != b.type()) - { - //LL_ERRS() << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << LL_ENDL; - return false; - } - else if (a.isUndefined()) - return false; - else if (a.isInteger()) - return a.asInteger() < b.asInteger(); - else if (a.isReal()) - return a.asReal() < b.asReal(); - else if (a.isString()) - return a.asString() < b.asString(); - else if (a.isUUID()) - return a.asUUID() < b.asUUID(); - else if (a.isDate()) - return a.asDate() < b.asDate(); - else if (a.isURI()) - return a.asString() < b.asString(); // compare URIs as strings - else if (a.isBoolean()) - return a.asBoolean() < b.asBoolean(); - else - return false; // no valid operation for Binary + if (a.type() != b.type()) + { + //LL_ERRS() << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << LL_ENDL; + return false; + } + else if (a.isUndefined()) + return false; + else if (a.isInteger()) + return a.asInteger() < b.asInteger(); + else if (a.isReal()) + return a.asReal() < b.asReal(); + else if (a.isString()) + return a.asString() < b.asString(); + else if (a.isUUID()) + return a.asUUID() < b.asUUID(); + else if (a.isDate()) + return a.asDate() < b.asDate(); + else if (a.isURI()) + return a.asString() < b.asString(); // compare URIs as strings + else if (a.isBoolean()) + return a.asBoolean() < b.asBoolean(); + else + return false; // no valid operation for Binary } |*==========================================================================*/ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) { - return llsd_equals(a, b); + return llsd_equals(a, b); } //************************************ LLFloater::Params::Params() -: title("title"), - short_title("short_title"), - single_instance("single_instance", false), - reuse_instance("reuse_instance", false), - can_resize("can_resize", false), - can_minimize("can_minimize", true), - can_close("can_close", true), - can_drag_on_left("can_drag_on_left", false), - can_tear_off("can_tear_off", true), - save_dock_state("save_dock_state", false), - save_rect("save_rect", false), - save_visibility("save_visibility", false), - can_dock("can_dock", false), - show_title("show_title", true), - positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), - header_height("header_height", 0), - legacy_header_height("legacy_header_height", 0), - close_image("close_image"), - restore_image("restore_image"), - minimize_image("minimize_image"), - tear_off_image("tear_off_image"), - dock_image("dock_image"), - help_image("help_image"), - close_pressed_image("close_pressed_image"), - restore_pressed_image("restore_pressed_image"), - minimize_pressed_image("minimize_pressed_image"), - tear_off_pressed_image("tear_off_pressed_image"), - dock_pressed_image("dock_pressed_image"), - help_pressed_image("help_pressed_image"), - open_callback("open_callback"), - close_callback("close_callback"), - follows("follows") -{ - changeDefault(visible, false); +: title("title"), + short_title("short_title"), + single_instance("single_instance", false), + reuse_instance("reuse_instance", false), + can_resize("can_resize", false), + can_minimize("can_minimize", true), + can_close("can_close", true), + can_drag_on_left("can_drag_on_left", false), + can_tear_off("can_tear_off", true), + save_dock_state("save_dock_state", false), + save_rect("save_rect", false), + save_visibility("save_visibility", false), + can_dock("can_dock", false), + show_title("show_title", true), + positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), + header_height("header_height", 0), + legacy_header_height("legacy_header_height", 0), + close_image("close_image"), + restore_image("restore_image"), + minimize_image("minimize_image"), + tear_off_image("tear_off_image"), + dock_image("dock_image"), + help_image("help_image"), + close_pressed_image("close_pressed_image"), + restore_pressed_image("restore_pressed_image"), + minimize_pressed_image("minimize_pressed_image"), + tear_off_pressed_image("tear_off_pressed_image"), + dock_pressed_image("dock_pressed_image"), + help_pressed_image("help_pressed_image"), + open_callback("open_callback"), + close_callback("close_callback"), + follows("follows") +{ + changeDefault(visible, false); } //static const LLFloater::Params& LLFloater::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } //static void LLFloater::initClass() { - // translate tooltips for floater buttons - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); - } + // translate tooltips for floater buttons + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); + } - LLControlVariable* ctrl = LLUI::sSettingGroups["config"]->getControl("ActiveFloaterTransparency").get(); - if (ctrl) - { - ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency)); - updateActiveFloaterTransparency(); - } + LLControlVariable* ctrl = LLUI::sSettingGroups["config"]->getControl("ActiveFloaterTransparency").get(); + if (ctrl) + { + ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency)); + updateActiveFloaterTransparency(); + } - ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get(); - if (ctrl) - { - ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency)); - updateInactiveFloaterTransparency(); - } + ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get(); + if (ctrl) + { + ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency)); + updateInactiveFloaterTransparency(); + } } @@ -234,1998 +234,1998 @@ void LLFloater::initClass() static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) -: LLPanel(), // intentionally do not pass params here, see initFromParams - mDragHandle(NULL), - mTitle(p.title), - mShortTitle(p.short_title), - mSingleInstance(p.single_instance), - mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default - mKey(key), - mCanTearOff(p.can_tear_off), - mCanMinimize(p.can_minimize), - mCanClose(p.can_close), - mDragOnLeft(p.can_drag_on_left), - mResizable(p.can_resize), - mPositioning(p.positioning), - mMinWidth(p.min_width), - mMinHeight(p.min_height), - mHeaderHeight(p.header_height), - mLegacyHeaderHeight(p.legacy_header_height), - mMinimized(FALSE), - mForeground(FALSE), - mFirstLook(TRUE), - mButtonScale(1.0f), - mAutoFocus(TRUE), // automatically take focus when opened - mCanDock(false), - mDocked(false), - mTornOff(false), - mHasBeenDraggedWhileMinimized(FALSE), - mPreviousMinimizedBottom(0), - mPreviousMinimizedLeft(0), - mMinimizeSignal(NULL) -// mNotificationContext(NULL) -{ - mPosition.setFloater(*this); -// mNotificationContext = new LLFloaterNotificationContext(getHandle()); - - // Clicks stop here. - setMouseOpaque(TRUE); - - // Floaters always draw their background, unlike every other panel. - setBackgroundVisible(TRUE); - - // Floaters start not minimized. When minimized, they save their - // prior rectangle to be used on restore. - mExpandedRect.set(0,0,0,0); - - memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool)); - memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*)); - - addDragHandle(); - addResizeCtrls(); - - initFromParams(p); - - initFloater(p); +: LLPanel(), // intentionally do not pass params here, see initFromParams + mDragHandle(NULL), + mTitle(p.title), + mShortTitle(p.short_title), + mSingleInstance(p.single_instance), + mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default + mKey(key), + mCanTearOff(p.can_tear_off), + mCanMinimize(p.can_minimize), + mCanClose(p.can_close), + mDragOnLeft(p.can_drag_on_left), + mResizable(p.can_resize), + mPositioning(p.positioning), + mMinWidth(p.min_width), + mMinHeight(p.min_height), + mHeaderHeight(p.header_height), + mLegacyHeaderHeight(p.legacy_header_height), + mMinimized(FALSE), + mForeground(FALSE), + mFirstLook(TRUE), + mButtonScale(1.0f), + mAutoFocus(TRUE), // automatically take focus when opened + mCanDock(false), + mDocked(false), + mTornOff(false), + mHasBeenDraggedWhileMinimized(FALSE), + mPreviousMinimizedBottom(0), + mPreviousMinimizedLeft(0), + mMinimizeSignal(NULL) +// mNotificationContext(NULL) +{ + mPosition.setFloater(*this); +// mNotificationContext = new LLFloaterNotificationContext(getHandle()); + + // Clicks stop here. + setMouseOpaque(TRUE); + + // Floaters always draw their background, unlike every other panel. + setBackgroundVisible(TRUE); + + // Floaters start not minimized. When minimized, they save their + // prior rectangle to be used on restore. + mExpandedRect.set(0,0,0,0); + + memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool)); + memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*)); + + addDragHandle(); + addResizeCtrls(); + + initFromParams(p); + + initFloater(p); } // Note: Floaters constructed from XML call init() twice! void LLFloater::initFloater(const Params& p) { - // Close button. - if (mCanClose) - { - mButtonsEnabled[BUTTON_CLOSE] = TRUE; - } + // Close button. + if (mCanClose) + { + mButtonsEnabled[BUTTON_CLOSE] = TRUE; + } - // Help button: '?' - if ( !mHelpTopic.empty() ) - { - mButtonsEnabled[BUTTON_HELP] = TRUE; - } + // Help button: '?' + if ( !mHelpTopic.empty() ) + { + mButtonsEnabled[BUTTON_HELP] = TRUE; + } - // Minimize button only for top draggers - if ( !mDragOnLeft && mCanMinimize ) - { - mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; - } + // Minimize button only for top draggers + if ( !mDragOnLeft && mCanMinimize ) + { + mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; + } - if(mCanDock) - { - mButtonsEnabled[BUTTON_DOCK] = TRUE; - } + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = TRUE; + } - buildButtons(p); + buildButtons(p); - // Floaters are created in the invisible state - setVisible(FALSE); + // Floaters are created in the invisible state + setVisible(FALSE); - if (!getParent()) - { - gFloaterView->addChild(this); - } + if (!getParent()) + { + gFloaterView->addChild(this); + } } void LLFloater::addDragHandle() { - if (!mDragHandle) - { - if (mDragOnLeft) - { - LLDragHandleLeft::Params p; - p.name("drag"); - p.follows.flags(FOLLOWS_ALL); - p.label(mTitle); - mDragHandle = LLUICtrlFactory::create(p); - } - else // drag on top - { - LLDragHandleTop::Params p; - p.name("Drag Handle"); - p.follows.flags(FOLLOWS_ALL); - p.label(mTitle); - mDragHandle = LLUICtrlFactory::create(p); - } - addChild(mDragHandle); - } - layoutDragHandle(); - applyTitle(); + if (!mDragHandle) + { + if (mDragOnLeft) + { + LLDragHandleLeft::Params p; + p.name("drag"); + p.follows.flags(FOLLOWS_ALL); + p.label(mTitle); + mDragHandle = LLUICtrlFactory::create(p); + } + else // drag on top + { + LLDragHandleTop::Params p; + p.name("Drag Handle"); + p.follows.flags(FOLLOWS_ALL); + p.label(mTitle); + mDragHandle = LLUICtrlFactory::create(p); + } + addChild(mDragHandle); + } + layoutDragHandle(); + applyTitle(); } void LLFloater::layoutDragHandle() { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - S32 close_box_size = mCanClose ? floater_close_box_size : 0; - - LLRect rect; - if (mDragOnLeft) - { - rect.setLeftTopAndSize(0, 0, DRAG_HANDLE_WIDTH, getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); - } - else // drag on top - { - rect = getLocalRect(); - } - mDragHandle->setShape(rect); - updateTitleButtons(); + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + S32 close_box_size = mCanClose ? floater_close_box_size : 0; + + LLRect rect; + if (mDragOnLeft) + { + rect.setLeftTopAndSize(0, 0, DRAG_HANDLE_WIDTH, getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); + } + else // drag on top + { + rect = getLocalRect(); + } + mDragHandle->setShape(rect); + updateTitleButtons(); } // static void LLFloater::updateActiveFloaterTransparency() { - sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency"); + sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency"); } // static void LLFloater::updateInactiveFloaterTransparency() { - sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency"); + sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency"); } void LLFloater::addResizeCtrls() -{ - // Resize bars (sides) - LLResizeBar::Params p; - p.name("resizebar_left"); - p.resizing_view(this); - p.min_size(mMinWidth); - p.side(LLResizeBar::LEFT); - mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::LEFT] ); - - p.name("resizebar_top"); - p.min_size(mMinHeight); - p.side(LLResizeBar::TOP); - - mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::TOP] ); - - p.name("resizebar_right"); - p.min_size(mMinWidth); - p.side(LLResizeBar::RIGHT); - mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::RIGHT] ); - - p.name("resizebar_bottom"); - p.min_size(mMinHeight); - p.side(LLResizeBar::BOTTOM); - mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::BOTTOM] ); - - // Resize handles (corners) - LLResizeHandle::Params handle_p; - // handles must not be mouse-opaque, otherwise they block hover events - // to other buttons like the close box. JC - handle_p.mouse_opaque(false); - handle_p.min_width(mMinWidth); - handle_p.min_height(mMinHeight); - handle_p.corner(LLResizeHandle::RIGHT_BOTTOM); - mResizeHandle[0] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[0]); - - handle_p.corner(LLResizeHandle::RIGHT_TOP); - mResizeHandle[1] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[1]); - - handle_p.corner(LLResizeHandle::LEFT_BOTTOM); - mResizeHandle[2] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[2]); - - handle_p.corner(LLResizeHandle::LEFT_TOP); - mResizeHandle[3] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[3]); - - layoutResizeCtrls(); +{ + // Resize bars (sides) + LLResizeBar::Params p; + p.name("resizebar_left"); + p.resizing_view(this); + p.min_size(mMinWidth); + p.side(LLResizeBar::LEFT); + mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::LEFT] ); + + p.name("resizebar_top"); + p.min_size(mMinHeight); + p.side(LLResizeBar::TOP); + + mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::TOP] ); + + p.name("resizebar_right"); + p.min_size(mMinWidth); + p.side(LLResizeBar::RIGHT); + mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::RIGHT] ); + + p.name("resizebar_bottom"); + p.min_size(mMinHeight); + p.side(LLResizeBar::BOTTOM); + mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::BOTTOM] ); + + // Resize handles (corners) + LLResizeHandle::Params handle_p; + // handles must not be mouse-opaque, otherwise they block hover events + // to other buttons like the close box. JC + handle_p.mouse_opaque(false); + handle_p.min_width(mMinWidth); + handle_p.min_height(mMinHeight); + handle_p.corner(LLResizeHandle::RIGHT_BOTTOM); + mResizeHandle[0] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[0]); + + handle_p.corner(LLResizeHandle::RIGHT_TOP); + mResizeHandle[1] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[1]); + + handle_p.corner(LLResizeHandle::LEFT_BOTTOM); + mResizeHandle[2] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[2]); + + handle_p.corner(LLResizeHandle::LEFT_TOP); + mResizeHandle[3] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[3]); + + layoutResizeCtrls(); } void LLFloater::layoutResizeCtrls() { - LLRect rect; + LLRect rect; - // Resize bars (sides) - const S32 RESIZE_BAR_THICKNESS = 3; - rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0); - mResizeBar[LLResizeBar::LEFT]->setRect(rect); + // Resize bars (sides) + const S32 RESIZE_BAR_THICKNESS = 3; + rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0); + mResizeBar[LLResizeBar::LEFT]->setRect(rect); - rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS); - mResizeBar[LLResizeBar::TOP]->setRect(rect); + rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS); + mResizeBar[LLResizeBar::TOP]->setRect(rect); - rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0); - mResizeBar[LLResizeBar::RIGHT]->setRect(rect); + rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0); + mResizeBar[LLResizeBar::RIGHT]->setRect(rect); - rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0); - mResizeBar[LLResizeBar::BOTTOM]->setRect(rect); + rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0); + mResizeBar[LLResizeBar::BOTTOM]->setRect(rect); - // Resize handles (corners) - rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0); - mResizeHandle[0]->setRect(rect); + // Resize handles (corners) + rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0); + mResizeHandle[0]->setRect(rect); - rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT); - mResizeHandle[1]->setRect(rect); - - rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ); - mResizeHandle[2]->setRect(rect); + rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT); + mResizeHandle[1]->setRect(rect); + + rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ); + mResizeHandle[2]->setRect(rect); - rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ); - mResizeHandle[3]->setRect(rect); + rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ); + mResizeHandle[3]->setRect(rect); } void LLFloater::enableResizeCtrls(bool enable, bool width, bool height) { - mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width); - mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width); + mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width); + mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width); - mResizeBar[LLResizeBar::TOP]->setVisible(enable && height); - mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height); - - mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width); - mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width); - - mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height); - mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height); + mResizeBar[LLResizeBar::TOP]->setVisible(enable && height); + mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height); + + mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width); + mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width); + + mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height); + mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height); - for (S32 i = 0; i < 4; ++i) - { - mResizeHandle[i]->setVisible(enable && width && height); - mResizeHandle[i]->setEnabled(enable && width && height); - } + for (S32 i = 0; i < 4; ++i) + { + mResizeHandle[i]->setVisible(enable && width && height); + mResizeHandle[i]->setEnabled(enable && width && height); + } } void LLFloater::destroy() { - // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before - // it was deleted via LLMortician::updateClass(). See EXT-8458. - LLFloaterReg::removeInstance(mInstanceName, mKey); - die(); + // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before + // it was deleted via LLMortician::updateClass(). See EXT-8458. + LLFloaterReg::removeInstance(mInstanceName, mKey); + die(); } // virtual LLFloater::~LLFloater() { - LLFloaterReg::removeInstance(mInstanceName, mKey); - - if( gFocusMgr.childHasKeyboardFocus(this)) - { - // Just in case we might still have focus here, release it. - releaseFocus(); - } - - // This is important so that floaters with persistent rects (i.e., those - // created with rect control rather than an LLRect) are restored in their - // correct, non-minimized positions. - setMinimized( FALSE ); - - delete mDragHandle; - for (S32 i = 0; i < 4; i++) - { - delete mResizeBar[i]; - delete mResizeHandle[i]; - } - - setVisible(false); // We're not visible if we're destroyed - storeVisibilityControl(); - storeDockStateControl(); - delete mMinimizeSignal; + LLFloaterReg::removeInstance(mInstanceName, mKey); + + if( gFocusMgr.childHasKeyboardFocus(this)) + { + // Just in case we might still have focus here, release it. + releaseFocus(); + } + + // This is important so that floaters with persistent rects (i.e., those + // created with rect control rather than an LLRect) are restored in their + // correct, non-minimized positions. + setMinimized( FALSE ); + + delete mDragHandle; + for (S32 i = 0; i < 4; i++) + { + delete mResizeBar[i]; + delete mResizeHandle[i]; + } + + setVisible(false); // We're not visible if we're destroyed + storeVisibilityControl(); + storeDockStateControl(); + delete mMinimizeSignal; } void LLFloater::storeRectControl() { - if (!mRectControl.empty()) - { - getControlGroup()->setRect( mRectControl, getRect() ); - } - if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) - { - getControlGroup()->setF32( mPosXControl, mPosition.mX ); - } - if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) - { - getControlGroup()->setF32( mPosYControl, mPosition.mY ); - } + if (!mRectControl.empty()) + { + getControlGroup()->setRect( mRectControl, getRect() ); + } + if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) + { + getControlGroup()->setF32( mPosXControl, mPosition.mX ); + } + if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) + { + getControlGroup()->setF32( mPosYControl, mPosition.mY ); + } } void LLFloater::storeVisibilityControl() { - if( !sQuitting && mVisibilityControl.size() > 1 ) - { - getControlGroup()->setBOOL( mVisibilityControl, getVisible() ); - } + if( !sQuitting && mVisibilityControl.size() > 1 ) + { + getControlGroup()->setBOOL( mVisibilityControl, getVisible() ); + } } void LLFloater::storeDockStateControl() { - if( !sQuitting && mDocStateControl.size() > 1 ) - { - getControlGroup()->setBOOL( mDocStateControl, isDocked() ); - } + if( !sQuitting && mDocStateControl.size() > 1 ) + { + getControlGroup()->setBOOL( mDocStateControl, isDocked() ); + } } // static std::string LLFloater::getControlName(const std::string& name, const LLSD& key) { - std::string ctrl_name = name; + std::string ctrl_name = name; - // Add the key to the control name if appropriate. - if (key.isString() && !key.asString().empty()) - { - ctrl_name += "_" + key.asString(); - } + // Add the key to the control name if appropriate. + if (key.isString() && !key.asString().empty()) + { + ctrl_name += "_" + key.asString(); + } - return ctrl_name; + return ctrl_name; } // static -LLControlGroup* LLFloater::getControlGroup() +LLControlGroup* LLFloater::getControlGroup() { - // Floater size, position, visibility, etc are saved in per-account settings. - return LLUI::sSettingGroups["account"]; + // Floater size, position, visibility, etc are saved in per-account settings. + return LLUI::sSettingGroups["account"]; } void LLFloater::setVisible( BOOL visible ) { - LLPanel::setVisible(visible); // calls onVisibilityChange() - if( visible && mFirstLook ) - { - mFirstLook = FALSE; - } + LLPanel::setVisible(visible); // calls onVisibilityChange() + if( visible && mFirstLook ) + { + mFirstLook = FALSE; + } - if( !visible ) - { - LLUI::removePopup(this); + if( !visible ) + { + LLUI::removePopup(this); - if( gFocusMgr.childHasMouseCapture( this ) ) - { - gFocusMgr.setMouseCapture(NULL); - } - } + if( gFocusMgr.childHasMouseCapture( this ) ) + { + gFocusMgr.setMouseCapture(NULL); + } + } - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - LLFloater* floaterp = dependent_it->get(); + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - floaterp->setVisible(visible); - } - ++dependent_it; - } + if (floaterp) + { + floaterp->setVisible(visible); + } + ++dependent_it; + } - storeVisibilityControl(); + storeVisibilityControl(); } void LLFloater::setIsSingleInstance(BOOL is_single_instance) { - mSingleInstance = is_single_instance; - if (!mIsReuseInitialized) - { - mReuseInstance = is_single_instance; // reuse single-instance floaters by default - } + mSingleInstance = is_single_instance; + if (!mIsReuseInitialized) + { + mReuseInstance = is_single_instance; // reuse single-instance floaters by default + } } // virtual void LLFloater::onVisibilityChange ( BOOL new_visibility ) { - if (new_visibility) - { - if (getHost()) - getHost()->setFloaterFlashing(this, FALSE); - } - LLPanel::onVisibilityChange ( new_visibility ); + if (new_visibility) + { + if (getHost()) + getHost()->setFloaterFlashing(this, FALSE); + } + LLPanel::onVisibilityChange ( new_visibility ); } void LLFloater::openFloater(const LLSD& key) { LL_INFOS() << "Opening floater " << getName() << " full path: " << getPathname() << LL_ENDL; - LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string - - mKey = key; // in case we need to open ourselves again - - if (getSoundFlags() != SILENT - // don't play open sound for hosted (tabbed) windows - && !getHost() - && !getFloaterHost() - && (!getVisible() || isMinimized())) - { - make_ui_sound("UISndWindowOpen"); - } - - //RN: for now, we don't allow rehosting from one multifloater to another - // just need to fix the bugs - if (getFloaterHost() != NULL && getHost() == NULL) - { - // needs a host - // only select tabs if window they are hosted in is visible - getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); - } - - if (getHost() != NULL) - { - getHost()->setMinimized(FALSE); - getHost()->setVisibleAndFrontmost(mAutoFocus); - getHost()->showFloater(this); - } - else - { - LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName); - if (!floater_to_stack) - { - floater_to_stack = LLFloaterReg::getLastFloaterCascading(); - } - applyControlsAndPosition(floater_to_stack); - setMinimized(FALSE); - setVisibleAndFrontmost(mAutoFocus); - } - - mOpenSignal(this, key); - onOpen(key); - - dirtyRect(); + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string + + mKey = key; // in case we need to open ourselves again + + if (getSoundFlags() != SILENT + // don't play open sound for hosted (tabbed) windows + && !getHost() + && !getFloaterHost() + && (!getVisible() || isMinimized())) + { + make_ui_sound("UISndWindowOpen"); + } + + //RN: for now, we don't allow rehosting from one multifloater to another + // just need to fix the bugs + if (getFloaterHost() != NULL && getHost() == NULL) + { + // needs a host + // only select tabs if window they are hosted in is visible + getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); + } + + if (getHost() != NULL) + { + getHost()->setMinimized(FALSE); + getHost()->setVisibleAndFrontmost(mAutoFocus); + getHost()->showFloater(this); + } + else + { + LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName); + if (!floater_to_stack) + { + floater_to_stack = LLFloaterReg::getLastFloaterCascading(); + } + applyControlsAndPosition(floater_to_stack); + setMinimized(FALSE); + setVisibleAndFrontmost(mAutoFocus); + } + + mOpenSignal(this, key); + onOpen(key); + + dirtyRect(); } void LLFloater::closeFloater(bool app_quitting) { - LL_INFOS() << "Closing floater " << getName() << LL_ENDL; - LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string - if (app_quitting) - { - LLFloater::sQuitting = true; - } - - // Always unminimize before trying to close. - // Most of the time the user will never see this state. - setMinimized(FALSE); - - if (canClose()) - { - if (getHost()) - { - ((LLMultiFloater*)getHost())->removeFloater(this); - gFloaterView->addChild(this); - } - - if (getSoundFlags() != SILENT - && getVisible() - && !getHost() - && !app_quitting) - { - make_ui_sound("UISndWindowClose"); - } - - gFocusMgr.clearLastFocusForGroup(this); - - if (hasFocus()) - { - // Do this early, so UI controls will commit before the - // window is taken down. - releaseFocus(); - - // give focus to dependee floater if it exists, and we had focus first - if (isDependent()) - { - LLFloater* dependee = mDependeeHandle.get(); - if (dependee && !dependee->isDead()) - { - dependee->setFocus(TRUE); - } - } - } - - - //If floater is a dependent, remove it from parent (dependee) + LL_INFOS() << "Closing floater " << getName() << LL_ENDL; + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string + if (app_quitting) + { + LLFloater::sQuitting = true; + } + + // Always unminimize before trying to close. + // Most of the time the user will never see this state. + setMinimized(FALSE); + + if (canClose()) + { + if (getHost()) + { + ((LLMultiFloater*)getHost())->removeFloater(this); + gFloaterView->addChild(this); + } + + if (getSoundFlags() != SILENT + && getVisible() + && !getHost() + && !app_quitting) + { + make_ui_sound("UISndWindowClose"); + } + + gFocusMgr.clearLastFocusForGroup(this); + + if (hasFocus()) + { + // Do this early, so UI controls will commit before the + // window is taken down. + releaseFocus(); + + // give focus to dependee floater if it exists, and we had focus first + if (isDependent()) + { + LLFloater* dependee = mDependeeHandle.get(); + if (dependee && !dependee->isDead()) + { + dependee->setFocus(TRUE); + } + } + } + + + //If floater is a dependent, remove it from parent (dependee) LLFloater* dependee = mDependeeHandle.get(); if (dependee) { dependee->removeDependentFloater(this); } - // now close dependent floater - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - ++dependent_it; - floaterp->closeFloater(app_quitting); - } - else - { - mDependents.erase(dependent_it++); - } - } - - cleanupHandles(); - - dirtyRect(); - - // Close callbacks - onClose(app_quitting); - mCloseSignal(this, LLSD(app_quitting)); - - // Hide or Destroy - if (mSingleInstance) - { - // Hide the instance - if (getHost()) - { - getHost()->setVisible(FALSE); - } - else - { - setVisible(FALSE); - if (!mReuseInstance) - { - destroy(); - } - } - } - else - { - setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called) - if (!mReuseInstance) - { - destroy(); - } - } - } + // now close dependent floater + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + ++dependent_it; + floaterp->closeFloater(app_quitting); + } + else + { + mDependents.erase(dependent_it++); + } + } + + cleanupHandles(); + + dirtyRect(); + + // Close callbacks + onClose(app_quitting); + mCloseSignal(this, LLSD(app_quitting)); + + // Hide or Destroy + if (mSingleInstance) + { + // Hide the instance + if (getHost()) + { + getHost()->setVisible(FALSE); + } + else + { + setVisible(FALSE); + if (!mReuseInstance) + { + destroy(); + } + } + } + else + { + setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called) + if (!mReuseInstance) + { + destroy(); + } + } + } } /*virtual*/ void LLFloater::closeHostedFloater() { - // When toggling *visibility*, close the host instead of the floater when hosted - if (getHost()) - { - getHost()->closeFloater(); - } - else - { - closeFloater(); - } + // When toggling *visibility*, close the host instead of the floater when hosted + if (getHost()) + { + getHost()->closeFloater(); + } + else + { + closeFloater(); + } } /*virtual*/ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent) { - LLPanel::reshape(width, height, called_from_parent); + LLPanel::reshape(width, height, called_from_parent); } void LLFloater::releaseFocus() { - LLUI::removePopup(this); + LLUI::removePopup(this); - setFocus(FALSE); + setFocus(FALSE); - if( gFocusMgr.childHasMouseCapture( this ) ) - { - gFocusMgr.setMouseCapture(NULL); - } + if( gFocusMgr.childHasMouseCapture( this ) ) + { + gFocusMgr.setMouseCapture(NULL); + } } void LLFloater::setResizeLimits( S32 min_width, S32 min_height ) { - mMinWidth = min_width; - mMinHeight = min_height; - - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeBar[i] ) - { - if (i == LLResizeBar::LEFT || i == LLResizeBar::RIGHT) - { - mResizeBar[i]->setResizeLimits( min_width, S32_MAX ); - } - else - { - mResizeBar[i]->setResizeLimits( min_height, S32_MAX ); - } - } - if( mResizeHandle[i] ) - { - mResizeHandle[i]->setResizeLimits( min_width, min_height ); - } - } + mMinWidth = min_width; + mMinHeight = min_height; + + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeBar[i] ) + { + if (i == LLResizeBar::LEFT || i == LLResizeBar::RIGHT) + { + mResizeBar[i]->setResizeLimits( min_width, S32_MAX ); + } + else + { + mResizeBar[i]->setResizeLimits( min_height, S32_MAX ); + } + } + if( mResizeHandle[i] ) + { + mResizeHandle[i]->setResizeLimits( min_width, min_height ); + } + } } void LLFloater::center() { - if(getHost()) - { - // hosted floaters can't move - return; - } - centerWithin(gFloaterView->getRect()); + if(getHost()) + { + // hosted floaters can't move + return; + } + centerWithin(gFloaterView->getRect()); } LLMultiFloater* LLFloater::getHost() { - return (LLMultiFloater*)mHostHandle.get(); + return (LLMultiFloater*)mHostHandle.get(); } void LLFloater::applyControlsAndPosition(LLFloater* other) { - if (!applyDockState()) - { - if (!applyRectControl()) - { - applyPositioning(other, true); - } - } + if (!applyDockState()) + { + if (!applyRectControl()) + { + applyPositioning(other, true); + } + } } bool LLFloater::applyRectControl() { - bool saved_rect = false; - - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - - LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName); - if (last_in_group && last_in_group != this) - { - // other floaters in our group, position ourselves relative to them and don't save the rect - mRectControl.clear(); - mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; - } - else - { - bool rect_specified = false; - if (!mRectControl.empty()) - { - // If we have a saved rect, use it - const LLRect& rect = getControlGroup()->getRect(mRectControl); - if (rect.notEmpty()) saved_rect = true; - if (saved_rect) - { - setOrigin(rect.mLeft, rect.mBottom); - - if (mResizable) - { - reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); - } - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - rect_specified = true; - } - } - - LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl); - LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl); - if (x_control.notNull() - && y_control.notNull() - && !x_control->isDefault() - && !y_control->isDefault()) - { - mPosition.mX = x_control->getValue().asReal(); - mPosition.mY = y_control->getValue().asReal(); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - applyRelativePosition(); - - saved_rect = true; - } - - // remember updated position - if (rect_specified) - { - storeRectControl(); - } - } - - if (saved_rect) - { - // propagate any derived positioning data back to settings file - storeRectControl(); - } - - - return saved_rect; + bool saved_rect = false; + + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + + LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName); + if (last_in_group && last_in_group != this) + { + // other floaters in our group, position ourselves relative to them and don't save the rect + mRectControl.clear(); + mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; + } + else + { + bool rect_specified = false; + if (!mRectControl.empty()) + { + // If we have a saved rect, use it + const LLRect& rect = getControlGroup()->getRect(mRectControl); + if (rect.notEmpty()) saved_rect = true; + if (saved_rect) + { + setOrigin(rect.mLeft, rect.mBottom); + + if (mResizable) + { + reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); + } + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + rect_specified = true; + } + } + + LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl); + LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl); + if (x_control.notNull() + && y_control.notNull() + && !x_control->isDefault() + && !y_control->isDefault()) + { + mPosition.mX = x_control->getValue().asReal(); + mPosition.mY = y_control->getValue().asReal(); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + applyRelativePosition(); + + saved_rect = true; + } + + // remember updated position + if (rect_specified) + { + storeRectControl(); + } + } + + if (saved_rect) + { + // propagate any derived positioning data back to settings file + storeRectControl(); + } + + + return saved_rect; } bool LLFloater::applyDockState() { - bool docked = false; + bool docked = false; - if (mDocStateControl.size() > 1) - { - docked = getControlGroup()->getBOOL(mDocStateControl); - setDocked(docked); - } + if (mDocStateControl.size() > 1) + { + docked = getControlGroup()->getBOOL(mDocStateControl); + setDocked(docked); + } - return docked; + return docked; } void LLFloater::applyPositioning(LLFloater* other, bool on_open) { - // Otherwise position according to the positioning code - switch (mPositioning) - { - case LLFloaterEnums::POSITIONING_CENTERED: - center(); - break; - - case LLFloaterEnums::POSITIONING_SPECIFIED: - break; - - case LLFloaterEnums::POSITIONING_CASCADING: - if (!on_open) - { - applyRelativePosition(); - } - // fall through - case LLFloaterEnums::POSITIONING_CASCADE_GROUP: - if (on_open) - { - if (other != NULL && other != this) - { - stackWith(*other); - } - else - { - static const U32 CASCADING_FLOATER_HOFFSET = 0; - static const U32 CASCADING_FLOATER_VOFFSET = 0; - - const LLRect& snap_rect = gFloaterView->getSnapRect(); - - const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; - const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; - - S32 rect_height = getRect().getHeight(); - setOrigin(horizontal_offset, vertical_offset - rect_height); - - translate(snap_rect.mLeft, snap_rect.mBottom); - } - setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); - } - break; - - case LLFloaterEnums::POSITIONING_RELATIVE: - { - applyRelativePosition(); - - break; - } - default: - // Do nothing - break; - } + // Otherwise position according to the positioning code + switch (mPositioning) + { + case LLFloaterEnums::POSITIONING_CENTERED: + center(); + break; + + case LLFloaterEnums::POSITIONING_SPECIFIED: + break; + + case LLFloaterEnums::POSITIONING_CASCADING: + if (!on_open) + { + applyRelativePosition(); + } + // fall through + case LLFloaterEnums::POSITIONING_CASCADE_GROUP: + if (on_open) + { + if (other != NULL && other != this) + { + stackWith(*other); + } + else + { + static const U32 CASCADING_FLOATER_HOFFSET = 0; + static const U32 CASCADING_FLOATER_VOFFSET = 0; + + const LLRect& snap_rect = gFloaterView->getSnapRect(); + + const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; + const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; + + S32 rect_height = getRect().getHeight(); + setOrigin(horizontal_offset, vertical_offset - rect_height); + + translate(snap_rect.mLeft, snap_rect.mBottom); + } + setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + } + break; + + case LLFloaterEnums::POSITIONING_RELATIVE: + { + applyRelativePosition(); + + break; + } + default: + // Do nothing + break; + } } void LLFloater::applyTitle() { - if (!mDragHandle) - { - return; - } + if (!mDragHandle) + { + return; + } - if (isMinimized() && !mShortTitle.empty()) - { - mDragHandle->setTitle( mShortTitle ); - } - else - { - mDragHandle->setTitle ( mTitle ); - } + if (isMinimized() && !mShortTitle.empty()) + { + mDragHandle->setTitle( mShortTitle ); + } + else + { + mDragHandle->setTitle ( mTitle ); + } - if (getHost()) - { - getHost()->updateFloaterTitle(this); - } + if (getHost()) + { + getHost()->updateFloaterTitle(this); + } } std::string LLFloater::getCurrentTitle() const { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; } void LLFloater::setTitle( const std::string& title ) { - mTitle = title; - applyTitle(); + mTitle = title; + applyTitle(); } std::string LLFloater::getTitle() const { - if (mTitle.empty()) - { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; - } - else - { - return mTitle; - } + if (mTitle.empty()) + { + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + } + else + { + return mTitle; + } } void LLFloater::setShortTitle( const std::string& short_title ) { - mShortTitle = short_title; - applyTitle(); + mShortTitle = short_title; + applyTitle(); } std::string LLFloater::getShortTitle() const { - if (mShortTitle.empty()) - { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; - } - else - { - return mShortTitle; - } + if (mShortTitle.empty()) + { + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + } + else + { + return mShortTitle; + } } BOOL LLFloater::canSnapTo(const LLView* other_view) { - if (NULL == other_view) - { - LL_WARNS() << "other_view is NULL" << LL_ENDL; - return FALSE; - } - - if (other_view != getParent()) - { - const LLFloater* other_floaterp = dynamic_cast(other_view); - if (other_floaterp - && other_floaterp->getSnapTarget() == getHandle() - && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) - { - // this is a dependent that is already snapped to us, so don't snap back to it - return FALSE; - } - } + if (NULL == other_view) + { + LL_WARNS() << "other_view is NULL" << LL_ENDL; + return FALSE; + } + + if (other_view != getParent()) + { + const LLFloater* other_floaterp = dynamic_cast(other_view); + if (other_floaterp + && other_floaterp->getSnapTarget() == getHandle() + && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) + { + // this is a dependent that is already snapped to us, so don't snap back to it + return FALSE; + } + } - return LLPanel::canSnapTo(other_view); + return LLPanel::canSnapTo(other_view); } void LLFloater::setSnappedTo(const LLView* snap_view) { - if (!snap_view || snap_view == getParent()) - { - clearSnapTarget(); - } - else - { - //RN: assume it's a floater as it must be a sibling to our parent floater - const LLFloater* floaterp = dynamic_cast(snap_view); - if (floaterp) - { - setSnapTarget(floaterp->getHandle()); - } - } + if (!snap_view || snap_view == getParent()) + { + clearSnapTarget(); + } + else + { + //RN: assume it's a floater as it must be a sibling to our parent floater + const LLFloater* floaterp = dynamic_cast(snap_view); + if (floaterp) + { + setSnapTarget(floaterp->getHandle()); + } + } } void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) { - const LLRect old_rect = getRect(); - LLView::handleReshape(new_rect, by_user); - - if (by_user && !getHost()) - { - LLFloaterView * floaterVp = dynamic_cast(getParent()); - if (floaterVp) - { - floaterVp->adjustToFitScreen(this, !isMinimized()); - } - } - - // if not minimized, adjust all snapped dependents to new shape - if (!isMinimized()) - { - if (by_user) - { - if (isDocked()) - { - setDocked( false, false); - } - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - } - storeRectControl(); - - // gather all snapped dependents - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - // is a dependent snapped to us? - if (floaterp && floaterp->getSnapTarget() == getHandle()) - { - S32 delta_x = 0; - S32 delta_y = 0; - // check to see if it snapped to right or top, and move if dependee floater is resizing - LLRect dependent_rect = floaterp->getRect(); - if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? - dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right - { - // was snapped directly onto right side or aligned with it - delta_x += new_rect.getWidth() - old_rect.getWidth(); - } - if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || - dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) - { - // was snapped directly onto top side or aligned with it - delta_y += new_rect.getHeight() - old_rect.getHeight(); - } - - // take translation of dependee floater into account as well - delta_x += new_rect.mLeft - old_rect.mLeft; - delta_y += new_rect.mBottom - old_rect.mBottom; - - dependent_rect.translate(delta_x, delta_y); - floaterp->setShape(dependent_rect, by_user); - } - } - } - else - { - // If minimized, and origin has changed, set - // mHasBeenDraggedWhileMinimized to TRUE - if ((new_rect.mLeft != old_rect.mLeft) || - (new_rect.mBottom != old_rect.mBottom)) - { - mHasBeenDraggedWhileMinimized = TRUE; - } - } + const LLRect old_rect = getRect(); + LLView::handleReshape(new_rect, by_user); + + if (by_user && !getHost()) + { + LLFloaterView * floaterVp = dynamic_cast(getParent()); + if (floaterVp) + { + floaterVp->adjustToFitScreen(this, !isMinimized()); + } + } + + // if not minimized, adjust all snapped dependents to new shape + if (!isMinimized()) + { + if (by_user) + { + if (isDocked()) + { + setDocked( false, false); + } + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + } + storeRectControl(); + + // gather all snapped dependents + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + // is a dependent snapped to us? + if (floaterp && floaterp->getSnapTarget() == getHandle()) + { + S32 delta_x = 0; + S32 delta_y = 0; + // check to see if it snapped to right or top, and move if dependee floater is resizing + LLRect dependent_rect = floaterp->getRect(); + if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? + dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right + { + // was snapped directly onto right side or aligned with it + delta_x += new_rect.getWidth() - old_rect.getWidth(); + } + if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || + dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) + { + // was snapped directly onto top side or aligned with it + delta_y += new_rect.getHeight() - old_rect.getHeight(); + } + + // take translation of dependee floater into account as well + delta_x += new_rect.mLeft - old_rect.mLeft; + delta_y += new_rect.mBottom - old_rect.mBottom; + + dependent_rect.translate(delta_x, delta_y); + floaterp->setShape(dependent_rect, by_user); + } + } + } + else + { + // If minimized, and origin has changed, set + // mHasBeenDraggedWhileMinimized to TRUE + if ((new_rect.mLeft != old_rect.mLeft) || + (new_rect.mBottom != old_rect.mBottom)) + { + mHasBeenDraggedWhileMinimized = TRUE; + } + } } void LLFloater::setMinimized(BOOL minimize) { - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); - S32 floater_header_size = default_params.header_height; - static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); - - if (minimize == mMinimized) return; - - if (mMinimizeSignal) - { - (*mMinimizeSignal)(this, LLSD(minimize)); - } - - if (minimize) - { - // minimized flag should be turned on before release focus - mMinimized = TRUE; - mExpandedRect = getRect(); - - // If the floater has been dragged while minimized in the - // past, then locate it at its previous minimized location. - // Otherwise, ask the view for a minimize position. - if (mHasBeenDraggedWhileMinimized) - { - setOrigin(mPreviousMinimizedLeft, mPreviousMinimizedBottom); - } - else - { - S32 left, bottom; - gFloaterView->getMinimizePosition(&left, &bottom); - setOrigin( left, bottom ); - } - - if (mButtonsEnabled[BUTTON_MINIMIZE]) - { - mButtonsEnabled[BUTTON_MINIMIZE] = FALSE; - mButtonsEnabled[BUTTON_RESTORE] = TRUE; - } - - setBorderVisible(TRUE); - - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); - ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - if (floaterp->isMinimizeable()) - { - floaterp->setMinimized(TRUE); - } - else if (!floaterp->isMinimized()) - { - floaterp->setVisible(FALSE); - } - } - } - - // Lose keyboard focus when minimized - releaseFocus(); - - for (S32 i = 0; i < 4; i++) - { - if (mResizeBar[i] != NULL) - { - mResizeBar[i]->setEnabled(FALSE); - } - if (mResizeHandle[i] != NULL) - { - mResizeHandle[i]->setEnabled(FALSE); - } - } - - // Reshape *after* setting mMinimized - reshape( minimized_width, floater_header_size, TRUE); - } - else - { - // If this window has been dragged while minimized (at any time), - // remember its position for the next time it's minimized. - if (mHasBeenDraggedWhileMinimized) - { - const LLRect& currentRect = getRect(); - mPreviousMinimizedLeft = currentRect.mLeft; - mPreviousMinimizedBottom = currentRect.mBottom; - } - - setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); - if (mButtonsEnabled[BUTTON_RESTORE]) - { - mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; - mButtonsEnabled[BUTTON_RESTORE] = FALSE; - } - - // show dependent floater - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); - ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - floaterp->setMinimized(FALSE); - floaterp->setVisible(TRUE); - } - } - - for (S32 i = 0; i < 4; i++) - { - if (mResizeBar[i] != NULL) - { - mResizeBar[i]->setEnabled(isResizable()); - } - if (mResizeHandle[i] != NULL) - { - mResizeHandle[i]->setEnabled(isResizable()); - } - } - - mMinimized = FALSE; - setFrontmost(); - // Reshape *after* setting mMinimized - reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); - } - - make_ui_sound("UISndWindowClose"); - updateTitleButtons(); - applyTitle (); + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); + + if (minimize == mMinimized) return; + + if (mMinimizeSignal) + { + (*mMinimizeSignal)(this, LLSD(minimize)); + } + + if (minimize) + { + // minimized flag should be turned on before release focus + mMinimized = TRUE; + mExpandedRect = getRect(); + + // If the floater has been dragged while minimized in the + // past, then locate it at its previous minimized location. + // Otherwise, ask the view for a minimize position. + if (mHasBeenDraggedWhileMinimized) + { + setOrigin(mPreviousMinimizedLeft, mPreviousMinimizedBottom); + } + else + { + S32 left, bottom; + gFloaterView->getMinimizePosition(&left, &bottom); + setOrigin( left, bottom ); + } + + if (mButtonsEnabled[BUTTON_MINIMIZE]) + { + mButtonsEnabled[BUTTON_MINIMIZE] = FALSE; + mButtonsEnabled[BUTTON_RESTORE] = TRUE; + } + + setBorderVisible(TRUE); + + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); + ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + if (floaterp->isMinimizeable()) + { + floaterp->setMinimized(TRUE); + } + else if (!floaterp->isMinimized()) + { + floaterp->setVisible(FALSE); + } + } + } + + // Lose keyboard focus when minimized + releaseFocus(); + + for (S32 i = 0; i < 4; i++) + { + if (mResizeBar[i] != NULL) + { + mResizeBar[i]->setEnabled(FALSE); + } + if (mResizeHandle[i] != NULL) + { + mResizeHandle[i]->setEnabled(FALSE); + } + } + + // Reshape *after* setting mMinimized + reshape( minimized_width, floater_header_size, TRUE); + } + else + { + // If this window has been dragged while minimized (at any time), + // remember its position for the next time it's minimized. + if (mHasBeenDraggedWhileMinimized) + { + const LLRect& currentRect = getRect(); + mPreviousMinimizedLeft = currentRect.mLeft; + mPreviousMinimizedBottom = currentRect.mBottom; + } + + setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); + if (mButtonsEnabled[BUTTON_RESTORE]) + { + mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; + mButtonsEnabled[BUTTON_RESTORE] = FALSE; + } + + // show dependent floater + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); + ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + floaterp->setMinimized(FALSE); + floaterp->setVisible(TRUE); + } + } + + for (S32 i = 0; i < 4; i++) + { + if (mResizeBar[i] != NULL) + { + mResizeBar[i]->setEnabled(isResizable()); + } + if (mResizeHandle[i] != NULL) + { + mResizeHandle[i]->setEnabled(isResizable()); + } + } + + mMinimized = FALSE; + setFrontmost(); + // Reshape *after* setting mMinimized + reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); + } + + make_ui_sound("UISndWindowClose"); + updateTitleButtons(); + applyTitle (); } void LLFloater::setFocus( BOOL b ) { - if (b && getIsChrome()) - { - return; - } - LLView* last_focus = gFocusMgr.getLastFocusForGroup(this); - // a descendent already has focus - BOOL child_had_focus = hasFocus(); - - // give focus to first valid descendent - LLPanel::setFocus(b); - - if (b) - { - // only push focused floaters to front of stack if not in midst of ctrl-tab cycle - LLFloaterView * parent = dynamic_cast(getParent()); - if (!getHost() && parent && !parent->getCycleMode()) - { - if (!isFrontmost()) - { - setFrontmost(); - } - } - - // when getting focus, delegate to last descendent which had focus - if (last_focus && !child_had_focus && - last_focus->isInEnabledChain() && - last_focus->isInVisibleChain()) - { - // *FIX: should handle case where focus doesn't stick - last_focus->setFocus(TRUE); - } - } - updateTransparency(b ? TT_ACTIVE : TT_INACTIVE); + if (b && getIsChrome()) + { + return; + } + LLView* last_focus = gFocusMgr.getLastFocusForGroup(this); + // a descendent already has focus + BOOL child_had_focus = hasFocus(); + + // give focus to first valid descendent + LLPanel::setFocus(b); + + if (b) + { + // only push focused floaters to front of stack if not in midst of ctrl-tab cycle + LLFloaterView * parent = dynamic_cast(getParent()); + if (!getHost() && parent && !parent->getCycleMode()) + { + if (!isFrontmost()) + { + setFrontmost(); + } + } + + // when getting focus, delegate to last descendent which had focus + if (last_focus && !child_had_focus && + last_focus->isInEnabledChain() && + last_focus->isInVisibleChain()) + { + // *FIX: should handle case where focus doesn't stick + last_focus->setFocus(TRUE); + } + } + updateTransparency(b ? TT_ACTIVE : TT_INACTIVE); } // virtual void LLFloater::setRect(const LLRect &rect) { - LLPanel::setRect(rect); - layoutDragHandle(); - layoutResizeCtrls(); + LLPanel::setRect(rect); + layoutDragHandle(); + layoutResizeCtrls(); } // virtual void LLFloater::setIsChrome(BOOL is_chrome) { - // chrome floaters don't take focus at all - if (is_chrome) - { - // remove focus if we're changing to chrome - setFocus(FALSE); - // can't Ctrl-Tab to "chrome" floaters - setFocusRoot(FALSE); - mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome))); - } - - LLPanel::setIsChrome(is_chrome); + // chrome floaters don't take focus at all + if (is_chrome) + { + // remove focus if we're changing to chrome + setFocus(FALSE); + // can't Ctrl-Tab to "chrome" floaters + setFocusRoot(FALSE); + mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome))); + } + + LLPanel::setIsChrome(is_chrome); } // Change the draw style to account for the foreground state. void LLFloater::setForeground(BOOL front) { - if (front != mForeground) - { - mForeground = front; - if (mDragHandle) - mDragHandle->setForeground( front ); + if (front != mForeground) + { + mForeground = front; + if (mDragHandle) + mDragHandle->setForeground( front ); - if (!front) - { - releaseFocus(); - } + if (!front) + { + releaseFocus(); + } - setBackgroundOpaque( front ); - } + setBackgroundOpaque( front ); + } } void LLFloater::cleanupHandles() { - // remove handles to non-existent dependents - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - LLFloater* floaterp = dependent_it->get(); - if (!floaterp) - { - mDependents.erase(dependent_it++); - } - else - { - ++dependent_it; - } - } + // remove handles to non-existent dependents + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + LLFloater* floaterp = dependent_it->get(); + if (!floaterp) + { + mDependents.erase(dependent_it++); + } + else + { + ++dependent_it; + } + } } void LLFloater::setHost(LLMultiFloater* host) { - if (mHostHandle.isDead() && host) - { - // make buttons smaller for hosted windows to differentiate from parent - mButtonScale = 0.9f; - - // add tear off button - if (mCanTearOff) - { - mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; - } - } - else if (!mHostHandle.isDead() && !host) - { - mButtonScale = 1.f; - //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; - } - if (host) - { - mHostHandle = host->getHandle(); - mLastHostHandle = host->getHandle(); - } - else - { - mHostHandle.markDead(); - } + if (mHostHandle.isDead() && host) + { + // make buttons smaller for hosted windows to differentiate from parent + mButtonScale = 0.9f; + + // add tear off button + if (mCanTearOff) + { + mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; + } + } + else if (!mHostHandle.isDead() && !host) + { + mButtonScale = 1.f; + //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; + } + if (host) + { + mHostHandle = host->getHandle(); + mLastHostHandle = host->getHandle(); + } + else + { + mHostHandle.markDead(); + } - updateTitleButtons(); + updateTitleButtons(); } void LLFloater::moveResizeHandlesToFront() { - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeBar[i] ) - { - sendChildToFront(mResizeBar[i]); - } - } + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeBar[i] ) + { + sendChildToFront(mResizeBar[i]); + } + } - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeHandle[i] ) - { - sendChildToFront(mResizeHandle[i]); - } - } + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeHandle[i] ) + { + sendChildToFront(mResizeHandle[i]); + } + } } /*virtual*/ BOOL LLFloater::isFrontmost() { - LLFloaterView* floater_view = getParentByType(); - return getVisible() - && (floater_view - && floater_view->getFrontmost() == this); + LLFloaterView* floater_view = getParentByType(); + return getVisible() + && (floater_view + && floater_view->getFrontmost() == this); } void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) { - mDependents.insert(floaterp->getHandle()); - floaterp->mDependeeHandle = getHandle(); + mDependents.insert(floaterp->getHandle()); + floaterp->mDependeeHandle = getHandle(); - if (reposition) - { - floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); - floaterp->setSnapTarget(getHandle()); - } - gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE); - if (floaterp->isFrontmost()) - { - // make sure to bring self and sibling floaters to front - gFloaterView->bringToFront(floaterp); - } + if (reposition) + { + floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); + floaterp->setSnapTarget(getHandle()); + } + gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE); + if (floaterp->isFrontmost()) + { + // make sure to bring self and sibling floaters to front + gFloaterView->bringToFront(floaterp); + } } void LLFloater::addDependentFloater(LLHandle dependent, BOOL reposition) { - LLFloater* dependent_floaterp = dependent.get(); - if(dependent_floaterp) - { - addDependentFloater(dependent_floaterp, reposition); - } + LLFloater* dependent_floaterp = dependent.get(); + if(dependent_floaterp) + { + addDependentFloater(dependent_floaterp, reposition); + } } void LLFloater::removeDependentFloater(LLFloater* floaterp) { - mDependents.erase(floaterp->getHandle()); - floaterp->mDependeeHandle = LLHandle(); + mDependents.erase(floaterp->getHandle()); + floaterp->mDependeeHandle = LLHandle(); } BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index) { - if( mButtonsEnabled[index] ) - { - LLButton* my_butt = mButtons[index]; - S32 local_x = x - my_butt->getRect().mLeft; - S32 local_y = y - my_butt->getRect().mBottom; + if( mButtonsEnabled[index] ) + { + LLButton* my_butt = mButtons[index]; + S32 local_x = x - my_butt->getRect().mLeft; + S32 local_y = y - my_butt->getRect().mBottom; - if ( - my_butt->pointInView(local_x, local_y) && - my_butt->handleMouseDown(local_x, local_y, mask)) - { - // the button handled it - return TRUE; - } - } - return FALSE; + if ( + my_butt->pointInView(local_x, local_y) && + my_butt->handleMouseDown(local_x, local_y, mask)) + { + // the button handled it + return TRUE; + } + } + return FALSE; } BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks) { - LLPanel::handleScrollWheel(x,y,clicks); - return TRUE;//always + LLPanel::handleScrollWheel(x,y,clicks); + return TRUE;//always } // virtual BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask) { - LL_DEBUGS() << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL; - BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView - if (handled) { - LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); - } - return handled; + LL_DEBUGS() << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL; + BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; } // virtual BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask) { - if( mMinimized ) - { - // Offer the click to titlebar buttons. - // Note: this block and the offerClickToButton helper method can be removed - // because the parent container will handle it for us but we'll keep it here - // for safety until after reworking the panel code to manage hidden children. - if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE; - - setFrontmost(TRUE, FALSE); - // Otherwise pass to drag handle for movement - return mDragHandle->handleMouseDown(x, y, mask); - } - else - { - bringToFront( x, y ); - BOOL handled = LLPanel::handleMouseDown( x, y, mask ); - if (handled) { - LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); - } - return handled; - } + if( mMinimized ) + { + // Offer the click to titlebar buttons. + // Note: this block and the offerClickToButton helper method can be removed + // because the parent container will handle it for us but we'll keep it here + // for safety until after reworking the panel code to manage hidden children. + if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE; + + setFrontmost(TRUE, FALSE); + // Otherwise pass to drag handle for movement + return mDragHandle->handleMouseDown(x, y, mask); + } + else + { + bringToFront( x, y ); + BOOL handled = LLPanel::handleMouseDown( x, y, mask ); + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; + } } // virtual BOOL LLFloater::handleRightMouseDown(S32 x, S32 y, MASK mask) { - BOOL was_minimized = mMinimized; - bringToFront( x, y ); - return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); + BOOL was_minimized = mMinimized; + bringToFront( x, y ); + return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); } BOOL LLFloater::handleMiddleMouseDown(S32 x, S32 y, MASK mask) { - bringToFront( x, y ); - return LLPanel::handleMiddleMouseDown( x, y, mask ); + bringToFront( x, y ); + return LLPanel::handleMiddleMouseDown( x, y, mask ); } // virtual BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) { - BOOL was_minimized = mMinimized; - setMinimized(FALSE); - return was_minimized || LLPanel::handleDoubleClick(x, y, mask); + BOOL was_minimized = mMinimized; + setMinimized(FALSE); + return was_minimized || LLPanel::handleDoubleClick(x, y, mask); } void LLFloater::bringToFront( S32 x, S32 y ) { - if (getVisible() && pointInView(x, y)) - { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - hostp->showFloater(this); - } - else - { - LLFloaterView* parent = dynamic_cast( getParent() ); - if (parent) - { - parent->bringToFront( this ); - } - } - } + if (getVisible() && pointInView(x, y)) + { + LLMultiFloater* hostp = getHost(); + if (hostp) + { + hostp->showFloater(this); + } + else + { + LLFloaterView* parent = dynamic_cast( getParent() ); + if (parent) + { + parent->bringToFront( this ); + } + } + } } // virtual void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key) { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - hostp->setVisible(TRUE); - hostp->setFrontmost(take_focus); - } - else - { - setVisible(TRUE); - setFrontmost(take_focus); - } + LLMultiFloater* hostp = getHost(); + if (hostp) + { + hostp->setVisible(TRUE); + hostp->setFrontmost(take_focus); + } + else + { + setVisible(TRUE); + setFrontmost(take_focus); + } } void LLFloater::setFrontmost(BOOL take_focus, BOOL restore) { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - // this will bring the host floater to the front and select - // the appropriate panel - hostp->showFloater(this); - } - else - { - // there are more than one floater view - // so we need to query our parent directly - LLFloaterView * parent = dynamic_cast( getParent() ); - if (parent) - { - parent->bringToFront(this, take_focus, restore); - } - - // Make sure to set the appropriate transparency type (STORM-732). - updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); - } + LLMultiFloater* hostp = getHost(); + if (hostp) + { + // this will bring the host floater to the front and select + // the appropriate panel + hostp->showFloater(this); + } + else + { + // there are more than one floater view + // so we need to query our parent directly + LLFloaterView * parent = dynamic_cast( getParent() ); + if (parent) + { + parent->bringToFront(this, take_focus, restore); + } + + // Make sure to set the appropriate transparency type (STORM-732). + updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); + } } void LLFloater::setCanDock(bool b) { - if(b != mCanDock) - { - mCanDock = b; - if(mCanDock) - { - mButtonsEnabled[BUTTON_DOCK] = !mDocked; - } - else - { - mButtonsEnabled[BUTTON_DOCK] = FALSE; - } - } - updateTitleButtons(); + if(b != mCanDock) + { + mCanDock = b; + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + } + else + { + mButtonsEnabled[BUTTON_DOCK] = FALSE; + } + } + updateTitleButtons(); } void LLFloater::setDocked(bool docked, bool pop_on_undock) { - if(docked != mDocked && mCanDock) - { - mDocked = docked; - mButtonsEnabled[BUTTON_DOCK] = !mDocked; + if(docked != mDocked && mCanDock) + { + mDocked = docked; + mButtonsEnabled[BUTTON_DOCK] = !mDocked; - if (mDocked) - { - setMinimized(FALSE); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - } + if (mDocked) + { + setMinimized(FALSE); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + } - updateTitleButtons(); + updateTitleButtons(); - storeDockStateControl(); - } - + storeDockStateControl(); + } + } // static void LLFloater::onClickMinimize(LLFloater* self) { - if (!self) - return; - self->setMinimized( !self->isMinimized() ); + if (!self) + return; + self->setMinimized( !self->isMinimized() ); } void LLFloater::onClickTearOff(LLFloater* self) { - if (!self) - return; - S32 floater_header_size = self->mHeaderHeight; - LLMultiFloater* host_floater = self->getHost(); - if (host_floater) //Tear off - { - LLRect new_rect; - host_floater->removeFloater(self); - // reparent to floater view - gFloaterView->addChild(self); - - self->openFloater(self->getKey()); - if (self->mSaveRect && !self->mRectControl.empty()) - { - self->applyRectControl(); - } - else - { // only force position for floaters that don't have that data saved - new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight()); - self->setRect(new_rect); - } - gFloaterView->adjustToFitScreen(self, FALSE); - // give focus to new window to keep continuity for the user - self->setFocus(TRUE); - self->setTornOff(true); - } - else //Attach to parent. - { - LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); - if (new_host) - { - if (self->mSaveRect) - { - self->storeRectControl(); - } - self->setMinimized(FALSE); // to reenable minimize button if it was minimized - new_host->showFloater(self); - // make sure host is visible - new_host->openFloater(new_host->getKey()); - } - self->setTornOff(false); - } - self->updateTitleButtons(); + if (!self) + return; + S32 floater_header_size = self->mHeaderHeight; + LLMultiFloater* host_floater = self->getHost(); + if (host_floater) //Tear off + { + LLRect new_rect; + host_floater->removeFloater(self); + // reparent to floater view + gFloaterView->addChild(self); + + self->openFloater(self->getKey()); + if (self->mSaveRect && !self->mRectControl.empty()) + { + self->applyRectControl(); + } + else + { // only force position for floaters that don't have that data saved + new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight()); + self->setRect(new_rect); + } + gFloaterView->adjustToFitScreen(self, FALSE); + // give focus to new window to keep continuity for the user + self->setFocus(TRUE); + self->setTornOff(true); + } + else //Attach to parent. + { + LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); + if (new_host) + { + if (self->mSaveRect) + { + self->storeRectControl(); + } + self->setMinimized(FALSE); // to reenable minimize button if it was minimized + new_host->showFloater(self); + // make sure host is visible + new_host->openFloater(new_host->getKey()); + } + self->setTornOff(false); + } + self->updateTitleButtons(); self->setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); } // static void LLFloater::onClickDock(LLFloater* self) { - if(self && self->mCanDock) - { - self->setDocked(!self->mDocked, true); - } + if(self && self->mCanDock) + { + self->setDocked(!self->mDocked, true); + } } // static void LLFloater::onClickHelp( LLFloater* self ) { - if (self && LLUI::sHelpImpl) - { - // find the current help context for this floater - std::string help_topic; - if (self->findHelpTopic(help_topic)) - { - LLUI::sHelpImpl->showTopic(help_topic); - } - } + if (self && LLUI::sHelpImpl) + { + // find the current help context for this floater + std::string help_topic; + if (self->findHelpTopic(help_topic)) + { + LLUI::sHelpImpl->showTopic(help_topic); + } + } } void LLFloater::initRectControl() { - // save_rect and save_visibility only apply to registered floaters - if (mSaveRect) - { - std::string ctrl_name = getControlName(mInstanceName, mKey); - mRectControl = LLFloaterReg::declareRectControl(ctrl_name); - mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); - mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); - } + // save_rect and save_visibility only apply to registered floaters + if (mSaveRect) + { + std::string ctrl_name = getControlName(mInstanceName, mKey); + mRectControl = LLFloaterReg::declareRectControl(ctrl_name); + mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); + mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); + } } // static void LLFloater::closeFrontmostFloater() { - LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); - if(floater_to_close) - { - floater_to_close->closeFloater(); - } + LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); + if(floater_to_close) + { + floater_to_close->closeFloater(); + } - // if nothing took focus after closing focused floater - // give it to next floater (to allow closing multiple windows via keyboard in rapid succession) - if (gFocusMgr.getKeyboardFocus() == NULL) - { - // HACK: use gFloaterView directly in case we are using Ctrl-W to close snapshot window - // which sits in gSnapshotFloaterView, and needs to pass focus on to normal floater view - gFloaterView->focusFrontFloater(); - } + // if nothing took focus after closing focused floater + // give it to next floater (to allow closing multiple windows via keyboard in rapid succession) + if (gFocusMgr.getKeyboardFocus() == NULL) + { + // HACK: use gFloaterView directly in case we are using Ctrl-W to close snapshot window + // which sits in gSnapshotFloaterView, and needs to pass focus on to normal floater view + gFloaterView->focusFrontFloater(); + } } // static void LLFloater::onClickClose( LLFloater* self ) { - if (!self) - return; - self->onClickCloseBtn(); + if (!self) + return; + self->onClickCloseBtn(); } void LLFloater::onClickCloseBtn(bool app_quitting) { - closeFloater(false); + closeFloater(false); } // virtual void LLFloater::draw() { - const F32 alpha = getCurrentTransparency(); - - // draw background - if( isBackgroundVisible() ) - { - drawShadow(this); - - S32 left = LLPANEL_BORDER_WIDTH; - S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; - S32 bottom = LLPANEL_BORDER_WIDTH; - - LLUIImage* image = NULL; - LLColor4 color; - LLColor4 overlay_color; - if (isBackgroundOpaque()) - { - // NOTE: image may not be set - image = getBackgroundImage(); - color = getBackgroundColor(); - overlay_color = getBackgroundImageOverlay(); - } - else - { - image = getTransparentImage(); - color = getTransparentColor(); - overlay_color = getTransparentImageOverlay(); - } - - if (image) - { - // We're using images for this floater's backgrounds - image->draw(getLocalRect(), overlay_color % alpha); - } - else - { - // We're not using images, use old-school flat colors - gl_rect_2d( left, top, right, bottom, color % alpha ); - - // draw highlight on title bar to indicate focus. RDW - if(hasFocus() - && !getIsChrome() - && !getCurrentTitle().empty()) - { - static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); - - const LLFontGL* font = LLFontGL::getFontSansSerif(); - LLRect r = getRect(); - gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1, - titlebar_focus_color % alpha, 0, TRUE); - } - } - } - - LLPanel::updateDefaultBtn(); - - if( getDefaultButton() ) - { - if (hasFocus() && getDefaultButton()->getEnabled()) - { - LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - // is this button a direct descendent and not a nested widget (e.g. checkbox)? - BOOL focus_is_child_button = dynamic_cast(focus_ctrl) != NULL && dynamic_cast(focus_ctrl)->getParent() == this; - // only enable default button when current focus is not a button - getDefaultButton()->setBorderEnabled(!focus_is_child_button); - } - else - { - getDefaultButton()->setBorderEnabled(FALSE); - } - } - if (isMinimized()) - { - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - drawChild(mButtons[i]); - } - drawChild(mDragHandle, 0, 0, TRUE); - } - else - { - // don't call LLPanel::draw() since we've implemented custom background rendering - LLView::draw(); - } - - // update tearoff button for torn off floaters - // when last host goes away - if (mCanTearOff && !getHost()) - { - LLFloater* old_host = mLastHostHandle.get(); - if (!old_host) - { - setCanTearOff(FALSE); - } - } -} - -void LLFloater::drawShadow(LLPanel* panel) -{ - S32 left = LLPANEL_BORDER_WIDTH; - S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH; - S32 bottom = LLPANEL_BORDER_WIDTH; - - static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0); - static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); - LLColor4 shadow_color = shadow_color_cached; - F32 shadow_offset = (F32)shadow_offset_S32; - - if (!panel->isBackgroundOpaque()) - { - shadow_offset *= 0.2f; - shadow_color.mV[VALPHA] *= 0.5f; - } - gl_drop_shadow(left, top, right, bottom, - shadow_color % getCurrentTransparency(), - ll_round(shadow_offset)); + const F32 alpha = getCurrentTransparency(); + + // draw background + if( isBackgroundVisible() ) + { + drawShadow(this); + + S32 left = LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; + S32 bottom = LLPANEL_BORDER_WIDTH; + + LLUIImage* image = NULL; + LLColor4 color; + LLColor4 overlay_color; + if (isBackgroundOpaque()) + { + // NOTE: image may not be set + image = getBackgroundImage(); + color = getBackgroundColor(); + overlay_color = getBackgroundImageOverlay(); + } + else + { + image = getTransparentImage(); + color = getTransparentColor(); + overlay_color = getTransparentImageOverlay(); + } + + if (image) + { + // We're using images for this floater's backgrounds + image->draw(getLocalRect(), overlay_color % alpha); + } + else + { + // We're not using images, use old-school flat colors + gl_rect_2d( left, top, right, bottom, color % alpha ); + + // draw highlight on title bar to indicate focus. RDW + if(hasFocus() + && !getIsChrome() + && !getCurrentTitle().empty()) + { + static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); + + const LLFontGL* font = LLFontGL::getFontSansSerif(); + LLRect r = getRect(); + gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1, + titlebar_focus_color % alpha, 0, TRUE); + } + } + } + + LLPanel::updateDefaultBtn(); + + if( getDefaultButton() ) + { + if (hasFocus() && getDefaultButton()->getEnabled()) + { + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); + // is this button a direct descendent and not a nested widget (e.g. checkbox)? + BOOL focus_is_child_button = dynamic_cast(focus_ctrl) != NULL && dynamic_cast(focus_ctrl)->getParent() == this; + // only enable default button when current focus is not a button + getDefaultButton()->setBorderEnabled(!focus_is_child_button); + } + else + { + getDefaultButton()->setBorderEnabled(FALSE); + } + } + if (isMinimized()) + { + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + drawChild(mButtons[i]); + } + drawChild(mDragHandle, 0, 0, TRUE); + } + else + { + // don't call LLPanel::draw() since we've implemented custom background rendering + LLView::draw(); + } + + // update tearoff button for torn off floaters + // when last host goes away + if (mCanTearOff && !getHost()) + { + LLFloater* old_host = mLastHostHandle.get(); + if (!old_host) + { + setCanTearOff(FALSE); + } + } +} + +void LLFloater::drawShadow(LLPanel* panel) +{ + S32 left = LLPANEL_BORDER_WIDTH; + S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH; + S32 bottom = LLPANEL_BORDER_WIDTH; + + static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0); + static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); + LLColor4 shadow_color = shadow_color_cached; + F32 shadow_offset = (F32)shadow_offset_S32; + + if (!panel->isBackgroundOpaque()) + { + shadow_offset *= 0.2f; + shadow_color.mV[VALPHA] *= 0.5f; + } + gl_drop_shadow(left, top, right, bottom, + shadow_color % getCurrentTransparency(), + ll_round(shadow_offset)); } void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type) { - if (!view) return; - child_list_t children = *view->getChildList(); - child_list_t::iterator it = children.begin(); + if (!view) return; + child_list_t children = *view->getChildList(); + child_list_t::iterator it = children.begin(); - LLUICtrl* ctrl = dynamic_cast(view); - if (ctrl) - { - ctrl->setTransparencyType(transparency_type); - } + LLUICtrl* ctrl = dynamic_cast(view); + if (ctrl) + { + ctrl->setTransparencyType(transparency_type); + } - for(; it != children.end(); ++it) - { - updateTransparency(*it, transparency_type); - } + for(; it != children.end(); ++it) + { + updateTransparency(*it, transparency_type); + } } void LLFloater::updateTransparency(ETypeTransparency transparency_type) { - updateTransparency(this, transparency_type); + updateTransparency(this, transparency_type); } -void LLFloater::setCanMinimize(BOOL can_minimize) +void LLFloater::setCanMinimize(BOOL can_minimize) { - // if removing minimize/restore button programmatically, - // go ahead and unminimize floater - mCanMinimize = can_minimize; - if (!can_minimize) - { - setMinimized(FALSE); - } + // if removing minimize/restore button programmatically, + // go ahead and unminimize floater + mCanMinimize = can_minimize; + if (!can_minimize) + { + setMinimized(FALSE); + } - mButtonsEnabled[BUTTON_MINIMIZE] = can_minimize && !isMinimized(); - mButtonsEnabled[BUTTON_RESTORE] = can_minimize && isMinimized(); + mButtonsEnabled[BUTTON_MINIMIZE] = can_minimize && !isMinimized(); + mButtonsEnabled[BUTTON_RESTORE] = can_minimize && isMinimized(); - updateTitleButtons(); + updateTitleButtons(); } -void LLFloater::setCanClose(BOOL can_close) +void LLFloater::setCanClose(BOOL can_close) { - mCanClose = can_close; - mButtonsEnabled[BUTTON_CLOSE] = can_close; + mCanClose = can_close; + mButtonsEnabled[BUTTON_CLOSE] = can_close; - updateTitleButtons(); + updateTitleButtons(); } -void LLFloater::setCanTearOff(BOOL can_tear_off) +void LLFloater::setCanTearOff(BOOL can_tear_off) { - mCanTearOff = can_tear_off; - mButtonsEnabled[BUTTON_TEAR_OFF] = mCanTearOff && !mHostHandle.isDead(); + mCanTearOff = can_tear_off; + mButtonsEnabled[BUTTON_TEAR_OFF] = mCanTearOff && !mHostHandle.isDead(); - updateTitleButtons(); + updateTitleButtons(); } void LLFloater::setCanResize(BOOL can_resize) { - mResizable = can_resize; - enableResizeCtrls(can_resize); + mResizable = can_resize; + enableResizeCtrls(can_resize); } void LLFloater::setCanDrag(BOOL can_drag) { - // if we delete drag handle, we no longer have access to the floater's title - // so just enable/disable it - if (!can_drag && mDragHandle->getEnabled()) - { - mDragHandle->setEnabled(FALSE); - } - else if (can_drag && !mDragHandle->getEnabled()) - { - mDragHandle->setEnabled(TRUE); - } + // if we delete drag handle, we no longer have access to the floater's title + // so just enable/disable it + if (!can_drag && mDragHandle->getEnabled()) + { + mDragHandle->setEnabled(FALSE); + } + else if (can_drag && !mDragHandle->getEnabled()) + { + mDragHandle->setEnabled(TRUE); + } } bool LLFloater::getCanDrag() { - return mDragHandle->getEnabled(); + return mDragHandle->getEnabled(); } void LLFloater::updateTitleButtons() { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); - LLRect buttons_rect; - S32 button_count = 0; - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - if (!mButtons[i]) - { - continue; - } - - bool enabled = mButtonsEnabled[i]; - if (i == BUTTON_HELP) - { - // don't show the help button if the floater is minimized - // or if it is a docked tear-off floater - if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff)) - { - enabled = false; - } - } - if (i == BUTTON_CLOSE && mButtonScale != 1.f) - { - //*HACK: always render close button for hosted floaters so - //that users don't accidentally hit the button when - //closing multiple windows in the chatterbox - enabled = true; - } - - mButtons[i]->setEnabled(enabled); - - if (enabled) - { - button_count++; - - LLRect btn_rect; - if (mDragOnLeft) - { - btn_rect.setLeftTopAndSize( - LLPANEL_BORDER_WIDTH, - getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * button_count, - ll_round((F32)floater_close_box_size * mButtonScale), - ll_round((F32)floater_close_box_size * mButtonScale)); - } - else - { - btn_rect.setLeftTopAndSize( - getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * button_count, - getRect().getHeight() - close_box_from_top, - ll_round((F32)floater_close_box_size * mButtonScale), - ll_round((F32)floater_close_box_size * mButtonScale)); - } - - // first time here, init 'buttons_rect' - if(1 == button_count) - { - buttons_rect = btn_rect; - } - else - { - // if mDragOnLeft=true then buttons are on top-left side vertically aligned - // title is not displayed in this case, calculating 'buttons_rect' for future use - mDragOnLeft ? buttons_rect.mBottom -= btn_rect.mBottom : - buttons_rect.mLeft = btn_rect.mLeft; - } - mButtons[i]->setRect(btn_rect); - mButtons[i]->setVisible(TRUE); - // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater - mButtons[i]->setTabStop(i == BUTTON_RESTORE); - } - else - { - mButtons[i]->setVisible(FALSE); - } - } - if (mDragHandle) - { - localRectToOtherView(buttons_rect, &buttons_rect, mDragHandle); - mDragHandle->setButtonsRect(buttons_rect); - } + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); + LLRect buttons_rect; + S32 button_count = 0; + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (!mButtons[i]) + { + continue; + } + + bool enabled = mButtonsEnabled[i]; + if (i == BUTTON_HELP) + { + // don't show the help button if the floater is minimized + // or if it is a docked tear-off floater + if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff)) + { + enabled = false; + } + } + if (i == BUTTON_CLOSE && mButtonScale != 1.f) + { + //*HACK: always render close button for hosted floaters so + //that users don't accidentally hit the button when + //closing multiple windows in the chatterbox + enabled = true; + } + + mButtons[i]->setEnabled(enabled); + + if (enabled) + { + button_count++; + + LLRect btn_rect; + if (mDragOnLeft) + { + btn_rect.setLeftTopAndSize( + LLPANEL_BORDER_WIDTH, + getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * button_count, + ll_round((F32)floater_close_box_size * mButtonScale), + ll_round((F32)floater_close_box_size * mButtonScale)); + } + else + { + btn_rect.setLeftTopAndSize( + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * button_count, + getRect().getHeight() - close_box_from_top, + ll_round((F32)floater_close_box_size * mButtonScale), + ll_round((F32)floater_close_box_size * mButtonScale)); + } + + // first time here, init 'buttons_rect' + if(1 == button_count) + { + buttons_rect = btn_rect; + } + else + { + // if mDragOnLeft=true then buttons are on top-left side vertically aligned + // title is not displayed in this case, calculating 'buttons_rect' for future use + mDragOnLeft ? buttons_rect.mBottom -= btn_rect.mBottom : + buttons_rect.mLeft = btn_rect.mLeft; + } + mButtons[i]->setRect(btn_rect); + mButtons[i]->setVisible(TRUE); + // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater + mButtons[i]->setTabStop(i == BUTTON_RESTORE); + } + else + { + mButtons[i]->setVisible(FALSE); + } + } + if (mDragHandle) + { + localRectToOtherView(buttons_rect, &buttons_rect, mDragHandle); + mDragHandle->setButtonsRect(buttons_rect); + } } void LLFloater::buildButtons(const Params& floater_params) { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - if (mButtons[i]) - { - removeChild(mButtons[i]); - delete mButtons[i]; - mButtons[i] = NULL; - } - - LLRect btn_rect; - if (mDragOnLeft) - { - btn_rect.setLeftTopAndSize( - LLPANEL_BORDER_WIDTH, - getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * (i + 1), - ll_round(floater_close_box_size * mButtonScale), - ll_round(floater_close_box_size * mButtonScale)); - } - else - { - btn_rect.setLeftTopAndSize( - getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * (i + 1), - getRect().getHeight() - close_box_from_top, - ll_round(floater_close_box_size * mButtonScale), - ll_round(floater_close_box_size * mButtonScale)); - } - - LLButton::Params p; - p.name(sButtonNames[i]); - p.rect(btn_rect); - p.image_unselected = getButtonImage(floater_params, (EFloaterButton)i); - // Selected, no matter if hovered or not, is "pressed" - LLUIImage* pressed_image = getButtonPressedImage(floater_params, (EFloaterButton)i); - p.image_selected = pressed_image; - p.image_hover_selected = pressed_image; - // Use a glow effect when the user hovers over the button - // These icons are really small, need glow amount increased - p.hover_glow_amount( 0.33f ); - p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); - p.tab_stop(false); - p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); - p.tool_tip = getButtonTooltip(floater_params, (EFloaterButton)i, getIsChrome()); - p.scale_image(true); - p.chrome(true); - - LLButton* buttonp = LLUICtrlFactory::create(p); - addChild(buttonp); - mButtons[i] = buttonp; - } - - updateTitleButtons(); + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (mButtons[i]) + { + removeChild(mButtons[i]); + delete mButtons[i]; + mButtons[i] = NULL; + } + + LLRect btn_rect; + if (mDragOnLeft) + { + btn_rect.setLeftTopAndSize( + LLPANEL_BORDER_WIDTH, + getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * (i + 1), + ll_round(floater_close_box_size * mButtonScale), + ll_round(floater_close_box_size * mButtonScale)); + } + else + { + btn_rect.setLeftTopAndSize( + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * (i + 1), + getRect().getHeight() - close_box_from_top, + ll_round(floater_close_box_size * mButtonScale), + ll_round(floater_close_box_size * mButtonScale)); + } + + LLButton::Params p; + p.name(sButtonNames[i]); + p.rect(btn_rect); + p.image_unselected = getButtonImage(floater_params, (EFloaterButton)i); + // Selected, no matter if hovered or not, is "pressed" + LLUIImage* pressed_image = getButtonPressedImage(floater_params, (EFloaterButton)i); + p.image_selected = pressed_image; + p.image_hover_selected = pressed_image; + // Use a glow effect when the user hovers over the button + // These icons are really small, need glow amount increased + p.hover_glow_amount( 0.33f ); + p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); + p.tab_stop(false); + p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); + p.tool_tip = getButtonTooltip(floater_params, (EFloaterButton)i, getIsChrome()); + p.scale_image(true); + p.chrome(true); + + LLButton* buttonp = LLUICtrlFactory::create(p); + addChild(buttonp); + mButtons[i] = buttonp; + } + + updateTitleButtons(); } // static LLUIImage* LLFloater::getButtonImage(const Params& p, EFloaterButton e) { - switch(e) - { - default: - case BUTTON_CLOSE: - return p.close_image; - case BUTTON_RESTORE: - return p.restore_image; - case BUTTON_MINIMIZE: - return p.minimize_image; - case BUTTON_TEAR_OFF: - return p.tear_off_image; - case BUTTON_DOCK: - return p.dock_image; - case BUTTON_HELP: - return p.help_image; - } + switch(e) + { + default: + case BUTTON_CLOSE: + return p.close_image; + case BUTTON_RESTORE: + return p.restore_image; + case BUTTON_MINIMIZE: + return p.minimize_image; + case BUTTON_TEAR_OFF: + return p.tear_off_image; + case BUTTON_DOCK: + return p.dock_image; + case BUTTON_HELP: + return p.help_image; + } } // static LLUIImage* LLFloater::getButtonPressedImage(const Params& p, EFloaterButton e) { - switch(e) - { - default: - case BUTTON_CLOSE: - return p.close_pressed_image; - case BUTTON_RESTORE: - return p.restore_pressed_image; - case BUTTON_MINIMIZE: - return p.minimize_pressed_image; - case BUTTON_TEAR_OFF: - return p.tear_off_pressed_image; - case BUTTON_DOCK: - return p.dock_pressed_image; - case BUTTON_HELP: - return p.help_pressed_image; - } + switch(e) + { + default: + case BUTTON_CLOSE: + return p.close_pressed_image; + case BUTTON_RESTORE: + return p.restore_pressed_image; + case BUTTON_MINIMIZE: + return p.minimize_pressed_image; + case BUTTON_TEAR_OFF: + return p.tear_off_pressed_image; + case BUTTON_DOCK: + return p.dock_pressed_image; + case BUTTON_HELP: + return p.help_pressed_image; + } } // static std::string LLFloater::getButtonTooltip(const Params& p, EFloaterButton e, bool is_chrome) { - // EXT-4081 (Lag Meter: Ctrl+W does not close floater) - // If floater is chrome set 'Close' text for close button's tooltip - if(is_chrome && BUTTON_CLOSE == e) - { - static std::string close_tooltip_chrome = LLTrans::getString("BUTTON_CLOSE_CHROME"); - return close_tooltip_chrome; - } - // TODO: per-floater localizable tooltips set in XML - return sButtonToolTips[e]; + // EXT-4081 (Lag Meter: Ctrl+W does not close floater) + // If floater is chrome set 'Close' text for close button's tooltip + if(is_chrome && BUTTON_CLOSE == e) + { + static std::string close_tooltip_chrome = LLTrans::getString("BUTTON_CLOSE_CHROME"); + return close_tooltip_chrome; + } + // TODO: per-floater localizable tooltips set in XML + return sButtonToolTips[e]; } ///////////////////////////////////////////////////// @@ -2234,946 +2234,946 @@ std::string LLFloater::getButtonTooltip(const Params& p, EFloaterButton e, bool static LLDefaultChildRegistry::Register r("floater_view"); LLFloaterView::LLFloaterView (const Params& p) -: LLUICtrl (p), - mFocusCycleMode(FALSE), - mMinimizePositionVOffset(0), - mSnapOffsetBottom(0), - mSnapOffsetRight(0), - mFrontChild(NULL) +: LLUICtrl (p), + mFocusCycleMode(FALSE), + mMinimizePositionVOffset(0), + mSnapOffsetBottom(0), + mSnapOffsetRight(0), + mFrontChild(NULL) { - mSnapView = getHandle(); + mSnapView = getHandle(); } // By default, adjust vertical. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) { - LLView::reshape(width, height, called_from_parent); - - mLastSnapRect = getSnapRect(); - - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - LLFloater* floaterp = dynamic_cast(viewp); - if (floaterp->isDependent()) - { - // dependents are moved with their "dependee" - continue; - } - - if (!floaterp->isMinimized() && floaterp->getCanDrag()) - { - LLRect old_rect = floaterp->getRect(); - floaterp->applyPositioning(NULL, false); - LLRect new_rect = floaterp->getRect(); - - //LLRect r = floaterp->getRect(); - - //// Compute absolute distance from each edge of screen - //S32 left_offset = llabs(r.mLeft - 0); - //S32 right_offset = llabs(old_right - r.mRight); - - //S32 top_offset = llabs(old_top - r.mTop); - //S32 bottom_offset = llabs(r.mBottom - 0); - - S32 translate_x = new_rect.mLeft - old_rect.mLeft; - S32 translate_y = new_rect.mBottom - old_rect.mBottom; - - //if (left_offset > right_offset) - //{ - // translate_x = new_right - old_right; - //} - - //if (top_offset < bottom_offset) - //{ - // translate_y = new_top - old_top; - //} - - // don't reposition immovable floaters - //if (floaterp->getCanDrag()) - //{ - // floaterp->translate(translate_x, translate_y); - //} - BOOST_FOREACH(LLHandle dependent_floater, floaterp->mDependents) - { - if (dependent_floater.get()) - { - dependent_floater.get()->translate(translate_x, translate_y); - } - } - } - } + LLView::reshape(width, height, called_from_parent); + + mLastSnapRect = getSnapRect(); + + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + LLFloater* floaterp = dynamic_cast(viewp); + if (floaterp->isDependent()) + { + // dependents are moved with their "dependee" + continue; + } + + if (!floaterp->isMinimized() && floaterp->getCanDrag()) + { + LLRect old_rect = floaterp->getRect(); + floaterp->applyPositioning(NULL, false); + LLRect new_rect = floaterp->getRect(); + + //LLRect r = floaterp->getRect(); + + //// Compute absolute distance from each edge of screen + //S32 left_offset = llabs(r.mLeft - 0); + //S32 right_offset = llabs(old_right - r.mRight); + + //S32 top_offset = llabs(old_top - r.mTop); + //S32 bottom_offset = llabs(r.mBottom - 0); + + S32 translate_x = new_rect.mLeft - old_rect.mLeft; + S32 translate_y = new_rect.mBottom - old_rect.mBottom; + + //if (left_offset > right_offset) + //{ + // translate_x = new_right - old_right; + //} + + //if (top_offset < bottom_offset) + //{ + // translate_y = new_top - old_top; + //} + + // don't reposition immovable floaters + //if (floaterp->getCanDrag()) + //{ + // floaterp->translate(translate_x, translate_y); + //} + BOOST_FOREACH(LLHandle dependent_floater, floaterp->mDependents) + { + if (dependent_floater.get()) + { + dependent_floater.get()->translate(translate_x, translate_y); + } + } + } + } } void LLFloaterView::restoreAll() { - // make sure all subwindows aren't minimized - child_list_t child_list = *(getChildList()); - for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (floaterp) - { - floaterp->setMinimized(FALSE); - } - } + // make sure all subwindows aren't minimized + child_list_t child_list = *(getChildList()); + for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (floaterp) + { + floaterp->setMinimized(FALSE); + } + } - // *FIX: make sure dependents are restored + // *FIX: make sure dependents are restored - // children then deleted by default view constructor + // children then deleted by default view constructor } LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor ) { - LLRect base_rect = reference_floater->getRect(); - LLRect::tCoordType width = neighbor->getRect().getWidth(); - LLRect::tCoordType height = neighbor->getRect().getHeight(); - LLRect new_rect = neighbor->getRect(); - - LLRect expanded_base_rect = base_rect; - expanded_base_rect.stretch(10); - for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); - dependent_it != reference_floater->mDependents.end(); ++dependent_it) - { - LLFloater* sibling = dependent_it->get(); - // check for dependents within 10 pixels of base floater - if (sibling && - sibling != neighbor && - sibling->getVisible() && - expanded_base_rect.overlaps(sibling->getRect())) - { - base_rect.unionWith(sibling->getRect()); - } - } - - LLRect::tCoordType left_margin = llmax(0, base_rect.mLeft); - LLRect::tCoordType right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); - LLRect::tCoordType top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); - LLRect::tCoordType bottom_margin = llmax(0, base_rect.mBottom); - - // find position for floater in following order - // right->left->bottom->top - for (S32 i = 0; i < 5; i++) - { - if (right_margin > width) - { - new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); - return new_rect; - } - else if (left_margin > width) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); - return new_rect; - } - else if (bottom_margin > height) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); - return new_rect; - } - else if (top_margin > height) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); - return new_rect; - } - - // keep growing margins to find "best" fit - left_margin += 20; - right_margin += 20; - top_margin += 20; - bottom_margin += 20; - } - - // didn't find anything, return initial rect - return new_rect; + LLRect base_rect = reference_floater->getRect(); + LLRect::tCoordType width = neighbor->getRect().getWidth(); + LLRect::tCoordType height = neighbor->getRect().getHeight(); + LLRect new_rect = neighbor->getRect(); + + LLRect expanded_base_rect = base_rect; + expanded_base_rect.stretch(10); + for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); + dependent_it != reference_floater->mDependents.end(); ++dependent_it) + { + LLFloater* sibling = dependent_it->get(); + // check for dependents within 10 pixels of base floater + if (sibling && + sibling != neighbor && + sibling->getVisible() && + expanded_base_rect.overlaps(sibling->getRect())) + { + base_rect.unionWith(sibling->getRect()); + } + } + + LLRect::tCoordType left_margin = llmax(0, base_rect.mLeft); + LLRect::tCoordType right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); + LLRect::tCoordType top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); + LLRect::tCoordType bottom_margin = llmax(0, base_rect.mBottom); + + // find position for floater in following order + // right->left->bottom->top + for (S32 i = 0; i < 5; i++) + { + if (right_margin > width) + { + new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); + return new_rect; + } + else if (left_margin > width) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); + return new_rect; + } + else if (bottom_margin > height) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); + return new_rect; + } + else if (top_margin > height) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); + return new_rect; + } + + // keep growing margins to find "best" fit + left_margin += 20; + right_margin += 20; + top_margin += 20; + bottom_margin += 20; + } + + // didn't find anything, return initial rect + return new_rect; } void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore) { - if (!child) - return; - - if (mFrontChild == child) - { - if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) - { - child->setFocus(TRUE); - } - return; - } - - mFrontChild = child; - - // *TODO: make this respect floater's mAutoFocus value, instead of - // using parameter - if (child->getHost()) - { - // this floater is hosted elsewhere and hence not one of our children, abort - return; - } - std::vector floaters_to_move; - // Look at all floaters...tab - for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it) - { - LLFloater* floater = dynamic_cast(*child_it); - - // ...but if I'm a dependent floater... - if (floater && child->isDependent()) - { - // ...look for floaters that have me as a dependent... - LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle()); - - if (found_dependent != floater->mDependents.end()) - { - // ...and make sure all children of that floater (including me) are brought to front... - for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); ++dependent_it) - { - LLFloater* sibling = dependent_it->get(); - if (sibling) - { - floaters_to_move.push_back(sibling); - } - } - //...before bringing my parent to the front... - floaters_to_move.push_back(floater); - } - } - } - - std::vector::iterator floater_it; - for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it) - { - LLFloater* floaterp = *floater_it; - sendChildToFront(floaterp); - - // always unminimize dependee, but allow dependents to stay minimized - if (!floaterp->isDependent()) - { - floaterp->setMinimized(FALSE); - } - } - floaters_to_move.clear(); - - // ...then bringing my own dependents to the front... - for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); - dependent_it != child->mDependents.end(); ++dependent_it) - { - LLFloater* dependent = dependent_it->get(); - if (dependent) - { - sendChildToFront(dependent); - } - } - - // ...and finally bringing myself to front - // (do this last, so that I'm left in front at end of this call) - if (*beginChild() != child) - { - sendChildToFront(child); - } - - if(restore) - { - child->setMinimized(FALSE); - } - - if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) - { - child->setFocus(TRUE); - // floater did not take focus, so relinquish focus to world - if (!child->hasFocus()) - { - gFocusMgr.setKeyboardFocus(NULL); - } - } + if (!child) + return; + + if (mFrontChild == child) + { + if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) + { + child->setFocus(TRUE); + } + return; + } + + mFrontChild = child; + + // *TODO: make this respect floater's mAutoFocus value, instead of + // using parameter + if (child->getHost()) + { + // this floater is hosted elsewhere and hence not one of our children, abort + return; + } + std::vector floaters_to_move; + // Look at all floaters...tab + for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it) + { + LLFloater* floater = dynamic_cast(*child_it); + + // ...but if I'm a dependent floater... + if (floater && child->isDependent()) + { + // ...look for floaters that have me as a dependent... + LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle()); + + if (found_dependent != floater->mDependents.end()) + { + // ...and make sure all children of that floater (including me) are brought to front... + for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); ++dependent_it) + { + LLFloater* sibling = dependent_it->get(); + if (sibling) + { + floaters_to_move.push_back(sibling); + } + } + //...before bringing my parent to the front... + floaters_to_move.push_back(floater); + } + } + } + + std::vector::iterator floater_it; + for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it) + { + LLFloater* floaterp = *floater_it; + sendChildToFront(floaterp); + + // always unminimize dependee, but allow dependents to stay minimized + if (!floaterp->isDependent()) + { + floaterp->setMinimized(FALSE); + } + } + floaters_to_move.clear(); + + // ...then bringing my own dependents to the front... + for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); + dependent_it != child->mDependents.end(); ++dependent_it) + { + LLFloater* dependent = dependent_it->get(); + if (dependent) + { + sendChildToFront(dependent); + } + } + + // ...and finally bringing myself to front + // (do this last, so that I'm left in front at end of this call) + if (*beginChild() != child) + { + sendChildToFront(child); + } + + if(restore) + { + child->setMinimized(FALSE); + } + + if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) + { + child->setFocus(TRUE); + // floater did not take focus, so relinquish focus to world + if (!child->hasFocus()) + { + gFocusMgr.setKeyboardFocus(NULL); + } + } } void LLFloaterView::highlightFocusedFloater() { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater *floater = (LLFloater *)(*child_it); - - // skip dependent floaters, as we'll handle them in a batch along with their dependee(?) - if (floater->isDependent()) - { - continue; - } - - BOOL floater_or_dependent_has_focus = gFocusMgr.childHasKeyboardFocus(floater); - for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); - ++dependent_it) - { - LLFloater* dependent_floaterp = dependent_it->get(); - if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) - { - floater_or_dependent_has_focus = TRUE; - } - } - - // now set this floater and all its dependents - floater->setForeground(floater_or_dependent_has_focus); - - for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); ) - { - LLFloater* dependent_floaterp = dependent_it->get(); - if (dependent_floaterp) - { - dependent_floaterp->setForeground(floater_or_dependent_has_focus); - } - ++dependent_it; - } - - floater->cleanupHandles(); - } + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater *floater = (LLFloater *)(*child_it); + + // skip dependent floaters, as we'll handle them in a batch along with their dependee(?) + if (floater->isDependent()) + { + continue; + } + + BOOL floater_or_dependent_has_focus = gFocusMgr.childHasKeyboardFocus(floater); + for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); + ++dependent_it) + { + LLFloater* dependent_floaterp = dependent_it->get(); + if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) + { + floater_or_dependent_has_focus = TRUE; + } + } + + // now set this floater and all its dependents + floater->setForeground(floater_or_dependent_has_focus); + + for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); ) + { + LLFloater* dependent_floaterp = dependent_it->get(); + if (dependent_floaterp) + { + dependent_floaterp->setForeground(floater_or_dependent_has_focus); + } + ++dependent_it; + } + + floater->cleanupHandles(); + } } LLFloater* LLFloaterView::getFrontmostClosableFloater() { - child_list_const_iter_t child_it; - LLFloater* frontmost_floater = NULL; + child_list_const_iter_t child_it; + LLFloater* frontmost_floater = NULL; - for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - frontmost_floater = (LLFloater *)(*child_it); + for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + frontmost_floater = (LLFloater *)(*child_it); - if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable()) - { - return frontmost_floater; - } - } + if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable()) + { + return frontmost_floater; + } + } - return NULL; + return NULL; } void LLFloaterView::unhighlightFocusedFloater() { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater *floater = (LLFloater *)(*child_it); + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater *floater = (LLFloater *)(*child_it); - floater->setForeground(FALSE); - } + floater->setForeground(FALSE); + } } void LLFloaterView::focusFrontFloater() { - LLFloater* floaterp = getFrontmost(); - if (floaterp) - { - floaterp->setFocus(TRUE); - } + LLFloater* floaterp = getFrontmost(); + if (floaterp) + { + floaterp->setFocus(TRUE); + } } void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) { - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); - S32 floater_header_size = default_params.header_height; - static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); - LLRect snap_rect_local = getLocalSnapRect(); - snap_rect_local.mTop += mMinimizePositionVOffset; - for(S32 col = snap_rect_local.mLeft; - col < snap_rect_local.getWidth() - minimized_width; - col += minimized_width) - { - for(S32 row = snap_rect_local.mTop - floater_header_size; - row > floater_header_size; - row -= floater_header_size ) //loop rows - { - - bool foundGap = TRUE; - for(child_list_const_iter_t child_it = getChildList()->begin(); - child_it != getChildList()->end(); - ++child_it) //loop floaters - { - // Examine minimized children. - LLFloater* floater = dynamic_cast(*child_it); - if(floater->isMinimized()) - { - LLRect r = floater->getRect(); - if((r.mBottom < (row + floater_header_size)) - && (r.mBottom > (row - floater_header_size)) - && (r.mLeft < (col + minimized_width)) - && (r.mLeft > (col - minimized_width))) - { - // needs the check for off grid. can't drag, - // but window resize makes them off - foundGap = FALSE; - break; - } - } - } //done floaters - if(foundGap) - { - *left = col; - *bottom = row; - return; //done - } - } //done this col - } - - // crude - stack'em all at 0,0 when screen is full of minimized - // floaters. - *left = snap_rect_local.mLeft; - *bottom = snap_rect_local.mBottom; + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); + LLRect snap_rect_local = getLocalSnapRect(); + snap_rect_local.mTop += mMinimizePositionVOffset; + for(S32 col = snap_rect_local.mLeft; + col < snap_rect_local.getWidth() - minimized_width; + col += minimized_width) + { + for(S32 row = snap_rect_local.mTop - floater_header_size; + row > floater_header_size; + row -= floater_header_size ) //loop rows + { + + bool foundGap = TRUE; + for(child_list_const_iter_t child_it = getChildList()->begin(); + child_it != getChildList()->end(); + ++child_it) //loop floaters + { + // Examine minimized children. + LLFloater* floater = dynamic_cast(*child_it); + if(floater->isMinimized()) + { + LLRect r = floater->getRect(); + if((r.mBottom < (row + floater_header_size)) + && (r.mBottom > (row - floater_header_size)) + && (r.mLeft < (col + minimized_width)) + && (r.mLeft > (col - minimized_width))) + { + // needs the check for off grid. can't drag, + // but window resize makes them off + foundGap = FALSE; + break; + } + } + } //done floaters + if(foundGap) + { + *left = col; + *bottom = row; + return; //done + } + } //done this col + } + + // crude - stack'em all at 0,0 when screen is full of minimized + // floaters. + *left = snap_rect_local.mLeft; + *bottom = snap_rect_local.mBottom; } void LLFloaterView::destroyAllChildren() { - LLView::deleteAllChildren(); + LLView::deleteAllChildren(); } void LLFloaterView::closeAllChildren(bool app_quitting) { - // iterate over a copy of the list, because closing windows will destroy - // some windows on the list. - child_list_t child_list = *(getChildList()); - - for (child_list_const_iter_t it = child_list.begin(); it != child_list.end(); ++it) - { - LLView* viewp = *it; - child_list_const_iter_t exists = std::find(getChildList()->begin(), getChildList()->end(), viewp); - if (exists == getChildList()->end()) - { - // this floater has already been removed - continue; - } - - LLFloater* floaterp = dynamic_cast(viewp); - - // Attempt to close floater. This will cause the "do you want to save" - // dialogs to appear. - // Skip invisible floaters if we're not quitting (STORM-192). - if (floaterp->canClose() && !floaterp->isDead() && - (app_quitting || floaterp->getVisible())) - { - floaterp->closeFloater(app_quitting); - } - } + // iterate over a copy of the list, because closing windows will destroy + // some windows on the list. + child_list_t child_list = *(getChildList()); + + for (child_list_const_iter_t it = child_list.begin(); it != child_list.end(); ++it) + { + LLView* viewp = *it; + child_list_const_iter_t exists = std::find(getChildList()->begin(), getChildList()->end(), viewp); + if (exists == getChildList()->end()) + { + // this floater has already been removed + continue; + } + + LLFloater* floaterp = dynamic_cast(viewp); + + // Attempt to close floater. This will cause the "do you want to save" + // dialogs to appear. + // Skip invisible floaters if we're not quitting (STORM-192). + if (floaterp->canClose() && !floaterp->isDead() && + (app_quitting || floaterp->getVisible())) + { + floaterp->closeFloater(app_quitting); + } + } } void LLFloaterView::hiddenFloaterClosed(LLFloater* floater) { - for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); - it != end_it; - ++it) - { - if (it->first.get() == floater) - { - it->second.disconnect(); - mHiddenFloaters.erase(it); - break; - } - } + for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); + it != end_it; + ++it) + { + if (it->first.get() == floater) + { + it->second.disconnect(); + mHiddenFloaters.erase(it); + break; + } + } } void LLFloaterView::hideAllFloaters() { - child_list_t child_list = *(getChildList()); + child_list_t child_list = *(getChildList()); - for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); - if (floaterp && floaterp->getVisible()) - { - floaterp->setVisible(false); - boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp)); - mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection)); - } - } + for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); + if (floaterp && floaterp->getVisible()) + { + floaterp->setVisible(false); + boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp)); + mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection)); + } + } } void LLFloaterView::showHiddenFloaters() { - for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); - it != end_it; - ++it) - { - LLFloater* floaterp = it->first.get(); - if (floaterp) - { - floaterp->setVisible(true); - } - it->second.disconnect(); - } - mHiddenFloaters.clear(); + for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); + it != end_it; + ++it) + { + LLFloater* floaterp = it->first.get(); + if (floaterp) + { + floaterp->setVisible(true); + } + it->second.disconnect(); + } + mHiddenFloaters.clear(); } BOOL LLFloaterView::allChildrenClosed() { - // see if there are any visible floaters (some floaters "close" - // by setting themselves invisible) - for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); + // see if there are any visible floaters (some floaters "close" + // by setting themselves invisible) + for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); - if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) - { - return false; - } - } - return true; + if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) + { + return false; + } + } + return true; } void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset) { - for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); + for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); - if (floaterp && floaterp->isMinimized()) - { - floaterp->translate(x_offset, y_offset); - } - } + if (floaterp && floaterp->isMinimized()) + { + floaterp->translate(x_offset, y_offset); + } + } } void LLFloaterView::refresh() { - LLRect snap_rect = getSnapRect(); - if (snap_rect != mLastSnapRect) - { - reshape(getRect().getWidth(), getRect().getHeight(), TRUE); - } - - // Constrain children to be entirely on the screen - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (floaterp && floaterp->getVisible() ) - { - // minimized floaters are kept fully onscreen - adjustToFitScreen(floaterp, !floaterp->isMinimized()); - } - } + LLRect snap_rect = getSnapRect(); + if (snap_rect != mLastSnapRect) + { + reshape(getRect().getWidth(), getRect().getHeight(), TRUE); + } + + // Constrain children to be entirely on the screen + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (floaterp && floaterp->getVisible() ) + { + // minimized floaters are kept fully onscreen + adjustToFitScreen(floaterp, !floaterp->isMinimized()); + } + } } void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/) { - if (floater->getParent() != this) - { - // floater is hosted elsewhere, so ignore - return; - } - LLRect::tCoordType screen_width = getSnapRect().getWidth(); - LLRect::tCoordType screen_height = getSnapRect().getHeight(); - - - // only automatically resize non-minimized, resizable floaters - if( floater->isResizable() && !floater->isMinimized() ) - { - LLRect view_rect = floater->getRect(); - S32 old_width = view_rect.getWidth(); - S32 old_height = view_rect.getHeight(); - S32 min_width; - S32 min_height; - floater->getResizeLimits( &min_width, &min_height ); - - // Make sure floater isn't already smaller than its min height/width? - S32 new_width = llmax( min_width, old_width ); - S32 new_height = llmax( min_height, old_height); - - if((new_width > screen_width) || (new_height > screen_height)) - { - // We have to make this window able to fit on screen - new_width = llmin(new_width, screen_width); - new_height = llmin(new_height, screen_height); - - // ...while respecting minimum width/height - new_width = llmax(new_width, min_width); - new_height = llmax(new_height, min_height); - - LLRect new_rect; - new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height); - - floater->setShape(new_rect); - - if (floater->followsRight()) - { - floater->translate(old_width - new_width, 0); - } - - if (floater->followsTop()) - { - floater->translate(0, old_height - new_height); - } - } - } - - const LLRect& floater_rect = floater->getRect(); - - S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0; - S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0; - S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0; - - // move window fully onscreen - if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX )) - { - floater->clearSnapTarget(); - } - else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom) - { - floater->translate(delta_left, 0); - } - else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight) - { - floater->translate(0, delta_bottom); - } - else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom) - { - floater->translate(delta_right, 0); - } + if (floater->getParent() != this) + { + // floater is hosted elsewhere, so ignore + return; + } + LLRect::tCoordType screen_width = getSnapRect().getWidth(); + LLRect::tCoordType screen_height = getSnapRect().getHeight(); + + + // only automatically resize non-minimized, resizable floaters + if( floater->isResizable() && !floater->isMinimized() ) + { + LLRect view_rect = floater->getRect(); + S32 old_width = view_rect.getWidth(); + S32 old_height = view_rect.getHeight(); + S32 min_width; + S32 min_height; + floater->getResizeLimits( &min_width, &min_height ); + + // Make sure floater isn't already smaller than its min height/width? + S32 new_width = llmax( min_width, old_width ); + S32 new_height = llmax( min_height, old_height); + + if((new_width > screen_width) || (new_height > screen_height)) + { + // We have to make this window able to fit on screen + new_width = llmin(new_width, screen_width); + new_height = llmin(new_height, screen_height); + + // ...while respecting minimum width/height + new_width = llmax(new_width, min_width); + new_height = llmax(new_height, min_height); + + LLRect new_rect; + new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height); + + floater->setShape(new_rect); + + if (floater->followsRight()) + { + floater->translate(old_width - new_width, 0); + } + + if (floater->followsTop()) + { + floater->translate(0, old_height - new_height); + } + } + } + + const LLRect& floater_rect = floater->getRect(); + + S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0; + S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0; + S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0; + + // move window fully onscreen + if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX )) + { + floater->clearSnapTarget(); + } + else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom) + { + floater->translate(delta_left, 0); + } + else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight) + { + floater->translate(0, delta_bottom); + } + else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom) + { + floater->translate(delta_right, 0); + } } void LLFloaterView::draw() { - refresh(); + refresh(); - // hide focused floater if in cycle mode, so that it can be drawn on top - LLFloater* focused_floater = getFocusedFloater(); + // hide focused floater if in cycle mode, so that it can be drawn on top + LLFloater* focused_floater = getFocusedFloater(); - if (mFocusCycleMode && focused_floater) - { - child_list_const_iter_t child_it = getChildList()->begin(); - for (;child_it != getChildList()->end(); ++child_it) - { - if ((*child_it) != focused_floater) - { - drawChild(*child_it); - } - } + if (mFocusCycleMode && focused_floater) + { + child_list_const_iter_t child_it = getChildList()->begin(); + for (;child_it != getChildList()->end(); ++child_it) + { + if ((*child_it) != focused_floater) + { + drawChild(*child_it); + } + } - drawChild(focused_floater, -TABBED_FLOATER_OFFSET, TABBED_FLOATER_OFFSET); - } - else - { - LLView::draw(); - } + drawChild(focused_floater, -TABBED_FLOATER_OFFSET, TABBED_FLOATER_OFFSET); + } + else + { + LLView::draw(); + } } LLRect LLFloaterView::getSnapRect() const { - LLRect snap_rect = getLocalRect(); + LLRect snap_rect = getLocalRect(); - LLView* snap_view = mSnapView.get(); - if (snap_view) - { - snap_view->localRectToOtherView(snap_view->getLocalRect(), &snap_rect, this); - } + LLView* snap_view = mSnapView.get(); + if (snap_view) + { + snap_view->localRectToOtherView(snap_view->getLocalRect(), &snap_rect, this); + } - return snap_rect; + return snap_rect; } LLFloater *LLFloaterView::getFocusedFloater() const { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - if ((*child_it)->isCtrl()) - { - LLFloater* ctrlp = dynamic_cast(*child_it); - if ( ctrlp && ctrlp->hasFocus() ) - { - return ctrlp; - } - } - } - return NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + if ((*child_it)->isCtrl()) + { + LLFloater* ctrlp = dynamic_cast(*child_it); + if ( ctrlp && ctrlp->hasFocus() ) + { + return ctrlp; + } + } + } + return NULL; } LLFloater *LLFloaterView::getFrontmost() const { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if ( viewp->getVisible() && !viewp->isDead()) - { - return (LLFloater *)viewp; - } - } - return NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if ( viewp->getVisible() && !viewp->isDead()) + { + return (LLFloater *)viewp; + } + } + return NULL; } LLFloater *LLFloaterView::getBackmost() const { - LLFloater* back_most = NULL; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if ( viewp->getVisible() ) - { - back_most = (LLFloater *)viewp; - } - } - return back_most; + LLFloater* back_most = NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if ( viewp->getVisible() ) + { + back_most = (LLFloater *)viewp; + } + } + return back_most; } void LLFloaterView::syncFloaterTabOrder() { - // look for a visible modal dialog, starting from first - LLModalDialog* modal_dialog = NULL; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLModalDialog* dialog = dynamic_cast(*child_it); - if (dialog && dialog->isModal() && dialog->getVisible()) - { - modal_dialog = dialog; - break; - } - } - - if (modal_dialog) - { - // If we have a visible modal dialog, make sure that it has focus - LLUI::addPopup(modal_dialog); - - if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) - { - modal_dialog->setFocus(TRUE); - } - - if( !gFocusMgr.childHasMouseCapture( modal_dialog ) ) - { - gFocusMgr.setMouseCapture( modal_dialog ); - } - } - else - { - // otherwise, make sure the focused floater is in the front of the child list - for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (gFocusMgr.childHasKeyboardFocus(floaterp)) - { - bringToFront(floaterp, FALSE); - break; - } - } - } -} - -LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const -{ - LLView* parentp = viewp->getParent(); - - while(parentp && parentp != this) - { - viewp = parentp; - parentp = parentp->getParent(); - } - - if (parentp == this) - { - return dynamic_cast(viewp); - } - - return NULL; + // look for a visible modal dialog, starting from first + LLModalDialog* modal_dialog = NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLModalDialog* dialog = dynamic_cast(*child_it); + if (dialog && dialog->isModal() && dialog->getVisible()) + { + modal_dialog = dialog; + break; + } + } + + if (modal_dialog) + { + // If we have a visible modal dialog, make sure that it has focus + LLUI::addPopup(modal_dialog); + + if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) + { + modal_dialog->setFocus(TRUE); + } + + if( !gFocusMgr.childHasMouseCapture( modal_dialog ) ) + { + gFocusMgr.setMouseCapture( modal_dialog ); + } + } + else + { + // otherwise, make sure the focused floater is in the front of the child list + for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (gFocusMgr.childHasKeyboardFocus(floaterp)) + { + bringToFront(floaterp, FALSE); + break; + } + } + } +} + +LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const +{ + LLView* parentp = viewp->getParent(); + + while(parentp && parentp != this) + { + viewp = parentp; + parentp = parentp->getParent(); + } + + if (parentp == this) + { + return dynamic_cast(viewp); + } + + return NULL; } S32 LLFloaterView::getZOrder(LLFloater* child) { - S32 rv = 0; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if(viewp == child) - { - break; - } - ++rv; - } - return rv; + S32 rv = 0; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if(viewp == child) + { + break; + } + ++rv; + } + return rv; } void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list) { - for (child_list_const_iter_t child_iter = getChildList()->begin(); - child_iter != getChildList()->end(); ++child_iter) - { - LLView *view = *child_iter; - if (skip_list.find(view) == skip_list.end()) - { - view->pushVisible(visible); - } - } + for (child_list_const_iter_t child_iter = getChildList()->begin(); + child_iter != getChildList()->end(); ++child_iter) + { + LLView *view = *child_iter; + if (skip_list.find(view) == skip_list.end()) + { + view->pushVisible(visible); + } + } - LLFloaterReg::blockShowFloaters(true); + LLFloaterReg::blockShowFloaters(true); } void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) { - // make a copy of the list since some floaters change their - // order in the childList when changing visibility. - child_list_t child_list_copy = *getChildList(); + // make a copy of the list since some floaters change their + // order in the childList when changing visibility. + child_list_t child_list_copy = *getChildList(); - for (child_list_const_iter_t child_iter = child_list_copy.begin(); - child_iter != child_list_copy.end(); ++child_iter) - { - LLView *view = *child_iter; - if (skip_list.find(view) == skip_list.end()) - { - view->popVisible(); - } - } + for (child_list_const_iter_t child_iter = child_list_copy.begin(); + child_iter != child_list_copy.end(); ++child_iter) + { + LLView *view = *child_iter; + if (skip_list.find(view) == skip_list.end()) + { + view->popVisible(); + } + } - LLFloaterReg::blockShowFloaters(false); + LLFloaterReg::blockShowFloaters(false); } void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect) { - switch (tb) - { - case LLToolBarEnums::TOOLBAR_LEFT: - mToolbarLeftRect = toolbar_rect; - break; - case LLToolBarEnums::TOOLBAR_BOTTOM: - mToolbarBottomRect = toolbar_rect; - break; - case LLToolBarEnums::TOOLBAR_RIGHT: - mToolbarRightRect = toolbar_rect; - break; - default: - LL_WARNS() << "setToolbarRect() passed odd toolbar number " << (S32) tb << LL_ENDL; - break; - } + switch (tb) + { + case LLToolBarEnums::TOOLBAR_LEFT: + mToolbarLeftRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_BOTTOM: + mToolbarBottomRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_RIGHT: + mToolbarRightRect = toolbar_rect; + break; + default: + LL_WARNS() << "setToolbarRect() passed odd toolbar number " << (S32) tb << LL_ENDL; + break; + } } void LLFloater::setInstanceName(const std::string& name) { - if (name != mInstanceName) - { - llassert_always(mInstanceName.empty()); - mInstanceName = name; - if (!mInstanceName.empty()) - { - std::string ctrl_name = getControlName(mInstanceName, mKey); - initRectControl(); - if (!mVisibilityControl.empty()) - { - mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); - } - if(!mDocStateControl.empty()) - { - mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); - } - } + if (name != mInstanceName) + { + llassert_always(mInstanceName.empty()); + mInstanceName = name; + if (!mInstanceName.empty()) + { + std::string ctrl_name = getControlName(mInstanceName, mKey); + initRectControl(); + if (!mVisibilityControl.empty()) + { + mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); + } + if(!mDocStateControl.empty()) + { + mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); + } + } } } void LLFloater::setKey(const LLSD& newkey) { - // Note: We don't have to do anything special with registration when we change keys - mKey = newkey; + // Note: We don't have to do anything special with registration when we change keys + mKey = newkey; } //static void LLFloater::setupParamsForExport(Params& p, LLView* parent) { - // Do rectangle munging to topleft layout first - LLPanel::setupParamsForExport(p, parent); + // Do rectangle munging to topleft layout first + LLPanel::setupParamsForExport(p, parent); - // Copy the rectangle out to apply layout constraints - LLRect rect = p.rect; + // Copy the rectangle out to apply layout constraints + LLRect rect = p.rect; - // Null out other settings - p.rect.left.setProvided(false); - p.rect.top.setProvided(false); - p.rect.right.setProvided(false); - p.rect.bottom.setProvided(false); + // Null out other settings + p.rect.left.setProvided(false); + p.rect.top.setProvided(false); + p.rect.right.setProvided(false); + p.rect.bottom.setProvided(false); - // Explicitly set width/height - p.rect.width.set( rect.getWidth(), true ); - p.rect.height.set( rect.getHeight(), true ); + // Explicitly set width/height + p.rect.width.set( rect.getWidth(), true ); + p.rect.height.set( rect.getHeight(), true ); - // If you can't resize this floater, don't export min_height - // and min_width - bool can_resize = p.can_resize; - if (!can_resize) - { - p.min_height.setProvided(false); - p.min_width.setProvided(false); - } + // If you can't resize this floater, don't export min_height + // and min_width + bool can_resize = p.can_resize; + if (!can_resize) + { + p.min_height.setProvided(false); + p.min_width.setProvided(false); + } } void LLFloater::initFromParams(const LLFloater::Params& p) { - // *NOTE: We have too many classes derived from LLFloater to retrofit them - // all to pass in params via constructors. So we use this method. - - // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible - LLPanel::initFromParams(p); - - // override any follows flags - if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED) - { - setFollows(FOLLOWS_NONE); - } - - mTitle = p.title; - mShortTitle = p.short_title; - applyTitle(); - - setCanTearOff(p.can_tear_off); - setCanMinimize(p.can_minimize); - setCanClose(p.can_close); - setCanDock(p.can_dock); - setCanResize(p.can_resize); - setResizeLimits(p.min_width, p.min_height); - - mDragOnLeft = p.can_drag_on_left; - mHeaderHeight = p.header_height; - mLegacyHeaderHeight = p.legacy_header_height; - mSingleInstance = p.single_instance; - mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; - - mPositioning = p.positioning; - - mSaveRect = p.save_rect; - if (p.save_visibility) - { - mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set - } - if(p.save_dock_state) - { - mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set - } - - // open callback - if (p.open_callback.isProvided()) - { - setOpenCallback(initCommitCallback(p.open_callback)); - } - // close callback - if (p.close_callback.isProvided()) - { - setCloseCallback(initCommitCallback(p.close_callback)); - } - - if (mDragHandle) - { - mDragHandle->setTitleVisible(p.show_title); - } + // *NOTE: We have too many classes derived from LLFloater to retrofit them + // all to pass in params via constructors. So we use this method. + + // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible + LLPanel::initFromParams(p); + + // override any follows flags + if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED) + { + setFollows(FOLLOWS_NONE); + } + + mTitle = p.title; + mShortTitle = p.short_title; + applyTitle(); + + setCanTearOff(p.can_tear_off); + setCanMinimize(p.can_minimize); + setCanClose(p.can_close); + setCanDock(p.can_dock); + setCanResize(p.can_resize); + setResizeLimits(p.min_width, p.min_height); + + mDragOnLeft = p.can_drag_on_left; + mHeaderHeight = p.header_height; + mLegacyHeaderHeight = p.legacy_header_height; + mSingleInstance = p.single_instance; + mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; + + mPositioning = p.positioning; + + mSaveRect = p.save_rect; + if (p.save_visibility) + { + mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set + } + if(p.save_dock_state) + { + mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set + } + + // open callback + if (p.open_callback.isProvided()) + { + setOpenCallback(initCommitCallback(p.open_callback)); + } + // close callback + if (p.close_callback.isProvided()) + { + setCloseCallback(initCommitCallback(p.close_callback)); + } + + if (mDragHandle) + { + mDragHandle->setTitleVisible(p.show_title); + } } boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_t::slot_type& cb ) { - if (!mMinimizeSignal) mMinimizeSignal = new commit_signal_t(); - return mMinimizeSignal->connect(cb); + if (!mMinimizeSignal) mMinimizeSignal = new commit_signal_t(); + return mMinimizeSignal->connect(cb); } boost::signals2::connection LLFloater::setOpenCallback( const commit_signal_t::slot_type& cb ) { - return mOpenSignal.connect(cb); + return mOpenSignal.connect(cb); } boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb ) { - return mCloseSignal.connect(cb); + return mCloseSignal.connect(cb); } LLTrace::BlockTimerStatHandle POST_BUILD("Floater Post Build"); @@ -3181,127 +3181,127 @@ static LLTrace::BlockTimerStatHandle FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floa bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node) { - Params default_params(LLUICtrlFactory::getDefaultParams()); - Params params(default_params); - - LLXUIParser parser; - parser.readXUI(node, params, filename); // *TODO: Error checking - - std::string xml_filename = params.filename; - - if (!xml_filename.empty()) - { - LLXMLNodePtr referenced_xml; - - if (output_node) - { - //if we are exporting, we want to export the current xml - //not the referenced xml - Params output_params; - parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName()); - setupParamsForExport(output_params, parent); - output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); - return TRUE; - } - - LLUICtrlFactory::instance().pushFileName(xml_filename); - - LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD); - if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) - { - LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; - - return FALSE; - } - - Params referenced_params; - parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName()); - params.fillFrom(referenced_params); - - // add children using dimensions from referenced xml for consistent layout - setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); - - LLUICtrlFactory::instance().popFileName(); - } - - - if (output_node) - { - Params output_params(params); - setupParamsForExport(output_params, parent); - output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); - } - - // Default floater position to top-left corner of screen - // However, some legacy floaters have explicit top or bottom - // coordinates set, so respect their wishes. - if (!params.rect.top.isProvided() && !params.rect.bottom.isProvided()) - { - params.rect.top.set(0); - } - if (!params.rect.left.isProvided() && !params.rect.right.isProvided()) - { - params.rect.left.set(0); - } - params.from_xui = true; - applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect()); - initFromParams(params); - - initFloater(params); - - LLMultiFloater* last_host = LLFloater::getFloaterHost(); - if (node->hasName("multi_floater")) - { - LLFloater::setFloaterHost((LLMultiFloater*) this); - } - - LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); - - if (node->hasName("multi_floater")) - { - LLFloater::setFloaterHost(last_host); - } - - // HACK: When we changed the header height to 25 pixels in Viewer 2, rather - // than re-layout all the floaters we use this value in pixels to make the - // whole floater bigger and change the top-left coordinate for widgets. - // The goal is to eventually set mLegacyHeaderHeight to zero, which would - // make the top-left corner for widget layout the same as the top-left - // corner of the window's content area. James - S32 header_stretch = (mHeaderHeight - mLegacyHeaderHeight); - if (header_stretch > 0) - { - // Stretch the floater vertically, don't move widgets - LLRect rect = getRect(); - rect.mTop += header_stretch; - - // This will also update drag handle, title bar, close box, etc. - setRect(rect); - } - - BOOL result; - { - LL_RECORD_BLOCK_TIME(POST_BUILD); - - result = postBuild(); - } - - if (!result) - { - LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL; - } - - applyRectControl(); // If we have a saved rect control, apply it - gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen - - moveResizeHandlesToFront(); - - applyDockState(); - - return true; // *TODO: Error checking + Params default_params(LLUICtrlFactory::getDefaultParams()); + Params params(default_params); + + LLXUIParser parser; + parser.readXUI(node, params, filename); // *TODO: Error checking + + std::string xml_filename = params.filename; + + if (!xml_filename.empty()) + { + LLXMLNodePtr referenced_xml; + + if (output_node) + { + //if we are exporting, we want to export the current xml + //not the referenced xml + Params output_params; + parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName()); + setupParamsForExport(output_params, parent); + output_node->setName(node->getName()->mString); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); + return TRUE; + } + + LLUICtrlFactory::instance().pushFileName(xml_filename); + + LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD); + if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) + { + LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; + + return FALSE; + } + + Params referenced_params; + parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName()); + params.fillFrom(referenced_params); + + // add children using dimensions from referenced xml for consistent layout + setShape(params.rect); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); + + LLUICtrlFactory::instance().popFileName(); + } + + + if (output_node) + { + Params output_params(params); + setupParamsForExport(output_params, parent); + output_node->setName(node->getName()->mString); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); + } + + // Default floater position to top-left corner of screen + // However, some legacy floaters have explicit top or bottom + // coordinates set, so respect their wishes. + if (!params.rect.top.isProvided() && !params.rect.bottom.isProvided()) + { + params.rect.top.set(0); + } + if (!params.rect.left.isProvided() && !params.rect.right.isProvided()) + { + params.rect.left.set(0); + } + params.from_xui = true; + applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect()); + initFromParams(params); + + initFloater(params); + + LLMultiFloater* last_host = LLFloater::getFloaterHost(); + if (node->hasName("multi_floater")) + { + LLFloater::setFloaterHost((LLMultiFloater*) this); + } + + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); + + if (node->hasName("multi_floater")) + { + LLFloater::setFloaterHost(last_host); + } + + // HACK: When we changed the header height to 25 pixels in Viewer 2, rather + // than re-layout all the floaters we use this value in pixels to make the + // whole floater bigger and change the top-left coordinate for widgets. + // The goal is to eventually set mLegacyHeaderHeight to zero, which would + // make the top-left corner for widget layout the same as the top-left + // corner of the window's content area. James + S32 header_stretch = (mHeaderHeight - mLegacyHeaderHeight); + if (header_stretch > 0) + { + // Stretch the floater vertically, don't move widgets + LLRect rect = getRect(); + rect.mTop += header_stretch; + + // This will also update drag handle, title bar, close box, etc. + setRect(rect); + } + + BOOL result; + { + LL_RECORD_BLOCK_TIME(POST_BUILD); + + result = postBuild(); + } + + if (!result) + { + LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL; + } + + applyRectControl(); // If we have a saved rect control, apply it + gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen + + moveResizeHandlesToFront(); + + applyDockState(); + + return true; // *TODO: Error checking } bool LLFloater::isShown() const @@ -3311,7 +3311,7 @@ bool LLFloater::isShown() const bool LLFloater::isDetachedAndNotMinimized() { - return !getHost() && !isMinimized(); + return !getHost() && !isMinimized(); } /* static */ @@ -3336,205 +3336,205 @@ static LLTrace::BlockTimerStatHandle FTM_BUILD_FLOATERS("Build Floaters"); bool LLFloater::buildFromFile(const std::string& filename) { - LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS); - LLXMLNodePtr root; - - if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) - { - LL_WARNS() << "Couldn't find (or parse) floater from: " << filename << LL_ENDL; - return false; - } - - // root must be called floater - if( !(root->hasName("floater") || root->hasName("multi_floater")) ) - { - LL_WARNS() << "Root node should be named floater in: " << filename << LL_ENDL; - return false; - } - - bool res = true; - - LL_DEBUGS() << "Building floater " << filename << LL_ENDL; - LLUICtrlFactory::instance().pushFileName(filename); - { - if (!getFactoryMap().empty()) - { - LLPanel::sFactoryStack.push_front(&getFactoryMap()); - } - - // for local registry callbacks; define in constructor, referenced in XUI or postBuild - getCommitCallbackRegistrar().pushScope(); - getEnableCallbackRegistrar().pushScope(); - - res = initFloaterXML(root, getParent(), filename, NULL); - - setXMLFilename(filename); - - getCommitCallbackRegistrar().popScope(); - getEnableCallbackRegistrar().popScope(); - - if (!getFactoryMap().empty()) - { - LLPanel::sFactoryStack.pop_front(); - } - } - LLUICtrlFactory::instance().popFileName(); - - return res; + LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS); + LLXMLNodePtr root; + + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + { + LL_WARNS() << "Couldn't find (or parse) floater from: " << filename << LL_ENDL; + return false; + } + + // root must be called floater + if( !(root->hasName("floater") || root->hasName("multi_floater")) ) + { + LL_WARNS() << "Root node should be named floater in: " << filename << LL_ENDL; + return false; + } + + bool res = true; + + LL_DEBUGS() << "Building floater " << filename << LL_ENDL; + LLUICtrlFactory::instance().pushFileName(filename); + { + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.push_front(&getFactoryMap()); + } + + // for local registry callbacks; define in constructor, referenced in XUI or postBuild + getCommitCallbackRegistrar().pushScope(); + getEnableCallbackRegistrar().pushScope(); + + res = initFloaterXML(root, getParent(), filename, NULL); + + setXMLFilename(filename); + + getCommitCallbackRegistrar().popScope(); + getEnableCallbackRegistrar().popScope(); + + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.pop_front(); + } + } + LLUICtrlFactory::instance().popFileName(); + + return res; } void LLFloater::stackWith(LLFloater& other) { - static LLUICachedControl floater_offset ("UIFloaterOffset", 16); + static LLUICachedControl floater_offset ("UIFloaterOffset", 16); - LLRect next_rect; - if (other.getHost()) - { - next_rect = other.getHost()->getRect(); - } - else - { - next_rect = other.getRect(); - } - next_rect.translate(floater_offset, -floater_offset); + LLRect next_rect; + if (other.getHost()) + { + next_rect = other.getHost()->getRect(); + } + else + { + next_rect = other.getRect(); + } + next_rect.translate(floater_offset, -floater_offset); - next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); - - setShape(next_rect); + next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); + + setShape(next_rect); - if (!other.getHost()) - { - other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; - other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); - } + if (!other.getHost()) + { + other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; + other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); + } } void LLFloater::applyRelativePosition() { - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - LLRect floater_screen_rect = calcScreenRect(); + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + LLRect floater_screen_rect = calcScreenRect(); - LLCoordGL new_center = mPosition.convert(); - LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY()); - translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); + LLCoordGL new_center = mPosition.convert(); + LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY()); + translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); } LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater) -: coord_t((S32)x, (S32)y) +: coord_t((S32)x, (S32)y) { - mFloater = floater.getHandle(); + mFloater = floater.getHandle(); } LLCoordFloater::LLCoordFloater(const LLCoordCommon& other, LLFloater& floater) { - mFloater = floater.getHandle(); - convertFromCommon(other); + mFloater = floater.getHandle(); + convertFromCommon(other); } LLCoordFloater& LLCoordFloater::operator=(const LLCoordFloater& other) { - mFloater = other.mFloater; - coord_t::operator =(other); - return *this; + mFloater = other.mFloater; + coord_t::operator =(other); + return *this; } void LLCoordFloater::setFloater(LLFloater& floater) { - mFloater = floater.getHandle(); + mFloater = floater.getHandle(); } bool LLCoordFloater::operator==(const LLCoordFloater& other) const { - return mX == other.mX && mY == other.mY && mFloater == other.mFloater; + return mX == other.mX && mY == other.mY && mFloater == other.mFloater; } LLCoordCommon LL_COORD_FLOATER::convertToCommon() const { - const LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); - - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - - LLFloater* floaterp = mFloater.get(); - S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; - S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; - LLCoordCommon out; - if (self.mX < -0.5f) - { - out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft)); - } - else if (self.mX > 0.5f) - { - out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)); - } - else - { - out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width)); - } - - if (self.mY < -0.5f) - { - out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom)); - } - else if (self.mY > 0.5f) - { - out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)); - } - else - { - out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height)); - } - - // return center point instead of lower left - out.mX += floater_width / 2; - out.mY += floater_height / 2; - - return out; + const LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); + + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + + LLFloater* floaterp = mFloater.get(); + S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; + S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; + LLCoordCommon out; + if (self.mX < -0.5f) + { + out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft)); + } + else if (self.mX > 0.5f) + { + out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)); + } + else + { + out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width)); + } + + if (self.mY < -0.5f) + { + out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom)); + } + else if (self.mY > 0.5f) + { + out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)); + } + else + { + out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height)); + } + + // return center point instead of lower left + out.mX += floater_width / 2; + out.mY += floater_height / 2; + + return out; } void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from) { - LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - - - LLFloater* floaterp = mFloater.get(); - S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; - S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; - - S32 from_x = from.mX - floater_width / 2; - S32 from_y = from.mY - floater_height / 2; - - if (from_x < snap_rect.mLeft) - { - self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f); - } - else if (from_x + floater_width > snap_rect.mRight) - { - self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); - } - else - { - self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f); - } - - if (from_y < snap_rect.mBottom) - { - self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f); - } - else if (from_y + floater_height > snap_rect.mTop) - { - self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); - } - else - { - self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f); - } + LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + + + LLFloater* floaterp = mFloater.get(); + S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; + S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; + + S32 from_x = from.mX - floater_width / 2; + S32 from_y = from.mY - floater_height / 2; + + if (from_x < snap_rect.mLeft) + { + self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f); + } + else if (from_x + floater_width > snap_rect.mRight) + { + self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); + } + else + { + self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f); + } + + if (from_y < snap_rect.mBottom) + { + self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f); + } + else if (from_y + floater_height > snap_rect.mTop) + { + self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); + } + else + { + self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f); + } } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index e53ecd30c2..1386f1290a 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -36,298 +36,298 @@ #include "llinitparam.h" #include "llview.h" -#include "llviewmodel.h" // *TODO move dependency to .cpp file +#include "llviewmodel.h" // *TODO move dependency to .cpp file const BOOL TAKE_FOCUS_YES = TRUE; const BOOL TAKE_FOCUS_NO = FALSE; class LLUICtrl - : public LLView, public boost::signals2::trackable + : public LLView, public boost::signals2::trackable { public: - typedef boost::function commit_callback_t; - typedef boost::signals2::signal commit_signal_t; - // *TODO: add xml support for this type of signal in the future - typedef boost::signals2::signal mouse_signal_t; - - typedef boost::function enable_callback_t; - typedef boost::signals2::signal enable_signal_t; - - struct CallbackParam : public LLInitParam::Block - { - Ignored name; - - Optional function_name; - Optional parameter; - - Optional control_name; - - CallbackParam(); - }; - - struct CommitCallbackParam : public LLInitParam::Block - { - Optional function; - }; - - // also used for visible callbacks - struct EnableCallbackParam : public LLInitParam::Block - { - Optional function; - }; - - struct EnableControls : public LLInitParam::ChoiceBlock - { - Alternative enabled; - Alternative disabled; - - EnableControls(); - }; - struct ControlVisibility : public LLInitParam::ChoiceBlock - { - Alternative visible; - Alternative invisible; - - ControlVisibility(); - }; - struct Params : public LLInitParam::Block - { - Optional label; - Optional tab_stop, - chrome, - requests_front; - Optional initial_value; - - Optional init_callback, - commit_callback; - Optional validate_callback; - - Optional mouseenter_callback, - mouseleave_callback; - - Optional control_name; - Optional enabled_controls; - Optional controls_visibility; - - // font params - Optional font; - Optional font_halign; - Optional font_valign; - - // cruft from LLXMLNode implementation - Ignored type, - length; - - Params(); - }; - - enum ETypeTransparency - { - TT_DEFAULT, - TT_ACTIVE, // focused floater - TT_INACTIVE, // other floaters - TT_FADING, // fading toast - }; - /*virtual*/ ~LLUICtrl(); - - void initFromParams(const Params& p); + typedef boost::function commit_callback_t; + typedef boost::signals2::signal commit_signal_t; + // *TODO: add xml support for this type of signal in the future + typedef boost::signals2::signal mouse_signal_t; + + typedef boost::function enable_callback_t; + typedef boost::signals2::signal enable_signal_t; + + struct CallbackParam : public LLInitParam::Block + { + Ignored name; + + Optional function_name; + Optional parameter; + + Optional control_name; + + CallbackParam(); + }; + + struct CommitCallbackParam : public LLInitParam::Block + { + Optional function; + }; + + // also used for visible callbacks + struct EnableCallbackParam : public LLInitParam::Block + { + Optional function; + }; + + struct EnableControls : public LLInitParam::ChoiceBlock + { + Alternative enabled; + Alternative disabled; + + EnableControls(); + }; + struct ControlVisibility : public LLInitParam::ChoiceBlock + { + Alternative visible; + Alternative invisible; + + ControlVisibility(); + }; + struct Params : public LLInitParam::Block + { + Optional label; + Optional tab_stop, + chrome, + requests_front; + Optional initial_value; + + Optional init_callback, + commit_callback; + Optional validate_callback; + + Optional mouseenter_callback, + mouseleave_callback; + + Optional control_name; + Optional enabled_controls; + Optional controls_visibility; + + // font params + Optional font; + Optional font_halign; + Optional font_valign; + + // cruft from LLXMLNode implementation + Ignored type, + length; + + Params(); + }; + + enum ETypeTransparency + { + TT_DEFAULT, + TT_ACTIVE, // focused floater + TT_INACTIVE, // other floaters + TT_FADING, // fading toast + }; + /*virtual*/ ~LLUICtrl(); + + void initFromParams(const Params& p); protected: - friend class LLUICtrlFactory; - static const Params& getDefaultParams(); - LLUICtrl(const Params& p = getDefaultParams(), + friend class LLUICtrlFactory; + static const Params& getDefaultParams(); + LLUICtrl(const Params& p = getDefaultParams(), const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel)); - - commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb); - enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb); + + commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb); + enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb); - // We need this virtual so we can override it with derived versions - virtual LLViewModel* getViewModel() const; + // We need this virtual so we can override it with derived versions + virtual LLViewModel* getViewModel() const; // We shouldn't ever need to set this directly //virtual void setViewModel(const LLViewModelPtr&); - virtual BOOL postBuild(); - + virtual BOOL postBuild(); + public: - // LLView interface - /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - /*virtual*/ BOOL isCtrl() const; - /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); - /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL canFocusChildren() const; - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - - // From LLFocusableElement - /*virtual*/ void setFocus( BOOL b ); - /*virtual*/ BOOL hasFocus() const; - - // New virtuals - - // Return NULL by default (overrride if the class has the appropriate interface) - virtual class LLCtrlSelectionInterface* getSelectionInterface(); - virtual class LLCtrlListInterface* getListInterface(); - virtual class LLCtrlScrollInterface* getScrollInterface(); - - bool setControlValue(const LLSD& value); - void setControlVariable(LLControlVariable* control); - virtual void setControlName(const std::string& control, LLView *context = NULL); - - LLControlVariable* getControlVariable() { return mControlVariable; } - - void setEnabledControlVariable(LLControlVariable* control); - void setDisabledControlVariable(LLControlVariable* control); - void setMakeVisibleControlVariable(LLControlVariable* control); - void setMakeInvisibleControlVariable(LLControlVariable* control); - - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; - virtual void setValue(const LLSD& value); - virtual LLSD getValue() const; + // LLView interface + /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + /*virtual*/ BOOL isCtrl() const; + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL canFocusChildren() const; + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + /*virtual*/ BOOL hasFocus() const; + + // New virtuals + + // Return NULL by default (overrride if the class has the appropriate interface) + virtual class LLCtrlSelectionInterface* getSelectionInterface(); + virtual class LLCtrlListInterface* getListInterface(); + virtual class LLCtrlScrollInterface* getScrollInterface(); + + bool setControlValue(const LLSD& value); + void setControlVariable(LLControlVariable* control); + virtual void setControlName(const std::string& control, LLView *context = NULL); + + LLControlVariable* getControlVariable() { return mControlVariable; } + + void setEnabledControlVariable(LLControlVariable* control); + void setDisabledControlVariable(LLControlVariable* control); + void setMakeVisibleControlVariable(LLControlVariable* control); + void setMakeInvisibleControlVariable(LLControlVariable* control); + + virtual void setTentative(BOOL b); + virtual BOOL getTentative() const; + virtual void setValue(const LLSD& value); + virtual LLSD getValue() const; /// When two widgets are displaying the same data (e.g. during a skin /// change), share their ViewModel. virtual void shareViewModelFrom(const LLUICtrl& other); - virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); - virtual void setIsChrome(BOOL is_chrome); - - virtual BOOL acceptsTextInput() const; // Defaults to false - - // A control is dirty if the user has modified its value. - // Editable controls should override this. - virtual BOOL isDirty() const; // Defauls to false - virtual void resetDirty(); //Defaults to no-op - - // Call appropriate callback - virtual void onCommit(); - - // Default to no-op: - virtual void onTabInto(); - - // Clear any user-provided input (text in a text editor, checked checkbox, - // selected radio button, etc.). Defaults to no-op. - virtual void clear(); - - virtual void setColor(const LLColor4& color); - - // Ansariel: Changed to virtual. We might want to change the transparency ourself! - virtual F32 getCurrentTransparency(); - - void setTransparencyType(ETypeTransparency type); - ETypeTransparency getTransparencyType() const {return mTransparencyType;} - - BOOL focusNextItem(BOOL text_entry_only); - BOOL focusPrevItem(BOOL text_entry_only); - BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); - - // Non Virtuals - LLHandle getHandle() const { return getDerivedHandle(); } - BOOL getIsChrome() const; - - void setTabStop( BOOL b ); - BOOL hasTabStop() const; - - LLUICtrl* getParentUICtrl() const; - - // return true if help topic found by crawling through parents - - // topic then put in help_topic_out - bool findHelpTopic(std::string& help_topic_out); - - boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb); - boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb); - - boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ); - boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ); - - boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ); - boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ); - - boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ); - - boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ); - - // *TODO: Deprecate; for backwards compatability only: - boost::signals2::connection setCommitCallback( boost::function cb, void* data); - boost::signals2::connection setValidateBeforeCommit( boost::function cb ); - - LLUICtrl* findRootMostFocusRoot(); - - class LLTextInputFilter : public LLQueryFilter, public LLSingleton - { - LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); - /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const - { - return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); - } - }; - - template class CallbackRegistry : public LLRegistrySingleton - {}; - - class CommitCallbackRegistry : public CallbackRegistry - { - LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); - }; - // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry - { - LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); - }; - + virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); + virtual void setIsChrome(BOOL is_chrome); + + virtual BOOL acceptsTextInput() const; // Defaults to false + + // A control is dirty if the user has modified its value. + // Editable controls should override this. + virtual BOOL isDirty() const; // Defauls to false + virtual void resetDirty(); //Defaults to no-op + + // Call appropriate callback + virtual void onCommit(); + + // Default to no-op: + virtual void onTabInto(); + + // Clear any user-provided input (text in a text editor, checked checkbox, + // selected radio button, etc.). Defaults to no-op. + virtual void clear(); + + virtual void setColor(const LLColor4& color); + + // Ansariel: Changed to virtual. We might want to change the transparency ourself! + virtual F32 getCurrentTransparency(); + + void setTransparencyType(ETypeTransparency type); + ETypeTransparency getTransparencyType() const {return mTransparencyType;} + + BOOL focusNextItem(BOOL text_entry_only); + BOOL focusPrevItem(BOOL text_entry_only); + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + + // Non Virtuals + LLHandle getHandle() const { return getDerivedHandle(); } + BOOL getIsChrome() const; + + void setTabStop( BOOL b ); + BOOL hasTabStop() const; + + LLUICtrl* getParentUICtrl() const; + + // return true if help topic found by crawling through parents - + // topic then put in help_topic_out + bool findHelpTopic(std::string& help_topic_out); + + boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb); + boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb); + + boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ); + boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ); + + boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ); + boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ); + + boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ); + + boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ); + + // *TODO: Deprecate; for backwards compatability only: + boost::signals2::connection setCommitCallback( boost::function cb, void* data); + boost::signals2::connection setValidateBeforeCommit( boost::function cb ); + + LLUICtrl* findRootMostFocusRoot(); + + class LLTextInputFilter : public LLQueryFilter, public LLSingleton + { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); + /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const + { + return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); + } + }; + + template class CallbackRegistry : public LLRegistrySingleton + {}; + + class CommitCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; + // the enable callback registry is also used for visiblity callbacks + class EnableCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; + protected: - static bool controlListener(const LLSD& newvalue, LLHandle handle, std::string type); + static bool controlListener(const LLSD& newvalue, LLHandle handle, std::string type); - commit_signal_t* mCommitSignal; - enable_signal_t* mValidateSignal; + commit_signal_t* mCommitSignal; + enable_signal_t* mValidateSignal; - commit_signal_t* mMouseEnterSignal; - commit_signal_t* mMouseLeaveSignal; - - mouse_signal_t* mMouseDownSignal; - mouse_signal_t* mMouseUpSignal; - mouse_signal_t* mRightMouseDownSignal; - mouse_signal_t* mRightMouseUpSignal; + commit_signal_t* mMouseEnterSignal; + commit_signal_t* mMouseLeaveSignal; + + mouse_signal_t* mMouseDownSignal; + mouse_signal_t* mMouseUpSignal; + mouse_signal_t* mRightMouseDownSignal; + mouse_signal_t* mRightMouseUpSignal; - mouse_signal_t* mDoubleClickSignal; - + mouse_signal_t* mDoubleClickSignal; + LLViewModelPtr mViewModel; - LLControlVariable* mControlVariable; - boost::signals2::connection mControlConnection; - LLControlVariable* mEnabledControlVariable; - boost::signals2::connection mEnabledControlConnection; - LLControlVariable* mDisabledControlVariable; - boost::signals2::connection mDisabledControlConnection; - LLControlVariable* mMakeVisibleControlVariable; - boost::signals2::connection mMakeVisibleControlConnection; - LLControlVariable* mMakeInvisibleControlVariable; - boost::signals2::connection mMakeInvisibleControlConnection; - - static F32 sActiveControlTransparency; - static F32 sInactiveControlTransparency; - - virtual void addInfo(LLSD & info); - + LLControlVariable* mControlVariable; + boost::signals2::connection mControlConnection; + LLControlVariable* mEnabledControlVariable; + boost::signals2::connection mEnabledControlConnection; + LLControlVariable* mDisabledControlVariable; + boost::signals2::connection mDisabledControlConnection; + LLControlVariable* mMakeVisibleControlVariable; + boost::signals2::connection mMakeVisibleControlConnection; + LLControlVariable* mMakeInvisibleControlVariable; + boost::signals2::connection mMakeInvisibleControlConnection; + + static F32 sActiveControlTransparency; + static F32 sInactiveControlTransparency; + + virtual void addInfo(LLSD & info); + private: - BOOL mIsChrome; - BOOL mRequestsFront; - BOOL mTabStop; - BOOL mTentative; + BOOL mIsChrome; + BOOL mRequestsFront; + BOOL mTabStop; + BOOL mTentative; - ETypeTransparency mTransparencyType; + ETypeTransparency mTransparencyType; }; // Build time optimization, generate once in .cpp file #ifndef LLUICTRL_CPP extern template class LLUICtrl* LLView::getChild( - const std::string& name, BOOL recurse) const; + const std::string& name, BOOL recurse) const; #endif #endif // LL_LLUICTRL_H diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index 338be1808d..be0ea8bb69 100755 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -38,13 +38,13 @@ // Stub for LLAvatarNameCache bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) { - return false; + return false; } LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { - callback_connection_t connection; - return connection; + callback_connection_t connection; + return connection; } // @@ -52,24 +52,24 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag // BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { - fullname = "Lynx Linden"; - return TRUE; + fullname = "Lynx Linden"; + return TRUE; } BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) { - group = "My Group"; - return TRUE; + group = "My Group"; + return TRUE; } boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { - return boost::signals2::connection(); + return boost::signals2::connection(); } boost::signals2::connection LLCacheName::getGroup(const LLUUID& id, const LLCacheNameCallback& callback) { - return boost::signals2::connection(); + return boost::signals2::connection(); } LLCacheName* gCacheName = NULL; @@ -80,12 +80,12 @@ LLCacheName* gCacheName = NULL; class LLTrans { public: - static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); + static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); }; std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { - return std::string(); + return std::string(); } // @@ -102,65 +102,65 @@ LLStyle::Params::Params() namespace LLInitParam { - ParamValue::ParamValue(const LLUIColor& color) - : super_t(color) - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) - { - return false; - } - - ParamValue::ParamValue(const LLFontGL* fontp) - : super_t(fontp) - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - void TypeValues::declareValues() - {} - - void TypeValues::declareValues() - {} - - void TypeValues::declareValues() - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - - bool ParamCompare::equals( - LLUIImage* const &a, - LLUIImage* const &b) - { - return false; - } - - bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) - { - return false; - } + ParamValue::ParamValue(const LLUIColor& color) + : super_t(color) + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + ParamValue::ParamValue(const LLFontGL* fontp) + : super_t(fontp) + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + + bool ParamCompare::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } } //static LLFontGL* LLFontGL::getFontDefault() { - return NULL; + return NULL; } char const* const _PREHASH_AgentData = (char *)"AgentData"; -- cgit v1.2.3 From ac2fc3029f3b9b6ba182949c29a7919f2f87eb02 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Tue, 12 Mar 2019 08:56:26 -0700 Subject: Backout tabs v spaces changes. 'warn-on-failure:no-tabs' --- indra/llui/llfloater.cpp | 5446 +++++++++++++++++----------------- indra/llui/lluictrl.h | 518 ++-- indra/llui/tests/llurlentry_stub.cpp | 128 +- 3 files changed, 3046 insertions(+), 3046 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 6b325f6232..2dcc62ce79 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -43,7 +43,7 @@ #include "llresizebar.h" #include "llresizehandle.h" #include "llkeyboard.h" -#include "llmenugl.h" // MENU_BAR_HEIGHT +#include "llmenugl.h" // MENU_BAR_HEIGHT #include "llmodaldialog.h" #include "lltextbox.h" #include "llresmgr.h" @@ -65,23 +65,23 @@ const S32 TABBED_FLOATER_OFFSET = 0; namespace LLInitParam { - void TypeValues::declareValues() - { - declare("relative", LLFloaterEnums::POSITIONING_RELATIVE); - declare("cascading", LLFloaterEnums::POSITIONING_CASCADING); - declare("centered", LLFloaterEnums::POSITIONING_CENTERED); - declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED); - } + void TypeValues::declareValues() + { + declare("relative", LLFloaterEnums::POSITIONING_RELATIVE); + declare("cascading", LLFloaterEnums::POSITIONING_CASCADING); + declare("centered", LLFloaterEnums::POSITIONING_CENTERED); + declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED); + } } -std::string LLFloater::sButtonNames[BUTTON_COUNT] = +std::string LLFloater::sButtonNames[BUTTON_COUNT] = { - "llfloater_close_btn", //BUTTON_CLOSE - "llfloater_restore_btn", //BUTTON_RESTORE - "llfloater_minimize_btn", //BUTTON_MINIMIZE - "llfloater_tear_off_btn", //BUTTON_TEAR_OFF - "llfloater_dock_btn", //BUTTON_DOCK - "llfloater_help_btn" //BUTTON_HELP + "llfloater_close_btn", //BUTTON_CLOSE + "llfloater_restore_btn", //BUTTON_RESTORE + "llfloater_minimize_btn", //BUTTON_MINIMIZE + "llfloater_tear_off_btn", //BUTTON_TEAR_OFF + "llfloater_dock_btn", //BUTTON_DOCK + "llfloater_help_btn" //BUTTON_HELP }; std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; @@ -89,29 +89,29 @@ std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= { #ifdef LL_DARWIN - "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE #else - "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE #endif - "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE - "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE - "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF - "BUTTON_DOCK", - "BUTTON_HELP" + "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE + "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE + "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF + "BUTTON_DOCK", + "BUTTON_HELP" }; LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = { - LLFloater::onClickClose, //BUTTON_CLOSE - LLFloater::onClickMinimize, //BUTTON_RESTORE - LLFloater::onClickMinimize, //BUTTON_MINIMIZE - LLFloater::onClickTearOff, //BUTTON_TEAR_OFF - LLFloater::onClickDock, //BUTTON_DOCK - LLFloater::onClickHelp //BUTTON_HELP + LLFloater::onClickClose, //BUTTON_CLOSE + LLFloater::onClickMinimize, //BUTTON_RESTORE + LLFloater::onClickMinimize, //BUTTON_MINIMIZE + LLFloater::onClickTearOff, //BUTTON_TEAR_OFF + LLFloater::onClickDock, //BUTTON_DOCK + LLFloater::onClickHelp //BUTTON_HELP }; LLMultiFloater* LLFloater::sHostp = NULL; -BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting +BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting LLFloaterView* gFloaterView = NULL; @@ -128,105 +128,105 @@ LLFloaterView* gFloaterView = NULL; //static bool LLFloater::KeyCompare::compare(const LLSD& a, const LLSD& b) { - if (a.type() != b.type()) - { - //LL_ERRS() << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << LL_ENDL; - return false; - } - else if (a.isUndefined()) - return false; - else if (a.isInteger()) - return a.asInteger() < b.asInteger(); - else if (a.isReal()) - return a.asReal() < b.asReal(); - else if (a.isString()) - return a.asString() < b.asString(); - else if (a.isUUID()) - return a.asUUID() < b.asUUID(); - else if (a.isDate()) - return a.asDate() < b.asDate(); - else if (a.isURI()) - return a.asString() < b.asString(); // compare URIs as strings - else if (a.isBoolean()) - return a.asBoolean() < b.asBoolean(); - else - return false; // no valid operation for Binary + if (a.type() != b.type()) + { + //LL_ERRS() << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << LL_ENDL; + return false; + } + else if (a.isUndefined()) + return false; + else if (a.isInteger()) + return a.asInteger() < b.asInteger(); + else if (a.isReal()) + return a.asReal() < b.asReal(); + else if (a.isString()) + return a.asString() < b.asString(); + else if (a.isUUID()) + return a.asUUID() < b.asUUID(); + else if (a.isDate()) + return a.asDate() < b.asDate(); + else if (a.isURI()) + return a.asString() < b.asString(); // compare URIs as strings + else if (a.isBoolean()) + return a.asBoolean() < b.asBoolean(); + else + return false; // no valid operation for Binary } |*==========================================================================*/ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) { - return llsd_equals(a, b); + return llsd_equals(a, b); } //************************************ LLFloater::Params::Params() -: title("title"), - short_title("short_title"), - single_instance("single_instance", false), - reuse_instance("reuse_instance", false), - can_resize("can_resize", false), - can_minimize("can_minimize", true), - can_close("can_close", true), - can_drag_on_left("can_drag_on_left", false), - can_tear_off("can_tear_off", true), - save_dock_state("save_dock_state", false), - save_rect("save_rect", false), - save_visibility("save_visibility", false), - can_dock("can_dock", false), - show_title("show_title", true), - positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), - header_height("header_height", 0), - legacy_header_height("legacy_header_height", 0), - close_image("close_image"), - restore_image("restore_image"), - minimize_image("minimize_image"), - tear_off_image("tear_off_image"), - dock_image("dock_image"), - help_image("help_image"), - close_pressed_image("close_pressed_image"), - restore_pressed_image("restore_pressed_image"), - minimize_pressed_image("minimize_pressed_image"), - tear_off_pressed_image("tear_off_pressed_image"), - dock_pressed_image("dock_pressed_image"), - help_pressed_image("help_pressed_image"), - open_callback("open_callback"), - close_callback("close_callback"), - follows("follows") -{ - changeDefault(visible, false); +: title("title"), + short_title("short_title"), + single_instance("single_instance", false), + reuse_instance("reuse_instance", false), + can_resize("can_resize", false), + can_minimize("can_minimize", true), + can_close("can_close", true), + can_drag_on_left("can_drag_on_left", false), + can_tear_off("can_tear_off", true), + save_dock_state("save_dock_state", false), + save_rect("save_rect", false), + save_visibility("save_visibility", false), + can_dock("can_dock", false), + show_title("show_title", true), + positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), + header_height("header_height", 0), + legacy_header_height("legacy_header_height", 0), + close_image("close_image"), + restore_image("restore_image"), + minimize_image("minimize_image"), + tear_off_image("tear_off_image"), + dock_image("dock_image"), + help_image("help_image"), + close_pressed_image("close_pressed_image"), + restore_pressed_image("restore_pressed_image"), + minimize_pressed_image("minimize_pressed_image"), + tear_off_pressed_image("tear_off_pressed_image"), + dock_pressed_image("dock_pressed_image"), + help_pressed_image("help_pressed_image"), + open_callback("open_callback"), + close_callback("close_callback"), + follows("follows") +{ + changeDefault(visible, false); } //static const LLFloater::Params& LLFloater::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } //static void LLFloater::initClass() { - // translate tooltips for floater buttons - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); - } + // translate tooltips for floater buttons + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); + } - LLControlVariable* ctrl = LLUI::sSettingGroups["config"]->getControl("ActiveFloaterTransparency").get(); - if (ctrl) - { - ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency)); - updateActiveFloaterTransparency(); - } + LLControlVariable* ctrl = LLUI::sSettingGroups["config"]->getControl("ActiveFloaterTransparency").get(); + if (ctrl) + { + ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency)); + updateActiveFloaterTransparency(); + } - ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get(); - if (ctrl) - { - ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency)); - updateInactiveFloaterTransparency(); - } + ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get(); + if (ctrl) + { + ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency)); + updateInactiveFloaterTransparency(); + } } @@ -234,1998 +234,1998 @@ void LLFloater::initClass() static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) -: LLPanel(), // intentionally do not pass params here, see initFromParams - mDragHandle(NULL), - mTitle(p.title), - mShortTitle(p.short_title), - mSingleInstance(p.single_instance), - mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default - mKey(key), - mCanTearOff(p.can_tear_off), - mCanMinimize(p.can_minimize), - mCanClose(p.can_close), - mDragOnLeft(p.can_drag_on_left), - mResizable(p.can_resize), - mPositioning(p.positioning), - mMinWidth(p.min_width), - mMinHeight(p.min_height), - mHeaderHeight(p.header_height), - mLegacyHeaderHeight(p.legacy_header_height), - mMinimized(FALSE), - mForeground(FALSE), - mFirstLook(TRUE), - mButtonScale(1.0f), - mAutoFocus(TRUE), // automatically take focus when opened - mCanDock(false), - mDocked(false), - mTornOff(false), - mHasBeenDraggedWhileMinimized(FALSE), - mPreviousMinimizedBottom(0), - mPreviousMinimizedLeft(0), - mMinimizeSignal(NULL) -// mNotificationContext(NULL) -{ - mPosition.setFloater(*this); -// mNotificationContext = new LLFloaterNotificationContext(getHandle()); - - // Clicks stop here. - setMouseOpaque(TRUE); - - // Floaters always draw their background, unlike every other panel. - setBackgroundVisible(TRUE); - - // Floaters start not minimized. When minimized, they save their - // prior rectangle to be used on restore. - mExpandedRect.set(0,0,0,0); - - memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool)); - memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*)); - - addDragHandle(); - addResizeCtrls(); - - initFromParams(p); - - initFloater(p); +: LLPanel(), // intentionally do not pass params here, see initFromParams + mDragHandle(NULL), + mTitle(p.title), + mShortTitle(p.short_title), + mSingleInstance(p.single_instance), + mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default + mKey(key), + mCanTearOff(p.can_tear_off), + mCanMinimize(p.can_minimize), + mCanClose(p.can_close), + mDragOnLeft(p.can_drag_on_left), + mResizable(p.can_resize), + mPositioning(p.positioning), + mMinWidth(p.min_width), + mMinHeight(p.min_height), + mHeaderHeight(p.header_height), + mLegacyHeaderHeight(p.legacy_header_height), + mMinimized(FALSE), + mForeground(FALSE), + mFirstLook(TRUE), + mButtonScale(1.0f), + mAutoFocus(TRUE), // automatically take focus when opened + mCanDock(false), + mDocked(false), + mTornOff(false), + mHasBeenDraggedWhileMinimized(FALSE), + mPreviousMinimizedBottom(0), + mPreviousMinimizedLeft(0), + mMinimizeSignal(NULL) +// mNotificationContext(NULL) +{ + mPosition.setFloater(*this); +// mNotificationContext = new LLFloaterNotificationContext(getHandle()); + + // Clicks stop here. + setMouseOpaque(TRUE); + + // Floaters always draw their background, unlike every other panel. + setBackgroundVisible(TRUE); + + // Floaters start not minimized. When minimized, they save their + // prior rectangle to be used on restore. + mExpandedRect.set(0,0,0,0); + + memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool)); + memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*)); + + addDragHandle(); + addResizeCtrls(); + + initFromParams(p); + + initFloater(p); } // Note: Floaters constructed from XML call init() twice! void LLFloater::initFloater(const Params& p) { - // Close button. - if (mCanClose) - { - mButtonsEnabled[BUTTON_CLOSE] = TRUE; - } + // Close button. + if (mCanClose) + { + mButtonsEnabled[BUTTON_CLOSE] = TRUE; + } - // Help button: '?' - if ( !mHelpTopic.empty() ) - { - mButtonsEnabled[BUTTON_HELP] = TRUE; - } + // Help button: '?' + if ( !mHelpTopic.empty() ) + { + mButtonsEnabled[BUTTON_HELP] = TRUE; + } - // Minimize button only for top draggers - if ( !mDragOnLeft && mCanMinimize ) - { - mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; - } + // Minimize button only for top draggers + if ( !mDragOnLeft && mCanMinimize ) + { + mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; + } - if(mCanDock) - { - mButtonsEnabled[BUTTON_DOCK] = TRUE; - } + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = TRUE; + } - buildButtons(p); + buildButtons(p); - // Floaters are created in the invisible state - setVisible(FALSE); + // Floaters are created in the invisible state + setVisible(FALSE); - if (!getParent()) - { - gFloaterView->addChild(this); - } + if (!getParent()) + { + gFloaterView->addChild(this); + } } void LLFloater::addDragHandle() { - if (!mDragHandle) - { - if (mDragOnLeft) - { - LLDragHandleLeft::Params p; - p.name("drag"); - p.follows.flags(FOLLOWS_ALL); - p.label(mTitle); - mDragHandle = LLUICtrlFactory::create(p); - } - else // drag on top - { - LLDragHandleTop::Params p; - p.name("Drag Handle"); - p.follows.flags(FOLLOWS_ALL); - p.label(mTitle); - mDragHandle = LLUICtrlFactory::create(p); - } - addChild(mDragHandle); - } - layoutDragHandle(); - applyTitle(); + if (!mDragHandle) + { + if (mDragOnLeft) + { + LLDragHandleLeft::Params p; + p.name("drag"); + p.follows.flags(FOLLOWS_ALL); + p.label(mTitle); + mDragHandle = LLUICtrlFactory::create(p); + } + else // drag on top + { + LLDragHandleTop::Params p; + p.name("Drag Handle"); + p.follows.flags(FOLLOWS_ALL); + p.label(mTitle); + mDragHandle = LLUICtrlFactory::create(p); + } + addChild(mDragHandle); + } + layoutDragHandle(); + applyTitle(); } void LLFloater::layoutDragHandle() { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - S32 close_box_size = mCanClose ? floater_close_box_size : 0; - - LLRect rect; - if (mDragOnLeft) - { - rect.setLeftTopAndSize(0, 0, DRAG_HANDLE_WIDTH, getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); - } - else // drag on top - { - rect = getLocalRect(); - } - mDragHandle->setShape(rect); - updateTitleButtons(); + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + S32 close_box_size = mCanClose ? floater_close_box_size : 0; + + LLRect rect; + if (mDragOnLeft) + { + rect.setLeftTopAndSize(0, 0, DRAG_HANDLE_WIDTH, getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); + } + else // drag on top + { + rect = getLocalRect(); + } + mDragHandle->setShape(rect); + updateTitleButtons(); } // static void LLFloater::updateActiveFloaterTransparency() { - sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency"); + sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency"); } // static void LLFloater::updateInactiveFloaterTransparency() { - sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency"); + sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency"); } void LLFloater::addResizeCtrls() -{ - // Resize bars (sides) - LLResizeBar::Params p; - p.name("resizebar_left"); - p.resizing_view(this); - p.min_size(mMinWidth); - p.side(LLResizeBar::LEFT); - mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::LEFT] ); - - p.name("resizebar_top"); - p.min_size(mMinHeight); - p.side(LLResizeBar::TOP); - - mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::TOP] ); - - p.name("resizebar_right"); - p.min_size(mMinWidth); - p.side(LLResizeBar::RIGHT); - mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::RIGHT] ); - - p.name("resizebar_bottom"); - p.min_size(mMinHeight); - p.side(LLResizeBar::BOTTOM); - mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create(p); - addChild( mResizeBar[LLResizeBar::BOTTOM] ); - - // Resize handles (corners) - LLResizeHandle::Params handle_p; - // handles must not be mouse-opaque, otherwise they block hover events - // to other buttons like the close box. JC - handle_p.mouse_opaque(false); - handle_p.min_width(mMinWidth); - handle_p.min_height(mMinHeight); - handle_p.corner(LLResizeHandle::RIGHT_BOTTOM); - mResizeHandle[0] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[0]); - - handle_p.corner(LLResizeHandle::RIGHT_TOP); - mResizeHandle[1] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[1]); - - handle_p.corner(LLResizeHandle::LEFT_BOTTOM); - mResizeHandle[2] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[2]); - - handle_p.corner(LLResizeHandle::LEFT_TOP); - mResizeHandle[3] = LLUICtrlFactory::create(handle_p); - addChild(mResizeHandle[3]); - - layoutResizeCtrls(); +{ + // Resize bars (sides) + LLResizeBar::Params p; + p.name("resizebar_left"); + p.resizing_view(this); + p.min_size(mMinWidth); + p.side(LLResizeBar::LEFT); + mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::LEFT] ); + + p.name("resizebar_top"); + p.min_size(mMinHeight); + p.side(LLResizeBar::TOP); + + mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::TOP] ); + + p.name("resizebar_right"); + p.min_size(mMinWidth); + p.side(LLResizeBar::RIGHT); + mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::RIGHT] ); + + p.name("resizebar_bottom"); + p.min_size(mMinHeight); + p.side(LLResizeBar::BOTTOM); + mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create(p); + addChild( mResizeBar[LLResizeBar::BOTTOM] ); + + // Resize handles (corners) + LLResizeHandle::Params handle_p; + // handles must not be mouse-opaque, otherwise they block hover events + // to other buttons like the close box. JC + handle_p.mouse_opaque(false); + handle_p.min_width(mMinWidth); + handle_p.min_height(mMinHeight); + handle_p.corner(LLResizeHandle::RIGHT_BOTTOM); + mResizeHandle[0] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[0]); + + handle_p.corner(LLResizeHandle::RIGHT_TOP); + mResizeHandle[1] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[1]); + + handle_p.corner(LLResizeHandle::LEFT_BOTTOM); + mResizeHandle[2] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[2]); + + handle_p.corner(LLResizeHandle::LEFT_TOP); + mResizeHandle[3] = LLUICtrlFactory::create(handle_p); + addChild(mResizeHandle[3]); + + layoutResizeCtrls(); } void LLFloater::layoutResizeCtrls() { - LLRect rect; + LLRect rect; - // Resize bars (sides) - const S32 RESIZE_BAR_THICKNESS = 3; - rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0); - mResizeBar[LLResizeBar::LEFT]->setRect(rect); + // Resize bars (sides) + const S32 RESIZE_BAR_THICKNESS = 3; + rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0); + mResizeBar[LLResizeBar::LEFT]->setRect(rect); - rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS); - mResizeBar[LLResizeBar::TOP]->setRect(rect); + rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS); + mResizeBar[LLResizeBar::TOP]->setRect(rect); - rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0); - mResizeBar[LLResizeBar::RIGHT]->setRect(rect); + rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0); + mResizeBar[LLResizeBar::RIGHT]->setRect(rect); - rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0); - mResizeBar[LLResizeBar::BOTTOM]->setRect(rect); + rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0); + mResizeBar[LLResizeBar::BOTTOM]->setRect(rect); - // Resize handles (corners) - rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0); - mResizeHandle[0]->setRect(rect); + // Resize handles (corners) + rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0); + mResizeHandle[0]->setRect(rect); - rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT); - mResizeHandle[1]->setRect(rect); - - rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ); - mResizeHandle[2]->setRect(rect); + rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT); + mResizeHandle[1]->setRect(rect); + + rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ); + mResizeHandle[2]->setRect(rect); - rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ); - mResizeHandle[3]->setRect(rect); + rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ); + mResizeHandle[3]->setRect(rect); } void LLFloater::enableResizeCtrls(bool enable, bool width, bool height) { - mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width); - mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width); + mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width); + mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width); - mResizeBar[LLResizeBar::TOP]->setVisible(enable && height); - mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height); - - mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width); - mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width); - - mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height); - mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height); + mResizeBar[LLResizeBar::TOP]->setVisible(enable && height); + mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height); + + mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width); + mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width); + + mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height); + mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height); - for (S32 i = 0; i < 4; ++i) - { - mResizeHandle[i]->setVisible(enable && width && height); - mResizeHandle[i]->setEnabled(enable && width && height); - } + for (S32 i = 0; i < 4; ++i) + { + mResizeHandle[i]->setVisible(enable && width && height); + mResizeHandle[i]->setEnabled(enable && width && height); + } } void LLFloater::destroy() { - // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before - // it was deleted via LLMortician::updateClass(). See EXT-8458. - LLFloaterReg::removeInstance(mInstanceName, mKey); - die(); + // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before + // it was deleted via LLMortician::updateClass(). See EXT-8458. + LLFloaterReg::removeInstance(mInstanceName, mKey); + die(); } // virtual LLFloater::~LLFloater() { - LLFloaterReg::removeInstance(mInstanceName, mKey); - - if( gFocusMgr.childHasKeyboardFocus(this)) - { - // Just in case we might still have focus here, release it. - releaseFocus(); - } - - // This is important so that floaters with persistent rects (i.e., those - // created with rect control rather than an LLRect) are restored in their - // correct, non-minimized positions. - setMinimized( FALSE ); - - delete mDragHandle; - for (S32 i = 0; i < 4; i++) - { - delete mResizeBar[i]; - delete mResizeHandle[i]; - } - - setVisible(false); // We're not visible if we're destroyed - storeVisibilityControl(); - storeDockStateControl(); - delete mMinimizeSignal; + LLFloaterReg::removeInstance(mInstanceName, mKey); + + if( gFocusMgr.childHasKeyboardFocus(this)) + { + // Just in case we might still have focus here, release it. + releaseFocus(); + } + + // This is important so that floaters with persistent rects (i.e., those + // created with rect control rather than an LLRect) are restored in their + // correct, non-minimized positions. + setMinimized( FALSE ); + + delete mDragHandle; + for (S32 i = 0; i < 4; i++) + { + delete mResizeBar[i]; + delete mResizeHandle[i]; + } + + setVisible(false); // We're not visible if we're destroyed + storeVisibilityControl(); + storeDockStateControl(); + delete mMinimizeSignal; } void LLFloater::storeRectControl() { - if (!mRectControl.empty()) - { - getControlGroup()->setRect( mRectControl, getRect() ); - } - if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) - { - getControlGroup()->setF32( mPosXControl, mPosition.mX ); - } - if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) - { - getControlGroup()->setF32( mPosYControl, mPosition.mY ); - } + if (!mRectControl.empty()) + { + getControlGroup()->setRect( mRectControl, getRect() ); + } + if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) + { + getControlGroup()->setF32( mPosXControl, mPosition.mX ); + } + if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE) + { + getControlGroup()->setF32( mPosYControl, mPosition.mY ); + } } void LLFloater::storeVisibilityControl() { - if( !sQuitting && mVisibilityControl.size() > 1 ) - { - getControlGroup()->setBOOL( mVisibilityControl, getVisible() ); - } + if( !sQuitting && mVisibilityControl.size() > 1 ) + { + getControlGroup()->setBOOL( mVisibilityControl, getVisible() ); + } } void LLFloater::storeDockStateControl() { - if( !sQuitting && mDocStateControl.size() > 1 ) - { - getControlGroup()->setBOOL( mDocStateControl, isDocked() ); - } + if( !sQuitting && mDocStateControl.size() > 1 ) + { + getControlGroup()->setBOOL( mDocStateControl, isDocked() ); + } } // static std::string LLFloater::getControlName(const std::string& name, const LLSD& key) { - std::string ctrl_name = name; + std::string ctrl_name = name; - // Add the key to the control name if appropriate. - if (key.isString() && !key.asString().empty()) - { - ctrl_name += "_" + key.asString(); - } + // Add the key to the control name if appropriate. + if (key.isString() && !key.asString().empty()) + { + ctrl_name += "_" + key.asString(); + } - return ctrl_name; + return ctrl_name; } // static -LLControlGroup* LLFloater::getControlGroup() +LLControlGroup* LLFloater::getControlGroup() { - // Floater size, position, visibility, etc are saved in per-account settings. - return LLUI::sSettingGroups["account"]; + // Floater size, position, visibility, etc are saved in per-account settings. + return LLUI::sSettingGroups["account"]; } void LLFloater::setVisible( BOOL visible ) { - LLPanel::setVisible(visible); // calls onVisibilityChange() - if( visible && mFirstLook ) - { - mFirstLook = FALSE; - } + LLPanel::setVisible(visible); // calls onVisibilityChange() + if( visible && mFirstLook ) + { + mFirstLook = FALSE; + } - if( !visible ) - { - LLUI::removePopup(this); + if( !visible ) + { + LLUI::removePopup(this); - if( gFocusMgr.childHasMouseCapture( this ) ) - { - gFocusMgr.setMouseCapture(NULL); - } - } + if( gFocusMgr.childHasMouseCapture( this ) ) + { + gFocusMgr.setMouseCapture(NULL); + } + } - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - LLFloater* floaterp = dependent_it->get(); + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - floaterp->setVisible(visible); - } - ++dependent_it; - } + if (floaterp) + { + floaterp->setVisible(visible); + } + ++dependent_it; + } - storeVisibilityControl(); + storeVisibilityControl(); } void LLFloater::setIsSingleInstance(BOOL is_single_instance) { - mSingleInstance = is_single_instance; - if (!mIsReuseInitialized) - { - mReuseInstance = is_single_instance; // reuse single-instance floaters by default - } + mSingleInstance = is_single_instance; + if (!mIsReuseInitialized) + { + mReuseInstance = is_single_instance; // reuse single-instance floaters by default + } } // virtual void LLFloater::onVisibilityChange ( BOOL new_visibility ) { - if (new_visibility) - { - if (getHost()) - getHost()->setFloaterFlashing(this, FALSE); - } - LLPanel::onVisibilityChange ( new_visibility ); + if (new_visibility) + { + if (getHost()) + getHost()->setFloaterFlashing(this, FALSE); + } + LLPanel::onVisibilityChange ( new_visibility ); } void LLFloater::openFloater(const LLSD& key) { LL_INFOS() << "Opening floater " << getName() << " full path: " << getPathname() << LL_ENDL; - LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string - - mKey = key; // in case we need to open ourselves again - - if (getSoundFlags() != SILENT - // don't play open sound for hosted (tabbed) windows - && !getHost() - && !getFloaterHost() - && (!getVisible() || isMinimized())) - { - make_ui_sound("UISndWindowOpen"); - } - - //RN: for now, we don't allow rehosting from one multifloater to another - // just need to fix the bugs - if (getFloaterHost() != NULL && getHost() == NULL) - { - // needs a host - // only select tabs if window they are hosted in is visible - getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); - } - - if (getHost() != NULL) - { - getHost()->setMinimized(FALSE); - getHost()->setVisibleAndFrontmost(mAutoFocus); - getHost()->showFloater(this); - } - else - { - LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName); - if (!floater_to_stack) - { - floater_to_stack = LLFloaterReg::getLastFloaterCascading(); - } - applyControlsAndPosition(floater_to_stack); - setMinimized(FALSE); - setVisibleAndFrontmost(mAutoFocus); - } - - mOpenSignal(this, key); - onOpen(key); - - dirtyRect(); + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string + + mKey = key; // in case we need to open ourselves again + + if (getSoundFlags() != SILENT + // don't play open sound for hosted (tabbed) windows + && !getHost() + && !getFloaterHost() + && (!getVisible() || isMinimized())) + { + make_ui_sound("UISndWindowOpen"); + } + + //RN: for now, we don't allow rehosting from one multifloater to another + // just need to fix the bugs + if (getFloaterHost() != NULL && getHost() == NULL) + { + // needs a host + // only select tabs if window they are hosted in is visible + getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); + } + + if (getHost() != NULL) + { + getHost()->setMinimized(FALSE); + getHost()->setVisibleAndFrontmost(mAutoFocus); + getHost()->showFloater(this); + } + else + { + LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName); + if (!floater_to_stack) + { + floater_to_stack = LLFloaterReg::getLastFloaterCascading(); + } + applyControlsAndPosition(floater_to_stack); + setMinimized(FALSE); + setVisibleAndFrontmost(mAutoFocus); + } + + mOpenSignal(this, key); + onOpen(key); + + dirtyRect(); } void LLFloater::closeFloater(bool app_quitting) { - LL_INFOS() << "Closing floater " << getName() << LL_ENDL; - LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string - if (app_quitting) - { - LLFloater::sQuitting = true; - } - - // Always unminimize before trying to close. - // Most of the time the user will never see this state. - setMinimized(FALSE); - - if (canClose()) - { - if (getHost()) - { - ((LLMultiFloater*)getHost())->removeFloater(this); - gFloaterView->addChild(this); - } - - if (getSoundFlags() != SILENT - && getVisible() - && !getHost() - && !app_quitting) - { - make_ui_sound("UISndWindowClose"); - } - - gFocusMgr.clearLastFocusForGroup(this); - - if (hasFocus()) - { - // Do this early, so UI controls will commit before the - // window is taken down. - releaseFocus(); - - // give focus to dependee floater if it exists, and we had focus first - if (isDependent()) - { - LLFloater* dependee = mDependeeHandle.get(); - if (dependee && !dependee->isDead()) - { - dependee->setFocus(TRUE); - } - } - } - - - //If floater is a dependent, remove it from parent (dependee) + LL_INFOS() << "Closing floater " << getName() << LL_ENDL; + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string + if (app_quitting) + { + LLFloater::sQuitting = true; + } + + // Always unminimize before trying to close. + // Most of the time the user will never see this state. + setMinimized(FALSE); + + if (canClose()) + { + if (getHost()) + { + ((LLMultiFloater*)getHost())->removeFloater(this); + gFloaterView->addChild(this); + } + + if (getSoundFlags() != SILENT + && getVisible() + && !getHost() + && !app_quitting) + { + make_ui_sound("UISndWindowClose"); + } + + gFocusMgr.clearLastFocusForGroup(this); + + if (hasFocus()) + { + // Do this early, so UI controls will commit before the + // window is taken down. + releaseFocus(); + + // give focus to dependee floater if it exists, and we had focus first + if (isDependent()) + { + LLFloater* dependee = mDependeeHandle.get(); + if (dependee && !dependee->isDead()) + { + dependee->setFocus(TRUE); + } + } + } + + + //If floater is a dependent, remove it from parent (dependee) LLFloater* dependee = mDependeeHandle.get(); if (dependee) { dependee->removeDependentFloater(this); } - // now close dependent floater - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - ++dependent_it; - floaterp->closeFloater(app_quitting); - } - else - { - mDependents.erase(dependent_it++); - } - } - - cleanupHandles(); - - dirtyRect(); - - // Close callbacks - onClose(app_quitting); - mCloseSignal(this, LLSD(app_quitting)); - - // Hide or Destroy - if (mSingleInstance) - { - // Hide the instance - if (getHost()) - { - getHost()->setVisible(FALSE); - } - else - { - setVisible(FALSE); - if (!mReuseInstance) - { - destroy(); - } - } - } - else - { - setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called) - if (!mReuseInstance) - { - destroy(); - } - } - } + // now close dependent floater + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + ++dependent_it; + floaterp->closeFloater(app_quitting); + } + else + { + mDependents.erase(dependent_it++); + } + } + + cleanupHandles(); + + dirtyRect(); + + // Close callbacks + onClose(app_quitting); + mCloseSignal(this, LLSD(app_quitting)); + + // Hide or Destroy + if (mSingleInstance) + { + // Hide the instance + if (getHost()) + { + getHost()->setVisible(FALSE); + } + else + { + setVisible(FALSE); + if (!mReuseInstance) + { + destroy(); + } + } + } + else + { + setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called) + if (!mReuseInstance) + { + destroy(); + } + } + } } /*virtual*/ void LLFloater::closeHostedFloater() { - // When toggling *visibility*, close the host instead of the floater when hosted - if (getHost()) - { - getHost()->closeFloater(); - } - else - { - closeFloater(); - } + // When toggling *visibility*, close the host instead of the floater when hosted + if (getHost()) + { + getHost()->closeFloater(); + } + else + { + closeFloater(); + } } /*virtual*/ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent) { - LLPanel::reshape(width, height, called_from_parent); + LLPanel::reshape(width, height, called_from_parent); } void LLFloater::releaseFocus() { - LLUI::removePopup(this); + LLUI::removePopup(this); - setFocus(FALSE); + setFocus(FALSE); - if( gFocusMgr.childHasMouseCapture( this ) ) - { - gFocusMgr.setMouseCapture(NULL); - } + if( gFocusMgr.childHasMouseCapture( this ) ) + { + gFocusMgr.setMouseCapture(NULL); + } } void LLFloater::setResizeLimits( S32 min_width, S32 min_height ) { - mMinWidth = min_width; - mMinHeight = min_height; - - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeBar[i] ) - { - if (i == LLResizeBar::LEFT || i == LLResizeBar::RIGHT) - { - mResizeBar[i]->setResizeLimits( min_width, S32_MAX ); - } - else - { - mResizeBar[i]->setResizeLimits( min_height, S32_MAX ); - } - } - if( mResizeHandle[i] ) - { - mResizeHandle[i]->setResizeLimits( min_width, min_height ); - } - } + mMinWidth = min_width; + mMinHeight = min_height; + + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeBar[i] ) + { + if (i == LLResizeBar::LEFT || i == LLResizeBar::RIGHT) + { + mResizeBar[i]->setResizeLimits( min_width, S32_MAX ); + } + else + { + mResizeBar[i]->setResizeLimits( min_height, S32_MAX ); + } + } + if( mResizeHandle[i] ) + { + mResizeHandle[i]->setResizeLimits( min_width, min_height ); + } + } } void LLFloater::center() { - if(getHost()) - { - // hosted floaters can't move - return; - } - centerWithin(gFloaterView->getRect()); + if(getHost()) + { + // hosted floaters can't move + return; + } + centerWithin(gFloaterView->getRect()); } LLMultiFloater* LLFloater::getHost() { - return (LLMultiFloater*)mHostHandle.get(); + return (LLMultiFloater*)mHostHandle.get(); } void LLFloater::applyControlsAndPosition(LLFloater* other) { - if (!applyDockState()) - { - if (!applyRectControl()) - { - applyPositioning(other, true); - } - } + if (!applyDockState()) + { + if (!applyRectControl()) + { + applyPositioning(other, true); + } + } } bool LLFloater::applyRectControl() { - bool saved_rect = false; - - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - - LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName); - if (last_in_group && last_in_group != this) - { - // other floaters in our group, position ourselves relative to them and don't save the rect - mRectControl.clear(); - mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; - } - else - { - bool rect_specified = false; - if (!mRectControl.empty()) - { - // If we have a saved rect, use it - const LLRect& rect = getControlGroup()->getRect(mRectControl); - if (rect.notEmpty()) saved_rect = true; - if (saved_rect) - { - setOrigin(rect.mLeft, rect.mBottom); - - if (mResizable) - { - reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); - } - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - rect_specified = true; - } - } - - LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl); - LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl); - if (x_control.notNull() - && y_control.notNull() - && !x_control->isDefault() - && !y_control->isDefault()) - { - mPosition.mX = x_control->getValue().asReal(); - mPosition.mY = y_control->getValue().asReal(); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - applyRelativePosition(); - - saved_rect = true; - } - - // remember updated position - if (rect_specified) - { - storeRectControl(); - } - } - - if (saved_rect) - { - // propagate any derived positioning data back to settings file - storeRectControl(); - } - - - return saved_rect; + bool saved_rect = false; + + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + + LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName); + if (last_in_group && last_in_group != this) + { + // other floaters in our group, position ourselves relative to them and don't save the rect + mRectControl.clear(); + mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; + } + else + { + bool rect_specified = false; + if (!mRectControl.empty()) + { + // If we have a saved rect, use it + const LLRect& rect = getControlGroup()->getRect(mRectControl); + if (rect.notEmpty()) saved_rect = true; + if (saved_rect) + { + setOrigin(rect.mLeft, rect.mBottom); + + if (mResizable) + { + reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); + } + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + rect_specified = true; + } + } + + LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl); + LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl); + if (x_control.notNull() + && y_control.notNull() + && !x_control->isDefault() + && !y_control->isDefault()) + { + mPosition.mX = x_control->getValue().asReal(); + mPosition.mY = y_control->getValue().asReal(); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + applyRelativePosition(); + + saved_rect = true; + } + + // remember updated position + if (rect_specified) + { + storeRectControl(); + } + } + + if (saved_rect) + { + // propagate any derived positioning data back to settings file + storeRectControl(); + } + + + return saved_rect; } bool LLFloater::applyDockState() { - bool docked = false; + bool docked = false; - if (mDocStateControl.size() > 1) - { - docked = getControlGroup()->getBOOL(mDocStateControl); - setDocked(docked); - } + if (mDocStateControl.size() > 1) + { + docked = getControlGroup()->getBOOL(mDocStateControl); + setDocked(docked); + } - return docked; + return docked; } void LLFloater::applyPositioning(LLFloater* other, bool on_open) { - // Otherwise position according to the positioning code - switch (mPositioning) - { - case LLFloaterEnums::POSITIONING_CENTERED: - center(); - break; - - case LLFloaterEnums::POSITIONING_SPECIFIED: - break; - - case LLFloaterEnums::POSITIONING_CASCADING: - if (!on_open) - { - applyRelativePosition(); - } - // fall through - case LLFloaterEnums::POSITIONING_CASCADE_GROUP: - if (on_open) - { - if (other != NULL && other != this) - { - stackWith(*other); - } - else - { - static const U32 CASCADING_FLOATER_HOFFSET = 0; - static const U32 CASCADING_FLOATER_VOFFSET = 0; - - const LLRect& snap_rect = gFloaterView->getSnapRect(); - - const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; - const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; - - S32 rect_height = getRect().getHeight(); - setOrigin(horizontal_offset, vertical_offset - rect_height); - - translate(snap_rect.mLeft, snap_rect.mBottom); - } - setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); - } - break; - - case LLFloaterEnums::POSITIONING_RELATIVE: - { - applyRelativePosition(); - - break; - } - default: - // Do nothing - break; - } + // Otherwise position according to the positioning code + switch (mPositioning) + { + case LLFloaterEnums::POSITIONING_CENTERED: + center(); + break; + + case LLFloaterEnums::POSITIONING_SPECIFIED: + break; + + case LLFloaterEnums::POSITIONING_CASCADING: + if (!on_open) + { + applyRelativePosition(); + } + // fall through + case LLFloaterEnums::POSITIONING_CASCADE_GROUP: + if (on_open) + { + if (other != NULL && other != this) + { + stackWith(*other); + } + else + { + static const U32 CASCADING_FLOATER_HOFFSET = 0; + static const U32 CASCADING_FLOATER_VOFFSET = 0; + + const LLRect& snap_rect = gFloaterView->getSnapRect(); + + const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET; + const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET; + + S32 rect_height = getRect().getHeight(); + setOrigin(horizontal_offset, vertical_offset - rect_height); + + translate(snap_rect.mLeft, snap_rect.mBottom); + } + setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + } + break; + + case LLFloaterEnums::POSITIONING_RELATIVE: + { + applyRelativePosition(); + + break; + } + default: + // Do nothing + break; + } } void LLFloater::applyTitle() { - if (!mDragHandle) - { - return; - } + if (!mDragHandle) + { + return; + } - if (isMinimized() && !mShortTitle.empty()) - { - mDragHandle->setTitle( mShortTitle ); - } - else - { - mDragHandle->setTitle ( mTitle ); - } + if (isMinimized() && !mShortTitle.empty()) + { + mDragHandle->setTitle( mShortTitle ); + } + else + { + mDragHandle->setTitle ( mTitle ); + } - if (getHost()) - { - getHost()->updateFloaterTitle(this); - } + if (getHost()) + { + getHost()->updateFloaterTitle(this); + } } std::string LLFloater::getCurrentTitle() const { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; } void LLFloater::setTitle( const std::string& title ) { - mTitle = title; - applyTitle(); + mTitle = title; + applyTitle(); } std::string LLFloater::getTitle() const { - if (mTitle.empty()) - { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; - } - else - { - return mTitle; - } + if (mTitle.empty()) + { + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + } + else + { + return mTitle; + } } void LLFloater::setShortTitle( const std::string& short_title ) { - mShortTitle = short_title; - applyTitle(); + mShortTitle = short_title; + applyTitle(); } std::string LLFloater::getShortTitle() const { - if (mShortTitle.empty()) - { - return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; - } - else - { - return mShortTitle; - } + if (mShortTitle.empty()) + { + return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null; + } + else + { + return mShortTitle; + } } BOOL LLFloater::canSnapTo(const LLView* other_view) { - if (NULL == other_view) - { - LL_WARNS() << "other_view is NULL" << LL_ENDL; - return FALSE; - } - - if (other_view != getParent()) - { - const LLFloater* other_floaterp = dynamic_cast(other_view); - if (other_floaterp - && other_floaterp->getSnapTarget() == getHandle() - && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) - { - // this is a dependent that is already snapped to us, so don't snap back to it - return FALSE; - } - } + if (NULL == other_view) + { + LL_WARNS() << "other_view is NULL" << LL_ENDL; + return FALSE; + } - return LLPanel::canSnapTo(other_view); + if (other_view != getParent()) + { + const LLFloater* other_floaterp = dynamic_cast(other_view); + if (other_floaterp + && other_floaterp->getSnapTarget() == getHandle() + && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) + { + // this is a dependent that is already snapped to us, so don't snap back to it + return FALSE; + } + } + + return LLPanel::canSnapTo(other_view); } void LLFloater::setSnappedTo(const LLView* snap_view) { - if (!snap_view || snap_view == getParent()) - { - clearSnapTarget(); - } - else - { - //RN: assume it's a floater as it must be a sibling to our parent floater - const LLFloater* floaterp = dynamic_cast(snap_view); - if (floaterp) - { - setSnapTarget(floaterp->getHandle()); - } - } + if (!snap_view || snap_view == getParent()) + { + clearSnapTarget(); + } + else + { + //RN: assume it's a floater as it must be a sibling to our parent floater + const LLFloater* floaterp = dynamic_cast(snap_view); + if (floaterp) + { + setSnapTarget(floaterp->getHandle()); + } + } } void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) { - const LLRect old_rect = getRect(); - LLView::handleReshape(new_rect, by_user); - - if (by_user && !getHost()) - { - LLFloaterView * floaterVp = dynamic_cast(getParent()); - if (floaterVp) - { - floaterVp->adjustToFitScreen(this, !isMinimized()); - } - } - - // if not minimized, adjust all snapped dependents to new shape - if (!isMinimized()) - { - if (by_user) - { - if (isDocked()) - { - setDocked( false, false); - } - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - } - storeRectControl(); - - // gather all snapped dependents - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - // is a dependent snapped to us? - if (floaterp && floaterp->getSnapTarget() == getHandle()) - { - S32 delta_x = 0; - S32 delta_y = 0; - // check to see if it snapped to right or top, and move if dependee floater is resizing - LLRect dependent_rect = floaterp->getRect(); - if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? - dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right - { - // was snapped directly onto right side or aligned with it - delta_x += new_rect.getWidth() - old_rect.getWidth(); - } - if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || - dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) - { - // was snapped directly onto top side or aligned with it - delta_y += new_rect.getHeight() - old_rect.getHeight(); - } - - // take translation of dependee floater into account as well - delta_x += new_rect.mLeft - old_rect.mLeft; - delta_y += new_rect.mBottom - old_rect.mBottom; - - dependent_rect.translate(delta_x, delta_y); - floaterp->setShape(dependent_rect, by_user); - } - } - } - else - { - // If minimized, and origin has changed, set - // mHasBeenDraggedWhileMinimized to TRUE - if ((new_rect.mLeft != old_rect.mLeft) || - (new_rect.mBottom != old_rect.mBottom)) - { - mHasBeenDraggedWhileMinimized = TRUE; - } - } + const LLRect old_rect = getRect(); + LLView::handleReshape(new_rect, by_user); + + if (by_user && !getHost()) + { + LLFloaterView * floaterVp = dynamic_cast(getParent()); + if (floaterVp) + { + floaterVp->adjustToFitScreen(this, !isMinimized()); + } + } + + // if not minimized, adjust all snapped dependents to new shape + if (!isMinimized()) + { + if (by_user) + { + if (isDocked()) + { + setDocked( false, false); + } + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + } + storeRectControl(); + + // gather all snapped dependents + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + // is a dependent snapped to us? + if (floaterp && floaterp->getSnapTarget() == getHandle()) + { + S32 delta_x = 0; + S32 delta_y = 0; + // check to see if it snapped to right or top, and move if dependee floater is resizing + LLRect dependent_rect = floaterp->getRect(); + if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? + dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right + { + // was snapped directly onto right side or aligned with it + delta_x += new_rect.getWidth() - old_rect.getWidth(); + } + if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || + dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) + { + // was snapped directly onto top side or aligned with it + delta_y += new_rect.getHeight() - old_rect.getHeight(); + } + + // take translation of dependee floater into account as well + delta_x += new_rect.mLeft - old_rect.mLeft; + delta_y += new_rect.mBottom - old_rect.mBottom; + + dependent_rect.translate(delta_x, delta_y); + floaterp->setShape(dependent_rect, by_user); + } + } + } + else + { + // If minimized, and origin has changed, set + // mHasBeenDraggedWhileMinimized to TRUE + if ((new_rect.mLeft != old_rect.mLeft) || + (new_rect.mBottom != old_rect.mBottom)) + { + mHasBeenDraggedWhileMinimized = TRUE; + } + } } void LLFloater::setMinimized(BOOL minimize) { - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); - S32 floater_header_size = default_params.header_height; - static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); - - if (minimize == mMinimized) return; - - if (mMinimizeSignal) - { - (*mMinimizeSignal)(this, LLSD(minimize)); - } - - if (minimize) - { - // minimized flag should be turned on before release focus - mMinimized = TRUE; - mExpandedRect = getRect(); - - // If the floater has been dragged while minimized in the - // past, then locate it at its previous minimized location. - // Otherwise, ask the view for a minimize position. - if (mHasBeenDraggedWhileMinimized) - { - setOrigin(mPreviousMinimizedLeft, mPreviousMinimizedBottom); - } - else - { - S32 left, bottom; - gFloaterView->getMinimizePosition(&left, &bottom); - setOrigin( left, bottom ); - } - - if (mButtonsEnabled[BUTTON_MINIMIZE]) - { - mButtonsEnabled[BUTTON_MINIMIZE] = FALSE; - mButtonsEnabled[BUTTON_RESTORE] = TRUE; - } - - setBorderVisible(TRUE); - - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); - ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - if (floaterp->isMinimizeable()) - { - floaterp->setMinimized(TRUE); - } - else if (!floaterp->isMinimized()) - { - floaterp->setVisible(FALSE); - } - } - } - - // Lose keyboard focus when minimized - releaseFocus(); - - for (S32 i = 0; i < 4; i++) - { - if (mResizeBar[i] != NULL) - { - mResizeBar[i]->setEnabled(FALSE); - } - if (mResizeHandle[i] != NULL) - { - mResizeHandle[i]->setEnabled(FALSE); - } - } - - // Reshape *after* setting mMinimized - reshape( minimized_width, floater_header_size, TRUE); - } - else - { - // If this window has been dragged while minimized (at any time), - // remember its position for the next time it's minimized. - if (mHasBeenDraggedWhileMinimized) - { - const LLRect& currentRect = getRect(); - mPreviousMinimizedLeft = currentRect.mLeft; - mPreviousMinimizedBottom = currentRect.mBottom; - } - - setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); - if (mButtonsEnabled[BUTTON_RESTORE]) - { - mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; - mButtonsEnabled[BUTTON_RESTORE] = FALSE; - } - - // show dependent floater - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); - ++dependent_it) - { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - floaterp->setMinimized(FALSE); - floaterp->setVisible(TRUE); - } - } - - for (S32 i = 0; i < 4; i++) - { - if (mResizeBar[i] != NULL) - { - mResizeBar[i]->setEnabled(isResizable()); - } - if (mResizeHandle[i] != NULL) - { - mResizeHandle[i]->setEnabled(isResizable()); - } - } - - mMinimized = FALSE; - setFrontmost(); - // Reshape *after* setting mMinimized - reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); - } - - make_ui_sound("UISndWindowClose"); - updateTitleButtons(); - applyTitle (); + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); + + if (minimize == mMinimized) return; + + if (mMinimizeSignal) + { + (*mMinimizeSignal)(this, LLSD(minimize)); + } + + if (minimize) + { + // minimized flag should be turned on before release focus + mMinimized = TRUE; + mExpandedRect = getRect(); + + // If the floater has been dragged while minimized in the + // past, then locate it at its previous minimized location. + // Otherwise, ask the view for a minimize position. + if (mHasBeenDraggedWhileMinimized) + { + setOrigin(mPreviousMinimizedLeft, mPreviousMinimizedBottom); + } + else + { + S32 left, bottom; + gFloaterView->getMinimizePosition(&left, &bottom); + setOrigin( left, bottom ); + } + + if (mButtonsEnabled[BUTTON_MINIMIZE]) + { + mButtonsEnabled[BUTTON_MINIMIZE] = FALSE; + mButtonsEnabled[BUTTON_RESTORE] = TRUE; + } + + setBorderVisible(TRUE); + + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); + ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + if (floaterp->isMinimizeable()) + { + floaterp->setMinimized(TRUE); + } + else if (!floaterp->isMinimized()) + { + floaterp->setVisible(FALSE); + } + } + } + + // Lose keyboard focus when minimized + releaseFocus(); + + for (S32 i = 0; i < 4; i++) + { + if (mResizeBar[i] != NULL) + { + mResizeBar[i]->setEnabled(FALSE); + } + if (mResizeHandle[i] != NULL) + { + mResizeHandle[i]->setEnabled(FALSE); + } + } + + // Reshape *after* setting mMinimized + reshape( minimized_width, floater_header_size, TRUE); + } + else + { + // If this window has been dragged while minimized (at any time), + // remember its position for the next time it's minimized. + if (mHasBeenDraggedWhileMinimized) + { + const LLRect& currentRect = getRect(); + mPreviousMinimizedLeft = currentRect.mLeft; + mPreviousMinimizedBottom = currentRect.mBottom; + } + + setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); + if (mButtonsEnabled[BUTTON_RESTORE]) + { + mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; + mButtonsEnabled[BUTTON_RESTORE] = FALSE; + } + + // show dependent floater + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); + ++dependent_it) + { + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + floaterp->setMinimized(FALSE); + floaterp->setVisible(TRUE); + } + } + + for (S32 i = 0; i < 4; i++) + { + if (mResizeBar[i] != NULL) + { + mResizeBar[i]->setEnabled(isResizable()); + } + if (mResizeHandle[i] != NULL) + { + mResizeHandle[i]->setEnabled(isResizable()); + } + } + + mMinimized = FALSE; + setFrontmost(); + // Reshape *after* setting mMinimized + reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); + } + + make_ui_sound("UISndWindowClose"); + updateTitleButtons(); + applyTitle (); } void LLFloater::setFocus( BOOL b ) { - if (b && getIsChrome()) - { - return; - } - LLView* last_focus = gFocusMgr.getLastFocusForGroup(this); - // a descendent already has focus - BOOL child_had_focus = hasFocus(); - - // give focus to first valid descendent - LLPanel::setFocus(b); - - if (b) - { - // only push focused floaters to front of stack if not in midst of ctrl-tab cycle - LLFloaterView * parent = dynamic_cast(getParent()); - if (!getHost() && parent && !parent->getCycleMode()) - { - if (!isFrontmost()) - { - setFrontmost(); - } - } - - // when getting focus, delegate to last descendent which had focus - if (last_focus && !child_had_focus && - last_focus->isInEnabledChain() && - last_focus->isInVisibleChain()) - { - // *FIX: should handle case where focus doesn't stick - last_focus->setFocus(TRUE); - } - } - updateTransparency(b ? TT_ACTIVE : TT_INACTIVE); + if (b && getIsChrome()) + { + return; + } + LLView* last_focus = gFocusMgr.getLastFocusForGroup(this); + // a descendent already has focus + BOOL child_had_focus = hasFocus(); + + // give focus to first valid descendent + LLPanel::setFocus(b); + + if (b) + { + // only push focused floaters to front of stack if not in midst of ctrl-tab cycle + LLFloaterView * parent = dynamic_cast(getParent()); + if (!getHost() && parent && !parent->getCycleMode()) + { + if (!isFrontmost()) + { + setFrontmost(); + } + } + + // when getting focus, delegate to last descendent which had focus + if (last_focus && !child_had_focus && + last_focus->isInEnabledChain() && + last_focus->isInVisibleChain()) + { + // *FIX: should handle case where focus doesn't stick + last_focus->setFocus(TRUE); + } + } + updateTransparency(b ? TT_ACTIVE : TT_INACTIVE); } // virtual void LLFloater::setRect(const LLRect &rect) { - LLPanel::setRect(rect); - layoutDragHandle(); - layoutResizeCtrls(); + LLPanel::setRect(rect); + layoutDragHandle(); + layoutResizeCtrls(); } // virtual void LLFloater::setIsChrome(BOOL is_chrome) { - // chrome floaters don't take focus at all - if (is_chrome) - { - // remove focus if we're changing to chrome - setFocus(FALSE); - // can't Ctrl-Tab to "chrome" floaters - setFocusRoot(FALSE); - mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome))); - } - - LLPanel::setIsChrome(is_chrome); + // chrome floaters don't take focus at all + if (is_chrome) + { + // remove focus if we're changing to chrome + setFocus(FALSE); + // can't Ctrl-Tab to "chrome" floaters + setFocusRoot(FALSE); + mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome))); + } + + LLPanel::setIsChrome(is_chrome); } // Change the draw style to account for the foreground state. void LLFloater::setForeground(BOOL front) { - if (front != mForeground) - { - mForeground = front; - if (mDragHandle) - mDragHandle->setForeground( front ); + if (front != mForeground) + { + mForeground = front; + if (mDragHandle) + mDragHandle->setForeground( front ); - if (!front) - { - releaseFocus(); - } + if (!front) + { + releaseFocus(); + } - setBackgroundOpaque( front ); - } + setBackgroundOpaque( front ); + } } void LLFloater::cleanupHandles() { - // remove handles to non-existent dependents - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) - { - LLFloater* floaterp = dependent_it->get(); - if (!floaterp) - { - mDependents.erase(dependent_it++); - } - else - { - ++dependent_it; - } - } + // remove handles to non-existent dependents + for(handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + LLFloater* floaterp = dependent_it->get(); + if (!floaterp) + { + mDependents.erase(dependent_it++); + } + else + { + ++dependent_it; + } + } } void LLFloater::setHost(LLMultiFloater* host) { - if (mHostHandle.isDead() && host) - { - // make buttons smaller for hosted windows to differentiate from parent - mButtonScale = 0.9f; - - // add tear off button - if (mCanTearOff) - { - mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; - } - } - else if (!mHostHandle.isDead() && !host) - { - mButtonScale = 1.f; - //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; - } - if (host) - { - mHostHandle = host->getHandle(); - mLastHostHandle = host->getHandle(); - } - else - { - mHostHandle.markDead(); - } + if (mHostHandle.isDead() && host) + { + // make buttons smaller for hosted windows to differentiate from parent + mButtonScale = 0.9f; + + // add tear off button + if (mCanTearOff) + { + mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; + } + } + else if (!mHostHandle.isDead() && !host) + { + mButtonScale = 1.f; + //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; + } + if (host) + { + mHostHandle = host->getHandle(); + mLastHostHandle = host->getHandle(); + } + else + { + mHostHandle.markDead(); + } - updateTitleButtons(); + updateTitleButtons(); } void LLFloater::moveResizeHandlesToFront() { - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeBar[i] ) - { - sendChildToFront(mResizeBar[i]); - } - } + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeBar[i] ) + { + sendChildToFront(mResizeBar[i]); + } + } - for( S32 i = 0; i < 4; i++ ) - { - if( mResizeHandle[i] ) - { - sendChildToFront(mResizeHandle[i]); - } - } + for( S32 i = 0; i < 4; i++ ) + { + if( mResizeHandle[i] ) + { + sendChildToFront(mResizeHandle[i]); + } + } } /*virtual*/ BOOL LLFloater::isFrontmost() { - LLFloaterView* floater_view = getParentByType(); - return getVisible() - && (floater_view - && floater_view->getFrontmost() == this); + LLFloaterView* floater_view = getParentByType(); + return getVisible() + && (floater_view + && floater_view->getFrontmost() == this); } void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) { - mDependents.insert(floaterp->getHandle()); - floaterp->mDependeeHandle = getHandle(); + mDependents.insert(floaterp->getHandle()); + floaterp->mDependeeHandle = getHandle(); - if (reposition) - { - floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); - floaterp->setSnapTarget(getHandle()); - } - gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE); - if (floaterp->isFrontmost()) - { - // make sure to bring self and sibling floaters to front - gFloaterView->bringToFront(floaterp); - } + if (reposition) + { + floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); + floaterp->setSnapTarget(getHandle()); + } + gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE); + if (floaterp->isFrontmost()) + { + // make sure to bring self and sibling floaters to front + gFloaterView->bringToFront(floaterp); + } } void LLFloater::addDependentFloater(LLHandle dependent, BOOL reposition) { - LLFloater* dependent_floaterp = dependent.get(); - if(dependent_floaterp) - { - addDependentFloater(dependent_floaterp, reposition); - } + LLFloater* dependent_floaterp = dependent.get(); + if(dependent_floaterp) + { + addDependentFloater(dependent_floaterp, reposition); + } } void LLFloater::removeDependentFloater(LLFloater* floaterp) { - mDependents.erase(floaterp->getHandle()); - floaterp->mDependeeHandle = LLHandle(); + mDependents.erase(floaterp->getHandle()); + floaterp->mDependeeHandle = LLHandle(); } BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index) { - if( mButtonsEnabled[index] ) - { - LLButton* my_butt = mButtons[index]; - S32 local_x = x - my_butt->getRect().mLeft; - S32 local_y = y - my_butt->getRect().mBottom; + if( mButtonsEnabled[index] ) + { + LLButton* my_butt = mButtons[index]; + S32 local_x = x - my_butt->getRect().mLeft; + S32 local_y = y - my_butt->getRect().mBottom; - if ( - my_butt->pointInView(local_x, local_y) && - my_butt->handleMouseDown(local_x, local_y, mask)) - { - // the button handled it - return TRUE; - } - } - return FALSE; + if ( + my_butt->pointInView(local_x, local_y) && + my_butt->handleMouseDown(local_x, local_y, mask)) + { + // the button handled it + return TRUE; + } + } + return FALSE; } BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks) { - LLPanel::handleScrollWheel(x,y,clicks); - return TRUE;//always + LLPanel::handleScrollWheel(x,y,clicks); + return TRUE;//always } // virtual BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask) { - LL_DEBUGS() << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL; - BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView - if (handled) { - LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); - } - return handled; + LL_DEBUGS() << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL; + BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; } // virtual BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask) { - if( mMinimized ) - { - // Offer the click to titlebar buttons. - // Note: this block and the offerClickToButton helper method can be removed - // because the parent container will handle it for us but we'll keep it here - // for safety until after reworking the panel code to manage hidden children. - if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE; - if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE; - - setFrontmost(TRUE, FALSE); - // Otherwise pass to drag handle for movement - return mDragHandle->handleMouseDown(x, y, mask); - } - else - { - bringToFront( x, y ); - BOOL handled = LLPanel::handleMouseDown( x, y, mask ); - if (handled) { - LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); - } - return handled; - } + if( mMinimized ) + { + // Offer the click to titlebar buttons. + // Note: this block and the offerClickToButton helper method can be removed + // because the parent container will handle it for us but we'll keep it here + // for safety until after reworking the panel code to manage hidden children. + if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE; + if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE; + + setFrontmost(TRUE, FALSE); + // Otherwise pass to drag handle for movement + return mDragHandle->handleMouseDown(x, y, mask); + } + else + { + bringToFront( x, y ); + BOOL handled = LLPanel::handleMouseDown( x, y, mask ); + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; + } } // virtual BOOL LLFloater::handleRightMouseDown(S32 x, S32 y, MASK mask) { - BOOL was_minimized = mMinimized; - bringToFront( x, y ); - return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); + BOOL was_minimized = mMinimized; + bringToFront( x, y ); + return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); } BOOL LLFloater::handleMiddleMouseDown(S32 x, S32 y, MASK mask) { - bringToFront( x, y ); - return LLPanel::handleMiddleMouseDown( x, y, mask ); + bringToFront( x, y ); + return LLPanel::handleMiddleMouseDown( x, y, mask ); } // virtual BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) { - BOOL was_minimized = mMinimized; - setMinimized(FALSE); - return was_minimized || LLPanel::handleDoubleClick(x, y, mask); + BOOL was_minimized = mMinimized; + setMinimized(FALSE); + return was_minimized || LLPanel::handleDoubleClick(x, y, mask); } void LLFloater::bringToFront( S32 x, S32 y ) { - if (getVisible() && pointInView(x, y)) - { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - hostp->showFloater(this); - } - else - { - LLFloaterView* parent = dynamic_cast( getParent() ); - if (parent) - { - parent->bringToFront( this ); - } - } - } + if (getVisible() && pointInView(x, y)) + { + LLMultiFloater* hostp = getHost(); + if (hostp) + { + hostp->showFloater(this); + } + else + { + LLFloaterView* parent = dynamic_cast( getParent() ); + if (parent) + { + parent->bringToFront( this ); + } + } + } } // virtual void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key) { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - hostp->setVisible(TRUE); - hostp->setFrontmost(take_focus); - } - else - { - setVisible(TRUE); - setFrontmost(take_focus); - } + LLMultiFloater* hostp = getHost(); + if (hostp) + { + hostp->setVisible(TRUE); + hostp->setFrontmost(take_focus); + } + else + { + setVisible(TRUE); + setFrontmost(take_focus); + } } void LLFloater::setFrontmost(BOOL take_focus, BOOL restore) { - LLMultiFloater* hostp = getHost(); - if (hostp) - { - // this will bring the host floater to the front and select - // the appropriate panel - hostp->showFloater(this); - } - else - { - // there are more than one floater view - // so we need to query our parent directly - LLFloaterView * parent = dynamic_cast( getParent() ); - if (parent) - { - parent->bringToFront(this, take_focus, restore); - } - - // Make sure to set the appropriate transparency type (STORM-732). - updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); - } + LLMultiFloater* hostp = getHost(); + if (hostp) + { + // this will bring the host floater to the front and select + // the appropriate panel + hostp->showFloater(this); + } + else + { + // there are more than one floater view + // so we need to query our parent directly + LLFloaterView * parent = dynamic_cast( getParent() ); + if (parent) + { + parent->bringToFront(this, take_focus, restore); + } + + // Make sure to set the appropriate transparency type (STORM-732). + updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); + } } void LLFloater::setCanDock(bool b) { - if(b != mCanDock) - { - mCanDock = b; - if(mCanDock) - { - mButtonsEnabled[BUTTON_DOCK] = !mDocked; - } - else - { - mButtonsEnabled[BUTTON_DOCK] = FALSE; - } - } - updateTitleButtons(); + if(b != mCanDock) + { + mCanDock = b; + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + } + else + { + mButtonsEnabled[BUTTON_DOCK] = FALSE; + } + } + updateTitleButtons(); } void LLFloater::setDocked(bool docked, bool pop_on_undock) { - if(docked != mDocked && mCanDock) - { - mDocked = docked; - mButtonsEnabled[BUTTON_DOCK] = !mDocked; + if(docked != mDocked && mCanDock) + { + mDocked = docked; + mButtonsEnabled[BUTTON_DOCK] = !mDocked; - if (mDocked) - { - setMinimized(FALSE); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - } + if (mDocked) + { + setMinimized(FALSE); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + } - updateTitleButtons(); + updateTitleButtons(); - storeDockStateControl(); - } - + storeDockStateControl(); + } + } // static void LLFloater::onClickMinimize(LLFloater* self) { - if (!self) - return; - self->setMinimized( !self->isMinimized() ); + if (!self) + return; + self->setMinimized( !self->isMinimized() ); } void LLFloater::onClickTearOff(LLFloater* self) { - if (!self) - return; - S32 floater_header_size = self->mHeaderHeight; - LLMultiFloater* host_floater = self->getHost(); - if (host_floater) //Tear off - { - LLRect new_rect; - host_floater->removeFloater(self); - // reparent to floater view - gFloaterView->addChild(self); - - self->openFloater(self->getKey()); - if (self->mSaveRect && !self->mRectControl.empty()) - { - self->applyRectControl(); - } - else - { // only force position for floaters that don't have that data saved - new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight()); - self->setRect(new_rect); - } - gFloaterView->adjustToFitScreen(self, FALSE); - // give focus to new window to keep continuity for the user - self->setFocus(TRUE); - self->setTornOff(true); - } - else //Attach to parent. - { - LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); - if (new_host) - { - if (self->mSaveRect) - { - self->storeRectControl(); - } - self->setMinimized(FALSE); // to reenable minimize button if it was minimized - new_host->showFloater(self); - // make sure host is visible - new_host->openFloater(new_host->getKey()); - } - self->setTornOff(false); - } - self->updateTitleButtons(); + if (!self) + return; + S32 floater_header_size = self->mHeaderHeight; + LLMultiFloater* host_floater = self->getHost(); + if (host_floater) //Tear off + { + LLRect new_rect; + host_floater->removeFloater(self); + // reparent to floater view + gFloaterView->addChild(self); + + self->openFloater(self->getKey()); + if (self->mSaveRect && !self->mRectControl.empty()) + { + self->applyRectControl(); + } + else + { // only force position for floaters that don't have that data saved + new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight()); + self->setRect(new_rect); + } + gFloaterView->adjustToFitScreen(self, FALSE); + // give focus to new window to keep continuity for the user + self->setFocus(TRUE); + self->setTornOff(true); + } + else //Attach to parent. + { + LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); + if (new_host) + { + if (self->mSaveRect) + { + self->storeRectControl(); + } + self->setMinimized(FALSE); // to reenable minimize button if it was minimized + new_host->showFloater(self); + // make sure host is visible + new_host->openFloater(new_host->getKey()); + } + self->setTornOff(false); + } + self->updateTitleButtons(); self->setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); } // static void LLFloater::onClickDock(LLFloater* self) { - if(self && self->mCanDock) - { - self->setDocked(!self->mDocked, true); - } + if(self && self->mCanDock) + { + self->setDocked(!self->mDocked, true); + } } // static void LLFloater::onClickHelp( LLFloater* self ) { - if (self && LLUI::sHelpImpl) - { - // find the current help context for this floater - std::string help_topic; - if (self->findHelpTopic(help_topic)) - { - LLUI::sHelpImpl->showTopic(help_topic); - } - } + if (self && LLUI::sHelpImpl) + { + // find the current help context for this floater + std::string help_topic; + if (self->findHelpTopic(help_topic)) + { + LLUI::sHelpImpl->showTopic(help_topic); + } + } } void LLFloater::initRectControl() { - // save_rect and save_visibility only apply to registered floaters - if (mSaveRect) - { - std::string ctrl_name = getControlName(mInstanceName, mKey); - mRectControl = LLFloaterReg::declareRectControl(ctrl_name); - mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); - mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); - } + // save_rect and save_visibility only apply to registered floaters + if (mSaveRect) + { + std::string ctrl_name = getControlName(mInstanceName, mKey); + mRectControl = LLFloaterReg::declareRectControl(ctrl_name); + mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); + mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); + } } // static void LLFloater::closeFrontmostFloater() { - LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); - if(floater_to_close) - { - floater_to_close->closeFloater(); - } + LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); + if(floater_to_close) + { + floater_to_close->closeFloater(); + } - // if nothing took focus after closing focused floater - // give it to next floater (to allow closing multiple windows via keyboard in rapid succession) - if (gFocusMgr.getKeyboardFocus() == NULL) - { - // HACK: use gFloaterView directly in case we are using Ctrl-W to close snapshot window - // which sits in gSnapshotFloaterView, and needs to pass focus on to normal floater view - gFloaterView->focusFrontFloater(); - } + // if nothing took focus after closing focused floater + // give it to next floater (to allow closing multiple windows via keyboard in rapid succession) + if (gFocusMgr.getKeyboardFocus() == NULL) + { + // HACK: use gFloaterView directly in case we are using Ctrl-W to close snapshot window + // which sits in gSnapshotFloaterView, and needs to pass focus on to normal floater view + gFloaterView->focusFrontFloater(); + } } // static void LLFloater::onClickClose( LLFloater* self ) { - if (!self) - return; - self->onClickCloseBtn(); + if (!self) + return; + self->onClickCloseBtn(); } void LLFloater::onClickCloseBtn(bool app_quitting) { - closeFloater(false); + closeFloater(false); } // virtual void LLFloater::draw() { - const F32 alpha = getCurrentTransparency(); - - // draw background - if( isBackgroundVisible() ) - { - drawShadow(this); - - S32 left = LLPANEL_BORDER_WIDTH; - S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; - S32 bottom = LLPANEL_BORDER_WIDTH; - - LLUIImage* image = NULL; - LLColor4 color; - LLColor4 overlay_color; - if (isBackgroundOpaque()) - { - // NOTE: image may not be set - image = getBackgroundImage(); - color = getBackgroundColor(); - overlay_color = getBackgroundImageOverlay(); - } - else - { - image = getTransparentImage(); - color = getTransparentColor(); - overlay_color = getTransparentImageOverlay(); - } - - if (image) - { - // We're using images for this floater's backgrounds - image->draw(getLocalRect(), overlay_color % alpha); - } - else - { - // We're not using images, use old-school flat colors - gl_rect_2d( left, top, right, bottom, color % alpha ); - - // draw highlight on title bar to indicate focus. RDW - if(hasFocus() - && !getIsChrome() - && !getCurrentTitle().empty()) - { - static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); - - const LLFontGL* font = LLFontGL::getFontSansSerif(); - LLRect r = getRect(); - gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1, - titlebar_focus_color % alpha, 0, TRUE); - } - } - } - - LLPanel::updateDefaultBtn(); - - if( getDefaultButton() ) - { - if (hasFocus() && getDefaultButton()->getEnabled()) - { - LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - // is this button a direct descendent and not a nested widget (e.g. checkbox)? - BOOL focus_is_child_button = dynamic_cast(focus_ctrl) != NULL && dynamic_cast(focus_ctrl)->getParent() == this; - // only enable default button when current focus is not a button - getDefaultButton()->setBorderEnabled(!focus_is_child_button); - } - else - { - getDefaultButton()->setBorderEnabled(FALSE); - } - } - if (isMinimized()) - { - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - drawChild(mButtons[i]); - } - drawChild(mDragHandle, 0, 0, TRUE); - } - else - { - // don't call LLPanel::draw() since we've implemented custom background rendering - LLView::draw(); - } - - // update tearoff button for torn off floaters - // when last host goes away - if (mCanTearOff && !getHost()) - { - LLFloater* old_host = mLastHostHandle.get(); - if (!old_host) - { - setCanTearOff(FALSE); - } - } -} - -void LLFloater::drawShadow(LLPanel* panel) -{ - S32 left = LLPANEL_BORDER_WIDTH; - S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH; - S32 bottom = LLPANEL_BORDER_WIDTH; - - static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0); - static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); - LLColor4 shadow_color = shadow_color_cached; - F32 shadow_offset = (F32)shadow_offset_S32; - - if (!panel->isBackgroundOpaque()) - { - shadow_offset *= 0.2f; - shadow_color.mV[VALPHA] *= 0.5f; - } - gl_drop_shadow(left, top, right, bottom, - shadow_color % getCurrentTransparency(), - ll_round(shadow_offset)); + const F32 alpha = getCurrentTransparency(); + + // draw background + if( isBackgroundVisible() ) + { + drawShadow(this); + + S32 left = LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; + S32 bottom = LLPANEL_BORDER_WIDTH; + + LLUIImage* image = NULL; + LLColor4 color; + LLColor4 overlay_color; + if (isBackgroundOpaque()) + { + // NOTE: image may not be set + image = getBackgroundImage(); + color = getBackgroundColor(); + overlay_color = getBackgroundImageOverlay(); + } + else + { + image = getTransparentImage(); + color = getTransparentColor(); + overlay_color = getTransparentImageOverlay(); + } + + if (image) + { + // We're using images for this floater's backgrounds + image->draw(getLocalRect(), overlay_color % alpha); + } + else + { + // We're not using images, use old-school flat colors + gl_rect_2d( left, top, right, bottom, color % alpha ); + + // draw highlight on title bar to indicate focus. RDW + if(hasFocus() + && !getIsChrome() + && !getCurrentTitle().empty()) + { + static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); + + const LLFontGL* font = LLFontGL::getFontSansSerif(); + LLRect r = getRect(); + gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1, + titlebar_focus_color % alpha, 0, TRUE); + } + } + } + + LLPanel::updateDefaultBtn(); + + if( getDefaultButton() ) + { + if (hasFocus() && getDefaultButton()->getEnabled()) + { + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); + // is this button a direct descendent and not a nested widget (e.g. checkbox)? + BOOL focus_is_child_button = dynamic_cast(focus_ctrl) != NULL && dynamic_cast(focus_ctrl)->getParent() == this; + // only enable default button when current focus is not a button + getDefaultButton()->setBorderEnabled(!focus_is_child_button); + } + else + { + getDefaultButton()->setBorderEnabled(FALSE); + } + } + if (isMinimized()) + { + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + drawChild(mButtons[i]); + } + drawChild(mDragHandle, 0, 0, TRUE); + } + else + { + // don't call LLPanel::draw() since we've implemented custom background rendering + LLView::draw(); + } + + // update tearoff button for torn off floaters + // when last host goes away + if (mCanTearOff && !getHost()) + { + LLFloater* old_host = mLastHostHandle.get(); + if (!old_host) + { + setCanTearOff(FALSE); + } + } +} + +void LLFloater::drawShadow(LLPanel* panel) +{ + S32 left = LLPANEL_BORDER_WIDTH; + S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH; + S32 bottom = LLPANEL_BORDER_WIDTH; + + static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0); + static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); + LLColor4 shadow_color = shadow_color_cached; + F32 shadow_offset = (F32)shadow_offset_S32; + + if (!panel->isBackgroundOpaque()) + { + shadow_offset *= 0.2f; + shadow_color.mV[VALPHA] *= 0.5f; + } + gl_drop_shadow(left, top, right, bottom, + shadow_color % getCurrentTransparency(), + ll_round(shadow_offset)); } void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type) { - if (!view) return; - child_list_t children = *view->getChildList(); - child_list_t::iterator it = children.begin(); + if (!view) return; + child_list_t children = *view->getChildList(); + child_list_t::iterator it = children.begin(); - LLUICtrl* ctrl = dynamic_cast(view); - if (ctrl) - { - ctrl->setTransparencyType(transparency_type); - } + LLUICtrl* ctrl = dynamic_cast(view); + if (ctrl) + { + ctrl->setTransparencyType(transparency_type); + } - for(; it != children.end(); ++it) - { - updateTransparency(*it, transparency_type); - } + for(; it != children.end(); ++it) + { + updateTransparency(*it, transparency_type); + } } void LLFloater::updateTransparency(ETypeTransparency transparency_type) { - updateTransparency(this, transparency_type); + updateTransparency(this, transparency_type); } -void LLFloater::setCanMinimize(BOOL can_minimize) +void LLFloater::setCanMinimize(BOOL can_minimize) { - // if removing minimize/restore button programmatically, - // go ahead and unminimize floater - mCanMinimize = can_minimize; - if (!can_minimize) - { - setMinimized(FALSE); - } + // if removing minimize/restore button programmatically, + // go ahead and unminimize floater + mCanMinimize = can_minimize; + if (!can_minimize) + { + setMinimized(FALSE); + } - mButtonsEnabled[BUTTON_MINIMIZE] = can_minimize && !isMinimized(); - mButtonsEnabled[BUTTON_RESTORE] = can_minimize && isMinimized(); + mButtonsEnabled[BUTTON_MINIMIZE] = can_minimize && !isMinimized(); + mButtonsEnabled[BUTTON_RESTORE] = can_minimize && isMinimized(); - updateTitleButtons(); + updateTitleButtons(); } -void LLFloater::setCanClose(BOOL can_close) +void LLFloater::setCanClose(BOOL can_close) { - mCanClose = can_close; - mButtonsEnabled[BUTTON_CLOSE] = can_close; + mCanClose = can_close; + mButtonsEnabled[BUTTON_CLOSE] = can_close; - updateTitleButtons(); + updateTitleButtons(); } -void LLFloater::setCanTearOff(BOOL can_tear_off) +void LLFloater::setCanTearOff(BOOL can_tear_off) { - mCanTearOff = can_tear_off; - mButtonsEnabled[BUTTON_TEAR_OFF] = mCanTearOff && !mHostHandle.isDead(); + mCanTearOff = can_tear_off; + mButtonsEnabled[BUTTON_TEAR_OFF] = mCanTearOff && !mHostHandle.isDead(); - updateTitleButtons(); + updateTitleButtons(); } void LLFloater::setCanResize(BOOL can_resize) { - mResizable = can_resize; - enableResizeCtrls(can_resize); + mResizable = can_resize; + enableResizeCtrls(can_resize); } void LLFloater::setCanDrag(BOOL can_drag) { - // if we delete drag handle, we no longer have access to the floater's title - // so just enable/disable it - if (!can_drag && mDragHandle->getEnabled()) - { - mDragHandle->setEnabled(FALSE); - } - else if (can_drag && !mDragHandle->getEnabled()) - { - mDragHandle->setEnabled(TRUE); - } + // if we delete drag handle, we no longer have access to the floater's title + // so just enable/disable it + if (!can_drag && mDragHandle->getEnabled()) + { + mDragHandle->setEnabled(FALSE); + } + else if (can_drag && !mDragHandle->getEnabled()) + { + mDragHandle->setEnabled(TRUE); + } } bool LLFloater::getCanDrag() { - return mDragHandle->getEnabled(); + return mDragHandle->getEnabled(); } void LLFloater::updateTitleButtons() { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); - LLRect buttons_rect; - S32 button_count = 0; - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - if (!mButtons[i]) - { - continue; - } - - bool enabled = mButtonsEnabled[i]; - if (i == BUTTON_HELP) - { - // don't show the help button if the floater is minimized - // or if it is a docked tear-off floater - if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff)) - { - enabled = false; - } - } - if (i == BUTTON_CLOSE && mButtonScale != 1.f) - { - //*HACK: always render close button for hosted floaters so - //that users don't accidentally hit the button when - //closing multiple windows in the chatterbox - enabled = true; - } - - mButtons[i]->setEnabled(enabled); - - if (enabled) - { - button_count++; - - LLRect btn_rect; - if (mDragOnLeft) - { - btn_rect.setLeftTopAndSize( - LLPANEL_BORDER_WIDTH, - getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * button_count, - ll_round((F32)floater_close_box_size * mButtonScale), - ll_round((F32)floater_close_box_size * mButtonScale)); - } - else - { - btn_rect.setLeftTopAndSize( - getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * button_count, - getRect().getHeight() - close_box_from_top, - ll_round((F32)floater_close_box_size * mButtonScale), - ll_round((F32)floater_close_box_size * mButtonScale)); - } - - // first time here, init 'buttons_rect' - if(1 == button_count) - { - buttons_rect = btn_rect; - } - else - { - // if mDragOnLeft=true then buttons are on top-left side vertically aligned - // title is not displayed in this case, calculating 'buttons_rect' for future use - mDragOnLeft ? buttons_rect.mBottom -= btn_rect.mBottom : - buttons_rect.mLeft = btn_rect.mLeft; - } - mButtons[i]->setRect(btn_rect); - mButtons[i]->setVisible(TRUE); - // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater - mButtons[i]->setTabStop(i == BUTTON_RESTORE); - } - else - { - mButtons[i]->setVisible(FALSE); - } - } - if (mDragHandle) - { - localRectToOtherView(buttons_rect, &buttons_rect, mDragHandle); - mDragHandle->setButtonsRect(buttons_rect); - } + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); + LLRect buttons_rect; + S32 button_count = 0; + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (!mButtons[i]) + { + continue; + } + + bool enabled = mButtonsEnabled[i]; + if (i == BUTTON_HELP) + { + // don't show the help button if the floater is minimized + // or if it is a docked tear-off floater + if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff)) + { + enabled = false; + } + } + if (i == BUTTON_CLOSE && mButtonScale != 1.f) + { + //*HACK: always render close button for hosted floaters so + //that users don't accidentally hit the button when + //closing multiple windows in the chatterbox + enabled = true; + } + + mButtons[i]->setEnabled(enabled); + + if (enabled) + { + button_count++; + + LLRect btn_rect; + if (mDragOnLeft) + { + btn_rect.setLeftTopAndSize( + LLPANEL_BORDER_WIDTH, + getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * button_count, + ll_round((F32)floater_close_box_size * mButtonScale), + ll_round((F32)floater_close_box_size * mButtonScale)); + } + else + { + btn_rect.setLeftTopAndSize( + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * button_count, + getRect().getHeight() - close_box_from_top, + ll_round((F32)floater_close_box_size * mButtonScale), + ll_round((F32)floater_close_box_size * mButtonScale)); + } + + // first time here, init 'buttons_rect' + if(1 == button_count) + { + buttons_rect = btn_rect; + } + else + { + // if mDragOnLeft=true then buttons are on top-left side vertically aligned + // title is not displayed in this case, calculating 'buttons_rect' for future use + mDragOnLeft ? buttons_rect.mBottom -= btn_rect.mBottom : + buttons_rect.mLeft = btn_rect.mLeft; + } + mButtons[i]->setRect(btn_rect); + mButtons[i]->setVisible(TRUE); + // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater + mButtons[i]->setTabStop(i == BUTTON_RESTORE); + } + else + { + mButtons[i]->setVisible(FALSE); + } + } + if (mDragHandle) + { + localRectToOtherView(buttons_rect, &buttons_rect, mDragHandle); + mDragHandle->setButtonsRect(buttons_rect); + } } void LLFloater::buildButtons(const Params& floater_params) { - static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); - static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - if (mButtons[i]) - { - removeChild(mButtons[i]); - delete mButtons[i]; - mButtons[i] = NULL; - } - - LLRect btn_rect; - if (mDragOnLeft) - { - btn_rect.setLeftTopAndSize( - LLPANEL_BORDER_WIDTH, - getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * (i + 1), - ll_round(floater_close_box_size * mButtonScale), - ll_round(floater_close_box_size * mButtonScale)); - } - else - { - btn_rect.setLeftTopAndSize( - getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * (i + 1), - getRect().getHeight() - close_box_from_top, - ll_round(floater_close_box_size * mButtonScale), - ll_round(floater_close_box_size * mButtonScale)); - } - - LLButton::Params p; - p.name(sButtonNames[i]); - p.rect(btn_rect); - p.image_unselected = getButtonImage(floater_params, (EFloaterButton)i); - // Selected, no matter if hovered or not, is "pressed" - LLUIImage* pressed_image = getButtonPressedImage(floater_params, (EFloaterButton)i); - p.image_selected = pressed_image; - p.image_hover_selected = pressed_image; - // Use a glow effect when the user hovers over the button - // These icons are really small, need glow amount increased - p.hover_glow_amount( 0.33f ); - p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); - p.tab_stop(false); - p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); - p.tool_tip = getButtonTooltip(floater_params, (EFloaterButton)i, getIsChrome()); - p.scale_image(true); - p.chrome(true); - - LLButton* buttonp = LLUICtrlFactory::create(p); - addChild(buttonp); - mButtons[i] = buttonp; - } - - updateTitleButtons(); + static LLUICachedControl floater_close_box_size ("UIFloaterCloseBoxSize", 0); + static LLUICachedControl close_box_from_top ("UICloseBoxFromTop", 0); + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (mButtons[i]) + { + removeChild(mButtons[i]); + delete mButtons[i]; + mButtons[i] = NULL; + } + + LLRect btn_rect; + if (mDragOnLeft) + { + btn_rect.setLeftTopAndSize( + LLPANEL_BORDER_WIDTH, + getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * (i + 1), + ll_round(floater_close_box_size * mButtonScale), + ll_round(floater_close_box_size * mButtonScale)); + } + else + { + btn_rect.setLeftTopAndSize( + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * (i + 1), + getRect().getHeight() - close_box_from_top, + ll_round(floater_close_box_size * mButtonScale), + ll_round(floater_close_box_size * mButtonScale)); + } + + LLButton::Params p; + p.name(sButtonNames[i]); + p.rect(btn_rect); + p.image_unselected = getButtonImage(floater_params, (EFloaterButton)i); + // Selected, no matter if hovered or not, is "pressed" + LLUIImage* pressed_image = getButtonPressedImage(floater_params, (EFloaterButton)i); + p.image_selected = pressed_image; + p.image_hover_selected = pressed_image; + // Use a glow effect when the user hovers over the button + // These icons are really small, need glow amount increased + p.hover_glow_amount( 0.33f ); + p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); + p.tab_stop(false); + p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); + p.tool_tip = getButtonTooltip(floater_params, (EFloaterButton)i, getIsChrome()); + p.scale_image(true); + p.chrome(true); + + LLButton* buttonp = LLUICtrlFactory::create(p); + addChild(buttonp); + mButtons[i] = buttonp; + } + + updateTitleButtons(); } // static LLUIImage* LLFloater::getButtonImage(const Params& p, EFloaterButton e) { - switch(e) - { - default: - case BUTTON_CLOSE: - return p.close_image; - case BUTTON_RESTORE: - return p.restore_image; - case BUTTON_MINIMIZE: - return p.minimize_image; - case BUTTON_TEAR_OFF: - return p.tear_off_image; - case BUTTON_DOCK: - return p.dock_image; - case BUTTON_HELP: - return p.help_image; - } + switch(e) + { + default: + case BUTTON_CLOSE: + return p.close_image; + case BUTTON_RESTORE: + return p.restore_image; + case BUTTON_MINIMIZE: + return p.minimize_image; + case BUTTON_TEAR_OFF: + return p.tear_off_image; + case BUTTON_DOCK: + return p.dock_image; + case BUTTON_HELP: + return p.help_image; + } } // static LLUIImage* LLFloater::getButtonPressedImage(const Params& p, EFloaterButton e) { - switch(e) - { - default: - case BUTTON_CLOSE: - return p.close_pressed_image; - case BUTTON_RESTORE: - return p.restore_pressed_image; - case BUTTON_MINIMIZE: - return p.minimize_pressed_image; - case BUTTON_TEAR_OFF: - return p.tear_off_pressed_image; - case BUTTON_DOCK: - return p.dock_pressed_image; - case BUTTON_HELP: - return p.help_pressed_image; - } + switch(e) + { + default: + case BUTTON_CLOSE: + return p.close_pressed_image; + case BUTTON_RESTORE: + return p.restore_pressed_image; + case BUTTON_MINIMIZE: + return p.minimize_pressed_image; + case BUTTON_TEAR_OFF: + return p.tear_off_pressed_image; + case BUTTON_DOCK: + return p.dock_pressed_image; + case BUTTON_HELP: + return p.help_pressed_image; + } } // static std::string LLFloater::getButtonTooltip(const Params& p, EFloaterButton e, bool is_chrome) { - // EXT-4081 (Lag Meter: Ctrl+W does not close floater) - // If floater is chrome set 'Close' text for close button's tooltip - if(is_chrome && BUTTON_CLOSE == e) - { - static std::string close_tooltip_chrome = LLTrans::getString("BUTTON_CLOSE_CHROME"); - return close_tooltip_chrome; - } - // TODO: per-floater localizable tooltips set in XML - return sButtonToolTips[e]; + // EXT-4081 (Lag Meter: Ctrl+W does not close floater) + // If floater is chrome set 'Close' text for close button's tooltip + if(is_chrome && BUTTON_CLOSE == e) + { + static std::string close_tooltip_chrome = LLTrans::getString("BUTTON_CLOSE_CHROME"); + return close_tooltip_chrome; + } + // TODO: per-floater localizable tooltips set in XML + return sButtonToolTips[e]; } ///////////////////////////////////////////////////// @@ -2234,946 +2234,946 @@ std::string LLFloater::getButtonTooltip(const Params& p, EFloaterButton e, bool static LLDefaultChildRegistry::Register r("floater_view"); LLFloaterView::LLFloaterView (const Params& p) -: LLUICtrl (p), - mFocusCycleMode(FALSE), - mMinimizePositionVOffset(0), - mSnapOffsetBottom(0), - mSnapOffsetRight(0), - mFrontChild(NULL) +: LLUICtrl (p), + mFocusCycleMode(FALSE), + mMinimizePositionVOffset(0), + mSnapOffsetBottom(0), + mSnapOffsetRight(0), + mFrontChild(NULL) { - mSnapView = getHandle(); + mSnapView = getHandle(); } // By default, adjust vertical. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) { - LLView::reshape(width, height, called_from_parent); - - mLastSnapRect = getSnapRect(); - - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - LLFloater* floaterp = dynamic_cast(viewp); - if (floaterp->isDependent()) - { - // dependents are moved with their "dependee" - continue; - } - - if (!floaterp->isMinimized() && floaterp->getCanDrag()) - { - LLRect old_rect = floaterp->getRect(); - floaterp->applyPositioning(NULL, false); - LLRect new_rect = floaterp->getRect(); - - //LLRect r = floaterp->getRect(); - - //// Compute absolute distance from each edge of screen - //S32 left_offset = llabs(r.mLeft - 0); - //S32 right_offset = llabs(old_right - r.mRight); - - //S32 top_offset = llabs(old_top - r.mTop); - //S32 bottom_offset = llabs(r.mBottom - 0); - - S32 translate_x = new_rect.mLeft - old_rect.mLeft; - S32 translate_y = new_rect.mBottom - old_rect.mBottom; - - //if (left_offset > right_offset) - //{ - // translate_x = new_right - old_right; - //} - - //if (top_offset < bottom_offset) - //{ - // translate_y = new_top - old_top; - //} - - // don't reposition immovable floaters - //if (floaterp->getCanDrag()) - //{ - // floaterp->translate(translate_x, translate_y); - //} - BOOST_FOREACH(LLHandle dependent_floater, floaterp->mDependents) - { - if (dependent_floater.get()) - { - dependent_floater.get()->translate(translate_x, translate_y); - } - } - } - } + LLView::reshape(width, height, called_from_parent); + + mLastSnapRect = getSnapRect(); + + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + LLFloater* floaterp = dynamic_cast(viewp); + if (floaterp->isDependent()) + { + // dependents are moved with their "dependee" + continue; + } + + if (!floaterp->isMinimized() && floaterp->getCanDrag()) + { + LLRect old_rect = floaterp->getRect(); + floaterp->applyPositioning(NULL, false); + LLRect new_rect = floaterp->getRect(); + + //LLRect r = floaterp->getRect(); + + //// Compute absolute distance from each edge of screen + //S32 left_offset = llabs(r.mLeft - 0); + //S32 right_offset = llabs(old_right - r.mRight); + + //S32 top_offset = llabs(old_top - r.mTop); + //S32 bottom_offset = llabs(r.mBottom - 0); + + S32 translate_x = new_rect.mLeft - old_rect.mLeft; + S32 translate_y = new_rect.mBottom - old_rect.mBottom; + + //if (left_offset > right_offset) + //{ + // translate_x = new_right - old_right; + //} + + //if (top_offset < bottom_offset) + //{ + // translate_y = new_top - old_top; + //} + + // don't reposition immovable floaters + //if (floaterp->getCanDrag()) + //{ + // floaterp->translate(translate_x, translate_y); + //} + BOOST_FOREACH(LLHandle dependent_floater, floaterp->mDependents) + { + if (dependent_floater.get()) + { + dependent_floater.get()->translate(translate_x, translate_y); + } + } + } + } } void LLFloaterView::restoreAll() { - // make sure all subwindows aren't minimized - child_list_t child_list = *(getChildList()); - for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (floaterp) - { - floaterp->setMinimized(FALSE); - } - } + // make sure all subwindows aren't minimized + child_list_t child_list = *(getChildList()); + for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (floaterp) + { + floaterp->setMinimized(FALSE); + } + } - // *FIX: make sure dependents are restored + // *FIX: make sure dependents are restored - // children then deleted by default view constructor + // children then deleted by default view constructor } LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor ) { - LLRect base_rect = reference_floater->getRect(); - LLRect::tCoordType width = neighbor->getRect().getWidth(); - LLRect::tCoordType height = neighbor->getRect().getHeight(); - LLRect new_rect = neighbor->getRect(); - - LLRect expanded_base_rect = base_rect; - expanded_base_rect.stretch(10); - for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); - dependent_it != reference_floater->mDependents.end(); ++dependent_it) - { - LLFloater* sibling = dependent_it->get(); - // check for dependents within 10 pixels of base floater - if (sibling && - sibling != neighbor && - sibling->getVisible() && - expanded_base_rect.overlaps(sibling->getRect())) - { - base_rect.unionWith(sibling->getRect()); - } - } - - LLRect::tCoordType left_margin = llmax(0, base_rect.mLeft); - LLRect::tCoordType right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); - LLRect::tCoordType top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); - LLRect::tCoordType bottom_margin = llmax(0, base_rect.mBottom); - - // find position for floater in following order - // right->left->bottom->top - for (S32 i = 0; i < 5; i++) - { - if (right_margin > width) - { - new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); - return new_rect; - } - else if (left_margin > width) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); - return new_rect; - } - else if (bottom_margin > height) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); - return new_rect; - } - else if (top_margin > height) - { - new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); - return new_rect; - } - - // keep growing margins to find "best" fit - left_margin += 20; - right_margin += 20; - top_margin += 20; - bottom_margin += 20; - } - - // didn't find anything, return initial rect - return new_rect; + LLRect base_rect = reference_floater->getRect(); + LLRect::tCoordType width = neighbor->getRect().getWidth(); + LLRect::tCoordType height = neighbor->getRect().getHeight(); + LLRect new_rect = neighbor->getRect(); + + LLRect expanded_base_rect = base_rect; + expanded_base_rect.stretch(10); + for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); + dependent_it != reference_floater->mDependents.end(); ++dependent_it) + { + LLFloater* sibling = dependent_it->get(); + // check for dependents within 10 pixels of base floater + if (sibling && + sibling != neighbor && + sibling->getVisible() && + expanded_base_rect.overlaps(sibling->getRect())) + { + base_rect.unionWith(sibling->getRect()); + } + } + + LLRect::tCoordType left_margin = llmax(0, base_rect.mLeft); + LLRect::tCoordType right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); + LLRect::tCoordType top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); + LLRect::tCoordType bottom_margin = llmax(0, base_rect.mBottom); + + // find position for floater in following order + // right->left->bottom->top + for (S32 i = 0; i < 5; i++) + { + if (right_margin > width) + { + new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); + return new_rect; + } + else if (left_margin > width) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); + return new_rect; + } + else if (bottom_margin > height) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); + return new_rect; + } + else if (top_margin > height) + { + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); + return new_rect; + } + + // keep growing margins to find "best" fit + left_margin += 20; + right_margin += 20; + top_margin += 20; + bottom_margin += 20; + } + + // didn't find anything, return initial rect + return new_rect; } void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore) { - if (!child) - return; - - if (mFrontChild == child) - { - if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) - { - child->setFocus(TRUE); - } - return; - } - - mFrontChild = child; - - // *TODO: make this respect floater's mAutoFocus value, instead of - // using parameter - if (child->getHost()) - { - // this floater is hosted elsewhere and hence not one of our children, abort - return; - } - std::vector floaters_to_move; - // Look at all floaters...tab - for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it) - { - LLFloater* floater = dynamic_cast(*child_it); - - // ...but if I'm a dependent floater... - if (floater && child->isDependent()) - { - // ...look for floaters that have me as a dependent... - LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle()); - - if (found_dependent != floater->mDependents.end()) - { - // ...and make sure all children of that floater (including me) are brought to front... - for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); ++dependent_it) - { - LLFloater* sibling = dependent_it->get(); - if (sibling) - { - floaters_to_move.push_back(sibling); - } - } - //...before bringing my parent to the front... - floaters_to_move.push_back(floater); - } - } - } - - std::vector::iterator floater_it; - for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it) - { - LLFloater* floaterp = *floater_it; - sendChildToFront(floaterp); - - // always unminimize dependee, but allow dependents to stay minimized - if (!floaterp->isDependent()) - { - floaterp->setMinimized(FALSE); - } - } - floaters_to_move.clear(); - - // ...then bringing my own dependents to the front... - for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); - dependent_it != child->mDependents.end(); ++dependent_it) - { - LLFloater* dependent = dependent_it->get(); - if (dependent) - { - sendChildToFront(dependent); - } - } - - // ...and finally bringing myself to front - // (do this last, so that I'm left in front at end of this call) - if (*beginChild() != child) - { - sendChildToFront(child); - } - - if(restore) - { - child->setMinimized(FALSE); - } - - if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) - { - child->setFocus(TRUE); - // floater did not take focus, so relinquish focus to world - if (!child->hasFocus()) - { - gFocusMgr.setKeyboardFocus(NULL); - } - } + if (!child) + return; + + if (mFrontChild == child) + { + if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) + { + child->setFocus(TRUE); + } + return; + } + + mFrontChild = child; + + // *TODO: make this respect floater's mAutoFocus value, instead of + // using parameter + if (child->getHost()) + { + // this floater is hosted elsewhere and hence not one of our children, abort + return; + } + std::vector floaters_to_move; + // Look at all floaters...tab + for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it) + { + LLFloater* floater = dynamic_cast(*child_it); + + // ...but if I'm a dependent floater... + if (floater && child->isDependent()) + { + // ...look for floaters that have me as a dependent... + LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle()); + + if (found_dependent != floater->mDependents.end()) + { + // ...and make sure all children of that floater (including me) are brought to front... + for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); ++dependent_it) + { + LLFloater* sibling = dependent_it->get(); + if (sibling) + { + floaters_to_move.push_back(sibling); + } + } + //...before bringing my parent to the front... + floaters_to_move.push_back(floater); + } + } + } + + std::vector::iterator floater_it; + for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it) + { + LLFloater* floaterp = *floater_it; + sendChildToFront(floaterp); + + // always unminimize dependee, but allow dependents to stay minimized + if (!floaterp->isDependent()) + { + floaterp->setMinimized(FALSE); + } + } + floaters_to_move.clear(); + + // ...then bringing my own dependents to the front... + for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); + dependent_it != child->mDependents.end(); ++dependent_it) + { + LLFloater* dependent = dependent_it->get(); + if (dependent) + { + sendChildToFront(dependent); + } + } + + // ...and finally bringing myself to front + // (do this last, so that I'm left in front at end of this call) + if (*beginChild() != child) + { + sendChildToFront(child); + } + + if(restore) + { + child->setMinimized(FALSE); + } + + if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) + { + child->setFocus(TRUE); + // floater did not take focus, so relinquish focus to world + if (!child->hasFocus()) + { + gFocusMgr.setKeyboardFocus(NULL); + } + } } void LLFloaterView::highlightFocusedFloater() { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater *floater = (LLFloater *)(*child_it); - - // skip dependent floaters, as we'll handle them in a batch along with their dependee(?) - if (floater->isDependent()) - { - continue; - } - - BOOL floater_or_dependent_has_focus = gFocusMgr.childHasKeyboardFocus(floater); - for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); - ++dependent_it) - { - LLFloater* dependent_floaterp = dependent_it->get(); - if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) - { - floater_or_dependent_has_focus = TRUE; - } - } - - // now set this floater and all its dependents - floater->setForeground(floater_or_dependent_has_focus); - - for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); - dependent_it != floater->mDependents.end(); ) - { - LLFloater* dependent_floaterp = dependent_it->get(); - if (dependent_floaterp) - { - dependent_floaterp->setForeground(floater_or_dependent_has_focus); - } - ++dependent_it; - } - - floater->cleanupHandles(); - } + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater *floater = (LLFloater *)(*child_it); + + // skip dependent floaters, as we'll handle them in a batch along with their dependee(?) + if (floater->isDependent()) + { + continue; + } + + BOOL floater_or_dependent_has_focus = gFocusMgr.childHasKeyboardFocus(floater); + for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); + ++dependent_it) + { + LLFloater* dependent_floaterp = dependent_it->get(); + if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) + { + floater_or_dependent_has_focus = TRUE; + } + } + + // now set this floater and all its dependents + floater->setForeground(floater_or_dependent_has_focus); + + for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); + dependent_it != floater->mDependents.end(); ) + { + LLFloater* dependent_floaterp = dependent_it->get(); + if (dependent_floaterp) + { + dependent_floaterp->setForeground(floater_or_dependent_has_focus); + } + ++dependent_it; + } + + floater->cleanupHandles(); + } } LLFloater* LLFloaterView::getFrontmostClosableFloater() { - child_list_const_iter_t child_it; - LLFloater* frontmost_floater = NULL; + child_list_const_iter_t child_it; + LLFloater* frontmost_floater = NULL; - for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - frontmost_floater = (LLFloater *)(*child_it); + for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + frontmost_floater = (LLFloater *)(*child_it); - if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable()) - { - return frontmost_floater; - } - } + if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable()) + { + return frontmost_floater; + } + } - return NULL; + return NULL; } void LLFloaterView::unhighlightFocusedFloater() { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater *floater = (LLFloater *)(*child_it); + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater *floater = (LLFloater *)(*child_it); - floater->setForeground(FALSE); - } + floater->setForeground(FALSE); + } } void LLFloaterView::focusFrontFloater() { - LLFloater* floaterp = getFrontmost(); - if (floaterp) - { - floaterp->setFocus(TRUE); - } + LLFloater* floaterp = getFrontmost(); + if (floaterp) + { + floaterp->setFocus(TRUE); + } } void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) { - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); - S32 floater_header_size = default_params.header_height; - static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); - LLRect snap_rect_local = getLocalSnapRect(); - snap_rect_local.mTop += mMinimizePositionVOffset; - for(S32 col = snap_rect_local.mLeft; - col < snap_rect_local.getWidth() - minimized_width; - col += minimized_width) - { - for(S32 row = snap_rect_local.mTop - floater_header_size; - row > floater_header_size; - row -= floater_header_size ) //loop rows - { - - bool foundGap = TRUE; - for(child_list_const_iter_t child_it = getChildList()->begin(); - child_it != getChildList()->end(); - ++child_it) //loop floaters - { - // Examine minimized children. - LLFloater* floater = dynamic_cast(*child_it); - if(floater->isMinimized()) - { - LLRect r = floater->getRect(); - if((r.mBottom < (row + floater_header_size)) - && (r.mBottom > (row - floater_header_size)) - && (r.mLeft < (col + minimized_width)) - && (r.mLeft > (col - minimized_width))) - { - // needs the check for off grid. can't drag, - // but window resize makes them off - foundGap = FALSE; - break; - } - } - } //done floaters - if(foundGap) - { - *left = col; - *bottom = row; - return; //done - } - } //done this col - } - - // crude - stack'em all at 0,0 when screen is full of minimized - // floaters. - *left = snap_rect_local.mLeft; - *bottom = snap_rect_local.mBottom; + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + static LLUICachedControl minimized_width ("UIMinimizedWidth", 0); + LLRect snap_rect_local = getLocalSnapRect(); + snap_rect_local.mTop += mMinimizePositionVOffset; + for(S32 col = snap_rect_local.mLeft; + col < snap_rect_local.getWidth() - minimized_width; + col += minimized_width) + { + for(S32 row = snap_rect_local.mTop - floater_header_size; + row > floater_header_size; + row -= floater_header_size ) //loop rows + { + + bool foundGap = TRUE; + for(child_list_const_iter_t child_it = getChildList()->begin(); + child_it != getChildList()->end(); + ++child_it) //loop floaters + { + // Examine minimized children. + LLFloater* floater = dynamic_cast(*child_it); + if(floater->isMinimized()) + { + LLRect r = floater->getRect(); + if((r.mBottom < (row + floater_header_size)) + && (r.mBottom > (row - floater_header_size)) + && (r.mLeft < (col + minimized_width)) + && (r.mLeft > (col - minimized_width))) + { + // needs the check for off grid. can't drag, + // but window resize makes them off + foundGap = FALSE; + break; + } + } + } //done floaters + if(foundGap) + { + *left = col; + *bottom = row; + return; //done + } + } //done this col + } + + // crude - stack'em all at 0,0 when screen is full of minimized + // floaters. + *left = snap_rect_local.mLeft; + *bottom = snap_rect_local.mBottom; } void LLFloaterView::destroyAllChildren() { - LLView::deleteAllChildren(); + LLView::deleteAllChildren(); } void LLFloaterView::closeAllChildren(bool app_quitting) { - // iterate over a copy of the list, because closing windows will destroy - // some windows on the list. - child_list_t child_list = *(getChildList()); - - for (child_list_const_iter_t it = child_list.begin(); it != child_list.end(); ++it) - { - LLView* viewp = *it; - child_list_const_iter_t exists = std::find(getChildList()->begin(), getChildList()->end(), viewp); - if (exists == getChildList()->end()) - { - // this floater has already been removed - continue; - } - - LLFloater* floaterp = dynamic_cast(viewp); - - // Attempt to close floater. This will cause the "do you want to save" - // dialogs to appear. - // Skip invisible floaters if we're not quitting (STORM-192). - if (floaterp->canClose() && !floaterp->isDead() && - (app_quitting || floaterp->getVisible())) - { - floaterp->closeFloater(app_quitting); - } - } + // iterate over a copy of the list, because closing windows will destroy + // some windows on the list. + child_list_t child_list = *(getChildList()); + + for (child_list_const_iter_t it = child_list.begin(); it != child_list.end(); ++it) + { + LLView* viewp = *it; + child_list_const_iter_t exists = std::find(getChildList()->begin(), getChildList()->end(), viewp); + if (exists == getChildList()->end()) + { + // this floater has already been removed + continue; + } + + LLFloater* floaterp = dynamic_cast(viewp); + + // Attempt to close floater. This will cause the "do you want to save" + // dialogs to appear. + // Skip invisible floaters if we're not quitting (STORM-192). + if (floaterp->canClose() && !floaterp->isDead() && + (app_quitting || floaterp->getVisible())) + { + floaterp->closeFloater(app_quitting); + } + } } void LLFloaterView::hiddenFloaterClosed(LLFloater* floater) { - for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); - it != end_it; - ++it) - { - if (it->first.get() == floater) - { - it->second.disconnect(); - mHiddenFloaters.erase(it); - break; - } - } + for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); + it != end_it; + ++it) + { + if (it->first.get() == floater) + { + it->second.disconnect(); + mHiddenFloaters.erase(it); + break; + } + } } void LLFloaterView::hideAllFloaters() { - child_list_t child_list = *(getChildList()); + child_list_t child_list = *(getChildList()); - for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); - if (floaterp && floaterp->getVisible()) - { - floaterp->setVisible(false); - boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp)); - mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection)); - } - } + for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); + if (floaterp && floaterp->getVisible()) + { + floaterp->setVisible(false); + boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp)); + mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection)); + } + } } void LLFloaterView::showHiddenFloaters() { - for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); - it != end_it; - ++it) - { - LLFloater* floaterp = it->first.get(); - if (floaterp) - { - floaterp->setVisible(true); - } - it->second.disconnect(); - } - mHiddenFloaters.clear(); + for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end(); + it != end_it; + ++it) + { + LLFloater* floaterp = it->first.get(); + if (floaterp) + { + floaterp->setVisible(true); + } + it->second.disconnect(); + } + mHiddenFloaters.clear(); } BOOL LLFloaterView::allChildrenClosed() { - // see if there are any visible floaters (some floaters "close" - // by setting themselves invisible) - for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); + // see if there are any visible floaters (some floaters "close" + // by setting themselves invisible) + for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); - if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) - { - return false; - } - } - return true; + if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) + { + return false; + } + } + return true; } void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset) { - for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) - { - LLFloater* floaterp = dynamic_cast(*it); + for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) + { + LLFloater* floaterp = dynamic_cast(*it); - if (floaterp && floaterp->isMinimized()) - { - floaterp->translate(x_offset, y_offset); - } - } + if (floaterp && floaterp->isMinimized()) + { + floaterp->translate(x_offset, y_offset); + } + } } void LLFloaterView::refresh() { - LLRect snap_rect = getSnapRect(); - if (snap_rect != mLastSnapRect) - { - reshape(getRect().getWidth(), getRect().getHeight(), TRUE); - } - - // Constrain children to be entirely on the screen - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (floaterp && floaterp->getVisible() ) - { - // minimized floaters are kept fully onscreen - adjustToFitScreen(floaterp, !floaterp->isMinimized()); - } - } + LLRect snap_rect = getSnapRect(); + if (snap_rect != mLastSnapRect) + { + reshape(getRect().getWidth(), getRect().getHeight(), TRUE); + } + + // Constrain children to be entirely on the screen + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (floaterp && floaterp->getVisible() ) + { + // minimized floaters are kept fully onscreen + adjustToFitScreen(floaterp, !floaterp->isMinimized()); + } + } } void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/) { - if (floater->getParent() != this) - { - // floater is hosted elsewhere, so ignore - return; - } - LLRect::tCoordType screen_width = getSnapRect().getWidth(); - LLRect::tCoordType screen_height = getSnapRect().getHeight(); - - - // only automatically resize non-minimized, resizable floaters - if( floater->isResizable() && !floater->isMinimized() ) - { - LLRect view_rect = floater->getRect(); - S32 old_width = view_rect.getWidth(); - S32 old_height = view_rect.getHeight(); - S32 min_width; - S32 min_height; - floater->getResizeLimits( &min_width, &min_height ); - - // Make sure floater isn't already smaller than its min height/width? - S32 new_width = llmax( min_width, old_width ); - S32 new_height = llmax( min_height, old_height); - - if((new_width > screen_width) || (new_height > screen_height)) - { - // We have to make this window able to fit on screen - new_width = llmin(new_width, screen_width); - new_height = llmin(new_height, screen_height); - - // ...while respecting minimum width/height - new_width = llmax(new_width, min_width); - new_height = llmax(new_height, min_height); - - LLRect new_rect; - new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height); - - floater->setShape(new_rect); - - if (floater->followsRight()) - { - floater->translate(old_width - new_width, 0); - } - - if (floater->followsTop()) - { - floater->translate(0, old_height - new_height); - } - } - } - - const LLRect& floater_rect = floater->getRect(); - - S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0; - S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0; - S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0; - - // move window fully onscreen - if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX )) - { - floater->clearSnapTarget(); - } - else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom) - { - floater->translate(delta_left, 0); - } - else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight) - { - floater->translate(0, delta_bottom); - } - else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom) - { - floater->translate(delta_right, 0); - } + if (floater->getParent() != this) + { + // floater is hosted elsewhere, so ignore + return; + } + LLRect::tCoordType screen_width = getSnapRect().getWidth(); + LLRect::tCoordType screen_height = getSnapRect().getHeight(); + + + // only automatically resize non-minimized, resizable floaters + if( floater->isResizable() && !floater->isMinimized() ) + { + LLRect view_rect = floater->getRect(); + S32 old_width = view_rect.getWidth(); + S32 old_height = view_rect.getHeight(); + S32 min_width; + S32 min_height; + floater->getResizeLimits( &min_width, &min_height ); + + // Make sure floater isn't already smaller than its min height/width? + S32 new_width = llmax( min_width, old_width ); + S32 new_height = llmax( min_height, old_height); + + if((new_width > screen_width) || (new_height > screen_height)) + { + // We have to make this window able to fit on screen + new_width = llmin(new_width, screen_width); + new_height = llmin(new_height, screen_height); + + // ...while respecting minimum width/height + new_width = llmax(new_width, min_width); + new_height = llmax(new_height, min_height); + + LLRect new_rect; + new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height); + + floater->setShape(new_rect); + + if (floater->followsRight()) + { + floater->translate(old_width - new_width, 0); + } + + if (floater->followsTop()) + { + floater->translate(0, old_height - new_height); + } + } + } + + const LLRect& floater_rect = floater->getRect(); + + S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0; + S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0; + S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0; + + // move window fully onscreen + if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX )) + { + floater->clearSnapTarget(); + } + else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom) + { + floater->translate(delta_left, 0); + } + else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight) + { + floater->translate(0, delta_bottom); + } + else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom) + { + floater->translate(delta_right, 0); + } } void LLFloaterView::draw() { - refresh(); + refresh(); - // hide focused floater if in cycle mode, so that it can be drawn on top - LLFloater* focused_floater = getFocusedFloater(); + // hide focused floater if in cycle mode, so that it can be drawn on top + LLFloater* focused_floater = getFocusedFloater(); - if (mFocusCycleMode && focused_floater) - { - child_list_const_iter_t child_it = getChildList()->begin(); - for (;child_it != getChildList()->end(); ++child_it) - { - if ((*child_it) != focused_floater) - { - drawChild(*child_it); - } - } + if (mFocusCycleMode && focused_floater) + { + child_list_const_iter_t child_it = getChildList()->begin(); + for (;child_it != getChildList()->end(); ++child_it) + { + if ((*child_it) != focused_floater) + { + drawChild(*child_it); + } + } - drawChild(focused_floater, -TABBED_FLOATER_OFFSET, TABBED_FLOATER_OFFSET); - } - else - { - LLView::draw(); - } + drawChild(focused_floater, -TABBED_FLOATER_OFFSET, TABBED_FLOATER_OFFSET); + } + else + { + LLView::draw(); + } } LLRect LLFloaterView::getSnapRect() const { - LLRect snap_rect = getLocalRect(); + LLRect snap_rect = getLocalRect(); - LLView* snap_view = mSnapView.get(); - if (snap_view) - { - snap_view->localRectToOtherView(snap_view->getLocalRect(), &snap_rect, this); - } + LLView* snap_view = mSnapView.get(); + if (snap_view) + { + snap_view->localRectToOtherView(snap_view->getLocalRect(), &snap_rect, this); + } - return snap_rect; + return snap_rect; } LLFloater *LLFloaterView::getFocusedFloater() const { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - if ((*child_it)->isCtrl()) - { - LLFloater* ctrlp = dynamic_cast(*child_it); - if ( ctrlp && ctrlp->hasFocus() ) - { - return ctrlp; - } - } - } - return NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + if ((*child_it)->isCtrl()) + { + LLFloater* ctrlp = dynamic_cast(*child_it); + if ( ctrlp && ctrlp->hasFocus() ) + { + return ctrlp; + } + } + } + return NULL; } LLFloater *LLFloaterView::getFrontmost() const { - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if ( viewp->getVisible() && !viewp->isDead()) - { - return (LLFloater *)viewp; - } - } - return NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if ( viewp->getVisible() && !viewp->isDead()) + { + return (LLFloater *)viewp; + } + } + return NULL; } LLFloater *LLFloaterView::getBackmost() const { - LLFloater* back_most = NULL; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if ( viewp->getVisible() ) - { - back_most = (LLFloater *)viewp; - } - } - return back_most; + LLFloater* back_most = NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if ( viewp->getVisible() ) + { + back_most = (LLFloater *)viewp; + } + } + return back_most; } void LLFloaterView::syncFloaterTabOrder() { - // look for a visible modal dialog, starting from first - LLModalDialog* modal_dialog = NULL; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLModalDialog* dialog = dynamic_cast(*child_it); - if (dialog && dialog->isModal() && dialog->getVisible()) - { - modal_dialog = dialog; - break; - } - } - - if (modal_dialog) - { - // If we have a visible modal dialog, make sure that it has focus - LLUI::addPopup(modal_dialog); - - if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) - { - modal_dialog->setFocus(TRUE); - } - - if( !gFocusMgr.childHasMouseCapture( modal_dialog ) ) - { - gFocusMgr.setMouseCapture( modal_dialog ); - } - } - else - { - // otherwise, make sure the focused floater is in the front of the child list - for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) - { - LLFloater* floaterp = dynamic_cast(*child_it); - if (gFocusMgr.childHasKeyboardFocus(floaterp)) - { - bringToFront(floaterp, FALSE); - break; - } - } - } -} - -LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const -{ - LLView* parentp = viewp->getParent(); - - while(parentp && parentp != this) - { - viewp = parentp; - parentp = parentp->getParent(); - } - - if (parentp == this) - { - return dynamic_cast(viewp); - } - - return NULL; + // look for a visible modal dialog, starting from first + LLModalDialog* modal_dialog = NULL; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLModalDialog* dialog = dynamic_cast(*child_it); + if (dialog && dialog->isModal() && dialog->getVisible()) + { + modal_dialog = dialog; + break; + } + } + + if (modal_dialog) + { + // If we have a visible modal dialog, make sure that it has focus + LLUI::addPopup(modal_dialog); + + if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) + { + modal_dialog->setFocus(TRUE); + } + + if( !gFocusMgr.childHasMouseCapture( modal_dialog ) ) + { + gFocusMgr.setMouseCapture( modal_dialog ); + } + } + else + { + // otherwise, make sure the focused floater is in the front of the child list + for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) + { + LLFloater* floaterp = dynamic_cast(*child_it); + if (gFocusMgr.childHasKeyboardFocus(floaterp)) + { + bringToFront(floaterp, FALSE); + break; + } + } + } +} + +LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const +{ + LLView* parentp = viewp->getParent(); + + while(parentp && parentp != this) + { + viewp = parentp; + parentp = parentp->getParent(); + } + + if (parentp == this) + { + return dynamic_cast(viewp); + } + + return NULL; } S32 LLFloaterView::getZOrder(LLFloater* child) { - S32 rv = 0; - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if(viewp == child) - { - break; - } - ++rv; - } - return rv; + S32 rv = 0; + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + LLView* viewp = *child_it; + if(viewp == child) + { + break; + } + ++rv; + } + return rv; } void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list) { - for (child_list_const_iter_t child_iter = getChildList()->begin(); - child_iter != getChildList()->end(); ++child_iter) - { - LLView *view = *child_iter; - if (skip_list.find(view) == skip_list.end()) - { - view->pushVisible(visible); - } - } + for (child_list_const_iter_t child_iter = getChildList()->begin(); + child_iter != getChildList()->end(); ++child_iter) + { + LLView *view = *child_iter; + if (skip_list.find(view) == skip_list.end()) + { + view->pushVisible(visible); + } + } - LLFloaterReg::blockShowFloaters(true); + LLFloaterReg::blockShowFloaters(true); } void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) { - // make a copy of the list since some floaters change their - // order in the childList when changing visibility. - child_list_t child_list_copy = *getChildList(); + // make a copy of the list since some floaters change their + // order in the childList when changing visibility. + child_list_t child_list_copy = *getChildList(); - for (child_list_const_iter_t child_iter = child_list_copy.begin(); - child_iter != child_list_copy.end(); ++child_iter) - { - LLView *view = *child_iter; - if (skip_list.find(view) == skip_list.end()) - { - view->popVisible(); - } - } + for (child_list_const_iter_t child_iter = child_list_copy.begin(); + child_iter != child_list_copy.end(); ++child_iter) + { + LLView *view = *child_iter; + if (skip_list.find(view) == skip_list.end()) + { + view->popVisible(); + } + } - LLFloaterReg::blockShowFloaters(false); + LLFloaterReg::blockShowFloaters(false); } void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect) { - switch (tb) - { - case LLToolBarEnums::TOOLBAR_LEFT: - mToolbarLeftRect = toolbar_rect; - break; - case LLToolBarEnums::TOOLBAR_BOTTOM: - mToolbarBottomRect = toolbar_rect; - break; - case LLToolBarEnums::TOOLBAR_RIGHT: - mToolbarRightRect = toolbar_rect; - break; - default: - LL_WARNS() << "setToolbarRect() passed odd toolbar number " << (S32) tb << LL_ENDL; - break; - } + switch (tb) + { + case LLToolBarEnums::TOOLBAR_LEFT: + mToolbarLeftRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_BOTTOM: + mToolbarBottomRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_RIGHT: + mToolbarRightRect = toolbar_rect; + break; + default: + LL_WARNS() << "setToolbarRect() passed odd toolbar number " << (S32) tb << LL_ENDL; + break; + } } void LLFloater::setInstanceName(const std::string& name) { - if (name != mInstanceName) - { - llassert_always(mInstanceName.empty()); - mInstanceName = name; - if (!mInstanceName.empty()) - { - std::string ctrl_name = getControlName(mInstanceName, mKey); - initRectControl(); - if (!mVisibilityControl.empty()) - { - mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); - } - if(!mDocStateControl.empty()) - { - mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); - } - } + if (name != mInstanceName) + { + llassert_always(mInstanceName.empty()); + mInstanceName = name; + if (!mInstanceName.empty()) + { + std::string ctrl_name = getControlName(mInstanceName, mKey); + initRectControl(); + if (!mVisibilityControl.empty()) + { + mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); + } + if(!mDocStateControl.empty()) + { + mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); + } + } } } void LLFloater::setKey(const LLSD& newkey) { - // Note: We don't have to do anything special with registration when we change keys - mKey = newkey; + // Note: We don't have to do anything special with registration when we change keys + mKey = newkey; } //static void LLFloater::setupParamsForExport(Params& p, LLView* parent) { - // Do rectangle munging to topleft layout first - LLPanel::setupParamsForExport(p, parent); + // Do rectangle munging to topleft layout first + LLPanel::setupParamsForExport(p, parent); - // Copy the rectangle out to apply layout constraints - LLRect rect = p.rect; + // Copy the rectangle out to apply layout constraints + LLRect rect = p.rect; - // Null out other settings - p.rect.left.setProvided(false); - p.rect.top.setProvided(false); - p.rect.right.setProvided(false); - p.rect.bottom.setProvided(false); + // Null out other settings + p.rect.left.setProvided(false); + p.rect.top.setProvided(false); + p.rect.right.setProvided(false); + p.rect.bottom.setProvided(false); - // Explicitly set width/height - p.rect.width.set( rect.getWidth(), true ); - p.rect.height.set( rect.getHeight(), true ); + // Explicitly set width/height + p.rect.width.set( rect.getWidth(), true ); + p.rect.height.set( rect.getHeight(), true ); - // If you can't resize this floater, don't export min_height - // and min_width - bool can_resize = p.can_resize; - if (!can_resize) - { - p.min_height.setProvided(false); - p.min_width.setProvided(false); - } + // If you can't resize this floater, don't export min_height + // and min_width + bool can_resize = p.can_resize; + if (!can_resize) + { + p.min_height.setProvided(false); + p.min_width.setProvided(false); + } } void LLFloater::initFromParams(const LLFloater::Params& p) { - // *NOTE: We have too many classes derived from LLFloater to retrofit them - // all to pass in params via constructors. So we use this method. - - // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible - LLPanel::initFromParams(p); - - // override any follows flags - if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED) - { - setFollows(FOLLOWS_NONE); - } - - mTitle = p.title; - mShortTitle = p.short_title; - applyTitle(); - - setCanTearOff(p.can_tear_off); - setCanMinimize(p.can_minimize); - setCanClose(p.can_close); - setCanDock(p.can_dock); - setCanResize(p.can_resize); - setResizeLimits(p.min_width, p.min_height); - - mDragOnLeft = p.can_drag_on_left; - mHeaderHeight = p.header_height; - mLegacyHeaderHeight = p.legacy_header_height; - mSingleInstance = p.single_instance; - mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; - - mPositioning = p.positioning; - - mSaveRect = p.save_rect; - if (p.save_visibility) - { - mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set - } - if(p.save_dock_state) - { - mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set - } - - // open callback - if (p.open_callback.isProvided()) - { - setOpenCallback(initCommitCallback(p.open_callback)); - } - // close callback - if (p.close_callback.isProvided()) - { - setCloseCallback(initCommitCallback(p.close_callback)); - } - - if (mDragHandle) - { - mDragHandle->setTitleVisible(p.show_title); - } + // *NOTE: We have too many classes derived from LLFloater to retrofit them + // all to pass in params via constructors. So we use this method. + + // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible + LLPanel::initFromParams(p); + + // override any follows flags + if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED) + { + setFollows(FOLLOWS_NONE); + } + + mTitle = p.title; + mShortTitle = p.short_title; + applyTitle(); + + setCanTearOff(p.can_tear_off); + setCanMinimize(p.can_minimize); + setCanClose(p.can_close); + setCanDock(p.can_dock); + setCanResize(p.can_resize); + setResizeLimits(p.min_width, p.min_height); + + mDragOnLeft = p.can_drag_on_left; + mHeaderHeight = p.header_height; + mLegacyHeaderHeight = p.legacy_header_height; + mSingleInstance = p.single_instance; + mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; + + mPositioning = p.positioning; + + mSaveRect = p.save_rect; + if (p.save_visibility) + { + mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set + } + if(p.save_dock_state) + { + mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set + } + + // open callback + if (p.open_callback.isProvided()) + { + setOpenCallback(initCommitCallback(p.open_callback)); + } + // close callback + if (p.close_callback.isProvided()) + { + setCloseCallback(initCommitCallback(p.close_callback)); + } + + if (mDragHandle) + { + mDragHandle->setTitleVisible(p.show_title); + } } boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_t::slot_type& cb ) { - if (!mMinimizeSignal) mMinimizeSignal = new commit_signal_t(); - return mMinimizeSignal->connect(cb); + if (!mMinimizeSignal) mMinimizeSignal = new commit_signal_t(); + return mMinimizeSignal->connect(cb); } boost::signals2::connection LLFloater::setOpenCallback( const commit_signal_t::slot_type& cb ) { - return mOpenSignal.connect(cb); + return mOpenSignal.connect(cb); } boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb ) { - return mCloseSignal.connect(cb); + return mCloseSignal.connect(cb); } LLTrace::BlockTimerStatHandle POST_BUILD("Floater Post Build"); @@ -3181,127 +3181,127 @@ static LLTrace::BlockTimerStatHandle FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floa bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node) { - Params default_params(LLUICtrlFactory::getDefaultParams()); - Params params(default_params); - - LLXUIParser parser; - parser.readXUI(node, params, filename); // *TODO: Error checking - - std::string xml_filename = params.filename; - - if (!xml_filename.empty()) - { - LLXMLNodePtr referenced_xml; - - if (output_node) - { - //if we are exporting, we want to export the current xml - //not the referenced xml - Params output_params; - parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName()); - setupParamsForExport(output_params, parent); - output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); - return TRUE; - } - - LLUICtrlFactory::instance().pushFileName(xml_filename); - - LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD); - if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) - { - LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; - - return FALSE; - } - - Params referenced_params; - parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName()); - params.fillFrom(referenced_params); - - // add children using dimensions from referenced xml for consistent layout - setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); - - LLUICtrlFactory::instance().popFileName(); - } - - - if (output_node) - { - Params output_params(params); - setupParamsForExport(output_params, parent); - output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); - } - - // Default floater position to top-left corner of screen - // However, some legacy floaters have explicit top or bottom - // coordinates set, so respect their wishes. - if (!params.rect.top.isProvided() && !params.rect.bottom.isProvided()) - { - params.rect.top.set(0); - } - if (!params.rect.left.isProvided() && !params.rect.right.isProvided()) - { - params.rect.left.set(0); - } - params.from_xui = true; - applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect()); - initFromParams(params); - - initFloater(params); - - LLMultiFloater* last_host = LLFloater::getFloaterHost(); - if (node->hasName("multi_floater")) - { - LLFloater::setFloaterHost((LLMultiFloater*) this); - } - - LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); - - if (node->hasName("multi_floater")) - { - LLFloater::setFloaterHost(last_host); - } - - // HACK: When we changed the header height to 25 pixels in Viewer 2, rather - // than re-layout all the floaters we use this value in pixels to make the - // whole floater bigger and change the top-left coordinate for widgets. - // The goal is to eventually set mLegacyHeaderHeight to zero, which would - // make the top-left corner for widget layout the same as the top-left - // corner of the window's content area. James - S32 header_stretch = (mHeaderHeight - mLegacyHeaderHeight); - if (header_stretch > 0) - { - // Stretch the floater vertically, don't move widgets - LLRect rect = getRect(); - rect.mTop += header_stretch; - - // This will also update drag handle, title bar, close box, etc. - setRect(rect); - } - - BOOL result; - { - LL_RECORD_BLOCK_TIME(POST_BUILD); - - result = postBuild(); - } - - if (!result) - { - LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL; - } - - applyRectControl(); // If we have a saved rect control, apply it - gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen - - moveResizeHandlesToFront(); - - applyDockState(); - - return true; // *TODO: Error checking + Params default_params(LLUICtrlFactory::getDefaultParams()); + Params params(default_params); + + LLXUIParser parser; + parser.readXUI(node, params, filename); // *TODO: Error checking + + std::string xml_filename = params.filename; + + if (!xml_filename.empty()) + { + LLXMLNodePtr referenced_xml; + + if (output_node) + { + //if we are exporting, we want to export the current xml + //not the referenced xml + Params output_params; + parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName()); + setupParamsForExport(output_params, parent); + output_node->setName(node->getName()->mString); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); + return TRUE; + } + + LLUICtrlFactory::instance().pushFileName(xml_filename); + + LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD); + if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) + { + LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; + + return FALSE; + } + + Params referenced_params; + parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName()); + params.fillFrom(referenced_params); + + // add children using dimensions from referenced xml for consistent layout + setShape(params.rect); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); + + LLUICtrlFactory::instance().popFileName(); + } + + + if (output_node) + { + Params output_params(params); + setupParamsForExport(output_params, parent); + output_node->setName(node->getName()->mString); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); + } + + // Default floater position to top-left corner of screen + // However, some legacy floaters have explicit top or bottom + // coordinates set, so respect their wishes. + if (!params.rect.top.isProvided() && !params.rect.bottom.isProvided()) + { + params.rect.top.set(0); + } + if (!params.rect.left.isProvided() && !params.rect.right.isProvided()) + { + params.rect.left.set(0); + } + params.from_xui = true; + applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect()); + initFromParams(params); + + initFloater(params); + + LLMultiFloater* last_host = LLFloater::getFloaterHost(); + if (node->hasName("multi_floater")) + { + LLFloater::setFloaterHost((LLMultiFloater*) this); + } + + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); + + if (node->hasName("multi_floater")) + { + LLFloater::setFloaterHost(last_host); + } + + // HACK: When we changed the header height to 25 pixels in Viewer 2, rather + // than re-layout all the floaters we use this value in pixels to make the + // whole floater bigger and change the top-left coordinate for widgets. + // The goal is to eventually set mLegacyHeaderHeight to zero, which would + // make the top-left corner for widget layout the same as the top-left + // corner of the window's content area. James + S32 header_stretch = (mHeaderHeight - mLegacyHeaderHeight); + if (header_stretch > 0) + { + // Stretch the floater vertically, don't move widgets + LLRect rect = getRect(); + rect.mTop += header_stretch; + + // This will also update drag handle, title bar, close box, etc. + setRect(rect); + } + + BOOL result; + { + LL_RECORD_BLOCK_TIME(POST_BUILD); + + result = postBuild(); + } + + if (!result) + { + LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL; + } + + applyRectControl(); // If we have a saved rect control, apply it + gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen + + moveResizeHandlesToFront(); + + applyDockState(); + + return true; // *TODO: Error checking } bool LLFloater::isShown() const @@ -3311,7 +3311,7 @@ bool LLFloater::isShown() const bool LLFloater::isDetachedAndNotMinimized() { - return !getHost() && !isMinimized(); + return !getHost() && !isMinimized(); } /* static */ @@ -3336,205 +3336,205 @@ static LLTrace::BlockTimerStatHandle FTM_BUILD_FLOATERS("Build Floaters"); bool LLFloater::buildFromFile(const std::string& filename) { - LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS); - LLXMLNodePtr root; - - if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) - { - LL_WARNS() << "Couldn't find (or parse) floater from: " << filename << LL_ENDL; - return false; - } - - // root must be called floater - if( !(root->hasName("floater") || root->hasName("multi_floater")) ) - { - LL_WARNS() << "Root node should be named floater in: " << filename << LL_ENDL; - return false; - } - - bool res = true; - - LL_DEBUGS() << "Building floater " << filename << LL_ENDL; - LLUICtrlFactory::instance().pushFileName(filename); - { - if (!getFactoryMap().empty()) - { - LLPanel::sFactoryStack.push_front(&getFactoryMap()); - } - - // for local registry callbacks; define in constructor, referenced in XUI or postBuild - getCommitCallbackRegistrar().pushScope(); - getEnableCallbackRegistrar().pushScope(); - - res = initFloaterXML(root, getParent(), filename, NULL); - - setXMLFilename(filename); - - getCommitCallbackRegistrar().popScope(); - getEnableCallbackRegistrar().popScope(); - - if (!getFactoryMap().empty()) - { - LLPanel::sFactoryStack.pop_front(); - } - } - LLUICtrlFactory::instance().popFileName(); - - return res; + LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS); + LLXMLNodePtr root; + + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + { + LL_WARNS() << "Couldn't find (or parse) floater from: " << filename << LL_ENDL; + return false; + } + + // root must be called floater + if( !(root->hasName("floater") || root->hasName("multi_floater")) ) + { + LL_WARNS() << "Root node should be named floater in: " << filename << LL_ENDL; + return false; + } + + bool res = true; + + LL_DEBUGS() << "Building floater " << filename << LL_ENDL; + LLUICtrlFactory::instance().pushFileName(filename); + { + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.push_front(&getFactoryMap()); + } + + // for local registry callbacks; define in constructor, referenced in XUI or postBuild + getCommitCallbackRegistrar().pushScope(); + getEnableCallbackRegistrar().pushScope(); + + res = initFloaterXML(root, getParent(), filename, NULL); + + setXMLFilename(filename); + + getCommitCallbackRegistrar().popScope(); + getEnableCallbackRegistrar().popScope(); + + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.pop_front(); + } + } + LLUICtrlFactory::instance().popFileName(); + + return res; } void LLFloater::stackWith(LLFloater& other) { - static LLUICachedControl floater_offset ("UIFloaterOffset", 16); + static LLUICachedControl floater_offset ("UIFloaterOffset", 16); - LLRect next_rect; - if (other.getHost()) - { - next_rect = other.getHost()->getRect(); - } - else - { - next_rect = other.getRect(); - } - next_rect.translate(floater_offset, -floater_offset); + LLRect next_rect; + if (other.getHost()) + { + next_rect = other.getHost()->getRect(); + } + else + { + next_rect = other.getRect(); + } + next_rect.translate(floater_offset, -floater_offset); - next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); - - setShape(next_rect); + next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight()); + + setShape(next_rect); - if (!other.getHost()) - { - other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; - other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); - } + if (!other.getHost()) + { + other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP; + other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); + } } void LLFloater::applyRelativePosition() { - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - LLRect floater_screen_rect = calcScreenRect(); + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + LLRect floater_screen_rect = calcScreenRect(); - LLCoordGL new_center = mPosition.convert(); - LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY()); - translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); + LLCoordGL new_center = mPosition.convert(); + LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY()); + translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); } LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater) -: coord_t((S32)x, (S32)y) +: coord_t((S32)x, (S32)y) { - mFloater = floater.getHandle(); + mFloater = floater.getHandle(); } LLCoordFloater::LLCoordFloater(const LLCoordCommon& other, LLFloater& floater) { - mFloater = floater.getHandle(); - convertFromCommon(other); + mFloater = floater.getHandle(); + convertFromCommon(other); } LLCoordFloater& LLCoordFloater::operator=(const LLCoordFloater& other) { - mFloater = other.mFloater; - coord_t::operator =(other); - return *this; + mFloater = other.mFloater; + coord_t::operator =(other); + return *this; } void LLCoordFloater::setFloater(LLFloater& floater) { - mFloater = floater.getHandle(); + mFloater = floater.getHandle(); } bool LLCoordFloater::operator==(const LLCoordFloater& other) const { - return mX == other.mX && mY == other.mY && mFloater == other.mFloater; + return mX == other.mX && mY == other.mY && mFloater == other.mFloater; } LLCoordCommon LL_COORD_FLOATER::convertToCommon() const { - const LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); - - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - - LLFloater* floaterp = mFloater.get(); - S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; - S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; - LLCoordCommon out; - if (self.mX < -0.5f) - { - out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft)); - } - else if (self.mX > 0.5f) - { - out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)); - } - else - { - out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width)); - } - - if (self.mY < -0.5f) - { - out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom)); - } - else if (self.mY > 0.5f) - { - out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)); - } - else - { - out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height)); - } - - // return center point instead of lower left - out.mX += floater_width / 2; - out.mY += floater_height / 2; - - return out; + const LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); + + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + + LLFloater* floaterp = mFloater.get(); + S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; + S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; + LLCoordCommon out; + if (self.mX < -0.5f) + { + out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft)); + } + else if (self.mX > 0.5f) + { + out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)); + } + else + { + out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width)); + } + + if (self.mY < -0.5f) + { + out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom)); + } + else if (self.mY > 0.5f) + { + out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)); + } + else + { + out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height)); + } + + // return center point instead of lower left + out.mX += floater_width / 2; + out.mY += floater_height / 2; + + return out; } void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from) { - LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); - LLRect snap_rect = gFloaterView->getSnapRect(); - LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); - snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); - - - LLFloater* floaterp = mFloater.get(); - S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; - S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; - - S32 from_x = from.mX - floater_width / 2; - S32 from_y = from.mY - floater_height / 2; - - if (from_x < snap_rect.mLeft) - { - self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f); - } - else if (from_x + floater_width > snap_rect.mRight) - { - self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); - } - else - { - self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f); - } - - if (from_y < snap_rect.mBottom) - { - self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f); - } - else if (from_y + floater_height > snap_rect.mTop) - { - self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); - } - else - { - self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f); - } + LLCoordFloater& self = static_cast(LLCoordFloater::getTypedCoords(*this)); + LLRect snap_rect = gFloaterView->getSnapRect(); + LLRect floater_view_screen_rect = gFloaterView->calcScreenRect(); + snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom); + + + LLFloater* floaterp = mFloater.get(); + S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0; + S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0; + + S32 from_x = from.mX - floater_width / 2; + S32 from_y = from.mY - floater_height / 2; + + if (from_x < snap_rect.mLeft) + { + self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f); + } + else if (from_x + floater_width > snap_rect.mRight) + { + self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); + } + else + { + self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f); + } + + if (from_y < snap_rect.mBottom) + { + self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f); + } + else if (from_y + floater_height > snap_rect.mTop) + { + self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f); + } + else + { + self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f); + } } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 1386f1290a..e53ecd30c2 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -36,298 +36,298 @@ #include "llinitparam.h" #include "llview.h" -#include "llviewmodel.h" // *TODO move dependency to .cpp file +#include "llviewmodel.h" // *TODO move dependency to .cpp file const BOOL TAKE_FOCUS_YES = TRUE; const BOOL TAKE_FOCUS_NO = FALSE; class LLUICtrl - : public LLView, public boost::signals2::trackable + : public LLView, public boost::signals2::trackable { public: - typedef boost::function commit_callback_t; - typedef boost::signals2::signal commit_signal_t; - // *TODO: add xml support for this type of signal in the future - typedef boost::signals2::signal mouse_signal_t; - - typedef boost::function enable_callback_t; - typedef boost::signals2::signal enable_signal_t; - - struct CallbackParam : public LLInitParam::Block - { - Ignored name; - - Optional function_name; - Optional parameter; - - Optional control_name; - - CallbackParam(); - }; - - struct CommitCallbackParam : public LLInitParam::Block - { - Optional function; - }; - - // also used for visible callbacks - struct EnableCallbackParam : public LLInitParam::Block - { - Optional function; - }; - - struct EnableControls : public LLInitParam::ChoiceBlock - { - Alternative enabled; - Alternative disabled; - - EnableControls(); - }; - struct ControlVisibility : public LLInitParam::ChoiceBlock - { - Alternative visible; - Alternative invisible; - - ControlVisibility(); - }; - struct Params : public LLInitParam::Block - { - Optional label; - Optional tab_stop, - chrome, - requests_front; - Optional initial_value; - - Optional init_callback, - commit_callback; - Optional validate_callback; - - Optional mouseenter_callback, - mouseleave_callback; - - Optional control_name; - Optional enabled_controls; - Optional controls_visibility; - - // font params - Optional font; - Optional font_halign; - Optional font_valign; - - // cruft from LLXMLNode implementation - Ignored type, - length; - - Params(); - }; - - enum ETypeTransparency - { - TT_DEFAULT, - TT_ACTIVE, // focused floater - TT_INACTIVE, // other floaters - TT_FADING, // fading toast - }; - /*virtual*/ ~LLUICtrl(); - - void initFromParams(const Params& p); + typedef boost::function commit_callback_t; + typedef boost::signals2::signal commit_signal_t; + // *TODO: add xml support for this type of signal in the future + typedef boost::signals2::signal mouse_signal_t; + + typedef boost::function enable_callback_t; + typedef boost::signals2::signal enable_signal_t; + + struct CallbackParam : public LLInitParam::Block + { + Ignored name; + + Optional function_name; + Optional parameter; + + Optional control_name; + + CallbackParam(); + }; + + struct CommitCallbackParam : public LLInitParam::Block + { + Optional function; + }; + + // also used for visible callbacks + struct EnableCallbackParam : public LLInitParam::Block + { + Optional function; + }; + + struct EnableControls : public LLInitParam::ChoiceBlock + { + Alternative enabled; + Alternative disabled; + + EnableControls(); + }; + struct ControlVisibility : public LLInitParam::ChoiceBlock + { + Alternative visible; + Alternative invisible; + + ControlVisibility(); + }; + struct Params : public LLInitParam::Block + { + Optional label; + Optional tab_stop, + chrome, + requests_front; + Optional initial_value; + + Optional init_callback, + commit_callback; + Optional validate_callback; + + Optional mouseenter_callback, + mouseleave_callback; + + Optional control_name; + Optional enabled_controls; + Optional controls_visibility; + + // font params + Optional font; + Optional font_halign; + Optional font_valign; + + // cruft from LLXMLNode implementation + Ignored type, + length; + + Params(); + }; + + enum ETypeTransparency + { + TT_DEFAULT, + TT_ACTIVE, // focused floater + TT_INACTIVE, // other floaters + TT_FADING, // fading toast + }; + /*virtual*/ ~LLUICtrl(); + + void initFromParams(const Params& p); protected: - friend class LLUICtrlFactory; - static const Params& getDefaultParams(); - LLUICtrl(const Params& p = getDefaultParams(), + friend class LLUICtrlFactory; + static const Params& getDefaultParams(); + LLUICtrl(const Params& p = getDefaultParams(), const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel)); - - commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb); - enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb); + + commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb); + enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb); - // We need this virtual so we can override it with derived versions - virtual LLViewModel* getViewModel() const; + // We need this virtual so we can override it with derived versions + virtual LLViewModel* getViewModel() const; // We shouldn't ever need to set this directly //virtual void setViewModel(const LLViewModelPtr&); - virtual BOOL postBuild(); - + virtual BOOL postBuild(); + public: - // LLView interface - /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - /*virtual*/ BOOL isCtrl() const; - /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); - /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL canFocusChildren() const; - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - - // From LLFocusableElement - /*virtual*/ void setFocus( BOOL b ); - /*virtual*/ BOOL hasFocus() const; - - // New virtuals - - // Return NULL by default (overrride if the class has the appropriate interface) - virtual class LLCtrlSelectionInterface* getSelectionInterface(); - virtual class LLCtrlListInterface* getListInterface(); - virtual class LLCtrlScrollInterface* getScrollInterface(); - - bool setControlValue(const LLSD& value); - void setControlVariable(LLControlVariable* control); - virtual void setControlName(const std::string& control, LLView *context = NULL); - - LLControlVariable* getControlVariable() { return mControlVariable; } - - void setEnabledControlVariable(LLControlVariable* control); - void setDisabledControlVariable(LLControlVariable* control); - void setMakeVisibleControlVariable(LLControlVariable* control); - void setMakeInvisibleControlVariable(LLControlVariable* control); - - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; - virtual void setValue(const LLSD& value); - virtual LLSD getValue() const; + // LLView interface + /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + /*virtual*/ BOOL isCtrl() const; + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL canFocusChildren() const; + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + /*virtual*/ BOOL hasFocus() const; + + // New virtuals + + // Return NULL by default (overrride if the class has the appropriate interface) + virtual class LLCtrlSelectionInterface* getSelectionInterface(); + virtual class LLCtrlListInterface* getListInterface(); + virtual class LLCtrlScrollInterface* getScrollInterface(); + + bool setControlValue(const LLSD& value); + void setControlVariable(LLControlVariable* control); + virtual void setControlName(const std::string& control, LLView *context = NULL); + + LLControlVariable* getControlVariable() { return mControlVariable; } + + void setEnabledControlVariable(LLControlVariable* control); + void setDisabledControlVariable(LLControlVariable* control); + void setMakeVisibleControlVariable(LLControlVariable* control); + void setMakeInvisibleControlVariable(LLControlVariable* control); + + virtual void setTentative(BOOL b); + virtual BOOL getTentative() const; + virtual void setValue(const LLSD& value); + virtual LLSD getValue() const; /// When two widgets are displaying the same data (e.g. during a skin /// change), share their ViewModel. virtual void shareViewModelFrom(const LLUICtrl& other); - virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); - virtual void setIsChrome(BOOL is_chrome); - - virtual BOOL acceptsTextInput() const; // Defaults to false - - // A control is dirty if the user has modified its value. - // Editable controls should override this. - virtual BOOL isDirty() const; // Defauls to false - virtual void resetDirty(); //Defaults to no-op - - // Call appropriate callback - virtual void onCommit(); - - // Default to no-op: - virtual void onTabInto(); - - // Clear any user-provided input (text in a text editor, checked checkbox, - // selected radio button, etc.). Defaults to no-op. - virtual void clear(); - - virtual void setColor(const LLColor4& color); - - // Ansariel: Changed to virtual. We might want to change the transparency ourself! - virtual F32 getCurrentTransparency(); - - void setTransparencyType(ETypeTransparency type); - ETypeTransparency getTransparencyType() const {return mTransparencyType;} - - BOOL focusNextItem(BOOL text_entry_only); - BOOL focusPrevItem(BOOL text_entry_only); - BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); - - // Non Virtuals - LLHandle getHandle() const { return getDerivedHandle(); } - BOOL getIsChrome() const; - - void setTabStop( BOOL b ); - BOOL hasTabStop() const; - - LLUICtrl* getParentUICtrl() const; - - // return true if help topic found by crawling through parents - - // topic then put in help_topic_out - bool findHelpTopic(std::string& help_topic_out); - - boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb); - boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb); - - boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ); - boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ); - - boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ); - boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ); - - boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ); - boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ); - - boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ); - - // *TODO: Deprecate; for backwards compatability only: - boost::signals2::connection setCommitCallback( boost::function cb, void* data); - boost::signals2::connection setValidateBeforeCommit( boost::function cb ); - - LLUICtrl* findRootMostFocusRoot(); - - class LLTextInputFilter : public LLQueryFilter, public LLSingleton - { - LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); - /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const - { - return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); - } - }; - - template class CallbackRegistry : public LLRegistrySingleton - {}; - - class CommitCallbackRegistry : public CallbackRegistry - { - LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); - }; - // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry - { - LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); - }; - + virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); + virtual void setIsChrome(BOOL is_chrome); + + virtual BOOL acceptsTextInput() const; // Defaults to false + + // A control is dirty if the user has modified its value. + // Editable controls should override this. + virtual BOOL isDirty() const; // Defauls to false + virtual void resetDirty(); //Defaults to no-op + + // Call appropriate callback + virtual void onCommit(); + + // Default to no-op: + virtual void onTabInto(); + + // Clear any user-provided input (text in a text editor, checked checkbox, + // selected radio button, etc.). Defaults to no-op. + virtual void clear(); + + virtual void setColor(const LLColor4& color); + + // Ansariel: Changed to virtual. We might want to change the transparency ourself! + virtual F32 getCurrentTransparency(); + + void setTransparencyType(ETypeTransparency type); + ETypeTransparency getTransparencyType() const {return mTransparencyType;} + + BOOL focusNextItem(BOOL text_entry_only); + BOOL focusPrevItem(BOOL text_entry_only); + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + + // Non Virtuals + LLHandle getHandle() const { return getDerivedHandle(); } + BOOL getIsChrome() const; + + void setTabStop( BOOL b ); + BOOL hasTabStop() const; + + LLUICtrl* getParentUICtrl() const; + + // return true if help topic found by crawling through parents - + // topic then put in help_topic_out + bool findHelpTopic(std::string& help_topic_out); + + boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb); + boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb); + + boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ); + boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ); + + boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ); + boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ); + + boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ); + boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ); + + boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ); + + // *TODO: Deprecate; for backwards compatability only: + boost::signals2::connection setCommitCallback( boost::function cb, void* data); + boost::signals2::connection setValidateBeforeCommit( boost::function cb ); + + LLUICtrl* findRootMostFocusRoot(); + + class LLTextInputFilter : public LLQueryFilter, public LLSingleton + { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); + /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const + { + return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); + } + }; + + template class CallbackRegistry : public LLRegistrySingleton + {}; + + class CommitCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; + // the enable callback registry is also used for visiblity callbacks + class EnableCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; + protected: - static bool controlListener(const LLSD& newvalue, LLHandle handle, std::string type); + static bool controlListener(const LLSD& newvalue, LLHandle handle, std::string type); - commit_signal_t* mCommitSignal; - enable_signal_t* mValidateSignal; + commit_signal_t* mCommitSignal; + enable_signal_t* mValidateSignal; - commit_signal_t* mMouseEnterSignal; - commit_signal_t* mMouseLeaveSignal; - - mouse_signal_t* mMouseDownSignal; - mouse_signal_t* mMouseUpSignal; - mouse_signal_t* mRightMouseDownSignal; - mouse_signal_t* mRightMouseUpSignal; + commit_signal_t* mMouseEnterSignal; + commit_signal_t* mMouseLeaveSignal; + + mouse_signal_t* mMouseDownSignal; + mouse_signal_t* mMouseUpSignal; + mouse_signal_t* mRightMouseDownSignal; + mouse_signal_t* mRightMouseUpSignal; - mouse_signal_t* mDoubleClickSignal; - + mouse_signal_t* mDoubleClickSignal; + LLViewModelPtr mViewModel; - LLControlVariable* mControlVariable; - boost::signals2::connection mControlConnection; - LLControlVariable* mEnabledControlVariable; - boost::signals2::connection mEnabledControlConnection; - LLControlVariable* mDisabledControlVariable; - boost::signals2::connection mDisabledControlConnection; - LLControlVariable* mMakeVisibleControlVariable; - boost::signals2::connection mMakeVisibleControlConnection; - LLControlVariable* mMakeInvisibleControlVariable; - boost::signals2::connection mMakeInvisibleControlConnection; - - static F32 sActiveControlTransparency; - static F32 sInactiveControlTransparency; - - virtual void addInfo(LLSD & info); - + LLControlVariable* mControlVariable; + boost::signals2::connection mControlConnection; + LLControlVariable* mEnabledControlVariable; + boost::signals2::connection mEnabledControlConnection; + LLControlVariable* mDisabledControlVariable; + boost::signals2::connection mDisabledControlConnection; + LLControlVariable* mMakeVisibleControlVariable; + boost::signals2::connection mMakeVisibleControlConnection; + LLControlVariable* mMakeInvisibleControlVariable; + boost::signals2::connection mMakeInvisibleControlConnection; + + static F32 sActiveControlTransparency; + static F32 sInactiveControlTransparency; + + virtual void addInfo(LLSD & info); + private: - BOOL mIsChrome; - BOOL mRequestsFront; - BOOL mTabStop; - BOOL mTentative; + BOOL mIsChrome; + BOOL mRequestsFront; + BOOL mTabStop; + BOOL mTentative; - ETypeTransparency mTransparencyType; + ETypeTransparency mTransparencyType; }; // Build time optimization, generate once in .cpp file #ifndef LLUICTRL_CPP extern template class LLUICtrl* LLView::getChild( - const std::string& name, BOOL recurse) const; + const std::string& name, BOOL recurse) const; #endif #endif // LL_LLUICTRL_H diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index be0ea8bb69..338be1808d 100755 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -38,13 +38,13 @@ // Stub for LLAvatarNameCache bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) { - return false; + return false; } LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { - callback_connection_t connection; - return connection; + callback_connection_t connection; + return connection; } // @@ -52,24 +52,24 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag // BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { - fullname = "Lynx Linden"; - return TRUE; + fullname = "Lynx Linden"; + return TRUE; } BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) { - group = "My Group"; - return TRUE; + group = "My Group"; + return TRUE; } boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { - return boost::signals2::connection(); + return boost::signals2::connection(); } boost::signals2::connection LLCacheName::getGroup(const LLUUID& id, const LLCacheNameCallback& callback) { - return boost::signals2::connection(); + return boost::signals2::connection(); } LLCacheName* gCacheName = NULL; @@ -80,12 +80,12 @@ LLCacheName* gCacheName = NULL; class LLTrans { public: - static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); + static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); }; std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { - return std::string(); + return std::string(); } // @@ -102,65 +102,65 @@ LLStyle::Params::Params() namespace LLInitParam { - ParamValue::ParamValue(const LLUIColor& color) - : super_t(color) - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) - { - return false; - } - - ParamValue::ParamValue(const LLFontGL* fontp) - : super_t(fontp) - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - void TypeValues::declareValues() - {} - - void TypeValues::declareValues() - {} - - void TypeValues::declareValues() - {} - - void ParamValue::updateValueFromBlock() - {} - - void ParamValue::updateBlockFromValue(bool) - {} - - - bool ParamCompare::equals( - LLUIImage* const &a, - LLUIImage* const &b) - { - return false; - } - - bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) - { - return false; - } + ParamValue::ParamValue(const LLUIColor& color) + : super_t(color) + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + ParamValue::ParamValue(const LLFontGL* fontp) + : super_t(fontp) + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void ParamValue::updateValueFromBlock() + {} + + void ParamValue::updateBlockFromValue(bool) + {} + + + bool ParamCompare::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } } //static LLFontGL* LLFontGL::getFontDefault() { - return NULL; + return NULL; } char const* const _PREHASH_AgentData = (char *)"AgentData"; -- cgit v1.2.3 From 3a78da70ad14eab11218cc056c2a3703af1b9738 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Fri, 29 Mar 2019 17:39:19 +0200 Subject: SL-10833 FIXED [EEP] Text in the Sky Altitudes boxes is low contrast and difficult to read. --- indra/llui/lllineeditor.cpp | 57 ++++++++++++++++++++++++++------------------- indra/llui/lllineeditor.h | 7 +++++- 2 files changed, 39 insertions(+), 25 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index cfab6b7fc8..ee8c445afb 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -96,6 +96,8 @@ LLLineEditor::Params::Params() ignore_tab("ignore_tab", true), is_password("is_password", false), cursor_color("cursor_color"), + use_bg_color("use_bg_color", false), + bg_color("bg_color"), text_color("text_color"), text_readonly_color("text_readonly_color"), text_tentative_color("text_tentative_color"), @@ -150,10 +152,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mBgImageDisabled( p.background_image_disabled ), mBgImageFocused( p.background_image_focused ), mShowImageFocused( p.bg_image_always_focused ), + mUseBgColor(p.use_bg_color), mHaveHistory(FALSE), mReplaceNewlinesWithSpaces( TRUE ), mLabel(p.label), mCursorColor(p.cursor_color()), + mBgColor(p.bg_color()), mFgColor(p.text_color()), mReadOnlyFgColor(p.text_readonly_color()), mTentativeFgColor(p.text_tentative_color()), @@ -1681,37 +1685,42 @@ void LLLineEditor::doDelete() void LLLineEditor::drawBackground() { - bool has_focus = hasFocus(); - LLUIImage* image; - if ( mReadOnly ) - { - image = mBgImageDisabled; - } - else if ( has_focus || mShowImageFocused) + F32 alpha = getCurrentTransparency(); + if (mUseBgColor) { - image = mBgImageFocused; + gl_rect_2d(getLocalRect(), mBgColor % alpha, TRUE); } else { - image = mBgImage; - } - - if (!image) return; - - F32 alpha = getCurrentTransparency(); + bool has_focus = hasFocus(); + LLUIImage* image; + if (mReadOnly) + { + image = mBgImageDisabled; + } + else if (has_focus || mShowImageFocused) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } - // optionally draw programmatic border - if (has_focus) - { - LLColor4 tmp_color = gFocusMgr.getFocusColor(); + if (!image) return; + // optionally draw programmatic border + if (has_focus) + { + LLColor4 tmp_color = gFocusMgr.getFocusColor(); + tmp_color.setAlpha(alpha); + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + tmp_color, + gFocusMgr.getFocusFlashWidth()); + } + LLColor4 tmp_color = UI_VERTEX_COLOR; tmp_color.setAlpha(alpha); - image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), - tmp_color, - gFocusMgr.getFocusFlashWidth()); + image->draw(getLocalRect(), tmp_color); } - LLColor4 tmp_color = UI_VERTEX_COLOR; - tmp_color.setAlpha(alpha); - image->draw(getLocalRect(), tmp_color); } void LLLineEditor::draw() diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 287837a15c..a711ccefab 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -91,10 +91,12 @@ public: commit_on_focus_lost, ignore_tab, bg_image_always_focused, - is_password; + is_password, + use_bg_color; // colors Optional cursor_color, + bg_color, text_color, text_readonly_color, text_tentative_color, @@ -365,6 +367,7 @@ protected: LLTimer mTripleClickTimer; LLUIColor mCursorColor; + LLUIColor mBgColor; LLUIColor mFgColor; LLUIColor mReadOnlyFgColor; LLUIColor mTentativeFgColor; @@ -385,6 +388,8 @@ protected: BOOL mShowImageFocused; + bool mUseBgColor; + LLWString mPreeditWString; LLWString mPreeditOverwrittenWString; std::vector mPreeditPositions; -- cgit v1.2.3 From 07f380d61a8f939e672dd1b07cc871dc799bdbc2 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Wed, 3 Apr 2019 08:47:44 -0700 Subject: Fix random Xcode 10.2 failures from unused vars and references to local objects. Modified llwindowmacosx to pass some things by value instead. --- indra/llui/lllayoutstack.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 69246a2f57..ce8dbb1f66 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -510,7 +510,6 @@ LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const { if (!panelp) return NULL; - e_panel_list_t::const_iterator panel_it; BOOST_FOREACH(LLLayoutPanel* p, mPanels) { if (p == panelp) -- cgit v1.2.3 From f67fe8fce7d84bc8687d409311518565d97a5fc5 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Thu, 2 May 2019 13:45:40 +0300 Subject: SL-10833 Restore missing code after a merge --- indra/llui/lllineeditor.cpp | 71 ++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 33 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index f1914ee9c5..de6bb23783 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1690,39 +1690,44 @@ void LLLineEditor::doDelete() } -void LLLineEditor::drawBackground() -{ - bool has_focus = hasFocus(); - LLUIImage* image; - if ( mReadOnly ) - { - image = mBgImageDisabled; - } - else if ( has_focus || mShowImageFocused) - { - image = mBgImageFocused; - } - else - { - image = mBgImage; - } - - if (!image) return; - - F32 alpha = getCurrentTransparency(); - - // optionally draw programmatic border - if (has_focus) - { - LLColor4 tmp_color = gFocusMgr.getFocusColor(); - tmp_color.setAlpha(alpha); - image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), - tmp_color, - gFocusMgr.getFocusFlashWidth()); - } - LLColor4 tmp_color = UI_VERTEX_COLOR; - tmp_color.setAlpha(alpha); - image->draw(getLocalRect(), tmp_color); +void LLLineEditor::drawBackground() +{ + F32 alpha = getCurrentTransparency(); + if (mUseBgColor) + { + gl_rect_2d(getLocalRect(), mBgColor % alpha, TRUE); + } + else + { + bool has_focus = hasFocus(); + LLUIImage* image; + if (mReadOnly) + { + image = mBgImageDisabled; + } + else if (has_focus || mShowImageFocused) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } + + if (!image) return; + // optionally draw programmatic border + if (has_focus) + { + LLColor4 tmp_color = gFocusMgr.getFocusColor(); + tmp_color.setAlpha(alpha); + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + tmp_color, + gFocusMgr.getFocusFlashWidth()); + } + LLColor4 tmp_color = UI_VERTEX_COLOR; + tmp_color.setAlpha(alpha); + image->draw(getLocalRect(), tmp_color); + } } void LLLineEditor::draw() -- cgit v1.2.3 From 24acb7d5c3b6c3af4d7d814b8ccb0b9652eb38d3 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Fri, 3 May 2019 14:58:51 -0700 Subject: Fix some line-endings to be newline only. --- indra/llui/lllineeditor.cpp | 76 ++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index de6bb23783..b9133c5a35 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1690,44 +1690,44 @@ void LLLineEditor::doDelete() } -void LLLineEditor::drawBackground() -{ - F32 alpha = getCurrentTransparency(); - if (mUseBgColor) - { - gl_rect_2d(getLocalRect(), mBgColor % alpha, TRUE); - } - else - { - bool has_focus = hasFocus(); - LLUIImage* image; - if (mReadOnly) - { - image = mBgImageDisabled; - } - else if (has_focus || mShowImageFocused) - { - image = mBgImageFocused; - } - else - { - image = mBgImage; - } - - if (!image) return; - // optionally draw programmatic border - if (has_focus) - { - LLColor4 tmp_color = gFocusMgr.getFocusColor(); - tmp_color.setAlpha(alpha); - image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), - tmp_color, - gFocusMgr.getFocusFlashWidth()); - } - LLColor4 tmp_color = UI_VERTEX_COLOR; - tmp_color.setAlpha(alpha); - image->draw(getLocalRect(), tmp_color); - } +void LLLineEditor::drawBackground() +{ + F32 alpha = getCurrentTransparency(); + if (mUseBgColor) + { + gl_rect_2d(getLocalRect(), mBgColor % alpha, TRUE); + } + else + { + bool has_focus = hasFocus(); + LLUIImage* image; + if (mReadOnly) + { + image = mBgImageDisabled; + } + else if (has_focus || mShowImageFocused) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } + + if (!image) return; + // optionally draw programmatic border + if (has_focus) + { + LLColor4 tmp_color = gFocusMgr.getFocusColor(); + tmp_color.setAlpha(alpha); + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + tmp_color, + gFocusMgr.getFocusFlashWidth()); + } + LLColor4 tmp_color = UI_VERTEX_COLOR; + tmp_color.setAlpha(alpha); + image->draw(getLocalRect(), tmp_color); + } } void LLLineEditor::draw() -- cgit v1.2.3 From 605c9c19661702755171669e2af846abe77d2a51 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Wed, 8 May 2019 11:42:31 -0700 Subject: Fix merge fail. --- indra/llui/llmenugl.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index aa87329020..1f11f26192 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -175,7 +175,12 @@ protected: // This function appends the character string representation of // the current accelerator key and mask to the provided string. void appendAcceleratorString( std::string& st ) const; - + + virtual std::string _getSearchText() const + { + return mLabel.getString(); + } + protected: KEY mAcceleratorKey; MASK mAcceleratorMask; -- cgit v1.2.3 From c1a586d7e459858d31ad1549a79294832dd8e62e Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Fri, 14 Jun 2019 17:53:43 +0300 Subject: SL-11425 FIXED [EEP] Wave vectors cross all over the Water tab if key frame is not selected. --- indra/llui/llxyvector.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llxyvector.cpp b/indra/llui/llxyvector.cpp index 08dedc157b..d7ba243e1d 100644 --- a/indra/llui/llxyvector.cpp +++ b/indra/llui/llxyvector.cpp @@ -81,7 +81,9 @@ LLXYVector::LLXYVector(const LLXYVector::Params& p) mMinValueY(p.min_val_y), mMaxValueY(p.max_val_y), mIncrementY(p.increment_y), - mLogarithmic(p.logarithmic) + mLogarithmic(p.logarithmic), + mValueX(0), + mValueY(0) { mGhostColor = p.ghost_color.isProvided() ? p.ghost_color() % 0.3f : p.arrow_color() % 0.3f; -- cgit v1.2.3 From 204d9c35e0fefd980a5d553f34a759e3a4b26731 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 30 Aug 2019 19:06:30 +0300 Subject: SL-1171 [Dev tools] UI controls <-> settings connection issues --- indra/llui/llmenugl.cpp | 6 ++++++ indra/llui/lluictrl.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 92543b952e..676c94468f 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -788,6 +788,12 @@ void LLMenuItemCallGL::initFromParams(const Params& p) { setEnabledControlVariable(control); } + else + { + LL_WARNS() << "Failed to assign 'enabled' control variable to menu " << getName() + << ": control " << p.on_enable.control_name() + << " does not exist." << LL_ENDL; + } } } if (p.on_click.isProvided()) diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index df74e113e9..c98da0d410 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -137,13 +137,29 @@ void LLUICtrl::initFromParams(const Params& p) { LLControlVariable* control = findControl(p.enabled_controls.enabled); if (control) + { setEnabledControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign 'enabled' control variable to " << getName() + << ": control " << p.enabled_controls.enabled() + << " does not exist." << LL_ENDL; + } } else if(p.enabled_controls.disabled.isChosen()) { LLControlVariable* control = findControl(p.enabled_controls.disabled); if (control) + { setDisabledControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign 'disabled' control variable to " << getName() + << ": control " << p.enabled_controls.disabled() + << " does not exist." << LL_ENDL; + } } } if(p.controls_visibility.isProvided()) @@ -152,13 +168,29 @@ void LLUICtrl::initFromParams(const Params& p) { LLControlVariable* control = findControl(p.controls_visibility.visible); if (control) + { setMakeVisibleControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign visibility control variable to " << getName() + << ": control " << p.controls_visibility.visible() + << " does not exist." << LL_ENDL; + } } else if (p.controls_visibility.invisible.isChosen()) { LLControlVariable* control = findControl(p.controls_visibility.invisible); if (control) + { setMakeInvisibleControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign invisibility control variable to " << getName() + << ": control " << p.controls_visibility.invisible() + << " does not exist." << LL_ENDL; + } } } @@ -497,6 +529,11 @@ void LLUICtrl::setControlName(const std::string& control_name, LLView *context) if (!control_name.empty()) { LLControlVariable* control = context->findControl(control_name); + if (!control) + { + LL_WARNS() << "Failed to assign control variable to " << getName() + << ": control "<< control_name << " does not exist." << LL_ENDL; + } setControlVariable(control); } } -- cgit v1.2.3 From e29b3605c31e2e1cbbc932ce75b327f98b70f513 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 5 Sep 2019 17:15:57 +0300 Subject: SL-11315 Viewer asks to play media and retains selected choice --- indra/llui/llnotifications.cpp | 17 +++++++++++------ indra/llui/llnotifications.h | 4 +++- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 7bafd711cb..2e6dc6731b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -68,7 +68,8 @@ LLNotificationForm::FormIgnore::FormIgnore() control("control"), invert_control("invert_control", false), save_option("save_option", false), - session_only("session_only", false) + session_only("session_only", false), + checkbox_only("checkbox_only", false) {} LLNotificationForm::FormButton::FormButton() @@ -195,9 +196,14 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica { if (p.ignore.isProvided()) { + // For all cases but IGNORE_CHECKBOX_ONLY this is name for use in preferences mIgnoreMsg = p.ignore.text; - if (!p.ignore.save_option) + if (p.ignore.checkbox_only) + { + mIgnore = IGNORE_CHECKBOX_ONLY; + } + else if (!p.ignore.save_option) { mIgnore = p.ignore.session_only ? IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY : IGNORE_WITH_DEFAULT_RESPONSE; } @@ -214,7 +220,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica mIgnoreSetting = LLUI::sSettingGroups["config"]->getControl(p.ignore.control); mInvertSetting = p.ignore.invert_control; } - else + else if (mIgnore > IGNORE_NO) { LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT); mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name); @@ -388,13 +394,12 @@ LLControlVariablePtr LLNotificationForm::getIgnoreSetting() bool LLNotificationForm::getIgnored() { bool show = true; - if (mIgnore != LLNotificationForm::IGNORE_NO + if (mIgnore > LLNotificationForm::IGNORE_NO && mIgnoreSetting) { show = mIgnoreSetting->getValue().asBoolean(); if (mInvertSetting) show = !show; } - return !show; } @@ -695,7 +700,7 @@ void LLNotification::respond(const LLSD& response) mTemporaryResponder = false; } - if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) + if (mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO) { mForm->setIgnored(mIgnored); if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 1509446920..62cf41256b 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -180,6 +180,7 @@ public: Optional control; Optional invert_control; Optional session_only; + Optional checkbox_only; FormIgnore(); }; @@ -232,7 +233,8 @@ public: typedef enum e_ignore_type { - IGNORE_NO, + IGNORE_CHECKBOX_ONLY = -1, // ignore won't be handled, will set value/checkbox only + IGNORE_NO = 0, IGNORE_WITH_DEFAULT_RESPONSE, IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY, IGNORE_WITH_LAST_RESPONSE, -- cgit v1.2.3 From 98b28e58813035df597d01e18657b73a94635ecd Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 10 Sep 2019 19:49:15 +0300 Subject: SL-11910 [Win] Horizontal scroll --- indra/llui/llscrollbar.cpp | 10 ++++++++++ indra/llui/llscrollbar.h | 1 + indra/llui/llscrollcontainer.cpp | 19 +++++++++++++++++++ indra/llui/llscrollcontainer.h | 1 + indra/llui/llscrolllistctrl.cpp | 14 ++++++++++++++ indra/llui/llscrolllistctrl.h | 1 + indra/llui/lltextbase.cpp | 1 + indra/llui/lltextbase.h | 1 + indra/llui/llview.cpp | 10 ++++++++++ indra/llui/llview.h | 2 ++ 10 files changed, 60 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 76134144a0..25daf9db8b 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -408,6 +408,16 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollbar::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + if (LLScrollbar::HORIZONTAL == mOrientation) + { + handled = changeLine(clicks * mStepSize, TRUE); + } + return handled; +} + BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg) { diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index e2bf52c14b..5f2f490d81 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -88,6 +88,7 @@ public: virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg); diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 6135cc56ad..3db38bbfac 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -272,6 +272,25 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) return FALSE; } +BOOL LLScrollContainer::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + if (LLUICtrl::handleScrollHWheel(x,y,clicks)) + { + return TRUE; + } + + LLScrollbar* horizontal = mScrollbar[HORIZONTAL]; + if (horizontal->getVisible() + && horizontal->getEnabled() + && horizontal->handleScrollHWheel( 0, 0, clicks ) ) + { + updateScroll(); + return TRUE; + } + + return FALSE; +} + BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index e6c7891397..c14099dbd5 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -107,6 +107,7 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks ); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f4028057e8..6c8fde580f 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1601,6 +1601,20 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollListCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + // Pretend the mouse is over the scrollbar + handled = mScrollbar->handleScrollHWheel( 0, 0, clicks ); + + if (mMouseWheelOpaque) + { + return TRUE; + } + + return handled; +} + // *NOTE: Requires a valid row_index and column_index LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) { diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index b35a8608e7..d7572d9fcf 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -317,6 +317,7 @@ public: /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ void setEnabled(BOOL enabled); /*virtual*/ void setFocus( BOOL b ); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a23741b6dd..00443a16b2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -3113,6 +3113,7 @@ BOOL LLTextSegment::handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; BOOL LLTextSegment::handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleHover(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; } +BOOL LLTextSegment::handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; } BOOL LLTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { return FALSE; } const std::string& LLTextSegment::getName() const { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9831c35858..4239cdf43c 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -103,6 +103,7 @@ public: /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ const std::string& getName() const; /*virtual*/ void onMouseCaptureLost(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 0e81277185..b0e346f513 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1060,6 +1060,11 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleScrollWheel( x, y, clicks ) != NULL; } +BOOL LLView::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleScrollHWheel( x, y, clicks ) != NULL; +} + BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) { return childrenHandleRightMouseDown( x, y, mask ) != NULL; @@ -1085,6 +1090,11 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleMouseEvent(&LLView::handleScrollWheel, x, y, clicks, false); } +LLView* LLView::childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleMouseEvent(&LLView::handleScrollHWheel, x, y, clicks, false); +} + // Called during downward traversal LLView* LLView::childrenHandleKey(KEY key, MASK mask) { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 8494bb338a..b448cc8397 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -426,6 +426,7 @@ public: /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); @@ -556,6 +557,7 @@ protected: LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); + LLView* childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks); LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask); -- cgit v1.2.3 From 5591515f193a1ae3ec0dfcee4020636e529af859 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 23 Oct 2019 20:27:05 +0300 Subject: MAC build fix --- indra/llui/tests/llurlentry_test.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 119cbebc81..3c34fd269e 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -36,6 +36,11 @@ #include +#if LL_WINDOWS +// because something pulls in window and lldxdiag dependencies which in turn need wbemuuid.lib + #pragma comment(lib, "wbemuuid.lib") +#endif + // namespace LLExperienceCache // { -- cgit v1.2.3 From 4acfc99fa608269d06a5a3e45a4c3fdc5e3d06ee Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Fri, 22 Nov 2019 18:26:56 +0200 Subject: SL-12317 UI Changes to Group limits --- indra/llui/lltextbase.cpp | 8 +++++--- indra/llui/lltextbase.h | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 22635f734e..8a4b224310 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -152,6 +152,7 @@ LLTextBase::Params::Params() plain_text("plain_text",false), track_end("track_end", false), read_only("read_only", false), + skip_link_underline("skip_link_underline", false), spellcheck("spellcheck", false), v_pad("v_pad", 0), h_pad("h_pad", 0), @@ -183,6 +184,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mFontShadow(p.font_shadow), mPopupMenuHandle(), mReadOnly(p.read_only), + mSkipLinkUnderline(p.skip_link_underline), mSpellCheck(p.spellcheck), mSpellCheckStart(-1), mSpellCheckEnd(-1), @@ -2289,7 +2291,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 cur_length = getLength(); LLStyleConstSP sp(new LLStyle(highlight_params)); LLTextSegmentPtr segmentp; - if(underline_on_hover_only) + if (underline_on_hover_only || mSkipLinkUnderline) { highlight_params.font.style("NORMAL"); LLStyleConstSP normal_sp(new LLStyle(highlight_params)); @@ -2313,7 +2315,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 segment_start = old_length; S32 segment_end = old_length + wide_text.size(); LLStyleConstSP sp(new LLStyle(style_params)); - if (underline_on_hover_only) + if (underline_on_hover_only || mSkipLinkUnderline) { LLStyle::Params normal_style_params(style_params); normal_style_params.font.style("NORMAL"); @@ -3488,7 +3490,7 @@ F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start /*virtual*/ BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask) { - mStyle = mHoveredStyle; + mStyle = mEditor.getSkipLinkUnderline() ? mNormalStyle : mHoveredStyle; return LLNormalTextSegment::handleHover(x, y, mask); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9831c35858..86aecf9236 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -309,6 +309,7 @@ public: border_visible, track_end, read_only, + skip_link_underline, spellcheck, allow_scroll, plain_text, @@ -448,6 +449,9 @@ public: void setReadOnly(bool read_only) { mReadOnly = read_only; } bool getReadOnly() { return mReadOnly; } + void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } + bool getSkipLinkUnderline() { return mSkipLinkUnderline; } + void setPlainText(bool value) { mPlainText = value;} bool getPlainText() const { return mPlainText; } @@ -691,6 +695,8 @@ protected: bool mAutoIndent; S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes + bool mSkipLinkUnderline; + // support widgets LLHandle mPopupMenuHandle; LLView* mDocumentView; -- cgit v1.2.3 From 9621dd8bbd1697b119574bcc879345f03b42969e Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 22 Nov 2019 20:18:30 +0200 Subject: SL-12100 Premium Enhancements - Changes to rates to create Groups, UI Work --- indra/llui/llscrolllistctrl.cpp | 8 ++++---- indra/llui/llscrolllistctrl.h | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f4028057e8..7415e7d974 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -137,6 +137,7 @@ LLScrollListCtrl::Params::Params() background_visible("background_visible"), draw_stripes("draw_stripes"), column_padding("column_padding"), + row_padding("row_padding", 2), fg_unselected_color("fg_unselected_color"), fg_selected_color("fg_selected_color"), bg_selected_color("bg_selected_color"), @@ -199,6 +200,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mHoveredColor(p.hovered_color()), mSearchColumn(p.search_column), mColumnPadding(p.column_padding), + mRowPadding(p.row_padding), mContextMenuType(MENU_NONE), mIsFriendSignal(NULL) { @@ -685,8 +687,6 @@ bool LLScrollListCtrl::updateColumnWidths() return width_changed; } -const S32 SCROLL_LIST_ROW_PAD = 2; - // Line height is the max height of all the cells in all the items. void LLScrollListCtrl::updateLineHeight() { @@ -699,7 +699,7 @@ void LLScrollListCtrl::updateLineHeight() S32 i = 0; for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) { - mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD ); + mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding ); } } } @@ -711,7 +711,7 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) S32 i = 0; for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) { - mLineHeight = llmax( mLineHeight, cell->getHeight() + SCROLL_LIST_ROW_PAD ); + mLineHeight = llmax( mLineHeight, cell->getHeight() + mRowPadding ); } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index b35a8608e7..51e0819ecc 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -108,7 +108,8 @@ public: // layout Optional column_padding, - page_lines, + row_padding, + page_lines, heading_height; // sort and search behavior @@ -283,8 +284,10 @@ public: void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; } void setDrawStripes(BOOL b) { mDrawStripes = b; } - void setColumnPadding(const S32 c) { mColumnPadding = c; } - S32 getColumnPadding() { return mColumnPadding; } + void setColumnPadding(const S32 c) { mColumnPadding = c; } + S32 getColumnPadding() const { return mColumnPadding; } + void setRowPadding(const S32 c) { mColumnPadding = c; } + S32 getRowPadding() const { return mColumnPadding; } void setCommitOnKeyboardMovement(BOOL b) { mCommitOnKeyboardMovement = b; } void setCommitOnSelectionChange(BOOL b) { mCommitOnSelectionChange = b; } void setAllowKeyboardMovement(BOOL b) { mAllowKeyboardMovement = b; } @@ -468,6 +471,7 @@ private: LLRect mItemListRect; S32 mColumnPadding; + S32 mRowPadding; BOOL mBackgroundVisible; BOOL mDrawStripes; -- cgit v1.2.3 From b6119253574cbc6ed355f342c056a4a198001a20 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 2 Jan 2020 22:19:21 +0200 Subject: SL-12484 EXP-696 Remade "Remember Password" checkbox to be multiline --- indra/llui/llcheckboxctrl.cpp | 34 ++++++++++++++++++++++++++-------- indra/llui/lltextbase.h | 2 ++ 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index eee6339caf..f5b64d58b0 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -87,18 +87,27 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) } mLabel = LLUICtrlFactory::create (tbparams); mLabel->reshapeToFitText(); - addChild(mLabel); - LLRect label_rect = mLabel->getRect(); + if (mLabel->getLineCount() > 1) + { + // reshapeToFitText uses LLView::reshape() which always reshapes + // from bottom to top, but we want to extend the bottom + // Note: might be better idea to use getRect().mTop of LLCheckBoxCtrl (+pad) as top point of new rect + S32 delta = ll_round((F32)mLabel->getFont()->getLineHeight() * mLabel->getLineSpacingMult()) - label_rect.getHeight(); + label_rect.translate(0, delta); + mLabel->setRect(label_rect); + } + + addChild(mLabel); // Button - // Note: button cover the label by extending all the way to the right. + // Note: button cover the label by extending all the way to the right and down. LLRect btn_rect = p.check_button.rect(); btn_rect.setOriginAndSize( btn_rect.mLeft, - btn_rect.mBottom, + llmin(btn_rect.mBottom, label_rect.mBottom), llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft), - llmax( label_rect.getHeight(), btn_rect.mTop)); + llmax(label_rect.getHeight(), btn_rect.mTop)); std::string active_true_id, active_false_id; std::string inactive_true_id, inactive_false_id; @@ -152,17 +161,26 @@ void LLCheckBoxCtrl::clear() void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) { - + S32 label_top = mLabel->getRect().mTop; mLabel->reshapeToFitText(); LLRect label_rect = mLabel->getRect(); + if (label_top != label_rect.mTop) + { + // reshapeToFitText uses LLView::reshape() which always reshapes + // from bottom to top, but we want to extend the bottom so + // reposition control + S32 delta = label_top - label_rect.mTop; + label_rect.translate(0, delta); + mLabel->setRect(label_rect); + } // Button - // Note: button cover the label by extending all the way to the right. + // Note: button cover the label by extending all the way to the right and down. LLRect btn_rect = mButton->getRect(); btn_rect.setOriginAndSize( btn_rect.mLeft, - btn_rect.mBottom, + llmin(btn_rect.mBottom, label_rect.mBottom), llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft), llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight())); mButton->setShape(btn_rect); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 4239cdf43c..058b804714 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -441,6 +441,8 @@ public: S32 getVPad() { return mVPad; } S32 getHPad() { return mHPad; } + F32 getLineSpacingMult() { return mLineSpacingMult; } + S32 getLineSpacingPixels() { return mLineSpacingPixels; } // only for multiline S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const; LLRect getLocalRectFromDocIndex(S32 pos) const; -- cgit v1.2.3 From d624c3f0d5d3f2667c34059b91a0952cf47cb360 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 20 Jan 2020 16:59:27 +0200 Subject: SL-12595 The checkbox overlaps buttons in the 'Delete selected item?' notification --- indra/llui/llcheckboxctrl.cpp | 46 +++++++++++++++++++++++++++++++++---------- indra/llui/llcheckboxctrl.h | 17 ++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index f5b64d58b0..6a51c4240b 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -47,10 +47,18 @@ static LLDefaultChildRegistry::Register r("check_box"); template class LLCheckBoxCtrl* LLView::getChild( const std::string& name, BOOL recurse) const; +void LLCheckBoxCtrl::WordWrap::declareValues() +{ + declare("none", EWordWrap::WRAP_NONE); + declare("down", EWordWrap::WRAP_DOWN); + declare("up", EWordWrap::WRAP_UP); +} + LLCheckBoxCtrl::Params::Params() : initial_value("initial_value", false), label_text("label_text"), check_button("check_button"), + word_wrap("word_wrap", EWordWrap::WRAP_NONE), radio_style("radio_style") {} @@ -59,14 +67,14 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) : LLUICtrl(p), mTextEnabledColor(p.label_text.text_color()), mTextDisabledColor(p.label_text.text_readonly_color()), - mFont(p.font()) + mFont(p.font()), + mWordWrap(p.word_wrap) { mViewModel->setValue(LLSD(p.initial_value)); mViewModel->resetDirty(); static LLUICachedControl llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0); static LLUICachedControl llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0); static LLUICachedControl llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0); - static LLUICachedControl llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); // must be big enough to hold all children setUseBoundingRect(TRUE); @@ -85,17 +93,35 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) { tbparams.font(p.font); } - mLabel = LLUICtrlFactory::create (tbparams); + + mLabel = LLUICtrlFactory::create(tbparams); + if (mWordWrap != WRAP_NONE) + { + // Not setWordWrap(mWordWrap != WRAP_NONE) because there might be some old lurking code that sets it manually + mLabel->setWordWrap(true); + S32 new_width = getRect().getWidth() - p.check_button.rect().getWidth() - llcheckboxctrl_hpad; + LLRect label_rect = mLabel->getRect(); + label_rect.mRight = label_rect.mLeft + new_width; + mLabel->setRect(label_rect); + } mLabel->reshapeToFitText(); + LLRect label_rect = mLabel->getRect(); if (mLabel->getLineCount() > 1) { - // reshapeToFitText uses LLView::reshape() which always reshapes - // from bottom to top, but we want to extend the bottom - // Note: might be better idea to use getRect().mTop of LLCheckBoxCtrl (+pad) as top point of new rect - S32 delta = ll_round((F32)mLabel->getFont()->getLineHeight() * mLabel->getLineSpacingMult()) - label_rect.getHeight(); - label_rect.translate(0, delta); - mLabel->setRect(label_rect); + if (mWordWrap == WRAP_DOWN) + { + // reshapeToFitText uses LLView::reshape() which always reshapes + // from bottom to top, but we want to extend the bottom + // Note: might be better idea to use getRect().mTop of LLCheckBoxCtrl (+pad) as top point of new rect + S32 delta = ll_round((F32)mLabel->getFont()->getLineHeight() * mLabel->getLineSpacingMult()) - label_rect.getHeight(); + label_rect.translate(0, delta); + mLabel->setRect(label_rect); + } + // else + // WRAP_UP is essentially done by reshapeToFitText() (extends from bottom to top) + // howhever it doesn't respect rect of checkbox + // todo: this should be fixed, but there are at least couple checkboxes that use this feature as is. } addChild(mLabel); @@ -165,7 +191,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) mLabel->reshapeToFitText(); LLRect label_rect = mLabel->getRect(); - if (label_top != label_rect.mTop) + if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN) { // reshapeToFitText uses LLView::reshape() which always reshapes // from bottom to top, but we want to extend the bottom so diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 07ae9c3b18..eb5bd5b6da 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -50,6 +50,19 @@ class LLCheckBoxCtrl , public ll::ui::SearchableControl { public: + + enum EWordWrap + { + WRAP_NONE, + WRAP_UP, + WRAP_DOWN + }; + + struct WordWrap : public LLInitParam::TypeValuesHelper + { + static void declareValues(); + }; + struct Params : public LLInitParam::Block { @@ -58,6 +71,8 @@ public: Optional label_text; Optional check_button; + Optional word_wrap; + Ignored radio_style; Params(); @@ -129,6 +144,8 @@ protected: LLUIColor mTextEnabledColor; LLUIColor mTextDisabledColor; + + EWordWrap mWordWrap; // off, shifts text up, shifts text down }; // Build time optimization, generate once in .cpp file -- cgit v1.2.3 From db2c32285b95d3517ebcd1dbf84faa2872ab6428 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Feb 2020 18:59:43 +0200 Subject: SL-12591 Fixed slider value comparison --- indra/llui/llmultislider.cpp | 18 +++++++++++------- indra/llui/llmultislider.h | 4 ++++ indra/llui/llmultisliderctrl.h | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index fbe0d3f065..acfe4a0cba 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -149,6 +149,16 @@ LLMultiSlider::~LLMultiSlider() delete mMouseUpSignal; } +F32 LLMultiSlider::getNearestIncrement(F32 value) const +{ + value = llclamp(value, mMinValue, mMaxValue); + + // Round to nearest increment (bias towards rounding down) + value -= mMinValue; + value += mIncrement / 2.0001f; + value -= fmod(value, mIncrement); + return mMinValue + value; +} void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from_event) { @@ -157,13 +167,7 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from return; } - value = llclamp( value, mMinValue, mMaxValue ); - - // Round to nearest increment (bias towards rounding down) - value -= mMinValue; - value += mIncrement/2.0001f; - value -= fmod(value, mIncrement); - F32 newValue = mMinValue + value; + F32 newValue = getNearestIncrement(value); // now, make sure no overlap // if we want that diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 20c3437ec4..99a78d6e09 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -77,6 +77,10 @@ protected: friend class LLUICtrlFactory; public: virtual ~LLMultiSlider(); + + // Multi-slider rounds values to nearest increments (bias towards rounding down) + F32 getNearestIncrement(F32 value) const; + void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE); F32 getSliderValue(const std::string& name) const; F32 getSliderValueFromPos(S32 xpos, S32 ypos) const; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index e16737b3c7..adb28676ec 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -107,6 +107,7 @@ public: void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} + F32 getNearestIncrement(F32 value) const { return mMultiSlider->getNearestIncrement(value); } F32 getSliderValueFromPos(S32 x, S32 y) const { return mMultiSlider->getSliderValueFromPos(x, y); } LLRect getSliderThumbRect(const std::string &name) const { return mMultiSlider->getSliderThumbRect(name); } -- cgit v1.2.3