* Floater positioning now based on position of other cascading windows currently
open.meow-7.2.2
parent
f95922c273
commit
309ebb84a8
|
|
@ -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;
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
protected:
|
||||
virtual void applySavedVariables();
|
||||
|
||||
virtual void applyRectControl();
|
||||
void applyDockState();
|
||||
void applyPositioning();
|
||||
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
|
||||
protected:
|
||||
void applyControlsAndPosition(LLFloater* other);
|
||||
|
||||
void stackWith(LLFloater& other);
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -109,15 +109,18 @@ BOOL LLNearbyChatBar::postBuild()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLNearbyChatBar::applyRectControl()
|
||||
bool LLNearbyChatBar::applyRectControl()
|
||||
{
|
||||
LLFloater::applyRectControl();
|
||||
if (getRect().getHeight() > getMinHeight())
|
||||
bool rect_controlled = LLFloater::applyRectControl();
|
||||
|
||||
if (getRect().getHeight() > getMinHeight())
|
||||
{
|
||||
getChildView("nearby_chat")->setVisible(true);
|
||||
mExpandedHeight = getRect().getHeight();
|
||||
enableResizeCtrls(true);
|
||||
}
|
||||
|
||||
return rect_controlled;
|
||||
}
|
||||
|
||||
void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ protected:
|
|||
void onChatBoxCommit();
|
||||
void onChatFontChange(LLFontGL* fontp);
|
||||
|
||||
/* virtual */ void applyRectControl();
|
||||
/* virtual */ bool applyRectControl();
|
||||
|
||||
void onToggleNearbyChatPanel();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
open_positioning="specified"
|
||||
specified_left="683"
|
||||
specified_bottom="0"
|
||||
legacy_header_height="18"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
follows="bottom"
|
||||
height="164"
|
||||
layout="topleft"
|
||||
left="683"
|
||||
bottom="0"
|
||||
name="camera_floater"
|
||||
help_topic="camera_floater"
|
||||
save_visibility="true"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
open_positioning="specified"
|
||||
specified_left="150"
|
||||
specified_bottom="0"
|
||||
height="60"
|
||||
left="150"
|
||||
bottom="0"
|
||||
layout="topleft"
|
||||
legacy_header_height="25"
|
||||
single_instance="true"
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
open_positioning="specified"
|
||||
specified_left="535"
|
||||
specified_bottom="0"
|
||||
legacy_header_height="18"
|
||||
can_dock="false"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
follows="bottom"
|
||||
height="110"
|
||||
left="535"
|
||||
bottom="0"
|
||||
layout="topleft"
|
||||
name="move_floater"
|
||||
help_topic="move_floater"
|
||||
|
|
|
|||
Loading…
Reference in New Issue