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