diff options
author | Leslie Linden <leslie@lindenlab.com> | 2011-10-12 17:43:47 -0700 |
---|---|---|
committer | Leslie Linden <leslie@lindenlab.com> | 2011-10-12 17:43:47 -0700 |
commit | 309ebb84a8cf93e03e2594525aa128b3002040bf (patch) | |
tree | 53133ec64c6419f44389a071269cd0709703fff2 /indra/llui | |
parent | f95922c27330b12ba22434203bf6955c06b74ba4 (diff) |
* Floater positioning now based on position of other cascading windows currently
open.
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llfloater.cpp | 84 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 19 | ||||
-rw-r--r-- | indra/llui/llfloaterreg.cpp | 73 | ||||
-rw-r--r-- | indra/llui/llfloaterreg.h | 2 |
4 files changed, 139 insertions, 39 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 0398c0d7eb..984b710b9d 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,6 +244,9 @@ 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), @@ -678,6 +683,7 @@ void LLFloater::openFloater(const LLSD& key) } else { + applyControlsAndPosition(LLFloaterReg::getLastFloaterCascading()); setMinimized(FALSE); setVisibleAndFrontmost(mAutoFocus); } @@ -840,39 +846,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 +905,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; @@ -2891,9 +2917,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 +2929,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 +3080,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..b094c76168 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -130,6 +130,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() @@ -291,8 +294,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 +318,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 +417,8 @@ private: BOOL mResizable; LLFloaterEnums::EOpenPositioning mOpenPositioning; + S32 mSpecifiedLeft; + S32 mSpecifiedBottom; S32 mMinWidth; S32 mMinHeight; 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 |