EXP-1021 FIX Position of web content browser dictates position of profile panel - profile panel position changes do not persist

EXP-1030 FIX Search button toggle can get out of synch in bottom bar
made llinstancetracker::iterator do own nested level management (removing need for separate guard)
added support for filename= to floaters
can pass in arbitrary window_class to floaters
meow-7.2.2
Richard Nelson 2011-07-26 14:26:27 -07:00
parent 95da8c81f3
commit fd9f3b9fe9
19 changed files with 325 additions and 208 deletions

View File

@ -58,19 +58,15 @@ LLEventTimer::~LLEventTimer()
void LLEventTimer::updateClass()
{
std::list<LLEventTimer*> completed_timers;
for (instance_iter iter = beginInstances(); iter != endInstances(); )
{
LLInstanceTrackerScopedGuard guard;
for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); )
{
LLEventTimer& timer = *iter++;
F32 et = timer.mEventTimer.getElapsedTimeF32();
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
timer.mEventTimer.reset();
if ( timer.tick() )
{
completed_timers.push_back( &timer );
}
LLEventTimer& timer = *iter++;
F32 et = timer.mEventTimer.getElapsedTimeF32();
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
timer.mEventTimer.reset();
if ( timer.tick() )
{
completed_timers.push_back( &timer );
}
}
}

View File

@ -219,11 +219,8 @@ LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
// static
void LLFastTimer::DeclareTimer::updateCachedPointers()
{
DeclareTimer::LLInstanceTrackerScopedGuard guard;
// propagate frame state pointers to timer declarations
for (DeclareTimer::instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
// update cached pointer
it->mFrameState = &it->mTimer.getFrameState();
@ -395,10 +392,7 @@ void LLFastTimer::NamedTimer::buildHierarchy()
// set up initial tree
{
NamedTimer::LLInstanceTrackerScopedGuard guard;
for (instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
NamedTimer& timer = *it;
if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
@ -526,10 +520,7 @@ void LLFastTimer::NamedTimer::resetFrame()
LLSD sd;
{
NamedTimer::LLInstanceTrackerScopedGuard guard;
for (NamedTimer::instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
NamedTimer& timer = *it;
FrameState& info = timer.getFrameState();
@ -566,7 +557,7 @@ void LLFastTimer::NamedTimer::resetFrame()
llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());
}
// sort timers by dfs traversal order to improve cache coherency
// sort timers by DFS traversal order to improve cache coherency
std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());
// update pointers into framestatelist now that we've sorted it
@ -574,10 +565,7 @@ void LLFastTimer::NamedTimer::resetFrame()
// reset for next frame
{
NamedTimer::LLInstanceTrackerScopedGuard guard;
for (NamedTimer::instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
NamedTimer& timer = *it;
@ -621,10 +609,7 @@ void LLFastTimer::NamedTimer::reset()
// reset all history
{
NamedTimer::LLInstanceTrackerScopedGuard guard;
for (NamedTimer::instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
NamedTimer& timer = *it;
if (&timer != NamedTimerFactory::instance().getRootTimer())
@ -872,7 +857,7 @@ std::string LLFastTimer::sClockType = "rdtsc";
#else
//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
// These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures.
// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.
U32 LLFastTimer::getCPUClockCount32()
{
return (U32)(get_clock_count()>>8);

View File

@ -52,13 +52,68 @@ class LLInstanceTracker : public LLInstanceTrackerBase
{
typedef typename std::map<KEY, T*> InstanceMap;
typedef LLInstanceTracker<T, KEY> MyT;
typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
public:
/// Dereferencing key_iter gives you a const KEY&
typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
/// Dereferencing instance_iter gives you a T&
typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
{
public:
instance_iter(typename InstanceMap::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
~instance_iter()
{
--sIterationNestDepth;
}
private:
friend class boost::iterator_core_access;
void increment() { mIterator++; }
bool equal(instance_iter const& other) const
{
return mIterator == other.m_iterator;
}
T& dereference() const
{
return mIterator->second;
}
typename InstanceMap::iterator mIterator;
};
class key_iter : public boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag>
{
public:
key_iter(typename InstanceMap::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
~key_iter()
{
--sIterationNestDepth;
}
private:
friend class boost::iterator_core_access;
void increment() { mIterator++; }
bool equal(instance_iter const& other) const
{
return mIterator == other.m_iterator;
}
KEY& dereference() const
{
return mIterator->first;
}
typename InstanceMap::iterator mIterator;
};
static T* getInstance(const KEY& k)
{
@ -66,42 +121,47 @@ public:
return (found == getMap_().end()) ? NULL : found->second;
}
static instance_iter beginInstances()
{
return instance_iter(getMap_().begin());
}
static instance_iter endInstances()
{
return instance_iter(getMap_().end());
}
static S32 instanceCount() { return getMap_().size(); }
static key_iter beginKeys()
{
return boost::make_transform_iterator(getMap_().begin(),
boost::bind(&InstanceMap::value_type::first, _1));
return key_iter(getMap_().begin());
}
static key_iter endKeys()
{
return boost::make_transform_iterator(getMap_().end(),
boost::bind(&InstanceMap::value_type::first, _1));
return key_iter(getMap_().end());
}
static instance_iter beginInstances()
{
return instance_iter(boost::make_transform_iterator(getMap_().begin(),
boost::bind(&InstanceMap::value_type::second, _1)));
}
static instance_iter endInstances()
{
return instance_iter(boost::make_transform_iterator(getMap_().end(),
boost::bind(&InstanceMap::value_type::second, _1)));
}
static S32 instanceCount() { return getMap_().size(); }
protected:
LLInstanceTracker(KEY key) { add_(key); }
virtual ~LLInstanceTracker() { remove_(); }
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
llassert(sIterationNestDepth == 0);
remove_();
}
virtual void setKey(KEY key) { remove_(); add_(key); }
virtual const KEY& getKey() const { return mKey; }
virtual const KEY& getKey() const { return mInstanceKey; }
private:
void add_(KEY key)
{
mKey = key;
mInstanceKey = key;
getMap_()[key] = static_cast<T*>(this);
}
void remove_()
{
getMap_().erase(mKey);
getMap_().erase(mInstanceKey);
}
static InstanceMap& getMap_()
@ -116,9 +176,12 @@ private:
private:
KEY mKey;
KEY mInstanceKey;
static S32 sIterationNestDepth;
};
template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
/// explicit specialization for default case where KEY is T*
/// use a simple std::set<T*>
template<typename T>
@ -127,15 +190,52 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
typedef typename std::set<T*> InstanceSet;
typedef LLInstanceTracker<T, T*> MyT;
public:
/// Dereferencing key_iter gives you a T* (since T* is the key)
typedef typename InstanceSet::iterator key_iter;
/// Dereferencing instance_iter gives you a T&
typedef boost::indirect_iterator<key_iter> instance_iter;
/// for completeness of analogy with the generic implementation
static T* getInstance(T* k) { return k; }
static S32 instanceCount() { return getSet_().size(); }
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
{
public:
instance_iter(typename InstanceSet::iterator& it)
: mIterator(it)
{
++sIterationNestDepth;
}
instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
++sIterationNestDepth;
}
~instance_iter()
{
--sIterationNestDepth;
}
private:
friend class boost::iterator_core_access;
void increment() { mIterator++; }
bool equal(instance_iter const& other) const
{
return mIterator == other.mIterator;
}
T& dereference() const
{
return **mIterator;
}
typename InstanceSet::iterator mIterator;
};
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
// DEPRECATED: iterators now increment and decrement iteration depth
// Instantiate this to get access to iterators for this type. It's a 'guard' in the sense
// that it treats deletes of this type as errors as long as there is an instance of
// this class alive in scope somewhere (i.e. deleting while iterating is bad).
@ -154,15 +254,12 @@ public:
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
static key_iter beginKeys() { return getSet_().begin(); }
static key_iter endKeys() { return getSet_().end(); }
};
protected:
LLInstanceTracker()
{
// it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this));
}
virtual ~LLInstanceTracker()
@ -174,7 +271,6 @@ protected:
LLInstanceTracker(const LLInstanceTracker& other)
{
//llassert(sIterationNestDepth == 0);
getSet_().insert(static_cast<T*>(this));
}

View File

@ -2110,8 +2110,7 @@ void LLGLNamePool::release(GLuint name)
void LLGLNamePool::upkeepPools()
{
LLMemType mt(LLMemType::MTYPE_UPKEEP_POOLS);
tracker_t::LLInstanceTrackerScopedGuard guard;
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
{
LLGLNamePool & pool = *iter;
pool.upkeep();
@ -2121,8 +2120,7 @@ void LLGLNamePool::upkeepPools()
//static
void LLGLNamePool::cleanupPools()
{
tracker_t::LLInstanceTrackerScopedGuard guard;
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
{
LLGLNamePool & pool = *iter;
pool.cleanup();

View File

@ -372,9 +372,7 @@ LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_t
// static
void LLConsole::updateClass()
{
LLInstanceTrackerScopedGuard guard;
for (instance_iter it = guard.beginInstances(); it != guard.endInstances(); ++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
it->update();
}

View File

@ -766,7 +766,6 @@ void LLFloater::closeFloater(bool app_quitting)
void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLPanel::reshape(width, height, called_from_parent);
storeRectControl();
}
void LLFloater::releaseFocus()
@ -968,6 +967,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
const LLRect old_rect = getRect();
LLView::handleReshape(new_rect, by_user);
if (by_user)
{
storeRectControl();
}
// if not minimized, adjust all snapped dependents to new shape
if (!isMinimized())
{
@ -2048,7 +2052,6 @@ static LLDefaultChildRegistry::Register<LLFloaterView> r("floater_view");
LLFloaterView::LLFloaterView (const Params& p)
: LLUICtrl (p),
mFocusCycleMode(FALSE),
mMinimizePositionVOffset(0),
mSnapOffsetBottom(0),
@ -2058,12 +2061,6 @@ LLFloaterView::LLFloaterView (const Params& p)
// By default, adjust vertical.
void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
reshapeFloater(width, height, called_from_parent, ADJUST_VERTICAL_YES);
}
// When reshaping this view, make the floaters follow their closest edge.
void LLFloaterView::reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical)
{
S32 old_width = getRect().getWidth();
S32 old_height = getRect().getHeight();
@ -2109,11 +2106,7 @@ void LLFloaterView::reshapeFloater(S32 width, S32 height, BOOL called_from_paren
// "No vertical adjustment" usually means that the bottom of the view
// has been pushed up or down. Hence we want the floaters to follow
// the top.
if (!adjust_vertical)
{
follow_flags |= FOLLOWS_TOP;
}
else if (top_offset < bottom_offset)
if (top_offset < bottom_offset)
{
follow_flags |= FOLLOWS_TOP;
}
@ -2847,7 +2840,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mAutoTile = p.auto_tile;
mOpenCentered = p.open_centered;
if (p.save_rect)
if (p.save_rect && mRectControl.empty())
{
mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
}
@ -2885,13 +2878,54 @@ boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::
}
LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
static LLFastTimer::DeclareTimer FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floater Reference");
bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)
{
Params params(LLUICtrlFactory::getDefaultParams<LLFloater>());
Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
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, &default_params);
return TRUE;
}
LLUICtrlFactory::instance().pushFileName(xml_filename);
LLFastTimer _(FTM_EXTERNAL_FLOATER_LOAD);
if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
{
llwarns << "Couldn't parse panel from: " << xml_filename << llendl;
return FALSE;
}
parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
// 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);
@ -2912,7 +2946,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
{
params.rect.left.set(0);
}
params.from_xui = true;
applyXUILayout(params, parent);
initFromParams(params);
@ -3054,3 +3087,24 @@ bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_n
return res;
}
void LLFloater::stackWith(LLFloater& other)
{
static LLUICachedControl<S32> 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);
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
mRectControl.clear(); // don't save rect of stacked floaters
setShape(next_rect);
}

View File

@ -265,6 +265,8 @@ 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();
@ -289,9 +291,6 @@ public:
void updateTransparency(ETypeTransparency transparency_type);
protected:
void setRectControl(const std::string& rectname) { mRectControl = rectname; };
virtual void applySavedVariables();
void applyRectControl();
@ -455,8 +454,6 @@ protected:
public:
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical);
/*virtual*/ void draw();
/*virtual*/ LLRect getSnapRect() const;
/*virtual*/ void refresh();

View File

@ -57,7 +57,7 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
}
//static
LLRect LLFloaterReg::getFloaterRect(const std::string& name)
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
{
LLRect rect;
const std::string& groupname = sGroupMap[name];
@ -66,20 +66,10 @@ LLRect LLFloaterReg::getFloaterRect(const std::string& name)
instance_list_t& list = sInstanceMap[groupname];
if (!list.empty())
{
static LLUICachedControl<S32> floater_offset ("UIFloaterOffset", 16);
LLFloater* last_floater = list.back();
if (last_floater->getHost())
{
rect = last_floater->getHost()->getRect();
}
else
{
rect = last_floater->getRect();
}
rect.translate(floater_offset, -floater_offset);
return list.back();
}
}
return rect;
return NULL;
}
//static
@ -137,12 +127,12 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
if (res->mAutoTile && !res->getHost() && index > 0)
{
const LLRect& cur_rect = res->getRect();
LLRect next_rect = getFloaterRect(groupname);
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, cur_rect.getWidth(), cur_rect.getHeight());
res->setRect(next_rect);
res->setRectControl(LLStringUtil::null); // don't save rect of tiled floaters
gFloaterView->adjustToFitScreen(res, true);
LLFloater* last_floater = getLastFloaterInGroup(groupname);
if (last_floater)
{
res->stackWith(*last_floater);
gFloaterView->adjustToFitScreen(res, true);
}
}
else
{

View File

@ -86,7 +86,7 @@ public:
const std::string& groupname = LLStringUtil::null);
// Helpers
static LLRect getFloaterRect(const std::string& name);
static LLFloater* getLastFloaterInGroup(const std::string& name);
// Find / get (create) / remove / destroy
static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());

View File

@ -713,10 +713,7 @@ void LLLayoutStack::createResizeBars()
//static
void LLLayoutStack::updateClass()
{
LLInstanceTrackerScopedGuard guard;
for (LLLayoutStack::instance_iter it = guard.beginInstances();
it != guard.endInstances();
++it)
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
it->updateLayout();
}

View File

@ -515,9 +515,6 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
if (!xml_filename.empty())
{
LLUICtrlFactory::instance().pushFileName(xml_filename);
LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
if (output_node)
{
//if we are exporting, we want to export the current xml
@ -530,6 +527,9 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
return TRUE;
}
LLUICtrlFactory::instance().pushFileName(xml_filename);
LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
{
llwarns << "Couldn't parse panel from: " << xml_filename << llendl;

View File

@ -265,6 +265,9 @@ protected:
std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer
typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t;
static factory_stack_t sFactoryStack;
// for setting the xml filename when building panel in context dependent cases
std::string mXMLFilename;
private:
BOOL mBgVisible; // any background at all?
@ -283,8 +286,6 @@ private:
typedef std::map<std::string, std::string> ui_string_map_t;
ui_string_map_t mUIStrings;
// for setting the xml filename when building panel in context dependent cases
std::string mXMLFilename;
}; // end class LLPanel

View File

@ -320,6 +320,7 @@ static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarNa
url(url).
id(agent_id).
show_chrome(show_chrome).
window_class("profile").
preferred_media_size(profile_rect));
}

View File

@ -887,18 +887,14 @@ void LLFloaterProperties::dirtyAll()
LLMultiProperties::LLMultiProperties()
: LLMultiFloater(LLSD())
{
// *TODO: There should be a .xml file for this
const LLRect& nextrect = LLFloaterReg::getFloaterRect("properties"); // place where the next properties should show up
if (nextrect.getWidth() > 0)
// start with a small rect in the top-left corner ; will get resized
LLRect rect;
rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20);
setRect(rect);
LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("properties");
if (last_floater)
{
setRect(nextrect);
}
else
{
// start with a small rect in the top-left corner ; will get resized
LLRect rect;
rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20);
setRect(rect);
stackWith(*last_floater);
}
setTitle(LLTrans::getString("MultiPropertiesTitle"));
buildTabContainer();

View File

@ -44,14 +44,17 @@ LLFloaterWebContent::_Params::_Params()
: url("url"),
target("target"),
id("id"),
window_class("window_class", "web_content"),
show_chrome("show_chrome", true),
allow_address_entry("allow_address_entry", true),
preferred_media_size("preferred_media_size"),
trusted_content("trusted_content", false)
{}
LLFloaterWebContent::LLFloaterWebContent( const Params& key )
: LLFloater( key )
LLFloaterWebContent::LLFloaterWebContent( const Params& params )
: LLFloater( params ),
LLInstanceTracker(params.id()),
mUUID(params.id().asString())
{
mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
@ -64,9 +67,9 @@ LLFloaterWebContent::LLFloaterWebContent( const Params& key )
BOOL LLFloaterWebContent::postBuild()
{
// these are used in a bunch of places so cache them
mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
mAddressCombo = getChild< LLComboBox >( "address" );
mStatusBarText = getChild< LLTextBox >( "statusbartext" );
mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
mAddressCombo = getChild< LLComboBox >( "address" );
mStatusBarText = getChild< LLTextBox >( "statusbartext" );
mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" );
// observe browser events
@ -110,10 +113,8 @@ void LLFloaterWebContent::initializeURLHistory()
// Get all of the entries in the "browser" collection
LLSD browser_history = LLURLHistory::getURLHistory("browser");
LLSD::array_iterator iter_history =
browser_history.beginArray();
LLSD::array_iterator end_history =
browser_history.endArray();
LLSD::array_iterator iter_history = browser_history.beginArray();
LLSD::array_iterator end_history = browser_history.endArray();
for(; iter_history != end_history; ++iter_history)
{
std::string url = (*iter_history).asString();
@ -123,7 +124,7 @@ void LLFloaterWebContent::initializeURLHistory()
}
//static
void LLFloaterWebContent::create( Params p)
LLFloater* LLFloaterWebContent::create( Params p)
{
lldebugs << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id().asString() << llendl;
@ -139,7 +140,9 @@ void LLFloaterWebContent::create( Params p)
S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit");
if(LLFloaterReg::findInstance("web_content", p.target()) != NULL)
LLSD sd;
sd["target"] = p.target;
if(LLFloaterReg::findInstance(p.window_class, sd) != NULL)
{
// There's already a web browser for this tag, so we won't be opening a new window.
}
@ -148,7 +151,7 @@ void LLFloaterWebContent::create( Params p)
// showInstance will open a new window. Figure out how many web browsers are already open,
// and close the least recently opened one if this will put us over the limit.
LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("web_content");
LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class);
lldebugs << "total instance count is " << instances.size() << llendl;
for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++)
@ -163,40 +166,26 @@ void LLFloaterWebContent::create( Params p)
}
}
LLFloaterReg::showInstance("web_content", p);
return LLFloaterReg::showInstance(p.window_class, p);
}
//static
void LLFloaterWebContent::closeRequest(const std::string &uuid)
{
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
LLFloaterWebContent* floaterp = getInstance(LLUUID(uuid));
if (floaterp)
{
LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
lldebugs << " " << i->mUUID << llendl;
if (i && i->mUUID == uuid)
{
i->closeFloater(false);
return;
}
}
floaterp->closeFloater(false);
}
}
//static
void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
{
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
LLFloaterWebContent* floaterp = getInstance(LLUUID(uuid));
if (floaterp)
{
LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
lldebugs << " " << i->mUUID << llendl;
if (i && i->mUUID == uuid)
{
i->geometryChanged(x, y, width, height);
return;
}
floaterp->geometryChanged(x, y, width, height);
}
}
@ -210,15 +199,21 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
getWindow()->getSize(&window_size);
// Adjust width and height for the size of the chrome on the web Browser window.
width += getRect().getWidth() - mWebBrowser->getRect().getWidth();
height += getRect().getHeight() - mWebBrowser->getRect().getHeight();
LLRect browser_rect;
mWebBrowser->localRectToOtherView(mWebBrowser->getLocalRect(), &browser_rect, this);
S32 requested_browser_bottom = window_size.mY - (y + height);
LLRect geom;
geom.setOriginAndSize(x, window_size.mY - (y + height), width, height);
geom.setOriginAndSize(x - browser_rect.mLeft,
requested_browser_bottom - browser_rect.mBottom,
width + getRect().getWidth() - browser_rect.getWidth(),
height + getRect().getHeight() - browser_rect.getHeight());
lldebugs << "geometry change: " << geom << llendl;
setShape(geom);
LLRect new_rect;
getParent()->screenRectToLocal(geom, &new_rect);
setShape(new_rect);
}
void LLFloaterWebContent::open_media(const Params& p)
@ -242,8 +237,12 @@ void LLFloaterWebContent::open_media(const Params& p)
if (!p.preferred_media_size().isEmpty())
{
//ignore x, y for now
geometryChanged(getRect().mLeft, getRect().mBottom, p.preferred_media_size().getWidth(), p.preferred_media_size().getHeight());
LLLayoutStack::updateClass();
LLRect browser_rect = mWebBrowser->calcScreenRect();
LLCoordWindow window_size;
getWindow()->getSize(&window_size);
geometryChanged(browser_rect.mLeft, window_size.mY - browser_rect.mTop, p.preferred_media_size().getWidth(), p.preferred_media_size().getHeight());
}
}
@ -258,11 +257,6 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
return;
}
if (params.target() == params.id().asString())
{
setRectControl("");
}
mUUID = params.id().asString();
mWebBrowser->setTrustedContent(params.trusted_content);
// tell the browser instance to load the specified URL
@ -279,7 +273,7 @@ void LLFloaterWebContent::onClose(bool app_quitting)
// virtual
void LLFloaterWebContent::draw()
{
// this is asychronous so we need to keep checking
// this is asynchronous so we need to keep checking
getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() );
getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() );
@ -421,7 +415,7 @@ void LLFloaterWebContent::onClickStop()
// still should happen when we catch the navigate complete event
// but sometimes (don't know why) that event isn't sent from Qt
// and we getto a point where the stop button stays active.
// and we ghetto a point where the stop button stays active.
getChildView("reload")->setVisible( true );
getChildView("stop")->setVisible( false );
}

View File

@ -39,7 +39,8 @@ class LLIconCtrl;
class LLFloaterWebContent :
public LLFloater,
public LLViewerMediaObserver
public LLViewerMediaObserver,
public LLInstanceTracker<LLFloaterWebContent, LLUUID>
{
public:
LOG_CLASS(LLFloaterWebContent);
@ -47,7 +48,8 @@ public:
struct _Params : public LLInitParam::Block<_Params>
{
Optional<std::string> url,
target;
target,
window_class;
Optional<LLUUID> id;
Optional<bool> show_chrome,
allow_address_entry,
@ -59,11 +61,11 @@ public:
typedef LLSDParamAdapter<_Params> Params;
LLFloaterWebContent(const Params& key);
LLFloaterWebContent(const Params& params);
void initializeURLHistory();
static void create(Params);
static LLFloater* create(Params);
static void closeRequest(const std::string &uuid);
static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);

View File

@ -444,18 +444,15 @@ void LLPreview::handleReshape(const LLRect& new_rect, bool by_user)
LLMultiPreview::LLMultiPreview()
: LLMultiFloater(LLSD())
{
// *TODO: There should be a .xml file for this
const LLRect& nextrect = LLFloaterReg::getFloaterRect("preview"); // place where the next preview should show up
if (nextrect.getWidth() > 0)
// start with a rect in the top-left corner ; will get resized
LLRect rect;
rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 400);
setRect(rect);
LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("preview");
if (last_floater)
{
setRect(nextrect);
}
else
{
// start with a rect in the top-left corner ; will get resized
LLRect rect;
rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 400);
setRect(rect);
stackWith(*last_floater);
}
setTitle(LLTrans::getString("MultiPreviewTitle"));
buildTabContainer();

View File

@ -246,15 +246,11 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml",
&LLFloaterReg::build<LLFloaterTestInspectors>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
LLFloaterReg::add("test_textbox", "floater_test_textbox.xml",
&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("test_text_editor", "floater_test_text_editor.xml",
&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("test_widgets", "floater_test_widgets.xml",
&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("test_textbox", "floater_test_textbox.xml", &LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("test_text_editor", "floater_test_text_editor.xml", &LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", &LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("top_objects", "floater_top_objects.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTopObjects>);
LLFloaterReg::add("reporter", "floater_report_abuse.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterReporter>);
@ -274,7 +270,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("search", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("profile", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWebContent>);
LLFloaterUIPreviewUtil::registerFloater();
LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
can_resize="true"
height="775"
layout="topleft"
min_height="400"
min_width="500"
name="floater_web_content"
help_topic="floater_web_content"
save_rect="true"
auto_tile="true"
save_visibility="true"
title=""
initial_mime_type="text/html"
width="780"
filename="floater_web_content.xml"/>