Enable gl sync fence. Missed a vertexbuffer flush. moved LLMultiFloater out of llfloater.(h|cpp) and into its own header and source file, matching v2.

This commit is contained in:
Shyotl
2011-12-26 23:40:18 -06:00
parent e1cbeb7e02
commit ca96e00135
19 changed files with 696 additions and 624 deletions

View File

@@ -88,8 +88,6 @@ BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
#undef GL_ARB_sync
class LLGLSyncFence : public LLGLFence
{
public:
@@ -2115,7 +2113,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
stop_glerror();

View File

@@ -192,7 +192,7 @@ protected:
virtual ~LLVertexBuffer(); // use unref()
virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
void setupVertexArray();
void genBuffer(U32 size);

View File

@@ -41,6 +41,7 @@ set(llui_SOURCE_FILES
lllineeditor.cpp
llmenugl.cpp
llmodaldialog.cpp
llmultifloater.cpp
llmultislider.cpp
llmultisliderctrl.cpp
llnotifications.cpp
@@ -101,6 +102,7 @@ set(llui_HEADER_FILES
llmemberlistener.h
llmenugl.h
llmodaldialog.h
llmultifloater.h
llmultisliderctrl.h
llmultislider.h
llnotificationptr.h

View File

@@ -35,7 +35,7 @@
#include "linden_common.h"
#include "llfloater.h"
#include "llmultifloater.h"
#include "llfocusmgr.h"
@@ -2480,519 +2480,7 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
}
}
//
// LLMultiFloater
//
LLMultiFloater::LLMultiFloater() :
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(TRUE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) :
mTabContainer(NULL),
mTabPos(tab_pos),
mAutoResize(TRUE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(const std::string &name) :
LLFloater(name),
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(FALSE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(
const std::string& name,
const LLRect& rect,
LLTabContainer::TabPosition tab_pos,
BOOL auto_resize) :
LLFloater(name, rect, name),
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(auto_resize),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
mTabPos,
FALSE,
FALSE);
mTabContainer->setFollowsAll();
if (isResizable())
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
addChild(mTabContainer);
}
LLMultiFloater::LLMultiFloater(
const std::string& name,
const std::string& rect_control,
LLTabContainer::TabPosition tab_pos,
BOOL auto_resize) :
LLFloater(name, rect_control, name),
mTabContainer(NULL),
mTabPos(tab_pos),
mAutoResize(auto_resize),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
mTabPos,
FALSE,
FALSE);
mTabContainer->setFollowsAll();
if (isResizable() && mTabPos == LLTabContainer::BOTTOM)
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
addChild(mTabContainer);
}
// virtual
LLXMLNodePtr LLMultiFloater::getXML(bool save_children) const
{
LLXMLNodePtr node = LLFloater::getXML();
node->setName(LL_MULTI_FLOATER_TAG);
return node;
}
void LLMultiFloater::open() /* Flawfinder: ignore */
{
if (mTabContainer->getTabCount() > 0)
{
LLFloater::open(); /* Flawfinder: ignore */
}
else
{
// for now, don't allow multifloaters
// without any child floaters
close();
}
}
void LLMultiFloater::onClose(bool app_quitting)
{
if(closeAllFloaters() == TRUE)
{
LLFloater::onClose(app_quitting);
}//else not all tabs could be closed...
}
void LLMultiFloater::draw()
{
if (mTabContainer->getTabCount() == 0)
{
//RN: could this potentially crash in draw hierarchy?
close();
}
else
{
for (S32 i = 0; i < mTabContainer->getTabCount(); i++)
{
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i);
if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i))
{
mTabContainer->setPanelTitle(i, floaterp->getShortTitle());
}
}
LLFloater::draw();
}
}
BOOL LLMultiFloater::closeAllFloaters()
{
S32 tabToClose = 0;
S32 lastTabCount = mTabContainer->getTabCount();
while (tabToClose < mTabContainer->getTabCount())
{
LLFloater* first_floater = (LLFloater*)mTabContainer->getPanelByIndex(tabToClose);
first_floater->close();
if(lastTabCount == mTabContainer->getTabCount())
{
//Tab did not actually close, possibly due to a pending Save Confirmation dialog..
//so try and close the next one in the list...
tabToClose++;
}else
{
//Tab closed ok.
lastTabCount = mTabContainer->getTabCount();
}
}
if( mTabContainer->getTabCount() != 0 )
return FALSE; // Couldn't close all the tabs (pending save dialog?) so return FALSE.
return TRUE; //else all tabs were successfully closed...
}
void LLMultiFloater::growToFit(S32 content_width, S32 content_height)
{
S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2);
S32 new_height = llmax(getRect().getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
if (isMinimized())
{
LLRect newrect;
newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height);
setExpandedRect(newrect);
}
else
{
S32 old_height = getRect().getHeight();
reshape(new_width, new_height);
// keep top left corner in same position
translate(0, old_height - new_height);
}
}
/**
void addFloater(LLFloater* floaterp, BOOL select_added_floater)
Adds the LLFloater pointed to by floaterp to this.
If floaterp is already hosted by this, then it is re-added to get
new titles, etc.
If select_added_floater is true, the LLFloater pointed to by floaterp will
become the selected tab in this
Affects: mTabContainer, floaterp
**/
void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
{
if (!floaterp)
{
return;
}
if (!mTabContainer)
{
llerrs << "Tab Container used without having been initialized." << llendl;
return;
}
if (floaterp->getHost() == this)
{
// already hosted by me, remove
// do this so we get updated title, etc.
mFloaterDataMap.erase(floaterp->getHandle());
mTabContainer->removeTabPanel(floaterp);
}
else if (floaterp->getHost())
{
// floaterp is hosted by somebody else and
// this is adding it, so remove it from it's old host
floaterp->getHost()->removeFloater(floaterp);
}
else if (floaterp->getParent() == gFloaterView)
{
// rehost preview floater as child panel
gFloaterView->removeChild(floaterp);
}
// store original configuration
LLFloaterData floater_data;
floater_data.mWidth = floaterp->getRect().getWidth();
floater_data.mHeight = floaterp->getRect().getHeight();
floater_data.mCanMinimize = floaterp->isMinimizeable();
floater_data.mCanResize = floaterp->isResizable();
// remove minimize and close buttons
floaterp->setCanMinimize(FALSE);
floaterp->setCanResize(FALSE);
floaterp->setCanDrag(FALSE);
floaterp->storeRectControl();
// avoid double rendering of floater background (makes it more opaque)
floaterp->setBackgroundVisible(FALSE);
if (mAutoResize)
{
growToFit(floater_data.mWidth, floater_data.mHeight);
}
//add the panel, add it to proper maps
mTabContainer->addTabPanel(floaterp, floaterp->getShortTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point);
mFloaterDataMap[floaterp->getHandle()] = floater_data;
updateResizeLimits();
if ( select_added_floater )
{
mTabContainer->selectTabPanel(floaterp);
}
else
{
// reassert visible tab (hiding new floater if necessary)
mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
}
floaterp->setHost(this);
if (isMinimized())
{
floaterp->setVisible(FALSE);
}
}
/**
BOOL selectFloater(LLFloater* floaterp)
If the LLFloater pointed to by floaterp is hosted by this,
then its tab is selected and returns true. Otherwise returns false.
Affects: mTabContainer
**/
BOOL LLMultiFloater::selectFloater(LLFloater* floaterp)
{
return mTabContainer->selectTabPanel(floaterp);
}
// virtual
void LLMultiFloater::selectNextFloater()
{
mTabContainer->selectNextTab();
}
// virtual
void LLMultiFloater::selectPrevFloater()
{
mTabContainer->selectPrevTab();
}
void LLMultiFloater::showFloater(LLFloater* floaterp)
{
// we won't select a panel that already is selected
// it is hard to do this internally to tab container
// as tab selection is handled via index and the tab at a given
// index might have changed
if (floaterp != mTabContainer->getCurrentPanel() &&
!mTabContainer->selectTabPanel(floaterp))
{
addFloater(floaterp, TRUE);
}
}
void LLMultiFloater::removeFloater(LLFloater* floaterp)
{
if ( floaterp->getHost() != this )
return;
floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle());
if (found_data_it != mFloaterDataMap.end())
{
LLFloaterData& floater_data = found_data_it->second;
floaterp->setCanMinimize(floater_data.mCanMinimize);
if (!floater_data.mCanResize)
{
// restore original size
floaterp->reshape(floater_data.mWidth, floater_data.mHeight);
}
floaterp->setCanResize(floater_data.mCanResize);
mFloaterDataMap.erase(found_data_it);
}
mTabContainer->removeTabPanel(floaterp);
floaterp->setBackgroundVisible(TRUE);
floaterp->setCanDrag(TRUE);
floaterp->setHost(NULL);
floaterp->applyRectControl();
updateResizeLimits();
tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);
}
void LLMultiFloater::tabOpen(LLFloater* opened_floater, bool from_click)
{
// default implementation does nothing
}
void LLMultiFloater::tabClose()
{
if (mTabContainer->getTabCount() == 0)
{
// no more children, close myself
close();
}
}
void LLMultiFloater::setVisible(BOOL visible)
{
// *FIX: shouldn't have to do this, fix adding to minimized multifloater
LLFloater::setVisible(visible);
if (mTabContainer)
{
LLPanel* cur_floaterp = mTabContainer->getCurrentPanel();
if (cur_floaterp)
{
cur_floaterp->setVisible(visible);
}
// if no tab selected, and we're being shown,
// select last tab to be added
if (visible && !cur_floaterp)
{
mTabContainer->selectLastTab();
}
}
}
BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
{
if (key == 'W' && mask == MASK_CONTROL)
{
LLFloater* floater = getActiveFloater();
// is user closeable and is system closeable
if (floater && floater->canClose() && floater->isCloseable())
{
floater->close();
}
return TRUE;
}
return LLFloater::handleKeyHere(key, mask);
}
LLFloater* LLMultiFloater::getActiveFloater()
{
return (LLFloater*)mTabContainer->getCurrentPanel();
}
S32 LLMultiFloater::getFloaterCount()
{
return mTabContainer->getTabCount();
}
/**
BOOL isFloaterFlashing(LLFloater* floaterp)
Returns true if the LLFloater pointed to by floaterp
is currently in a flashing state and is hosted by this.
False otherwise.
Requires: floaterp != NULL
**/
BOOL LLMultiFloater::isFloaterFlashing(LLFloater* floaterp)
{
if ( floaterp && floaterp->getHost() == this )
return mTabContainer->getTabPanelFlashing(floaterp);
return FALSE;
}
/**
BOOL setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
Sets the current flashing state of the LLFloater pointed
to by floaterp to be the BOOL flashing if the LLFloater pointed
to by floaterp is hosted by this.
Requires: floaterp != NULL
**/
void LLMultiFloater::setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
{
if ( floaterp && floaterp->getHost() == this )
mTabContainer->setTabPanelFlashing(floaterp, flashing);
}
//static
void LLMultiFloater::onTabSelected(void* userdata, bool from_click)
{
LLMultiFloater* floaterp = (LLMultiFloater*)userdata;
floaterp->tabOpen((LLFloater*)floaterp->mTabContainer->getCurrentPanel(), from_click);
}
void LLMultiFloater::setCanResize(BOOL can_resize)
{
LLFloater::setCanResize(can_resize);
if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM)
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
else
{
mTabContainer->setRightTabBtnOffset(0);
}
}
BOOL LLMultiFloater::postBuild()
{
// remember any original xml minimum size
getResizeLimits(&mOrigMinWidth, &mOrigMinHeight);
if (mTabContainer)
{
return TRUE;
}
requires<LLTabContainer>("Preview Tabs");
if (checkRequirements())
{
mTabContainer = getChild<LLTabContainer>("Preview Tabs");
return TRUE;
}
return FALSE;
}
void LLMultiFloater::updateResizeLimits()
{
// initialize minimum size constraint to the original xml values.
S32 new_min_width = mOrigMinWidth;
S32 new_min_height = mOrigMinHeight;
// possibly increase minimum size constraint due to children's minimums.
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
{
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
if (floaterp)
{
new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
new_min_height = llmax(new_min_height, floaterp->getMinHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
}
}
setResizeLimits(new_min_width, new_min_height);
S32 cur_height = getRect().getHeight();
S32 new_width = llmax(getRect().getWidth(), new_min_width);
S32 new_height = llmax(getRect().getHeight(), new_min_height);
if (isMinimized())
{
const LLRect& expanded = getExpandedRect();
LLRect newrect;
newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height));
setExpandedRect(newrect);
}
else
{
reshape(new_width, new_height);
// make sure upper left corner doesn't move
translate(0, cur_height - getRect().getHeight());
// make sure this window is visible on screen when it has been modified
// (tab added, etc)
gFloaterView->adjustToFitScreen(this, TRUE);
}
}
// virtual
LLXMLNodePtr LLFloater::getXML(bool save_children) const
@@ -3129,3 +2617,15 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
moveResizeHandlesToFront();
}
/*static */void VisibilityPolicy<LLFloater>::show(LLFloater* instance, const LLSD& key)
{
if (instance)
{
instance->open();
if (instance->getHost())
{
instance->getHost()->open();
}
}
}

View File

@@ -90,7 +90,8 @@ private:
class LLFloater : public LLPanel
{
friend class LLFloaterView;
friend class LLFloaterView;
friend class LLMultiFloater;
public:
enum EFloaterButtons
{
@@ -395,69 +396,6 @@ private:
S32 mSnapOffsetBottom;
};
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376
class LLMultiFloater : public LLFloater
{
public:
LLMultiFloater();
LLMultiFloater(LLTabContainer::TabPosition tab_pos);
LLMultiFloater(const std::string& name);
LLMultiFloater(const std::string& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
LLMultiFloater(const std::string& name, const std::string& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
virtual ~LLMultiFloater() {};
virtual BOOL postBuild();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void open(); /* Flawfinder: ignore */
/*virtual*/ void onClose(bool app_quitting);
/*virtual*/ void draw();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
virtual void setCanResize(BOOL can_resize);
virtual void growToFit(S32 content_width, S32 content_height);
virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
virtual void showFloater(LLFloater* floaterp);
virtual void removeFloater(LLFloater* floaterp);
virtual void tabOpen(LLFloater* opened_floater, bool from_click);
virtual void tabClose();
virtual BOOL selectFloater(LLFloater* floaterp);
virtual void selectNextFloater();
virtual void selectPrevFloater();
virtual LLFloater* getActiveFloater();
virtual BOOL isFloaterFlashing(LLFloater* floaterp);
virtual S32 getFloaterCount();
virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing);
virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs
void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; }
static void onTabSelected(void* userdata, bool);
virtual void updateResizeLimits();
protected:
struct LLFloaterData
{
S32 mWidth;
S32 mHeight;
BOOL mCanMinimize;
BOOL mCanResize;
};
LLTabContainer* mTabContainer;
typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t;
floater_data_map_t mFloaterDataMap;
LLTabContainer::TabPosition mTabPos;
BOOL mAutoResize;
S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
};
// visibility policy specialized for floaters
template<>
class VisibilityPolicy<LLFloater>
@@ -473,17 +411,7 @@ public:
return FALSE;
}
static void show(LLFloater* instance, const LLSD& key)
{
if (instance)
{
instance->open();
if (instance->getHost())
{
instance->getHost()->open();
}
}
}
static void show(LLFloater* instance, const LLSD& key);
static void hide(LLFloater* instance, const LLSD& key)
{

View File

@@ -0,0 +1,547 @@
/**
* @file llmultifloater.cpp
* @brief LLFloater that hosts other floaters
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
// Floating "windows" within the GL display, like the inventory floater,
// mini-map floater, etc.
#include "linden_common.h"
#include "llmultifloater.h"
#include "llresizehandle.h"
//
// LLMultiFloater
//
LLMultiFloater::LLMultiFloater() :
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(TRUE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) :
mTabContainer(NULL),
mTabPos(tab_pos),
mAutoResize(TRUE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(const std::string &name) :
LLFloater(name),
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(FALSE),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
}
LLMultiFloater::LLMultiFloater(
const std::string& name,
const LLRect& rect,
LLTabContainer::TabPosition tab_pos,
BOOL auto_resize) :
LLFloater(name, rect, name),
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(auto_resize),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
mTabPos,
FALSE,
FALSE);
mTabContainer->setFollowsAll();
if (isResizable())
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
addChild(mTabContainer);
}
LLMultiFloater::LLMultiFloater(
const std::string& name,
const std::string& rect_control,
LLTabContainer::TabPosition tab_pos,
BOOL auto_resize) :
LLFloater(name, rect_control, name),
mTabContainer(NULL),
mTabPos(tab_pos),
mAutoResize(auto_resize),
mOrigMinWidth(0),
mOrigMinHeight(0)
{
mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
mTabPos,
FALSE,
FALSE);
mTabContainer->setFollowsAll();
if (isResizable() && mTabPos == LLTabContainer::BOTTOM)
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
addChild(mTabContainer);
}
// virtual
LLXMLNodePtr LLMultiFloater::getXML(bool save_children) const
{
LLXMLNodePtr node = LLFloater::getXML();
node->setName(LL_MULTI_FLOATER_TAG);
return node;
}
void LLMultiFloater::open() /* Flawfinder: ignore */
{
if (mTabContainer->getTabCount() > 0)
{
LLFloater::open(); /* Flawfinder: ignore */
}
else
{
// for now, don't allow multifloaters
// without any child floaters
close();
}
}
void LLMultiFloater::onClose(bool app_quitting)
{
if(closeAllFloaters() == TRUE)
{
LLFloater::onClose(app_quitting);
}//else not all tabs could be closed...
}
void LLMultiFloater::draw()
{
if (mTabContainer->getTabCount() == 0)
{
//RN: could this potentially crash in draw hierarchy?
close();
}
else
{
for (S32 i = 0; i < mTabContainer->getTabCount(); i++)
{
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i);
if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i))
{
mTabContainer->setPanelTitle(i, floaterp->getShortTitle());
}
}
LLFloater::draw();
}
}
BOOL LLMultiFloater::closeAllFloaters()
{
S32 tabToClose = 0;
S32 lastTabCount = mTabContainer->getTabCount();
while (tabToClose < mTabContainer->getTabCount())
{
LLFloater* first_floater = (LLFloater*)mTabContainer->getPanelByIndex(tabToClose);
first_floater->close();
if(lastTabCount == mTabContainer->getTabCount())
{
//Tab did not actually close, possibly due to a pending Save Confirmation dialog..
//so try and close the next one in the list...
tabToClose++;
}else
{
//Tab closed ok.
lastTabCount = mTabContainer->getTabCount();
}
}
if( mTabContainer->getTabCount() != 0 )
return FALSE; // Couldn't close all the tabs (pending save dialog?) so return FALSE.
return TRUE; //else all tabs were successfully closed...
}
void LLMultiFloater::growToFit(S32 content_width, S32 content_height)
{
S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2);
S32 new_height = llmax(getRect().getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
if (isMinimized())
{
LLRect newrect;
newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height);
setExpandedRect(newrect);
}
else
{
S32 old_height = getRect().getHeight();
reshape(new_width, new_height);
// keep top left corner in same position
translate(0, old_height - new_height);
}
}
/**
void addFloater(LLFloater* floaterp, BOOL select_added_floater)
Adds the LLFloater pointed to by floaterp to this.
If floaterp is already hosted by this, then it is re-added to get
new titles, etc.
If select_added_floater is true, the LLFloater pointed to by floaterp will
become the selected tab in this
Affects: mTabContainer, floaterp
**/
void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
{
if (!floaterp)
{
return;
}
if (!mTabContainer)
{
llerrs << "Tab Container used without having been initialized." << llendl;
return;
}
if (floaterp->getHost() == this)
{
// already hosted by me, remove
// do this so we get updated title, etc.
mFloaterDataMap.erase(floaterp->getHandle());
mTabContainer->removeTabPanel(floaterp);
}
else if (floaterp->getHost())
{
// floaterp is hosted by somebody else and
// this is adding it, so remove it from it's old host
floaterp->getHost()->removeFloater(floaterp);
}
else if (floaterp->getParent() == gFloaterView)
{
// rehost preview floater as child panel
gFloaterView->removeChild(floaterp);
}
// store original configuration
LLFloaterData floater_data;
floater_data.mWidth = floaterp->getRect().getWidth();
floater_data.mHeight = floaterp->getRect().getHeight();
floater_data.mCanMinimize = floaterp->isMinimizeable();
floater_data.mCanResize = floaterp->isResizable();
// remove minimize and close buttons
floaterp->setCanMinimize(FALSE);
floaterp->setCanResize(FALSE);
floaterp->setCanDrag(FALSE);
floaterp->storeRectControl();
// avoid double rendering of floater background (makes it more opaque)
floaterp->setBackgroundVisible(FALSE);
if (mAutoResize)
{
growToFit(floater_data.mWidth, floater_data.mHeight);
}
//add the panel, add it to proper maps
mTabContainer->addTabPanel(floaterp, floaterp->getShortTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point);
mFloaterDataMap[floaterp->getHandle()] = floater_data;
updateResizeLimits();
if ( select_added_floater )
{
mTabContainer->selectTabPanel(floaterp);
}
else
{
// reassert visible tab (hiding new floater if necessary)
mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
}
floaterp->setHost(this);
if (isMinimized())
{
floaterp->setVisible(FALSE);
}
}
/**
BOOL selectFloater(LLFloater* floaterp)
If the LLFloater pointed to by floaterp is hosted by this,
then its tab is selected and returns true. Otherwise returns false.
Affects: mTabContainer
**/
BOOL LLMultiFloater::selectFloater(LLFloater* floaterp)
{
return mTabContainer->selectTabPanel(floaterp);
}
// virtual
void LLMultiFloater::selectNextFloater()
{
mTabContainer->selectNextTab();
}
// virtual
void LLMultiFloater::selectPrevFloater()
{
mTabContainer->selectPrevTab();
}
void LLMultiFloater::showFloater(LLFloater* floaterp)
{
// we won't select a panel that already is selected
// it is hard to do this internally to tab container
// as tab selection is handled via index and the tab at a given
// index might have changed
if (floaterp != mTabContainer->getCurrentPanel() &&
!mTabContainer->selectTabPanel(floaterp))
{
addFloater(floaterp, TRUE);
}
}
void LLMultiFloater::removeFloater(LLFloater* floaterp)
{
if (!floaterp || floaterp->getHost() != this )
return;
floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle());
if (found_data_it != mFloaterDataMap.end())
{
LLFloaterData& floater_data = found_data_it->second;
floaterp->setCanMinimize(floater_data.mCanMinimize);
if (!floater_data.mCanResize)
{
// restore original size
floaterp->reshape(floater_data.mWidth, floater_data.mHeight);
}
floaterp->setCanResize(floater_data.mCanResize);
mFloaterDataMap.erase(found_data_it);
}
mTabContainer->removeTabPanel(floaterp);
floaterp->setBackgroundVisible(TRUE);
floaterp->setCanDrag(TRUE);
floaterp->setHost(NULL);
floaterp->applyRectControl();
updateResizeLimits();
tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);
}
void LLMultiFloater::tabOpen(LLFloater* opened_floater, bool from_click)
{
// default implementation does nothing
}
void LLMultiFloater::tabClose()
{
if (mTabContainer->getTabCount() == 0)
{
// no more children, close myself
close();
}
}
void LLMultiFloater::setVisible(BOOL visible)
{
// *FIX: shouldn't have to do this, fix adding to minimized multifloater
LLFloater::setVisible(visible);
if (mTabContainer)
{
LLPanel* cur_floaterp = mTabContainer->getCurrentPanel();
if (cur_floaterp)
{
cur_floaterp->setVisible(visible);
}
// if no tab selected, and we're being shown,
// select last tab to be added
if (visible && !cur_floaterp)
{
mTabContainer->selectLastTab();
}
}
}
BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
{
if (key == 'W' && mask == MASK_CONTROL)
{
LLFloater* floater = getActiveFloater();
// is user closeable and is system closeable
if (floater && floater->canClose() && floater->isCloseable())
{
floater->close();
}
return TRUE;
}
return LLFloater::handleKeyHere(key, mask);
}
LLFloater* LLMultiFloater::getActiveFloater()
{
return (LLFloater*)mTabContainer->getCurrentPanel();
}
S32 LLMultiFloater::getFloaterCount()
{
return mTabContainer->getTabCount();
}
/**
BOOL isFloaterFlashing(LLFloater* floaterp)
Returns true if the LLFloater pointed to by floaterp
is currently in a flashing state and is hosted by this.
False otherwise.
Requires: floaterp != NULL
**/
BOOL LLMultiFloater::isFloaterFlashing(LLFloater* floaterp)
{
if ( floaterp && floaterp->getHost() == this )
return mTabContainer->getTabPanelFlashing(floaterp);
return FALSE;
}
/**
BOOL setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
Sets the current flashing state of the LLFloater pointed
to by floaterp to be the BOOL flashing if the LLFloater pointed
to by floaterp is hosted by this.
Requires: floaterp != NULL
**/
void LLMultiFloater::setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
{
if ( floaterp && floaterp->getHost() == this )
mTabContainer->setTabPanelFlashing(floaterp, flashing);
}
//static
void LLMultiFloater::onTabSelected(void* userdata, bool from_click)
{
LLMultiFloater* floaterp = (LLMultiFloater*)userdata;
floaterp->tabOpen((LLFloater*)floaterp->mTabContainer->getCurrentPanel(), from_click);
}
void LLMultiFloater::setCanResize(BOOL can_resize)
{
LLFloater::setCanResize(can_resize);
if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM)
{
mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
}
else
{
mTabContainer->setRightTabBtnOffset(0);
}
}
BOOL LLMultiFloater::postBuild()
{
// remember any original xml minimum size
getResizeLimits(&mOrigMinWidth, &mOrigMinHeight);
if (mTabContainer)
{
return TRUE;
}
requires<LLTabContainer>("Preview Tabs");
if (checkRequirements())
{
mTabContainer = getChild<LLTabContainer>("Preview Tabs");
return TRUE;
}
return FALSE;
}
void LLMultiFloater::updateResizeLimits()
{
// initialize minimum size constraint to the original xml values.
S32 new_min_width = mOrigMinWidth;
S32 new_min_height = mOrigMinHeight;
// possibly increase minimum size constraint due to children's minimums.
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
{
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
if (floaterp)
{
new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
new_min_height = llmax(new_min_height, floaterp->getMinHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
}
}
setResizeLimits(new_min_width, new_min_height);
S32 cur_height = getRect().getHeight();
S32 new_width = llmax(getRect().getWidth(), new_min_width);
S32 new_height = llmax(getRect().getHeight(), new_min_height);
if (isMinimized())
{
const LLRect& expanded = getExpandedRect();
LLRect newrect;
newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height));
setExpandedRect(newrect);
}
else
{
reshape(new_width, new_height);
// make sure upper left corner doesn't move
translate(0, cur_height - getRect().getHeight());
// make sure this window is visible on screen when it has been modified
// (tab added, etc)
gFloaterView->adjustToFitScreen(this, TRUE);
}
}

103
indra/llui/llmultifloater.h Normal file
View File

@@ -0,0 +1,103 @@
/**
* @file llmultifloater.h
* @brief LLFloater that hosts other floaters
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
// Floating "windows" within the GL display, like the inventory floater,
// mini-map floater, etc.
#ifndef LL_MULTI_FLOATER_H
#define LL_MULTI_FLOATER_H
#include "llfloater.h"
#include "lltabcontainer.h" // for LLTabContainer::eInsertionPoint
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376
class LLMultiFloater : public LLFloater
{
public:
LLMultiFloater();
LLMultiFloater(LLTabContainer::TabPosition tab_pos);
LLMultiFloater(const std::string& name);
LLMultiFloater(const std::string& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
LLMultiFloater(const std::string& name, const std::string& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
virtual ~LLMultiFloater() {};
virtual BOOL postBuild();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void open(); /* Flawfinder: ignore */
/*virtual*/ void onClose(bool app_quitting);
/*virtual*/ void draw();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
virtual void setCanResize(BOOL can_resize);
virtual void growToFit(S32 content_width, S32 content_height);
virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
virtual void showFloater(LLFloater* floaterp);
virtual void removeFloater(LLFloater* floaterp);
virtual void tabOpen(LLFloater* opened_floater, bool from_click);
virtual void tabClose();
virtual BOOL selectFloater(LLFloater* floaterp);
virtual void selectNextFloater();
virtual void selectPrevFloater();
virtual LLFloater* getActiveFloater();
virtual BOOL isFloaterFlashing(LLFloater* floaterp);
virtual S32 getFloaterCount();
virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing);
virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs
void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; }
static void onTabSelected(void* userdata, bool);
virtual void updateResizeLimits();
protected:
struct LLFloaterData
{
S32 mWidth;
S32 mHeight;
BOOL mCanMinimize;
BOOL mCanResize;
};
LLTabContainer* mTabContainer;
typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t;
floater_data_map_t mFloaterDataMap;
LLTabContainer::TabPosition mTabPos;
BOOL mAutoResize;
S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
};
#endif // LL_MULTI_FLOATER_H

View File

@@ -42,6 +42,7 @@
#include "lluictrlfactory.h"
#include "lltabcontainervertical.h"
#include "llrender.h"
#include "llmultifloater.h"
const F32 SCROLL_STEP_TIME = 0.4f;
const F32 SCROLL_DELAY_TIME = 0.5f;

View File

@@ -43,7 +43,6 @@
#ifndef LL_LLFLEXIBLEOBJECT_H
#define LL_LLFLEXIBLEOBJECT_H
#include "llmemory.h"
#include "llprimitive.h"
#include "llvovolume.h"
#include "llwind.h"

View File

@@ -34,7 +34,7 @@
#define LL_LLFLOATERPROPERTIES_H
#include <map>
#include "llfloater.h"
#include "llmultifloater.h"
#include "lliconctrl.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -33,7 +33,7 @@
#ifndef LL_LLFLOATERSCRIPTDEBUG_H
#define LL_LLFLOATERSCRIPTDEBUG_H
#include "llfloater.h"
#include "llmultifloater.h"
class LLTextEditor;
class LLUUID;

View File

@@ -2,6 +2,7 @@
#include "llcheckboxctrl.h"
#include "llfocusmgr.h"
#include "lluictrlfactory.h"
#include "llmultifloater.h"
#include "llfloatersearchreplace.h"

View File

@@ -37,7 +37,7 @@
* Base class and manager for in-world 2.5D non-interactive objects
*/
#include "llmemory.h"
#include "llpointer.h"
#include "v4color.h"
#include "v3math.h"

View File

@@ -33,7 +33,7 @@
#ifndef LL_LLIMVIEW_H
#define LL_LLIMVIEW_H
#include "llfloater.h"
#include "llmultifloater.h"
#include "llinstantmessage.h"
#include "lluuid.h"

View File

@@ -91,15 +91,14 @@ void LLMorphView::initialize()
mCameraYaw = 0.f;
mCameraDist = -1.f;
LLVOAvatar *avatarp = gAgentAvatarp;
if (!avatarp || avatarp->isDead())
if (!isAgentAvatarValid() || gAgentAvatarp->isDead())
{
gAgentCamera.changeCameraToDefault();
return;
}
avatarp->stopMotion( ANIM_AGENT_BODY_NOISE );
avatarp->mSpecialRenderMode = 3;
gAgentAvatarp->stopMotion( ANIM_AGENT_BODY_NOISE );
gAgentAvatarp->mSpecialRenderMode = 3;
// set up camera for close look at avatar
mOldCameraNearClip = LLViewerCamera::getInstance()->getNear();
@@ -113,11 +112,10 @@ void LLMorphView::shutdown()
{
LLVOAvatar::onCustomizeEnd();
LLVOAvatar *avatarp = gAgentAvatarp;
if(avatarp && !avatarp->isDead())
if (isAgentAvatarValid())
{
avatarp->startMotion( ANIM_AGENT_BODY_NOISE );
avatarp->mSpecialRenderMode = 0;
gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
gAgentAvatarp->mSpecialRenderMode = 0;
// reset camera
LLViewerCamera::getInstance()->setNear(mOldCameraNearClip);
}
@@ -167,14 +165,10 @@ void LLMorphView::updateCamera()
if (!mCameraTargetJoint)
{
setCameraTargetJoint(gAgentAvatarp->getJoint("mHead"));
}
LLVOAvatar* avatar = gAgentAvatarp;
if( !avatar )
{
return;
}
LLJoint* root_joint = avatar->getRootJoint();
}
if (!isAgentAvatarValid()) return;
LLJoint* root_joint = gAgentAvatarp->getRootJoint();
if( !root_joint )
{
return;

View File

@@ -33,7 +33,7 @@
#ifndef LL_LLPREVIEW_H
#define LL_LLPREVIEW_H
#include "llfloater.h"
#include "llmultifloater.h"
#include "llresizehandle.h"
#include "llmap.h"
#include "lluuid.h"

View File

@@ -3820,8 +3820,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
std::string version_channel;
msg->getString("SimData", "ChannelVersion", version_channel);
LLVOAvatar* avatarp = gAgentAvatarp;
if (!avatarp)
if (!isAgentAvatarValid())
{
// Could happen if you were immediately god-teleported away on login,
// maybe other cases. Continue, but warn.
@@ -3882,7 +3881,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
gAgent.sendAgentSetAppearance();
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
if ( (avatarp) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
if ( (gAgentAvatarp) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
// [/RLVa:KB]
// if (avatarp)
{
@@ -3892,9 +3891,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
LLFloaterChat::addChatHistory(chat);
// Set the new position
avatarp->setPositionAgent(agent_pos);
avatarp->clearChat();
avatarp->slamPosition();
gAgentAvatarp->setPositionAgent(agent_pos);
gAgentAvatarp->clearChat();
gAgentAvatarp->slamPosition();
}
// add teleport destination to the list of visited places
@@ -3968,9 +3967,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
gAgent.clearBusy();
}
if (avatarp)
if (isAgentAvatarValid())
{
avatarp->mFootPlane.clearVec();
gAgentAvatarp->mFootPlane.clearVec();
}
// send walk-vs-run status

View File

@@ -168,7 +168,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
*(texCoordsp++) = LLVector2(0.f, 1.f);
*(texCoordsp++) = LLVector2(0.5f, 0.5f);
face->getVertexBuffer()->setBuffer(0);
face->getVertexBuffer()->flush();
LLPipeline::sCompiles++;
return TRUE;
}

View File

@@ -63,7 +63,7 @@ public:
};
// virtual
void setupVertexBuffer(U32 data_mask) const
void setupVertexBuffer(U32 data_mask)
{
if (LLGLSLShader::sNoFixedFunction)
{ //just use default if shaders are in play