summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2011-10-12 18:13:01 -0700
committerMerov Linden <merov@lindenlab.com>2011-10-12 18:13:01 -0700
commit40ebe180a6592381804555d1c9e8df84bf35345a (patch)
tree523d687dedb2921d30e1d553184a8caa87ee3c45 /indra/llui
parentaa1f0215c764fa346625ace43c467a0e0f803057 (diff)
parent1181e7c75747361e1a57f083cf82c63ef152bfc5 (diff)
Pull from richard/viewer-experience-fui
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llbutton.cpp2
-rw-r--r--indra/llui/llfloater.cpp153
-rw-r--r--indra/llui/llfloater.h33
-rw-r--r--indra/llui/llfloaterreg.cpp73
-rw-r--r--indra/llui/llfloaterreg.h2
-rw-r--r--indra/llui/lltoolbar.cpp6
-rw-r--r--indra/llui/lltoolbar.h4
7 files changed, 225 insertions, 48 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 0a7584a576..4f0c0d31bd 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -548,7 +548,7 @@ void LLButton::setHighlight(bool b)
BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
{
if (isInEnabledChain()
- && (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() != this))
+ && (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this))
mNeedsHighlight = TRUE;
if (!childrenHandleHover(x, y, mask))
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 0398c0d7eb..81b14aac17 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -175,6 +175,8 @@ LLFloater::Params::Params()
save_visibility("save_visibility", false),
can_dock("can_dock", false),
open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE),
+ specified_left("specified_left"),
+ specified_bottom("specified_bottom"),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
close_image("close_image"),
@@ -242,11 +244,15 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mCanClose(p.can_close),
mDragOnLeft(p.can_drag_on_left),
mResizable(p.can_resize),
+ mOpenPositioning(p.open_positioning),
+ mSpecifiedLeft(p.specified_left),
+ mSpecifiedBottom(p.specified_bottom),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
mMinimized(FALSE),
+ mVisibleWhenMinimized(TRUE),
mForeground(FALSE),
mFirstLook(TRUE),
mButtonScale(1.0f),
@@ -678,6 +684,7 @@ void LLFloater::openFloater(const LLSD& key)
}
else
{
+ applyControlsAndPosition(LLFloaterReg::getLastFloaterCascading());
setMinimized(FALSE);
setVisibleAndFrontmost(mAutoFocus);
}
@@ -840,39 +847,54 @@ LLMultiFloater* LLFloater::getHost()
return (LLMultiFloater*)mHostHandle.get();
}
-void LLFloater::applySavedVariables()
+void LLFloater::applyControlsAndPosition(LLFloater* other)
{
- applyRectControl();
- applyDockState();
+ if (!applyDockState())
+ {
+ if (!applyRectControl())
+ {
+ applyPositioning(other);
+ }
+ }
}
-void LLFloater::applyRectControl()
+bool LLFloater::applyRectControl()
{
+ bool saved_rect = false;
+
// If we have a saved rect, use it
if (mRectControl.size() > 1)
{
const LLRect& rect = getControlGroup()->getRect(mRectControl);
- if (rect.notEmpty())
+ saved_rect = rect.notEmpty();
+ if (saved_rect)
{
setOrigin(rect.mLeft, rect.mBottom);
+
if (mResizable)
{
reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
}
}
}
+
+ return saved_rect;
}
-void LLFloater::applyDockState()
+bool LLFloater::applyDockState()
{
+ bool docked = false;
+
if (mDocStateControl.size() > 1)
{
- bool dockState = getControlGroup()->getBOOL(mDocStateControl);
- setDocked(dockState);
+ docked = getControlGroup()->getBOOL(mDocStateControl);
+ setDocked(docked);
}
+
+ return docked;
}
-void LLFloater::applyPositioning()
+void LLFloater::applyPositioning(LLFloater* other)
{
// Otherwise position according to the positioning code
switch (mOpenPositioning)
@@ -884,28 +906,33 @@ void LLFloater::applyPositioning()
case LLFloaterEnums::OPEN_POSITIONING_SPECIFIED:
{
// Translate relative to snap rect
- LLRect r = getRect();
- r.mBottom = getSnapRect().getHeight() - r.getHeight() - r.mBottom;
- setOrigin(r.mLeft, r.mBottom);
- translateIntoRect(getSnapRect(), FALSE);
+ setOrigin(mSpecifiedLeft, mSpecifiedBottom);
+ const LLRect& snap_rect = gFloaterView->getSnapRect();
+ translate(snap_rect.mLeft, snap_rect.mBottom);
+ translateIntoRect(snap_rect, FALSE);
}
break;
case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
+ if (other != NULL)
{
- static const U32 CASCADING_FLOATER_HOFFSET = 25;
- static const U32 CASCADING_FLOATER_VOFFSET = 25;
- static const S32 CASCADING_FLOATER_LIMIT = 15;
- static S32 cascading_floater_count = 1;
- const S32 top = CASCADING_FLOATER_VOFFSET * cascading_floater_count;
- const S32 left = CASCADING_FLOATER_HOFFSET * cascading_floater_count;
- setOrigin(left, top);
- translateIntoRect(getSnapRect(), FALSE);
+ stackWith(*other);
+ }
+ else
+ {
+ static const U32 CASCADING_FLOATER_HOFFSET = 0;
+ static const U32 CASCADING_FLOATER_VOFFSET = 0;
+
+ const LLRect& snap_rect = gFloaterView->getSnapRect();
- if (++cascading_floater_count > CASCADING_FLOATER_LIMIT)
- {
- cascading_floater_count = 1;
- }
+ 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);
+ translateIntoRect(snap_rect, FALSE);
}
break;
@@ -1406,6 +1433,17 @@ void LLFloater::removeDependentFloater(LLFloater* floaterp)
floaterp->mDependeeHandle = LLHandle<LLFloater>();
}
+void LLFloater::setVisibleWhenMinimized(bool visible)
+{
+ mVisibleWhenMinimized = visible;
+ if (visible && isMinimized())
+ {
+ // restack in minimized stack
+ setMinimized(FALSE);
+ setMinimized(TRUE);
+ }
+}
+
BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index)
{
if( mButtonsEnabled[index] )
@@ -1782,11 +1820,14 @@ void LLFloater::draw()
}
if (isMinimized())
{
- for (S32 i = 0; i < BUTTON_COUNT; i++)
+ if (mVisibleWhenMinimized)
{
- drawChild(mButtons[i]);
+ for (S32 i = 0; i < BUTTON_COUNT; i++)
+ {
+ drawChild(mButtons[i]);
+ }
+ drawChild(mDragHandle);
}
- drawChild(mDragHandle);
}
else
{
@@ -2441,7 +2482,7 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
{
// Examine minimized children.
LLFloater* floater = (LLFloater*)((LLView*)*child_it);
- if(floater->isMinimized())
+ if(floater->isMinimized() && floater->getVisibleWhenMinimized())
{
LLRect r = floater->getRect();
if((r.mBottom < (row + floater_header_size))
@@ -2506,6 +2547,52 @@ void LLFloaterView::closeAllChildren(bool 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;
+ }
+ }
+}
+
+void LLFloaterView::hideAllFloaters()
+{
+ child_list_t child_list = *(getChildList());
+
+ for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it)
+ {
+ LLFloater* floaterp = dynamic_cast<LLFloater*>(*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();
+}
BOOL LLFloaterView::allChildrenClosed()
{
@@ -2891,9 +2978,11 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mHeaderHeight = p.header_height;
mLegacyHeaderHeight = p.legacy_header_height;
mSingleInstance = p.single_instance;
+
mOpenPositioning = p.open_positioning;
+ mSpecifiedLeft = p.specified_left;
+ mSpecifiedBottom = p.specified_bottom;
- /*
if (p.save_rect && mRectControl.empty())
{
mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
@@ -2901,8 +2990,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
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
@@ -3053,7 +3141,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
llerrs << "Failed to construct floater " << getName() << llendl;
}
- applyPositioning();
applyRectControl(); // If we have a saved rect control, apply it
gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index b404306e94..7cfec09e5f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -35,6 +35,7 @@
#include "lluuid.h"
//#include "llnotificationsutil.h"
#include <set>
+#include <boost/signals2.hpp>
class LLDragHandle;
class LLResizeHandle;
@@ -130,6 +131,9 @@ public:
can_dock;
Optional<LLFloaterEnums::EOpenPositioning> open_positioning;
+ Optional<S32> specified_left;
+ Optional<S32> specified_bottom;
+
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
@@ -213,6 +217,8 @@ public:
LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
void removeDependentFloater(LLFloater* dependent);
BOOL isMinimized() const { return mMinimized; }
+ void setVisibleWhenMinimized(bool visible);
+ bool getVisibleWhenMinimized() const { return mVisibleWhenMinimized;}
/// isShown() differs from getVisible() in that isShown() also considers
/// isMinimized(). isShown() is true only if visible and not minimized.
bool isShown() const;
@@ -291,8 +297,6 @@ public:
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
- void stackWith(LLFloater& other);
-
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
@@ -317,12 +321,16 @@ public:
void updateTransparency(ETypeTransparency transparency_type);
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
+
+ bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
protected:
- virtual void applySavedVariables();
+ void applyControlsAndPosition(LLFloater* other);
+
+ void stackWith(LLFloater& other);
- virtual void applyRectControl();
- void applyDockState();
- void applyPositioning();
+ virtual bool applyRectControl();
+ bool applyDockState();
+ void applyPositioning(LLFloater* other);
void storeRectControl();
void storeVisibilityControl();
void storeDockStateControl();
@@ -412,6 +420,8 @@ private:
BOOL mResizable;
LLFloaterEnums::EOpenPositioning mOpenPositioning;
+ S32 mSpecifiedLeft;
+ S32 mSpecifiedBottom;
S32 mMinWidth;
S32 mMinHeight;
@@ -419,6 +429,7 @@ private:
S32 mLegacyHeaderHeight;// HACK see initFloaterXML()
BOOL mMinimized;
+ bool mVisibleWhenMinimized;
BOOL mForeground;
LLHandle<LLFloater> mDependeeHandle;
@@ -454,8 +465,6 @@ private:
typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
static handle_map_t sFloaterMap;
- std::vector<LLHandle<LLView> > mMinimizedHiddenChildren;
-
BOOL mHasBeenDraggedWhileMinimized;
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
@@ -509,6 +518,10 @@ public:
BOOL allChildrenClosed();
void shiftFloaters(S32 x_offset, S32 y_offset);
+ void hideAllFloaters();
+ void showHiddenFloaters();
+
+
LLFloater* getFrontmost() const;
LLFloater* getBackmost() const;
LLFloater* getParentFloater(LLView* viewp) const;
@@ -523,11 +536,15 @@ public:
void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
private:
+ void hiddenFloaterClosed(LLFloater* floater);
+
LLHandle<LLView> mSnapView;
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
S32 mSnapOffsetRight;
S32 mMinimizePositionVOffset;
+ typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
+ hidden_floaters_t mHiddenFloaters;
};
//
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 058223abbd..a148f5a32e 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -59,19 +59,57 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
//static
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
{
- LLRect rect;
const std::string& groupname = sGroupMap[name];
if (!groupname.empty())
{
instance_list_t& list = sInstanceMap[groupname];
if (!list.empty())
{
- return list.back();
+ for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
+ {
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible() && !inst->isMinimized())
+ {
+ return inst;
+ }
+ }
}
}
return NULL;
}
+LLFloater* LLFloaterReg::getLastFloaterCascading()
+{
+ LLRect candidate_rect;
+ candidate_rect.mTop = 100000;
+ LLFloater* candidate_floater = NULL;
+
+ std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
+ for( ; it != it_end; ++it)
+ {
+ const std::string& group_name = it->second;
+
+ instance_list_t& instances = sInstanceMap[group_name];
+
+ for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING))
+ {
+ if (candidate_rect.mTop > inst->getRect().mTop)
+ {
+ candidate_floater = inst;
+ candidate_rect = inst->getRect();
+ }
+ }
+ }
+ }
+
+ return candidate_floater;
+}
+
//static
LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
{
@@ -127,9 +165,10 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
res->mKey = key;
}
res->setInstanceName(name);
- res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
- // apply list.size() and possibly stackWith(getLastFloaterInGroup(groupname))
+ LLFloater *last_floater = (list.empty() ? NULL : list.back());
+ res->applyControlsAndPosition(last_floater);
+
gFloaterView->adjustToFitScreen(res, false);
list.push_back(res);
@@ -533,3 +572,29 @@ bool LLFloaterReg::floaterInstanceMinimized(const LLSD& sdname)
LLFloater* instance = findInstance(name, key);
return LLFloater::isShown(instance);
}
+
+// static
+U32 LLFloaterReg::getVisibleFloaterInstanceCount()
+{
+ U32 count = 0;
+
+ std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
+ for( ; it != it_end; ++it)
+ {
+ const std::string& group_name = it->second;
+
+ instance_list_t& instances = sInstanceMap[group_name];
+
+ for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible() && !inst->isMinimized())
+ {
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 07ae45cc4c..817fe2e8c6 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -87,6 +87,7 @@ public:
// Helpers
static LLFloater* getLastFloaterInGroup(const std::string& name);
+ static LLFloater* getLastFloaterCascading();
// Find / get (create) / remove / destroy
static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
@@ -153,6 +154,7 @@ public:
static void blockShowFloaters(bool value) { sBlockShowFloaters = value;}
+ static U32 getVisibleFloaterInstanceCount();
};
#endif
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index ce3ef1db97..21eeed1d27 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -99,6 +99,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mSideType(p.side),
mWrap(p.wrap),
mNeedsLayout(false),
+ mModified(false),
mButtonPanel(NULL),
mCenteringStack(NULL),
mPadLeft(p.pad_left),
@@ -909,7 +910,10 @@ void LLToolBarButton::onMouseEnter(S32 x, S32 y, MASK mask)
LLUICtrl::onMouseEnter(x, y, mask);
// Always highlight toolbar buttons, even if they are disabled
- mNeedsHighlight = TRUE;
+ if (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this)
+ {
+ mNeedsHighlight = TRUE;
+ }
}
void LLToolBarButton::onMouseCaptureLost()
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 8fd509bacc..7f8ae4f839 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -178,7 +178,8 @@ public:
LLToolBarButton* createButton(const LLCommandId& id);
- bool hasButtons() { return !mButtons.empty(); }
+ bool hasButtons() const { return !mButtons.empty(); }
+ bool isModified() const { return mModified; }
protected:
friend class LLUICtrlFactory;
@@ -227,6 +228,7 @@ private:
bool mWrap;
bool mNeedsLayout;
+ bool mModified;
S32 mPadLeft,
mPadRight,
mPadTop,