00001
00032
00033
00034 #include "linden_common.h"
00035
00036 #include "llpanel.h"
00037
00038 #include "llalertdialog.h"
00039 #include "llfocusmgr.h"
00040 #include "llfontgl.h"
00041 #include "llrect.h"
00042 #include "llerror.h"
00043 #include "lltimer.h"
00044
00045 #include "llmenugl.h"
00046
00047 #include "llui.h"
00048 #include "llkeyboard.h"
00049 #include "lllineeditor.h"
00050 #include "llcontrol.h"
00051 #include "lltextbox.h"
00052 #include "lluictrl.h"
00053 #include "lluictrlfactory.h"
00054 #include "llviewborder.h"
00055 #include "llbutton.h"
00056
00057
00058 #include "llgl.h"
00059 #include "llglheaders.h"
00060 #include "llresizebar.h"
00061 #include "llcriticaldamp.h"
00062
00063 LLPanel::panel_map_t LLPanel::sPanelMap;
00064 LLPanel::alert_queue_t LLPanel::sAlertQueue;
00065
00066 const S32 RESIZE_BAR_OVERLAP = 1;
00067 const S32 PANEL_STACK_GAP = RESIZE_BAR_HEIGHT;
00068
00069 void LLPanel::init()
00070 {
00071
00072 mBgColorAlpha = LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" );
00073 mBgColorOpaque = LLUI::sColorsGroup->getColor( "FocusBackgroundColor" );
00074 mDefaultBtnHighlight = LLUI::sColorsGroup->getColor( "DefaultHighlightLight" );
00075 mBgVisible = FALSE;
00076 mBgOpaque = FALSE;
00077 mBorder = NULL;
00078 mDefaultBtn = NULL;
00079 setIsChrome(FALSE);
00080 mLastTabGroup = 0;
00081
00082
00083 sPanelMap[mViewHandle] = this;
00084 setTabStop(FALSE);
00085 }
00086
00087 LLPanel::LLPanel()
00088 : mRectControl()
00089 {
00090 init();
00091 }
00092
00093 LLPanel::LLPanel(const LLString& name)
00094 : LLUICtrl(name, LLRect(0, 0, 0, 0), TRUE, NULL, NULL),
00095 mRectControl()
00096 {
00097 init();
00098 }
00099
00100
00101 LLPanel::LLPanel(const LLString& name, const LLRect& rect, BOOL bordered)
00102 : LLUICtrl(name, rect, TRUE, NULL, NULL),
00103 mRectControl()
00104 {
00105 init();
00106 if (bordered)
00107 {
00108 addBorder();
00109 }
00110 }
00111
00112
00113 LLPanel::LLPanel(const LLString& name, const LLString& rect_control, BOOL bordered)
00114 : LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control), TRUE, NULL, NULL),
00115 mRectControl( rect_control )
00116 {
00117 init();
00118 if (bordered)
00119 {
00120 addBorder();
00121 }
00122 }
00123
00124 void LLPanel::addBorder(LLViewBorder::EBevel border_bevel,
00125 LLViewBorder::EStyle border_style, S32 border_thickness)
00126 {
00127 mBorder = new LLViewBorder( "panel border",
00128 LLRect(0, mRect.getHeight(), mRect.getWidth(), 0),
00129 border_bevel, border_style, border_thickness );
00130 mBorder->setSaveToXML(false);
00131 addChild( mBorder );
00132 }
00133
00134 void LLPanel::removeBorder()
00135 {
00136 delete mBorder;
00137 mBorder = NULL;
00138 }
00139
00140
00141 LLPanel::~LLPanel()
00142 {
00143 storeRectControl();
00144 sPanelMap.erase(mViewHandle);
00145 }
00146
00147
00148
00149 EWidgetType LLPanel::getWidgetType() const
00150 {
00151 return WIDGET_TYPE_PANEL;
00152 }
00153
00154
00155 LLString LLPanel::getWidgetTag() const
00156 {
00157 return LL_PANEL_TAG;
00158 }
00159
00160
00161 BOOL LLPanel::isPanel()
00162 {
00163 return TRUE;
00164 }
00165
00166
00167 BOOL LLPanel::postBuild()
00168 {
00169 return TRUE;
00170 }
00171
00172
00173 void LLPanel::clearCtrls()
00174 {
00175 LLView::ctrl_list_t ctrls = getCtrlList();
00176 for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it)
00177 {
00178 LLUICtrl* ctrl = *ctrl_it;
00179 ctrl->setFocus( FALSE );
00180 ctrl->setEnabled( FALSE );
00181 ctrl->clear();
00182 }
00183 }
00184
00185 void LLPanel::setCtrlsEnabled( BOOL b )
00186 {
00187 LLView::ctrl_list_t ctrls = getCtrlList();
00188 for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it)
00189 {
00190 LLUICtrl* ctrl = *ctrl_it;
00191 ctrl->setEnabled( b );
00192 }
00193 }
00194
00195 void LLPanel::draw()
00196 {
00197
00198 if( mBgVisible )
00199 {
00200
00201 S32 left = 0;
00202 S32 top = mRect.getHeight();
00203 S32 right = mRect.getWidth();
00204 S32 bottom = 0;
00205
00206 if (mBgOpaque )
00207 {
00208 gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
00209 }
00210 else
00211 {
00212 gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
00213 }
00214 }
00215
00216 if( mDefaultBtn)
00217 {
00218 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
00219 {
00220 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
00221 BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn();
00222
00223 mDefaultBtn->setBorderEnabled(!focus_is_child_button);
00224 }
00225 else
00226 {
00227 mDefaultBtn->setBorderEnabled(FALSE);
00228 }
00229 }
00230
00231 LLView::draw();
00232 }
00233
00234 void LLPanel::refresh()
00235 {
00236
00237
00238 }
00239
00240 void LLPanel::setDefaultBtn(LLButton* btn)
00241 {
00242 if (mDefaultBtn && mDefaultBtn->getEnabled())
00243 {
00244 mDefaultBtn->setBorderEnabled(FALSE);
00245 }
00246 mDefaultBtn = btn;
00247 if (mDefaultBtn)
00248 {
00249 mDefaultBtn->setBorderEnabled(TRUE);
00250 }
00251 }
00252
00253 void LLPanel::setDefaultBtn(const LLString& id)
00254 {
00255 LLButton *button = LLUICtrlFactory::getButtonByName(this, id);
00256 if (button)
00257 {
00258 setDefaultBtn(button);
00259 }
00260 else
00261 {
00262 setDefaultBtn(NULL);
00263 }
00264 }
00265
00266 BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent)
00267 {
00268 BOOL handled = FALSE;
00269 if (getVisible() && getEnabled())
00270 {
00271 if( (mask == MASK_SHIFT) && (KEY_TAB == key))
00272 {
00273
00274 LLView* cur_focus = gFocusMgr.getKeyboardFocus();
00275 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
00276 {
00277 LLView* focus_root = cur_focus;
00278 while(cur_focus->getParent())
00279 {
00280 cur_focus = cur_focus->getParent();
00281 if (cur_focus->isFocusRoot())
00282 {
00283
00284 focus_root = cur_focus;
00285 }
00286 }
00287 handled = focus_root->focusPrevItem(FALSE);
00288 }
00289 else if (!cur_focus && mIsFocusRoot)
00290 {
00291 handled = focusLastItem();
00292 if (!handled)
00293 {
00294 setFocus(TRUE);
00295 handled = TRUE;
00296 }
00297 }
00298 }
00299 else
00300 if( (mask == MASK_NONE ) && (KEY_TAB == key))
00301 {
00302
00303 LLView* cur_focus = gFocusMgr.getKeyboardFocus();
00304 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
00305 {
00306 LLView* focus_root = cur_focus;
00307 while(cur_focus->getParent())
00308 {
00309 cur_focus = cur_focus->getParent();
00310 if (cur_focus->isFocusRoot())
00311 {
00312 focus_root = cur_focus;
00313 }
00314 }
00315 handled = focus_root->focusNextItem(FALSE);
00316 }
00317 else if (!cur_focus && mIsFocusRoot)
00318 {
00319 handled = focusFirstItem();
00320 if (!handled)
00321 {
00322 setFocus(TRUE);
00323 handled = TRUE;
00324 }
00325 }
00326 }
00327 }
00328
00329 if (!handled)
00330 {
00331 handled = LLView::handleKey(key, mask, called_from_parent);
00332 }
00333
00334 return handled;
00335 }
00336
00337 void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
00338 {
00339 mLastTabGroup = tab_group;
00340
00341 LLView::addCtrl(ctrl, tab_group);
00342
00343 if (!ctrl->getIsChrome())
00344 {
00345 ctrl->setIsChrome(getIsChrome());
00346 }
00347 }
00348
00349 void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
00350 {
00351 mLastTabGroup = tab_group;
00352
00353 LLView::addCtrlAtEnd(ctrl, tab_group);
00354 if (!ctrl->getIsChrome())
00355 {
00356 ctrl->setIsChrome(getIsChrome());
00357 }
00358 }
00359
00360 BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
00361 {
00362 BOOL handled = FALSE;
00363
00364 if( getVisible() && getEnabled() && gFocusMgr.childHasKeyboardFocus(this) && KEY_ESCAPE == key )
00365 {
00366 gFocusMgr.setKeyboardFocus(NULL, NULL);
00367 return TRUE;
00368 }
00369
00370 if( getVisible() && getEnabled() &&
00371 gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent )
00372 {
00373 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
00374
00375
00376
00377 if (cur_focus && !(cur_focus->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(cur_focus)->getCommitOnReturn()))
00378 {
00379
00380 if (key == KEY_RETURN && mask == MASK_NONE
00381 && mDefaultBtn != NULL
00382 && mDefaultBtn->getVisible()
00383 && mDefaultBtn->getEnabled())
00384 {
00385 mDefaultBtn->onCommit();
00386 handled = TRUE;
00387 }
00388 }
00389
00390 if (key == KEY_RETURN && mask == MASK_NONE)
00391 {
00392
00393 if (cur_focus && cur_focus->acceptsTextInput())
00394 {
00395 cur_focus->onCommit();
00396 handled = TRUE;
00397 }
00398 }
00399 }
00400
00401 return handled;
00402 }
00403
00404 void LLPanel::requires(LLString name, EWidgetType type)
00405 {
00406 mRequirements[name] = type;
00407 }
00408
00409 BOOL LLPanel::checkRequirements()
00410 {
00411 BOOL retval = TRUE;
00412 LLString message;
00413
00414 for (requirements_map_t::iterator i = mRequirements.begin(); i != mRequirements.end(); ++i)
00415 {
00416 if (!this->getCtrlByNameAndType(i->first, i->second))
00417 {
00418 retval = FALSE;
00419 message += i->first + " " + LLUICtrlFactory::getWidgetType(i->second) + "\n";
00420 }
00421 }
00422
00423 if (!retval)
00424 {
00425 LLString::format_map_t args;
00426 args["[COMPONENTS]"] = message;
00427 args["[FLOATER]"] = getName();
00428
00429 llwarns << getName() << " failed requirements check on: \n"
00430 << message << llendl;
00431
00432 alertXml("FailedRequirementsCheck", args);
00433 }
00434
00435 return retval;
00436 }
00437
00438
00439 void LLPanel::alertXml(LLString label, LLString::format_map_t args)
00440 {
00441 sAlertQueue.push(LLAlertInfo(label,args));
00442 }
00443
00444
00445 BOOL LLPanel::nextAlert(LLAlertInfo &alert)
00446 {
00447 if (!sAlertQueue.empty())
00448 {
00449 alert = sAlertQueue.front();
00450 sAlertQueue.pop();
00451 return TRUE;
00452 }
00453
00454 return FALSE;
00455 }
00456
00457 void LLPanel::setFocus(BOOL b)
00458 {
00459 if( b )
00460 {
00461 if (!gFocusMgr.childHasKeyboardFocus(this))
00462 {
00463
00464 if (!focusFirstItem())
00465 {
00466 LLUICtrl::setFocus(TRUE);
00467 }
00468 onFocusReceived();
00469 }
00470 }
00471 else
00472 {
00473 if( this == gFocusMgr.getKeyboardFocus() )
00474 {
00475 gFocusMgr.setKeyboardFocus( NULL, NULL );
00476 }
00477 else
00478 {
00479
00480 LLView::ctrl_list_t ctrls = getCtrlList();
00481 for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it)
00482 {
00483 LLUICtrl* ctrl = *ctrl_it;
00484 ctrl->setFocus( FALSE );
00485 }
00486 }
00487 }
00488 }
00489
00490 void LLPanel::setBackgroundColor(const LLColor4& color)
00491 {
00492 mBgColorOpaque = color;
00493 }
00494
00495 LLColor4 LLPanel::getBackgroundColor()
00496 {
00497 return mBgColorOpaque;
00498 }
00499
00500 void LLPanel::setTransparentColor(const LLColor4& color)
00501 {
00502 mBgColorAlpha = color;
00503 }
00504
00505 void LLPanel::setBorderVisible(BOOL b)
00506 {
00507 if (mBorder)
00508 {
00509 mBorder->setVisible( b );
00510 }
00511 }
00512
00513 LLView* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type)
00514 {
00515 LLView* view = getChildByName(name, TRUE);
00516 if (view)
00517 {
00518 if (type == WIDGET_TYPE_DONTCARE || view->getWidgetType() == type)
00519 {
00520 return view;
00521 }
00522 else
00523 {
00524 llwarns << "Widget " << name << " has improper type in panel " << mName << "\n"
00525 << "Is: \t\t" << view->getWidgetType() << "\n"
00526 << "Should be: \t" << type
00527 << llendl;
00528 }
00529 }
00530 else
00531 {
00532 childNotFound(name);
00533 }
00534 return NULL;
00535 }
00536
00537
00538 LLPanel* LLPanel::getPanelByHandle(LLViewHandle handle)
00539 {
00540 if (!sPanelMap.count(handle))
00541 {
00542 return NULL;
00543 }
00544
00545 return sPanelMap[handle];
00546 }
00547
00548
00549 LLXMLNodePtr LLPanel::getXML(bool save_children) const
00550 {
00551 LLXMLNodePtr node = LLView::getXML();
00552
00553 if (mBorder && mBorder->getVisible())
00554 {
00555 node->createChild("border", TRUE)->setBoolValue(TRUE);
00556 }
00557
00558 if (!mRectControl.empty())
00559 {
00560 node->createChild("rect_control", TRUE)->setStringValue(mRectControl);
00561 }
00562
00563 if (!mLabel.empty())
00564 {
00565 node->createChild("label", TRUE)->setStringValue(mLabel);
00566 }
00567
00568 if (save_children)
00569 {
00570 LLView::child_list_const_reverse_iter_t rit;
00571 for (rit = getChildList()->rbegin(); rit != getChildList()->rend(); ++rit)
00572 {
00573 LLView* childp = *rit;
00574
00575 if (childp->getSaveToXML())
00576 {
00577 LLXMLNodePtr xml_node = childp->getXML();
00578
00579 node->addChild(xml_node);
00580 }
00581 }
00582 }
00583
00584 return node;
00585 }
00586
00587 LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *factory)
00588 {
00589 LLString name("panel");
00590 node->getAttributeString("name", name);
00591
00592 LLPanel* panelp = factory->createFactoryPanel(name);
00593
00594 if (!panelp)
00595 {
00596 LLRect rect;
00597 createRect(node, rect, parent, LLRect());
00598 panelp = new LLPanel(name, rect);
00599 panelp->initPanelXML(node, parent, factory);
00600
00601 const LLRect& panelrect = panelp->getRect();
00602 S32 w = panelrect.getWidth();
00603 S32 h = panelrect.getHeight();
00604 rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
00605 panelp->setRect(rect);
00606 }
00607 else
00608 {
00609 panelp->initPanelXML(node, parent, factory);
00610 }
00611 return panelp;
00612 }
00613
00614 BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
00615 {
00616 LLString name("panel");
00617 node->getAttributeString("name", name);
00618 setName(name);
00619
00620 setPanelParameters(node, parent);
00621
00622 initChildrenXML(node, factory);
00623
00624 LLString xml_filename;
00625 node->getAttributeString("filename", xml_filename);
00626
00627 BOOL didPost;
00628
00629 if (!xml_filename.empty())
00630 {
00631
00632 LLRect rect(getRect());
00633 didPost = factory->buildPanel(this, xml_filename, NULL);
00634 S32 w = getRect().getWidth();
00635 S32 h = getRect().getHeight();
00636 rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
00637 setRect(rect);
00638 }
00639 else
00640 {
00641 didPost = FALSE;
00642 }
00643
00644 if (!didPost)
00645 {
00646 postBuild();
00647 didPost = TRUE;
00648 }
00649
00650 return didPost;
00651 }
00652
00653 void LLPanel::initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory)
00654 {
00655 LLXMLNodePtr child;
00656 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
00657 {
00658
00659 if (child->hasName("string"))
00660 {
00661 LLString string_name;
00662 child->getAttributeString("name", string_name);
00663 if (!string_name.empty())
00664 {
00665 mUIStrings[string_name] = LLUIString(child->getTextContents());
00666 }
00667 }
00668 else
00669 {
00670 factory->createWidget(this, child);
00671 }
00672 }
00673 }
00674
00675 void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent)
00676 {
00678 initFromXML(node, parent);
00679
00681 BOOL border = FALSE;
00682 node->getAttributeBOOL("border", border);
00683 if (border)
00684 {
00685 LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_OUT;
00686 LLViewBorder::getBevelFromAttribute(node, bevel_style);
00687
00688 LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE;
00689 LLString border_string;
00690 node->getAttributeString("border_style", border_string);
00691 LLString::toLower(border_string);
00692
00693 if (border_string == "texture")
00694 {
00695 border_style = LLViewBorder::STYLE_TEXTURE;
00696 }
00697
00698 S32 border_thickness = LLPANEL_BORDER_WIDTH;
00699 node->getAttributeS32("border_thickness", border_thickness);
00700
00701 addBorder(bevel_style, border_style, border_thickness);
00702 }
00703 else
00704 {
00705 removeBorder();
00706 }
00707
00709 BOOL background_visible = FALSE;
00710 node->getAttributeBOOL("background_visible", background_visible);
00711 setBackgroundVisible(background_visible);
00712
00713 BOOL background_opaque = FALSE;
00714 node->getAttributeBOOL("background_opaque", background_opaque);
00715 setBackgroundOpaque(background_opaque);
00716
00717 LLColor4 color;
00718 color = LLUI::sColorsGroup->getColor( "FocusBackgroundColor" );
00719 LLUICtrlFactory::getAttributeColor(node,"bg_opaque_color", color);
00720 setBackgroundColor(color);
00721
00722 color = LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" );
00723 LLUICtrlFactory::getAttributeColor(node,"bg_alpha_color", color);
00724 setTransparentColor(color);
00725
00726 LLString label;
00727 node->getAttributeString("label", label);
00728 setLabel(label);
00729 }
00730
00731 LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::format_map_t& args) const
00732 {
00733 ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
00734 if (found_it != mUIStrings.end())
00735 {
00736
00737 LLUIString formatted_string = found_it->second;
00738 formatted_string.setArgList(args);
00739 return formatted_string.getString();
00740 }
00741 return LLString::null;
00742 }
00743
00744 LLUIString LLPanel::getUIString(const LLString& name) const
00745 {
00746 ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
00747 if (found_it != mUIStrings.end())
00748 {
00749 return found_it->second;
00750 }
00751 return LLUIString(LLString::null);
00752 }
00753
00754
00755 void LLPanel::childSetVisible(const LLString& id, bool visible)
00756 {
00757 LLView* child = getChildByName(id, true);
00758 if (child)
00759 {
00760 child->setVisible(visible);
00761 }
00762 }
00763
00764 bool LLPanel::childIsVisible(const LLString& id) const
00765 {
00766 LLView* child = getChildByName(id, true);
00767 if (child)
00768 {
00769 return (bool)child->getVisible();
00770 }
00771 return false;
00772 }
00773
00774 void LLPanel::childSetEnabled(const LLString& id, bool enabled)
00775 {
00776 LLView* child = getChildByName(id, true);
00777 if (child)
00778 {
00779 child->setEnabled(enabled);
00780 }
00781 }
00782
00783 void LLPanel::childSetTentative(const LLString& id, bool tentative)
00784 {
00785 LLView* child = getChildByName(id, true);
00786 if (child)
00787 {
00788 child->setTentative(tentative);
00789 }
00790 }
00791
00792 bool LLPanel::childIsEnabled(const LLString& id) const
00793 {
00794 LLView* child = getChildByName(id, true);
00795 if (child)
00796 {
00797 return (bool)child->getEnabled();
00798 }
00799 return false;
00800 }
00801
00802
00803 void LLPanel::childSetToolTip(const LLString& id, const LLString& msg)
00804 {
00805 LLView* child = getChildByName(id, true);
00806 if (child)
00807 {
00808 child->setToolTip(msg);
00809 }
00810 }
00811
00812 void LLPanel::childSetRect(const LLString& id, const LLRect& rect)
00813 {
00814 LLView* child = getChildByName(id, true);
00815 if (child)
00816 {
00817 child->setRect(rect);
00818 }
00819 }
00820
00821 bool LLPanel::childGetRect(const LLString& id, LLRect& rect) const
00822 {
00823 LLView* child = getChildByName(id, true);
00824 if (child)
00825 {
00826 rect = child->getRect();
00827 return true;
00828 }
00829 return false;
00830 }
00831
00832 void LLPanel::childSetFocus(const LLString& id, BOOL focus)
00833 {
00834 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00835 if (child)
00836 {
00837 child->setFocus(focus);
00838 }
00839 }
00840
00841 BOOL LLPanel::childHasFocus(const LLString& id)
00842 {
00843 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00844 if (child)
00845 {
00846 return child->hasFocus();
00847 }
00848 else
00849 {
00850 childNotFound(id);
00851 return FALSE;
00852 }
00853 }
00854
00855
00856 void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLUICtrl*, void*))
00857 {
00858 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00859 if (child)
00860 {
00861 child->setFocusChangedCallback(cb);
00862 }
00863 }
00864
00865 void LLPanel::childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, void*), void *userdata )
00866 {
00867 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00868 if (child)
00869 {
00870 child->setCommitCallback(cb);
00871 child->setCallbackUserData(userdata);
00872 }
00873 }
00874
00875 void LLPanel::childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void *userdata )
00876 {
00877 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00878 if (child)
00879 {
00880 child->setDoubleClickCallback(cb);
00881 if (userdata)
00882 {
00883 child->setCallbackUserData(userdata);
00884 }
00885 }
00886 }
00887
00888 void LLPanel::childSetValidate(const LLString& id, BOOL (*cb)(LLUICtrl*, void*))
00889 {
00890 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00891 if (child)
00892 {
00893 child->setValidateBeforeCommit(cb);
00894 }
00895 }
00896
00897 void LLPanel::childSetUserData(const LLString& id, void* userdata)
00898 {
00899 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00900 if (child)
00901 {
00902 child->setCallbackUserData(userdata);
00903 }
00904 }
00905
00906 void LLPanel::childSetColor(const LLString& id, const LLColor4& color)
00907 {
00908 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00909 if (child)
00910 {
00911 child->setColor(color);
00912 }
00913 }
00914
00915 LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id)
00916 {
00917 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00918 if (child)
00919 {
00920 return child->getSelectionInterface();
00921 }
00922 return NULL;
00923 }
00924
00925 LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id)
00926 {
00927 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00928 if (child)
00929 {
00930 return child->getListInterface();
00931 }
00932 return NULL;
00933 }
00934
00935 LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id)
00936 {
00937 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00938 if (child)
00939 {
00940 return child->getScrollInterface();
00941 }
00942 return NULL;
00943 }
00944
00945 void LLPanel::childSetValue(const LLString& id, LLSD value)
00946 {
00947 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00948 if (child)
00949 {
00950 child->setValue(value);
00951 }
00952 }
00953
00954 LLSD LLPanel::childGetValue(const LLString& id) const
00955 {
00956 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00957 if (child)
00958 {
00959 return child->getValue();
00960 }
00961
00962 return LLSD();
00963 }
00964
00965 BOOL LLPanel::childSetTextArg(const LLString& id, const LLString& key, const LLStringExplicit& text)
00966 {
00967 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00968 if (child)
00969 {
00970 return child->setTextArg(key, text);
00971 }
00972 return FALSE;
00973 }
00974
00975 BOOL LLPanel::childSetLabelArg(const LLString& id, const LLString& key, const LLStringExplicit& text)
00976 {
00977 LLView* child = getChildByName(id, true);
00978 if (child)
00979 {
00980 return child->setLabelArg(key, text);
00981 }
00982 return FALSE;
00983 }
00984
00985 void LLPanel::childSetMinValue(const LLString& id, LLSD min_value)
00986 {
00987 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00988 if (child)
00989 {
00990 child->setMinValue(min_value);
00991 }
00992 }
00993
00994 void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value)
00995 {
00996 LLUICtrl* child = (LLUICtrl*)getChildByName(id, true);
00997 if (child)
00998 {
00999 child->setMaxValue(max_value);
01000 }
01001 }
01002
01003 void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible)
01004 {
01005 LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id);
01006 if (child)
01007 {
01008 child->selectTabByName(tabname);
01009 }
01010 }
01011
01012 LLPanel *LLPanel::childGetVisibleTab(const LLString& id)
01013 {
01014 LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id);
01015 if (child)
01016 {
01017 return child->getCurrentPanel();
01018 }
01019 return NULL;
01020 }
01021
01022 void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata)
01023 {
01024 LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id);
01025 if (child)
01026 {
01027 LLPanel *panel = child->getPanelByName(tabname);
01028 if (panel)
01029 {
01030 child->setTabChangeCallback(panel, on_tab_clicked);
01031 child->setTabUserData(panel, userdata);
01032 }
01033 }
01034 }
01035
01036 void LLPanel::childSetText(const LLString& id, const LLStringExplicit& text)
01037 {
01038 childSetValue(id, LLSD(text));
01039 }
01040
01041 void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data)
01042 {
01043 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id);
01044 if (child)
01045 {
01046 child->setKeystrokeCallback(keystroke_callback);
01047 if (user_data)
01048 {
01049 child->setCallbackUserData(user_data);
01050 }
01051 }
01052 }
01053
01054 void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) )
01055 {
01056 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id);
01057 if (child)
01058 {
01059 child->setPrevalidate(func);
01060 }
01061 }
01062
01063 LLString LLPanel::childGetText(const LLString& id)
01064 {
01065 return childGetValue(id).asString();
01066 }
01067
01068 void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible)
01069 {
01070 LLTextBox* child = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX);
01071 if (child)
01072 {
01073 child->setVisible(visible);
01074 child->setWrappedText(text);
01075 }
01076 }
01077
01078 void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value)
01079 {
01080 LLButton* button = (LLButton*)getCtrlByNameAndType(id, WIDGET_TYPE_BUTTON);
01081 if (button)
01082 {
01083 button->setClickedCallback(function, value);
01084 }
01085 }
01086
01087 void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*))
01088 {
01089 LLTextBox* textbox = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX);
01090 if (textbox)
01091 {
01092 textbox->setClickedCallback(function);
01093 }
01094 }
01095
01096 void LLPanel::childSetControlName(const LLString& id, const LLString& control_name)
01097 {
01098 LLView* view = getChildByName(id, TRUE);
01099 if (view)
01100 {
01101 view->setControlName(control_name, NULL);
01102 }
01103 }
01104
01105
01106 LLView* LLPanel::getChildByName(const LLString& name, BOOL recurse) const
01107 {
01108 LLView* view = LLUICtrl::getChildByName(name, recurse);
01109 if (!view && !recurse)
01110 {
01111 childNotFound(name);
01112 }
01113 return view;
01114 }
01115
01116 void LLPanel::childNotFound(const LLString& id) const
01117 {
01118 if (mExpectedMembers.find(id) == mExpectedMembers.end())
01119 {
01120 mNewExpectedMembers.insert(id);
01121 }
01122 }
01123
01124 void LLPanel::childDisplayNotFound()
01125 {
01126 if (mNewExpectedMembers.empty())
01127 {
01128 return;
01129 }
01130 LLString msg;
01131 expected_members_list_t::iterator itor;
01132 for (itor=mNewExpectedMembers.begin(); itor!=mNewExpectedMembers.end(); ++itor)
01133 {
01134 msg.append(*itor);
01135 msg.append("\n");
01136 mExpectedMembers.insert(*itor);
01137 }
01138 mNewExpectedMembers.clear();
01139 LLString::format_map_t args;
01140 args["[CONTROLS]"] = msg;
01141 LLAlertDialog::showXml("FloaterNotFound", args);
01142 }
01143
01144 void LLPanel::storeRectControl()
01145 {
01146 if( !mRectControl.empty() )
01147 {
01148 LLUI::sConfigGroup->setRect( mRectControl, mRect );
01149 }
01150 }
01151
01152
01153
01154
01155
01156 struct LLLayoutStack::LLEmbeddedPanel
01157 {
01158 LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize) :
01159 mPanel(panelp),
01160 mMinWidth(min_width),
01161 mMinHeight(min_height),
01162 mAutoResize(auto_resize),
01163 mOrientation(orientation),
01164 mVisibleAmt(1.f)
01165 {
01166 LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
01167 LLRect resize_bar_rect = panelp->getRect();
01168
01169 S32 min_dim;
01170 if (orientation == HORIZONTAL)
01171 {
01172 min_dim = mMinHeight;
01173 }
01174 else
01175 {
01176 min_dim = mMinWidth;
01177 }
01178 mResizeBar = new LLResizeBar("resizer", mPanel, LLRect(), min_dim, S32_MAX, side);
01179 mResizeBar->setEnableSnapping(FALSE);
01180
01181 if (!mPanel->getVisible())
01182 {
01183 mVisibleAmt = 0.f;
01184 }
01185 }
01186
01187 LLPanel* mPanel;
01188 S32 mMinWidth;
01189 S32 mMinHeight;
01190 BOOL mAutoResize;
01191 LLResizeBar* mResizeBar;
01192 eLayoutOrientation mOrientation;
01193 F32 mVisibleAmt;
01194 };
01195
01196 LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
01197 mOrientation(orientation),
01198 mMinWidth(0),
01199 mMinHeight(0)
01200 {
01201 }
01202
01203 LLLayoutStack::~LLLayoutStack()
01204 {
01205 }
01206
01207 void LLLayoutStack::draw()
01208 {
01209 updateLayout();
01210 {
01211
01212 LLLocalClipRect clip(getLocalRect(), mRect.getWidth() > mMinWidth || mRect.getHeight() > mMinHeight);
01213 e_panel_list_t::iterator panel_it;
01214 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01215 {
01216 LLRect clip_rect = (*panel_it)->mPanel->getRect();
01217
01218 if (mOrientation == HORIZONTAL)
01219 {
01220 clip_rect.mRight = clip_rect.mLeft + llround(clip_rect.getWidth() * (*panel_it)->mVisibleAmt);
01221 }
01222 else
01223 {
01224 clip_rect.mBottom = clip_rect.mTop - llround(clip_rect.getHeight() * (*panel_it)->mVisibleAmt);
01225 }
01226 LLLocalClipRect clip(clip_rect, (*panel_it)->mVisibleAmt < 1.f);
01227
01228 drawChild((*panel_it)->mPanel, 0, 0, (*panel_it)->mVisibleAmt > 0.f);
01229 }
01230 }
01231 }
01232
01233 void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
01234 {
01235 LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl);
01236
01237 if (embedded_panelp)
01238 {
01239 mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
01240 delete embedded_panelp;
01241 }
01242
01243 calcMinExtents();
01244
01245 LLView::removeCtrl(ctrl);
01246 }
01247
01248 void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
01249 {
01250 LLView::reshape(width, height, called_from_parent);
01251
01252 }
01253
01254 LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const
01255 {
01256 LLXMLNodePtr node = LLView::getXML();
01257 return node;
01258 }
01259
01260
01261 LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
01262 {
01263 LLString orientation_string("vertical");
01264 node->getAttributeString("orientation", orientation_string);
01265
01266 eLayoutOrientation orientation = VERTICAL;
01267
01268 if (orientation_string == "horizontal")
01269 {
01270 orientation = HORIZONTAL;
01271 }
01272 else if (orientation_string == "vertical")
01273 {
01274 orientation = VERTICAL;
01275 }
01276 else
01277 {
01278 llwarns << "Unknown orientation " << orientation_string << ", using vertical" << llendl;
01279 }
01280
01281 LLLayoutStack* layout_stackp = new LLLayoutStack(orientation);
01282
01283 layout_stackp->initFromXML(node, parent);
01284
01285 LLXMLNodePtr child;
01286 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
01287 {
01288 if (child->hasName("layout_panel"))
01289 {
01290 S32 min_width = 0;
01291 S32 min_height = 0;
01292 BOOL auto_resize = TRUE;
01293
01294 child->getAttributeS32("min_width", min_width);
01295 child->getAttributeS32("min_height", min_height);
01296 child->getAttributeBOOL("auto_resize", auto_resize);
01297
01298 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
01299 if (panelp)
01300 {
01301 panelp->setFollowsNone();
01302 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize);
01303 }
01304 }
01305 }
01306
01307 return layout_stackp;
01308 }
01309
01310 S32 LLLayoutStack::getMinWidth()
01311 {
01312 return mMinWidth;
01313 }
01314
01315 S32 LLLayoutStack::getMinHeight()
01316 {
01317 return mMinHeight;
01318 }
01319
01320 void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index)
01321 {
01322 LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize);
01323
01324 mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
01325 addChild(panel);
01326 addChild(embedded_panel->mResizeBar);
01327
01328
01329
01330 for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01331 {
01332 e_panel_list_t::iterator next_it = panel_it;
01333 ++next_it;
01334
01335 LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
01336 sendChildToFront(resize_barp);
01337
01338 if ( next_it == mPanels.end() )
01339 {
01340 resize_barp->setEnabled(FALSE);
01341 }
01342 else
01343 {
01344 resize_barp->setEnabled(TRUE);
01345 }
01346 }
01347
01348
01349 }
01350
01351 void LLLayoutStack::removePanel(LLPanel* panel)
01352 {
01353 removeChild(panel);
01354
01355 }
01356
01357 void LLLayoutStack::updateLayout(BOOL force_resize)
01358 {
01359 calcMinExtents();
01360
01361
01362 S32 cur_width = 0;
01363 S32 cur_height = 0;
01364
01365 const F32 ANIM_OPEN_TIME = 0.02f;
01366 const F32 ANIM_CLOSE_TIME = 0.02f;
01367
01368 e_panel_list_t::iterator panel_it;
01369 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01370 {
01371 LLPanel* panelp = (*panel_it)->mPanel;
01372 if (panelp->getVisible())
01373 {
01374 (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
01375 if ((*panel_it)->mVisibleAmt > 0.99f)
01376 {
01377 (*panel_it)->mVisibleAmt = 1.f;
01378 }
01379 }
01380 else
01381 {
01382 (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
01383 if ((*panel_it)->mVisibleAmt < 0.001f)
01384 {
01385 (*panel_it)->mVisibleAmt = 0.f;
01386 }
01387 }
01388 if (mOrientation == HORIZONTAL)
01389 {
01390
01391 cur_height = llmax(mMinHeight, panelp->getRect().getHeight());
01392 cur_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
01393 if (panel_it != mPanels.end())
01394 {
01395 cur_width += PANEL_STACK_GAP;
01396 }
01397 }
01398 else
01399 {
01400 cur_width = llmax(mMinWidth, panelp->getRect().getWidth());
01401 cur_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
01402 if (panel_it != mPanels.end())
01403 {
01404 cur_height += PANEL_STACK_GAP;
01405 }
01406 }
01407 }
01408
01409 S32 num_resizable_panels = 0;
01410 S32 shrink_headroom_available = 0;
01411 S32 shrink_headroom_total = 0;
01412 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01413 {
01414
01415 if ((*panel_it)->mVisibleAmt < 1.f)
01416 continue;
01417
01418
01419 if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize))
01420 {
01421 if (mOrientation == HORIZONTAL)
01422 {
01423 shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
01424 }
01425 else
01426 {
01427 shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
01428 }
01429 }
01430 else
01431 {
01432 num_resizable_panels++;
01433 if (mOrientation == HORIZONTAL)
01434 {
01435 shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
01436 shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
01437 }
01438 else
01439 {
01440 shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
01441 shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
01442 }
01443 }
01444 }
01445
01446
01447 S32 pixels_to_distribute;
01448 if (mOrientation == HORIZONTAL)
01449 {
01450 pixels_to_distribute = mRect.getWidth() - cur_width;
01451 }
01452 else
01453 {
01454 pixels_to_distribute = mRect.getHeight() - cur_height;
01455 }
01456
01457 S32 cur_x = 0;
01458 S32 cur_y = mRect.getHeight();
01459
01460 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01461 {
01462 LLPanel* panelp = (*panel_it)->mPanel;
01463
01464 S32 cur_width = panelp->getRect().getWidth();
01465 S32 cur_height = panelp->getRect().getHeight();
01466 S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
01467 S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
01468
01469 S32 delta_size = 0;
01470
01471
01472 if ((*panel_it)->mVisibleAmt == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture())
01473 {
01474 if (mOrientation == HORIZONTAL)
01475 {
01476
01477 if (pixels_to_distribute < 0)
01478 {
01479
01480 delta_size = llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available);
01481 }
01482 else
01483 {
01484
01485 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
01486 }
01487 new_width = llmax((*panel_it)->mMinWidth, panelp->getRect().getWidth() + delta_size);
01488 }
01489 else
01490 {
01491 new_width = llmax(mMinWidth, mRect.getWidth());
01492 }
01493
01494 if (mOrientation == VERTICAL)
01495 {
01496 if (pixels_to_distribute < 0)
01497 {
01498
01499 delta_size = llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available);
01500 }
01501 else
01502 {
01503 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
01504 }
01505 new_height = llmax((*panel_it)->mMinHeight, panelp->getRect().getHeight() + delta_size);
01506 }
01507 else
01508 {
01509 new_height = llmax(mMinHeight, mRect.getHeight());
01510 }
01511 }
01512 else
01513 {
01514 if (mOrientation == HORIZONTAL)
01515 {
01516 new_height = llmax(mMinHeight, mRect.getHeight());
01517 }
01518 else
01519 {
01520 new_width = llmax(mMinWidth, mRect.getWidth());
01521 }
01522 }
01523
01524
01525 shrink_headroom_total += delta_size;
01526
01527 panelp->reshape(new_width, new_height);
01528 panelp->setOrigin(cur_x, cur_y - new_height);
01529
01530 LLRect panel_rect = panelp->getRect();
01531 LLRect resize_bar_rect = panel_rect;
01532 if (mOrientation == HORIZONTAL)
01533 {
01534 resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP;
01535 resize_bar_rect.mRight = panel_rect.mRight + PANEL_STACK_GAP + RESIZE_BAR_OVERLAP;
01536 }
01537 else
01538 {
01539 resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP;
01540 resize_bar_rect.mBottom = panel_rect.mBottom - PANEL_STACK_GAP - RESIZE_BAR_OVERLAP;
01541 }
01542 (*panel_it)->mResizeBar->setRect(resize_bar_rect);
01543
01544 if (mOrientation == HORIZONTAL)
01545 {
01546 cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
01547 }
01548 else
01549 {
01550 cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
01551 }
01552 }
01553
01554
01555 LLResizeBar* last_resize_bar = NULL;
01556 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01557 {
01558 LLPanel* panelp = (*panel_it)->mPanel;
01559
01560 if (mOrientation == HORIZONTAL)
01561 {
01562 (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinWidth, (*panel_it)->mMinWidth + shrink_headroom_total);
01563 }
01564 else
01565 {
01566 (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinHeight, (*panel_it)->mMinHeight + shrink_headroom_total);
01567 }
01568
01569 (*panel_it)->mResizeBar->setVisible(panelp->getVisible());
01570 if (panelp->getVisible())
01571 {
01572 last_resize_bar = (*panel_it)->mResizeBar;
01573 }
01574 }
01575
01576
01577 if (last_resize_bar)
01578 {
01579 last_resize_bar->setVisible(FALSE);
01580 }
01581
01582
01583 if (!force_resize &&
01584 ((cur_y != -PANEL_STACK_GAP) || (cur_x != mRect.getWidth() + PANEL_STACK_GAP)))
01585 {
01586
01587
01588 llassert_always(force_resize == FALSE);
01589 updateLayout(TRUE);
01590 }
01591 }
01592
01593 LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp)
01594 {
01595 e_panel_list_t::iterator panel_it;
01596 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01597 {
01598 if ((*panel_it)->mPanel == panelp)
01599 {
01600 return *panel_it;
01601 }
01602 }
01603 return NULL;
01604 }
01605
01606 void LLLayoutStack::calcMinExtents()
01607 {
01608 mMinWidth = 0;
01609 mMinHeight = 0;
01610
01611 e_panel_list_t::iterator panel_it;
01612 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
01613 {
01614 if (mOrientation == HORIZONTAL)
01615 {
01616 mMinHeight = llmax(mMinHeight, (*panel_it)->mMinHeight);
01617 mMinWidth += (*panel_it)->mMinWidth;
01618 if (panel_it != mPanels.begin())
01619 {
01620 mMinWidth += PANEL_STACK_GAP;
01621 }
01622 }
01623 else
01624 {
01625 mMinWidth = llmax(mMinWidth, (*panel_it)->mMinWidth);
01626 mMinHeight += (*panel_it)->mMinHeight;
01627 if (panel_it != mPanels.begin())
01628 {
01629 mMinHeight += PANEL_STACK_GAP;
01630 }
01631 }
01632 }
01633 }