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:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
547
indra/llui/llmultifloater.cpp
Normal file
547
indra/llui/llmultifloater.cpp
Normal 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
103
indra/llui/llmultifloater.h
Normal 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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#ifndef LL_LLFLEXIBLEOBJECT_H
|
||||
#define LL_LLFLEXIBLEOBJECT_H
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llprimitive.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llwind.h"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define LL_LLFLOATERPROPERTIES_H
|
||||
|
||||
#include <map>
|
||||
#include "llfloater.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "lliconctrl.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#ifndef LL_LLFLOATERSCRIPTDEBUG_H
|
||||
#define LL_LLFLOATERSCRIPTDEBUG_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llmultifloater.h"
|
||||
|
||||
class LLTextEditor;
|
||||
class LLUUID;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llmultifloater.h"
|
||||
|
||||
#include "llfloatersearchreplace.h"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#ifndef LL_LLIMVIEW_H
|
||||
#define LL_LLIMVIEW_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "llinstantmessage.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user