1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786 |
- /**
- * @file llpanel.cpp
- * @brief LLPanel base class
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- // Opaque view with a background and a border. Can contain LLUICtrls.
- #include "linden_common.h"
- #include "llpanel.h"
- #include "llalertdialog.h"
- #include "llbutton.h"
- #include "llcontrol.h"
- #include "llcriticaldamp.h" // Used by LLLayoutStack
- #include "llkeyboard.h"
- #include "llfloater.h"
- #include "lliconctrl.h"
- #include "lllineeditor.h"
- #include "llmenugl.h"
- #include "llresizebar.h" // Used by LLLayoutStack
- #include "llstl.h" // For DeletePointer()
- #include "lltextbox.h"
- #include "lltimer.h"
- #include "lluictrl.h"
- #include "lluictrlfactory.h"
- #include "llviewborder.h"
- constexpr S32 RESIZE_BAR_OVERLAP = 1;
- constexpr S32 RESIZE_BAR_HEIGHT = 3;
- static const std::string LL_LAYOUT_PANEL_TAG = "layout_panel";
- static const std::string LL_PANEL_TAG = "panel";
- static LLRegisterWidget<LLPanel> r14(LL_PANEL_TAG);
- void LLPanel::init()
- {
- // mRectControl
- mBgColorAlpha = LLUI::sDefaultBackgroundColor;
- mBgColorOpaque = LLUI::sFocusBackgroundColor;
- mDefaultBtnHighlight = LLUI::sDefaultHighlightLight;
- mBgVisible = false;
- mBgOpaque = false;
- mBorder = NULL;
- mDefaultBtn = NULL;
- setIsChrome(false); // is this a decorator to a live window or a form ?
- mLastTabGroup = 0;
- setTabStop(false);
- }
- LLPanel::LLPanel()
- {
- init();
- setName(LL_PANEL_TAG);
- }
- LLPanel::LLPanel(const std::string& name)
- : LLUICtrl(name, LLRect(0, 0, 0, 0), true, NULL, NULL)
- {
- init();
- }
- LLPanel::LLPanel(const std::string& name, const LLRect& rect, bool bordered)
- : LLUICtrl(name, rect, true, NULL, NULL)
- {
- init();
- if (bordered)
- {
- addBorder();
- }
- }
- LLPanel::LLPanel(const std::string& name, const std::string& rect_control,
- bool bordered)
- : LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control.c_str()), true,
- NULL, NULL),
- mRectControl(rect_control)
- {
- init();
- if (bordered)
- {
- addBorder();
- }
- }
- LLPanel::~LLPanel()
- {
- storeRectControl();
- }
- // virtual
- bool LLPanel::postBuild()
- {
- return true;
- }
- void LLPanel::addBorder(LLViewBorder::EBevel border_bevel,
- LLViewBorder::EStyle border_style,
- S32 border_thickness)
- {
- removeBorder();
- mBorder = new LLViewBorder("panel border",
- LLRect(0, getRect().getHeight(),
- getRect().getWidth(), 0),
- border_bevel, border_style, border_thickness);
- mBorder->setSaveToXML(false);
- addChild(mBorder);
- }
- void LLPanel::removeBorder()
- {
- delete mBorder;
- mBorder = NULL;
- }
- // virtual
- void LLPanel::clearCtrls()
- {
- LLView::ctrl_list_t ctrls = getCtrlList();
- for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(), end = ctrls.end();
- ctrl_it != end; ++ctrl_it)
- {
- LLUICtrl* ctrl = *ctrl_it;
- ctrl->setFocus(false);
- ctrl->setEnabled(false);
- ctrl->clear();
- }
- }
- void LLPanel::setCtrlsEnabled(bool b)
- {
- LLView::ctrl_list_t ctrls = getCtrlList();
- for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(), end = ctrls.end();
- ctrl_it != end; ++ctrl_it)
- {
- LLUICtrl* ctrl = *ctrl_it;
- ctrl->setEnabled(b);
- }
- }
- void LLPanel::draw()
- {
- // Draw background
- if (mBgVisible)
- {
- // RN: I do not see the point of this
- S32 top = getRect().getHeight(); // - LLPANEL_BORDER_WIDTH;
- S32 right = getRect().getWidth(); // - LLPANEL_BORDER_WIDTH;
- if (mBgOpaque)
- {
- gl_rect_2d(0, top, right, 0, mBgColorOpaque);
- }
- else
- {
- gl_rect_2d(0, top, right, 0, mBgColorAlpha);
- }
- }
- updateDefaultBtn();
- LLView::draw();
- }
- //virtual
- void LLPanel::setAlpha(F32 alpha)
- {
- mBgColorOpaque.setAlpha(alpha);
- }
- void LLPanel::updateDefaultBtn()
- {
- // This method does not call LLView::draw() so callers will need
- // to take care of that themselves at the appropriate place in
- // their rendering sequence
- if (mDefaultBtn)
- {
- if (gFocusMgr.childHasKeyboardFocus(this) &&
- mDefaultBtn->getEnabled())
- {
- LLButton* buttonp;
- buttonp = dynamic_cast<LLButton*>(gFocusMgr.getKeyboardFocus());
- bool focus_is_child_button = buttonp && buttonp->getCommitOnReturn();
- // only enable default button when current focus is not a
- // return-capturing button
- mDefaultBtn->setBorderEnabled(!focus_is_child_button);
- }
- else
- {
- mDefaultBtn->setBorderEnabled(false);
- }
- }
- }
- void LLPanel::refresh()
- {
- // do nothing by default
- // but is automatically called in setFocus(true)
- }
- void LLPanel::setDefaultBtn(LLButton* btn)
- {
- if (mDefaultBtn && mDefaultBtn->getEnabled())
- {
- mDefaultBtn->setBorderEnabled(false);
- }
- mDefaultBtn = btn;
- if (mDefaultBtn)
- {
- mDefaultBtn->setBorderEnabled(true);
- }
- }
- void LLPanel::setDefaultBtn(const char* id)
- {
- LLButton* button = NULL;
- if (id[0])
- {
- button = getChild<LLButton>(id, true, false);
- }
- setDefaultBtn(button);
- }
- void LLPanel::addCtrl(LLUICtrl* ctrl, S32 tab_group)
- {
- mLastTabGroup = tab_group;
- LLView::addCtrl(ctrl, tab_group);
- }
- void LLPanel::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group)
- {
- mLastTabGroup = tab_group;
- LLView::addCtrlAtEnd(ctrl, tab_group);
- }
- bool LLPanel::handleKeyHere(KEY key, MASK mask)
- {
- bool handled = false;
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocusUICtrl();
- // Handle user hitting ESC to defocus
- if (key == KEY_ESCAPE && mask == MASK_NONE)
- {
- gFocusMgr.setKeyboardFocus(NULL);
- return true;
- }
- else if (mask == MASK_SHIFT && KEY_TAB == key)
- {
- // SHIFT-TAB
- if (cur_focus)
- {
- LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
- if (focus_root)
- {
- handled = focus_root->focusPrevItem(false);
- }
- }
- }
- else if (mask == MASK_NONE && KEY_TAB == key)
- {
- // TAB
- if (cur_focus)
- {
- LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
- if (focus_root)
- {
- handled = focus_root->focusNextItem(false);
- }
- }
- }
- // If we have a default button, click it when return is pressed, unless
- // current focus is a return-capturing button in which case *that* button
- // will handle the return key
- LLButton* focused_button = dynamic_cast<LLButton*>(cur_focus);
- if (cur_focus && !(focused_button && focused_button->getCommitOnReturn()))
- {
- // RETURN key means hit default button in this case
- if (key == KEY_RETURN && mask == MASK_NONE && mDefaultBtn != NULL &&
- mDefaultBtn->getVisible() && mDefaultBtn->getEnabled())
- {
- mDefaultBtn->onCommit();
- handled = true;
- }
- }
- if (key == KEY_RETURN && mask == MASK_NONE)
- {
- // set keyboard focus to self to trigger commitOnFocusLost behavior on
- // current ctrl
- if (cur_focus && cur_focus->acceptsTextInput())
- {
- cur_focus->onCommit();
- handled = true;
- }
- }
- return handled;
- }
- void LLPanel::setFocus(bool b)
- {
- if (b)
- {
- if (!gFocusMgr.childHasKeyboardFocus(this))
- {
- #if 0
- refresh();
- #endif
- if (!focusFirstItem())
- {
- LLUICtrl::setFocus(true);
- }
- onFocusReceived();
- }
- }
- else
- {
- if (this == gFocusMgr.getKeyboardFocus())
- {
- gFocusMgr.setKeyboardFocus(NULL);
- }
- else
- {
- //RN: why is this here?
- LLView::ctrl_list_t ctrls = getCtrlList();
- for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(),
- end = ctrls.end();
- ctrl_it != end; ++ctrl_it)
- {
- LLUICtrl* ctrl = *ctrl_it;
- ctrl->setFocus(false);
- }
- }
- }
- }
- void LLPanel::setBorderVisible(bool b)
- {
- if (mBorder)
- {
- mBorder->setVisible(b);
- }
- }
- //virtual
- const std::string& LLPanel::getTag() const
- {
- return LL_PANEL_TAG;
- }
- // virtual
- LLXMLNodePtr LLPanel::getXML(bool save_children) const
- {
- LLXMLNodePtr node = LLUICtrl::getXML();
- node->setName(LL_PANEL_TAG);
- if (mBorder && mBorder->getVisible())
- {
- node->createChild("border", true)->setBoolValue(true);
- }
- if (!mRectControl.empty())
- {
- node->createChild("rect_control", true)->setStringValue(mRectControl);
- }
- if (!mLabel.empty())
- {
- node->createChild("label", true)->setStringValue(mLabel);
- }
- ui_string_map_t::const_iterator i = mUIStrings.begin();
- ui_string_map_t::const_iterator end = mUIStrings.end();
- for ( ; i != end; ++i)
- {
- LLXMLNodePtr child_node = node->createChild("string", false);
- child_node->setStringValue(i->second);
- child_node->createChild("name", true)->setStringValue(i->first);
- }
- if (save_children)
- {
- LLView::child_list_const_reverse_iter_t rit;
- for (rit = getChildList()->rbegin(); rit != getChildList()->rend();
- ++rit)
- {
- LLView* childp = *rit;
- if (childp->getSaveToXML())
- {
- LLXMLNodePtr xml_node = childp->getXML();
- node->addChild(xml_node);
- }
- }
- }
- return node;
- }
- LLView* LLPanel::fromXML(LLXMLNodePtr nodep, LLView* parentp,
- LLUICtrlFactory* factoryp)
- {
- std::string name = LL_PANEL_TAG;
- nodep->getAttributeString("name", name);
- LLPanel* panelp = factoryp->createFactoryPanel(name);
- // Fall back on a default panel, if there was no special factory.
- if (!panelp)
- {
- LLRect rect;
- createRect(nodep, rect, parentp, LLRect());
- // Create a new panel without a border, by default
- panelp = new LLPanel(name, rect, false);
- panelp->initPanelXML(nodep, parentp, factoryp);
- // Preserve the panel width and height, but override the location.
- const LLRect& panelrect = panelp->getRect();
- S32 w = panelrect.getWidth();
- S32 h = panelrect.getHeight();
- rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
- panelp->setRect(rect);
- }
- else
- {
- panelp->initPanelXML(nodep, parentp, factoryp);
- }
- return panelp;
- }
- bool LLPanel::initPanelXML(LLXMLNodePtr nodep, LLView* parentp,
- LLUICtrlFactory* factoryp)
- {
- std::string name = getName();
- nodep->getAttributeString("name", name);
- setName(name);
- setPanelParameters(nodep, parentp);
- initChildrenXML(nodep, factoryp);
- std::string xml_filename;
- nodep->getAttributeString("filename", xml_filename);
- bool did_post;
- if (!xml_filename.empty())
- {
- did_post = factoryp->buildPanel(this, xml_filename, NULL);
- LLRect new_rect = getRect();
- // Override rectangle with embedding parameters as provided
- createRect(nodep, new_rect, parentp);
- setOrigin(new_rect.mLeft, new_rect.mBottom);
- reshape(new_rect.getWidth(), new_rect.getHeight());
- // Optionally override follows flags from including nodes
- parseFollowsFlags(nodep);
- }
- else
- {
- did_post = false;
- }
- if (!did_post)
- {
- postBuild();
- did_post = true;
- }
- return did_post;
- }
- void LLPanel::initChildrenXML(LLXMLNodePtr nodep, LLUICtrlFactory* factoryp)
- {
- LLXMLNodePtr childp;
- for (childp = nodep->getFirstChild(); childp.notNull();
- childp = childp->getNextSibling())
- {
- // Look for string declarations for programmatic text
- if (childp->hasName("string"))
- {
- std::string string_name;
- childp->getAttributeString("name", string_name);
- if (!string_name.empty())
- {
- mUIStrings[string_name] = childp->getTextContents();
- }
- }
- else
- {
- factoryp->createWidget(this, childp);
- }
- }
- }
- void LLPanel::setPanelParameters(LLXMLNodePtr nodep, LLView* parentp)
- {
- // Rect, follows, tool_tip, enabled, visible attributes
- initFromXML(nodep, parentp);
- // Border attributes
- bool border = mBorder != NULL;
- nodep->getAttributeBool("border", border);
- if (border)
- {
- LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_OUT;
- LLViewBorder::getBevelFromAttribute(nodep, bevel_style);
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE;
- std::string border_string;
- nodep->getAttributeString("border_style", border_string);
- LLStringUtil::toLower(border_string);
- if (border_string == "texture")
- {
- border_style = LLViewBorder::STYLE_TEXTURE;
- }
- S32 border_thickness = LLPANEL_BORDER_WIDTH;
- nodep->getAttributeS32("border_thickness", border_thickness);
- addBorder(bevel_style, border_style, border_thickness);
- }
- else
- {
- removeBorder();
- }
- // Background attributes
- bool background_visible = mBgVisible;
- nodep->getAttributeBool("background_visible", background_visible);
- setBackgroundVisible(background_visible);
- bool background_opaque = mBgOpaque;
- nodep->getAttributeBool("background_opaque", background_opaque);
- setBackgroundOpaque(background_opaque);
- LLColor4 color;
- color = mBgColorOpaque;
- LLUICtrlFactory::getAttributeColor(nodep, "bg_opaque_color", color);
- setBackgroundColor(color);
- color = mBgColorAlpha;
- LLUICtrlFactory::getAttributeColor(nodep, "bg_alpha_color", color);
- setTransparentColor(color);
- // Label
- std::string label = getLabel();
- nodep->getAttributeString("label", label);
- setLabel(label);
- }
- LLFloater* LLPanel::getParentFloater() const
- {
- LLFloater* floaterp = NULL;
- LLView* parentp = getParent();
- while (parentp && !floaterp)
- {
- floaterp = parentp->asFloater();
- parentp = parentp->getParent();
- }
- return floaterp;
- }
- std::string LLPanel::getString(const std::string& name,
- const LLStringUtil::format_map_t& args) const
- {
- LL_DEBUGS("GetStringUI") << "Requested UI string: " << name << LL_ENDL;
- ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
- if (found_it != mUIStrings.end())
- {
- // Make a copy as format works in place
- LLUIString formatted_string = LLUIString(found_it->second);
- formatted_string.setArgList(args);
- return formatted_string.getString();
- }
- llwarns << "Failed to find string " << name << " in panel " << getName()
- << llendl;
- return LLStringUtil::null;
- }
- std::string LLPanel::getString(const std::string& name) const
- {
- LL_DEBUGS("GetStringUI") << "Requested UI string: " << name << LL_ENDL;
- ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
- if (found_it != mUIStrings.end())
- {
- return found_it->second;
- }
- llwarns << "Failed to find string " << name << " in panel " << getName()
- << llendl;
- return LLStringUtil::null;
- }
- void LLPanel::childSetVisible(const char* id, bool visible)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- child->setVisible(visible);
- }
- }
- bool LLPanel::childIsVisible(const char* id) const
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- return (bool)child->getVisible();
- }
- return false;
- }
- void LLPanel::childSetEnabled(const char* id, bool enabled)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- child->setEnabled(enabled);
- }
- }
- void LLPanel::childSetTentative(const char* id, bool tentative)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- child->setTentative(tentative);
- }
- }
- bool LLPanel::childIsEnabled(const char* id) const
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- return (bool)child->getEnabled();
- }
- return false;
- }
- void LLPanel::childSetToolTip(const char* id, const std::string& msg)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- child->setToolTip(msg);
- }
- }
- void LLPanel::childSetRect(const char* id, const LLRect& rect)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- child->setRect(rect);
- }
- }
- bool LLPanel::childGetRect(const char* id, LLRect& rect) const
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- rect = child->getRect();
- return true;
- }
- return false;
- }
- void LLPanel::childSetFocus(const char* id, bool focus)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setFocus(focus);
- }
- }
- bool LLPanel::childHasFocus(const char* id)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- return child->hasFocus();
- }
- childNotFound(id);
- return false;
- }
- void LLPanel::childSetFocusChangedCallback(const char* id,
- void (*cb)(LLFocusableElement*, void*),
- void* user_data)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setFocusChangedCallback(cb, user_data);
- }
- }
- void LLPanel::childSetCommitCallback(const char* id,
- void (*cb)(LLUICtrl*, void*),
- void *userdata)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setCommitCallback(cb);
- child->setCallbackUserData(userdata);
- }
- }
- void LLPanel::childSetDoubleClickCallback(const char* id,
- void (*cb)(void*), void* userdata)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setDoubleClickCallback(cb);
- if (userdata)
- {
- child->setCallbackUserData(userdata);
- }
- }
- }
- void LLPanel::childSetValidate(const char* id,
- bool (*cb)(LLUICtrl*, void*))
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setValidateBeforeCommit(cb);
- }
- }
- void LLPanel::childSetUserData(const char* id, void* userdata)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setCallbackUserData(userdata);
- }
- }
- void LLPanel::childSetColor(const char* id, const LLColor4& color)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setColor(color);
- }
- }
- void LLPanel::childSetAlpha(const char* id, F32 alpha)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setAlpha(alpha);
- }
- }
- void LLPanel::childSetValue(const char* id, LLSD value)
- {
- LLView* child = getChild<LLView>(id, true);
- if (child)
- {
- child->setValue(value);
- }
- }
- LLSD LLPanel::childGetValue(const char* id) const
- {
- LLView* child = getChild<LLView>(id, true);
- if (child)
- {
- return child->getValue();
- }
- // Not found => return undefined
- return LLSD();
- }
- bool LLPanel::childSetTextArg(const char* id, const std::string& key,
- const std::string& text)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- return child->setTextArg(key, text);
- }
- return false;
- }
- bool LLPanel::childSetLabelArg(const char* id, const std::string& key,
- const std::string& text)
- {
- LLView* child = getChild<LLView>(id);
- if (child)
- {
- return child->setLabelArg(key, text);
- }
- return false;
- }
- bool LLPanel::childSetToolTipArg(const char* id, const std::string& key,
- const std::string& text)
- {
- LLView* child = getChildView(id, true, false);
- if (child)
- {
- return child->setToolTipArg(key, text);
- }
- return false;
- }
- void LLPanel::childSetBadge(const char* id, Badge badge, bool visible)
- {
- LLIconCtrl* child = getChild<LLIconCtrl>(id);
- if (child)
- {
- child->setVisible(visible);
- switch (badge)
- {
- default:
- case BADGE_OK:
- child->setImage("badge_ok.j2c");
- break;
- case BADGE_NOTE:
- child->setImage("badge_note.j2c");
- break;
- case BADGE_WARN:
- child->setImage("badge_warn.j2c");
- break;
- case BADGE_ERROR:
- child->setImage("badge_error.j2c");
- }
- }
- }
- void LLPanel::childSetMinValue(const char* id, LLSD min_value)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setMinValue(min_value);
- }
- }
- void LLPanel::childSetMaxValue(const char* id, LLSD max_value)
- {
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setMaxValue(max_value);
- }
- }
- void LLPanel::childShowTab(const char* id, const std::string& tabname,
- bool visible)
- {
- LLTabContainer* child = getChild<LLTabContainer>(id);
- if (child)
- {
- child->selectTabByName(tabname);
- }
- }
- LLPanel *LLPanel::childGetVisibleTab(const char* id) const
- {
- LLTabContainer* child = getChild<LLTabContainer>(id);
- if (child)
- {
- return child->getCurrentPanel();
- }
- return NULL;
- }
- void LLPanel::childSetTabChangeCallback(const char* id,
- const std::string& tabname,
- void (*on_tab_clicked)(void*, bool),
- void *userdata,
- void (*on_precommit)(void*, bool))
- {
- LLTabContainer* child = getChild<LLTabContainer>(id);
- if (child)
- {
- LLPanel* panel = child->getPanelByName(tabname);
- if (panel)
- {
- child->setTabChangeCallback(panel, on_tab_clicked);
- child->setTabUserData(panel, userdata);
- if (on_precommit)
- {
- child->setTabPrecommitChangeCallback(panel, on_precommit);
- }
- }
- }
- }
- void LLPanel::childSetKeystrokeCallback(const char* id,
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data),
- void* user_data)
- {
- LLLineEditor* child = getChild<LLLineEditor>(id);
- if (child)
- {
- child->setKeystrokeCallback(keystroke_callback);
- if (user_data)
- {
- child->setCallbackUserData(user_data);
- }
- }
- }
- void LLPanel::childSetPrevalidate(const char* id,
- bool (*func)(const LLWString &))
- {
- LLLineEditor* child = getChild<LLLineEditor>(id);
- if (child)
- {
- child->setPrevalidate(func);
- }
- }
- void LLPanel::childSetWrappedText(const char* id,
- const std::string& text, bool visible)
- {
- LLTextBox* child = getChild<LLTextBox>(id);
- if (child)
- {
- child->setVisible(visible);
- child->setWrappedText(text);
- }
- }
- void LLPanel::childSetAction(const char* id, void(*function)(void*),
- void* value)
- {
- LLButton* button = getChild<LLButton>(id);
- if (button)
- {
- button->setClickedCallback(function, value);
- }
- }
- void LLPanel::childSetActionTextbox(const char* id,
- void(*function)(void*), void* value)
- {
- LLTextBox* textbox = getChild<LLTextBox>(id);
- if (textbox)
- {
- textbox->setClickedCallback(function, value);
- }
- }
- void LLPanel::childSetControlName(const char* id, const char* control_name)
- {
- LLView* view = getChild<LLView>(id);
- if (view)
- {
- view->setControlName(control_name, NULL);
- }
- }
- //virtual
- LLView* LLPanel::getChildView(const char* name, bool recurse,
- bool create_if_missing) const
- {
- // Just get child, do not try to create a dummy one
- LLView* view = LLUICtrl::getChildView(name, recurse, false);
- if (!view && !recurse)
- {
- childNotFound(name);
- }
- if (!view && create_if_missing)
- {
- view = createDummyWidget<LLView>(name);
- }
- return view;
- }
- void LLPanel::childNotFound(const char* id) const
- {
- if (mExpectedMembers.find(id) == mExpectedMembers.end())
- {
- mNewExpectedMembers.emplace(id);
- }
- }
- void LLPanel::childDisplayNotFound()
- {
- if (mNewExpectedMembers.empty())
- {
- return;
- }
- std::string msg;
- expected_members_list_t::iterator itor;
- for (itor = mNewExpectedMembers.begin(); itor != mNewExpectedMembers.end();
- ++itor)
- {
- msg.append(*itor);
- msg.append("\n");
- mExpectedMembers.emplace(*itor);
- }
- mNewExpectedMembers.clear();
- LLSD args;
- args["CONTROLS"] = msg;
- gNotifications.add("FloaterNotFound", args);
- }
- void LLPanel::storeRectControl()
- {
- if (!mRectControl.empty())
- {
- LLUI::sConfigGroup->setRect(mRectControl.c_str(), getRect());
- }
- }
- //
- // LLLayoutStack
- //
- struct LLLayoutStack::LLEmbeddedPanel
- {
- LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation,
- S32 min_width, S32 min_height,
- bool auto_resize, bool user_resize)
- : mPanel(panelp),
- mMinWidth(min_width),
- mMinHeight(min_height),
- mAutoResize(auto_resize),
- mUserResize(user_resize),
- mOrientation(orientation),
- mCollapsed(false),
- mCollapseAmt(0.f),
- mVisibleAmt(1.f) // default to fully visible
- {
- LLResizeBar::Side side;
- S32 min_dim;
- if (orientation == HORIZONTAL)
- {
- side = LLResizeBar::RIGHT;
- min_dim = mMinHeight;
- }
- else
- {
- side = LLResizeBar::BOTTOM;
- min_dim = mMinWidth;
- }
- mResizeBar = new LLResizeBar("resizer", mPanel, LLRect(), min_dim,
- S32_MAX, side);
- mResizeBar->setEnableSnapping(false);
- // Panels initialized as hidden should not start out partially visible
- if (!mPanel->getVisible())
- {
- mVisibleAmt = 0.f;
- }
- }
- ~LLEmbeddedPanel()
- {
- // Probably not necessary, but...
- delete mResizeBar;
- mResizeBar = NULL;
- }
- F32 getCollapseFactor()
- {
- F32 collapse_amt;
- if (mOrientation == HORIZONTAL)
- {
- collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f,
- (F32)mMinWidth /
- (F32)llmax(1, mPanel->getRect().getWidth()));
- }
- else
- {
- collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f,
- llmin(1.f, (F32)mMinHeight /
- (F32)llmax(1, mPanel->getRect().getHeight())));
- }
- return mVisibleAmt * collapse_amt;
- }
- LLPanel* mPanel;
- LLResizeBar* mResizeBar;
- S32 mMinWidth;
- S32 mMinHeight;
- F32 mVisibleAmt;
- F32 mCollapseAmt;
- eLayoutOrientation mOrientation;
- bool mAutoResize;
- bool mUserResize;
- bool mCollapsed;
- };
- static const std::string LL_LAYOUT_STACK_TAG = "layout_stack";
- static LLRegisterWidget<LLLayoutStack> r15(LL_LAYOUT_STACK_TAG);
- LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation)
- : mOrientation(orientation),
- mMinWidth(0),
- mMinHeight(0),
- mPanelSpacing(RESIZE_BAR_HEIGHT)
- {
- }
- //virtual
- LLLayoutStack::~LLLayoutStack()
- {
- std::for_each(mPanels.begin(), mPanels.end(), DeletePointer());
- mPanels.clear();
- }
- //virtual
- void LLLayoutStack::draw()
- {
- updateLayout();
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- LLPanel* panelp = (*it)->mPanel;
- if (!panelp) continue; // Paranoia
- // Clip to layout rectangle, not bounding rectangle
- LLRect clip_rect = panelp->getRect();
- // Scale clipping rectangle by visible amount
- if (mOrientation == HORIZONTAL)
- {
- clip_rect.mRight = clip_rect.mLeft +
- ll_roundp((F32)clip_rect.getWidth() *
- (*it)->getCollapseFactor());
- }
- else
- {
- clip_rect.mBottom = clip_rect.mTop -
- ll_roundp((F32)clip_rect.getHeight() *
- (*it)->getCollapseFactor());
- }
- LLLocalClipRect clip(clip_rect);
- // Only force drawing invisible children if visible amount is non-zero
- drawChild(panelp, 0, 0, !clip_rect.isEmpty());
- }
- }
- void LLLayoutStack::deleteAllChildren()
- {
- mPanels.clear();
- LLView::deleteAllChildren();
- mMinWidth = mMinHeight = 0;
- }
- void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
- {
- LLEmbeddedPanel* embeddedp = findEmbeddedPanel((LLPanel*)ctrl);
- if (embeddedp)
- {
- mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embeddedp));
- LLView::removeChild(ctrl);
- }
- else
- {
- LLView::removeCtrl(ctrl);
- }
- // Need to update resizebars
- calcMinExtents();
- }
- //virtual
- const std::string& LLLayoutStack::getTag() const
- {
- return LL_LAYOUT_STACK_TAG;
- }
- LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const
- {
- LLXMLNodePtr nodep = LLView::getXML();
- nodep->setName(LL_LAYOUT_STACK_TAG);
- if (mOrientation == HORIZONTAL)
- {
- nodep->createChild("orientation", true)->setStringValue("horizontal");
- }
- else
- {
- nodep->createChild("orientation", true)->setStringValue("vertical");
- }
- if (save_children)
- {
- for (child_list_const_reverse_iter_t rit = getChildList()->rbegin(),
- rend = getChildList()->rend();
- rit != rend; ++rit)
- {
- LLView* childp = *rit;
- if (childp->getSaveToXML())
- {
- LLXMLNodePtr xml_node = childp->getXML();
- if (xml_node->hasName(LL_PANEL_TAG))
- {
- xml_node->setName(LL_LAYOUT_PANEL_TAG);
- }
- nodep->addChild(xml_node);
- }
- }
- }
- return nodep;
- }
- //static
- LLView* LLLayoutStack::fromXML(LLXMLNodePtr nodep, LLView* parentp,
- LLUICtrlFactory* factoryp)
- {
- std::string orientation_string("vertical");
- nodep->getAttributeString("orientation", orientation_string);
- eLayoutOrientation orientation = VERTICAL;
- if (orientation_string == "horizontal")
- {
- orientation = HORIZONTAL;
- }
- else if (orientation_string == "vertical")
- {
- orientation = VERTICAL;
- }
- else
- {
- llwarns << "Unknown orientation " << orientation_string
- << ", using vertical" << llendl;
- }
- LLLayoutStack* layout_stackp = new LLLayoutStack(orientation);
- nodep->getAttributeS32("border_size", layout_stackp->mPanelSpacing);
- // don't allow negative spacing values
- layout_stackp->mPanelSpacing = llmax(layout_stackp->mPanelSpacing, 0);
- std::string name = "stack";
- nodep->getAttributeString("name", name);
- layout_stackp->setName(name);
- layout_stackp->initFromXML(nodep, parentp);
- LLXMLNodePtr childp;
- for (childp = nodep->getFirstChild(); childp.notNull();
- childp = childp->getNextSibling())
- {
- S32 min_width = 0;
- S32 min_height = 0;
- bool auto_resize = true;
- childp->getAttributeS32("min_width", min_width);
- childp->getAttributeS32("min_height", min_height);
- childp->getAttributeBool("auto_resize", auto_resize);
- if (childp->hasName(LL_LAYOUT_PANEL_TAG))
- {
- bool user_resize = true;
- childp->getAttributeBool("user_resize", user_resize);
- LLPanel* panelp = (LLPanel*)LLPanel::fromXML(childp, layout_stackp,
- factoryp);
- if (panelp)
- {
- panelp->setFollowsNone();
- layout_stackp->addPanel(panelp, min_width, min_height,
- auto_resize, user_resize);
- }
- }
- else
- {
- bool user_resize = false;
- childp->getAttributeBool("user_resize", user_resize);
- LLPanel* panelp = new LLPanel("auto_panel");
- LLView* new_childp = factoryp->createWidget(panelp, childp);
- if (new_childp)
- {
- // Put child in new embedded panel
- layout_stackp->addPanel(panelp, min_width, min_height,
- auto_resize, user_resize);
- // Resize panel to contain widget and move widget to be
- // contained in panel
- panelp->setRect(new_childp->getRect());
- new_childp->setOrigin(0, 0);
- }
- else
- {
- panelp->die();
- }
- }
- }
- layout_stackp->updateLayout();
- return layout_stackp;
- }
- S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
- {
- // If we are spanning our children (crude upward propagation of size) then
- // do not enforce our size on our children
- if (mOrientation == HORIZONTAL)
- {
- cur_height = llmax(mMinHeight, getRect().getHeight());
- }
- return cur_height;
- }
- S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
- {
- // If we are spanning our children (crude upward propagation of size) then
- // do not enforce our size on our children
- if (mOrientation == VERTICAL)
- {
- cur_width = llmax(mMinWidth, getRect().getWidth());
- }
- return cur_width;
- }
- void LLLayoutStack::addPanel(LLPanel* panelp, S32 min_width, S32 min_height,
- bool auto_resize, bool user_resize,
- EAnimate animate, S32 index)
- {
- // Panel starts off invisible (collapsed)
- if (animate == ANIMATE)
- {
- panelp->setVisible(false);
- }
- LLEmbeddedPanel* embeddedp = new LLEmbeddedPanel(panelp, mOrientation,
- min_width, min_height,
- auto_resize, user_resize);
- mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()),
- embeddedp);
- addChild(panelp);
- addChild(embeddedp->mResizeBar);
- // Bring all resize bars to the front so that they are clickable even over
- // the panels with a bit of overlap
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- LLResizeBar* resize_barp = (*it)->mResizeBar;
- sendChildToFront(resize_barp);
- }
- // Start expanding panel animation
- if (animate == ANIMATE)
- {
- panelp->setVisible(true);
- }
- }
- void LLLayoutStack::removePanel(LLPanel* panel)
- {
- removeChild(panel);
- }
- void LLLayoutStack::collapsePanel(LLPanel* panel, bool collapsed)
- {
- LLEmbeddedPanel* embeddedp = findEmbeddedPanel(panel);
- if (embeddedp)
- {
- embeddedp->mCollapsed = collapsed;
- }
- }
- void LLLayoutStack::updateLayout(bool force_resize)
- {
- calcMinExtents();
- // Calculate current extents
- S32 total_width = 0;
- S32 total_height = 0;
- constexpr F32 ANIM_OPEN_TIME = 0.02f;
- F32 open_interpolant = LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME);
- constexpr F32 ANIM_CLOSE_TIME = 0.03f;
- F32 close_interpolant = LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME);
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- LLPanel* panelp = (*it)->mPanel;
- if (!panelp) continue; // Paranoia
- F32& visible_amt = (*it)->mVisibleAmt;
- if (panelp->getVisible())
- {
- visible_amt = lerp(visible_amt, 1.f, open_interpolant);
- if (visible_amt > 0.99f)
- {
- visible_amt = 1.f;
- }
- }
- else // Not visible
- {
- visible_amt = lerp(visible_amt, 0.f, close_interpolant);
- if (visible_amt < 0.001f)
- {
- visible_amt = 0.f;
- }
- }
- F32& collapse_amt = (*it)->mCollapseAmt;
- if ((*it)->mCollapsed)
- {
- collapse_amt = lerp(collapse_amt, 1.f, close_interpolant);
- }
- else
- {
- collapse_amt = lerp(collapse_amt, 0.f, close_interpolant);
- }
- if (mOrientation == HORIZONTAL)
- {
- S32 min_width = (*it)->mMinWidth;
- // Enforce minimize size constraint by default
- if (panelp->getRect().getWidth() < min_width)
- {
- panelp->reshape(min_width, panelp->getRect().getHeight());
- }
- total_width += ll_roundp(panelp->getRect().getWidth() *
- (*it)->getCollapseFactor());
- // Want n-1 panel gaps for n panels
- if (it != mPanels.begin())
- {
- total_width += mPanelSpacing;
- }
- }
- else // VERTICAL
- {
- S32 min_height = (*it)->mMinHeight;
- // Enforce minimize size constraint by default
- if (panelp->getRect().getHeight() < min_height)
- {
- panelp->reshape(panelp->getRect().getWidth(),
- min_height);
- }
- total_height += ll_roundp(panelp->getRect().getHeight() *
- (*it)->getCollapseFactor());
- if (it != mPanels.begin())
- {
- total_height += mPanelSpacing;
- }
- }
- }
- S32 num_resizable_panels = 0;
- S32 shrink_headroom_available = 0;
- S32 shrink_headroom_total = 0;
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- // Panels that are not fully visible do not count towards shrink
- // headroom
- if ((*it)->getCollapseFactor() < 1.f)
- {
- continue;
- }
- LLPanel* panelp = (*it)->mPanel;
- if (!panelp) continue; // Paranoia
- S32 min_width = (*it)->mMinWidth;
- S32 min_height = (*it)->mMinHeight;
- // If currently resizing a panel or the panel is flagged as not
- // automatically resizing only track total available headroom, but do
- // not use it for automatic resize logic
- if ((*it)->mResizeBar->hasMouseCapture() ||
- (!(*it)->mAutoResize && !force_resize))
- {
- if (mOrientation == HORIZONTAL)
- {
- shrink_headroom_total += panelp->getRect().getWidth() -
- min_width;
- }
- else // VERTICAL
- {
- shrink_headroom_total += panelp->getRect().getHeight() -
- min_height;
- }
- }
- else
- {
- ++num_resizable_panels;
- if (mOrientation == HORIZONTAL)
- {
- shrink_headroom_available += panelp->getRect().getWidth() -
- min_width;
- shrink_headroom_total += panelp->getRect().getWidth() -
- min_width;
- }
- else // VERTICAL
- {
- shrink_headroom_available += panelp->getRect().getHeight() -
- min_height;
- shrink_headroom_total += panelp->getRect().getHeight() -
- min_height;
- }
- }
- }
- // Calculate how many pixels need to be distributed among layout panels
- // positive means panels need to grow, negative means shrink
- S32 pixels_to_distribute;
- if (mOrientation == HORIZONTAL)
- {
- pixels_to_distribute = getRect().getWidth() - total_width;
- }
- else // VERTICAL
- {
- pixels_to_distribute = getRect().getHeight() - total_height;
- }
- // Now we distribute the pixels...
- S32 cur_x = 0;
- S32 cur_y = getRect().getHeight();
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- LLPanel* panelp = (*it)->mPanel;
- if (!panelp) continue; // Paranoia
- S32 min_width = (*it)->mMinWidth;
- S32 min_height = (*it)->mMinHeight;
- S32 cur_width = panelp->getRect().getWidth();
- S32 cur_height = panelp->getRect().getHeight();
- S32 new_width = llmax(min_width, cur_width);
- S32 new_height = llmax(min_height, cur_height);
- S32 delta_size = 0;
- // If panel can automatically resize (not animating, and resize flag
- // set)...
- if ((*it)->getCollapseFactor() == 1.f &&
- (force_resize || (*it)->mAutoResize) &&
- !(*it)->mResizeBar->hasMouseCapture())
- {
- if (mOrientation == HORIZONTAL)
- {
- if (pixels_to_distribute < 0) // If we are shrinking
- {
- // Shrink proportionally to amount over minimum so we can
- // do this in one pass
- delta_size = 0;
- if (shrink_headroom_available > 0)
- {
- delta_size =
- ll_roundp((F32)pixels_to_distribute *
- ((F32)(cur_width - min_width) /
- (F32)shrink_headroom_available));
- }
- shrink_headroom_available -= cur_width - min_width;
- }
- else // Grow all elements equally
- {
- delta_size = ll_roundp((F32)pixels_to_distribute /
- (F32)num_resizable_panels);
- --num_resizable_panels;
- }
- pixels_to_distribute -= delta_size;
- new_width = llmax(min_width, cur_width + delta_size);
- }
- else
- {
- new_width = getDefaultWidth(new_width);
- }
- if (mOrientation == VERTICAL)
- {
- if (pixels_to_distribute < 0)
- {
- // Shrink proportionally to amount over minimum so we can
- // do this in one pass
- delta_size = shrink_headroom_available > 0 ?
- ll_roundp((F32)pixels_to_distribute *
- ((F32)(cur_height - min_height) /
- (F32)shrink_headroom_available))
- : 0;
- shrink_headroom_available -= cur_height - min_height;
- }
- else
- {
- delta_size = ll_roundp((F32)pixels_to_distribute /
- (F32)num_resizable_panels);
- num_resizable_panels--;
- }
- pixels_to_distribute -= delta_size;
- new_height = llmax(min_height, cur_height + delta_size);
- }
- else
- {
- new_height = getDefaultHeight(new_height);
- }
- }
- else
- {
- if (mOrientation == HORIZONTAL)
- {
- new_height = getDefaultHeight(new_height);
- }
- else // VERTICAL
- {
- new_width = getDefaultWidth(new_width);
- }
- }
- // Adjust running headroom count based on new sizes
- shrink_headroom_total += delta_size;
- panelp->reshape(new_width, new_height);
- panelp->setOrigin(cur_x, cur_y - new_height);
- LLRect panel_rect = panelp->getRect();
- LLRect resize_bar_rect = panel_rect;
- if (mOrientation == HORIZONTAL)
- {
- resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP;
- resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing +
- RESIZE_BAR_OVERLAP;
- }
- else
- {
- resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP;
- resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing -
- RESIZE_BAR_OVERLAP;
- }
- (*it)->mResizeBar->setRect(resize_bar_rect);
- if (mOrientation == HORIZONTAL)
- {
- cur_x += ll_roundp(new_width * (*it)->getCollapseFactor()) +
- mPanelSpacing;
- }
- else // VERTICAL
- {
- cur_y -= ll_roundp(new_height * (*it)->getCollapseFactor()) +
- mPanelSpacing;
- }
- }
- // Update resize bars with new limits
- LLResizeBar* last_resize_bar = NULL;
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- LLPanel* panelp = (*it)->mPanel;
- if (!panelp) continue; // Paranoia
- if (mOrientation == HORIZONTAL)
- {
- S32 min_width = (*it)->mMinWidth;
- (*it)->mResizeBar->setResizeLimits(min_width,
- min_width +
- shrink_headroom_total);
- }
- else // VERTICAL
- {
- S32 min_height = (*it)->mMinHeight;
- (*it)->mResizeBar->setResizeLimits(min_height,
- min_height +
- shrink_headroom_total);
- }
- // Toggle resize bars based on panel visibility, resizability, etc
- bool resize_bar_enabled = panelp->getVisible() && (*it)->mUserResize;
- (*it)->mResizeBar->setVisible(resize_bar_enabled);
- if (resize_bar_enabled)
- {
- last_resize_bar = (*it)->mResizeBar;
- }
- }
- // Hide last resize bar as there is nothing past it; resize bars need to be
- // in between two resizable panels.
- if (last_resize_bar)
- {
- last_resize_bar->setVisible(false);
- }
- // Not enough room to fit existing contents
- if (!force_resize &&
- // layout did not complete by reaching target position
- ((mOrientation == VERTICAL && cur_y != -mPanelSpacing) ||
- (mOrientation == HORIZONTAL &&
- cur_x != getRect().getWidth() + mPanelSpacing)))
- {
- // Do another layout pass with all stacked elements contributing even
- // those that do not usually resize
- updateLayout(true);
- }
- }
- LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
- {
- if (!panelp) return NULL;
- for (e_panel_list_t::const_iterator it = mPanels.begin(),
- end = mPanels.end();
- it != end; ++it)
- {
- if ((*it)->mPanel == panelp)
- {
- return *it;
- }
- }
- return NULL;
- }
- void LLLayoutStack::calcMinExtents()
- {
- mMinWidth = mMinHeight = 0;
- for (e_panel_list_t::iterator it = mPanels.begin(), end = mPanels.end();
- it != end; ++it)
- {
- if (mOrientation == HORIZONTAL)
- {
- mMinHeight = llmax(mMinHeight, (*it)->mMinHeight);
- mMinWidth += (*it)->mMinWidth;
- if (it != mPanels.begin())
- {
- mMinWidth += mPanelSpacing;
- }
- }
- else // VERTICAL
- {
- mMinWidth = llmax(mMinWidth, (*it)->mMinWidth);
- mMinHeight += (*it)->mMinHeight;
- if (it != mPanels.begin())
- {
- mMinHeight += mPanelSpacing;
- }
- }
- }
- }
|