aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llpanel.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:42 -0500
committerJacek Antonelli2008-08-15 23:45:42 -0500
commitce28e056c20bf2723f565bbf464b87781ec248a2 (patch)
treeef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llui/llpanel.cpp
parentSecond Life viewer sources 1.19.1.4b (diff)
downloadmeta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz
Second Life viewer sources 1.20.2
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/llpanel.cpp320
1 files changed, 129 insertions, 191 deletions
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp
index 567d29e..7db3725 100644
--- a/linden/indra/llui/llpanel.cpp
+++ b/linden/indra/llui/llpanel.cpp
@@ -65,6 +65,8 @@ LLPanel::alert_queue_t LLPanel::sAlertQueue;
65const S32 RESIZE_BAR_OVERLAP = 1; 65const S32 RESIZE_BAR_OVERLAP = 1;
66const S32 RESIZE_BAR_HEIGHT = 3; 66const S32 RESIZE_BAR_HEIGHT = 3;
67 67
68static LLRegisterWidget<LLPanel> r1("panel");
69
68void LLPanel::init() 70void LLPanel::init()
69{ 71{
70 // mRectControl 72 // mRectControl
@@ -126,18 +128,6 @@ LLPanel::~LLPanel()
126} 128}
127 129
128// virtual 130// virtual
129EWidgetType LLPanel::getWidgetType() const
130{
131 return WIDGET_TYPE_PANEL;
132}
133
134// virtual
135LLString LLPanel::getWidgetTag() const
136{
137 return LL_PANEL_TAG;
138}
139
140// virtual
141BOOL LLPanel::isPanel() const 131BOOL LLPanel::isPanel() const
142{ 132{
143 return TRUE; 133 return TRUE;
@@ -227,7 +217,8 @@ void LLPanel::updateDefaultBtn()
227 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) 217 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
228 { 218 {
229 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); 219 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
230 BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn(); 220 LLButton* buttonp = dynamic_cast<LLButton*>(focus_ctrl);
221 BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn();
231 // only enable default button when current focus is not a return-capturing button 222 // only enable default button when current focus is not a return-capturing button
232 mDefaultBtn->setBorderEnabled(!focus_is_child_button); 223 mDefaultBtn->setBorderEnabled(!focus_is_child_button);
233 } 224 }
@@ -259,7 +250,7 @@ void LLPanel::setDefaultBtn(LLButton* btn)
259 250
260void LLPanel::setDefaultBtn(const LLString& id) 251void LLPanel::setDefaultBtn(const LLString& id)
261{ 252{
262 LLButton *button = LLUICtrlFactory::getButtonByName(this, id); 253 LLButton *button = getChild<LLButton>(id);
263 if (button) 254 if (button)
264 { 255 {
265 setDefaultBtn(button); 256 setDefaultBtn(button);
@@ -270,77 +261,6 @@ void LLPanel::setDefaultBtn(const LLString& id)
270 } 261 }
271} 262}
272 263
273BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent)
274{
275 BOOL handled = FALSE;
276 if (getVisible() && getEnabled())
277 {
278 if( (mask == MASK_SHIFT) && (KEY_TAB == key))
279 {
280 //SHIFT-TAB
281 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
282 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
283 {
284 LLUICtrl* focus_root = cur_focus;
285 while(cur_focus->getParentUICtrl())
286 {
287 cur_focus = cur_focus->getParentUICtrl();
288 if (cur_focus->isFocusRoot())
289 {
290 // this is the root-most focus root found so far
291 focus_root = cur_focus;
292 }
293 }
294 handled = focus_root->focusPrevItem(FALSE);
295 }
296 else if (!cur_focus && isFocusRoot())
297 {
298 handled = focusLastItem();
299 if (!handled)
300 {
301 setFocus(TRUE);
302 handled = TRUE;
303 }
304 }
305 }
306 else
307 if( (mask == MASK_NONE ) && (KEY_TAB == key))
308 {
309 //TAB
310 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
311 if (cur_focus && gFocusMgr.childHasKeyboardFocus(this))
312 {
313 LLUICtrl* focus_root = cur_focus;
314 while(cur_focus->getParentUICtrl())
315 {
316 cur_focus = cur_focus->getParentUICtrl();
317 if (cur_focus->isFocusRoot())
318 {
319 focus_root = cur_focus;
320 }
321 }
322 handled = focus_root->focusNextItem(FALSE);
323 }
324 else if (!cur_focus && isFocusRoot())
325 {
326 handled = focusFirstItem();
327 if (!handled)
328 {
329 setFocus(TRUE);
330 handled = TRUE;
331 }
332 }
333 }
334 }
335
336 if (!handled)
337 {
338 handled = LLView::handleKey(key, mask, called_from_parent);
339 }
340
341 return handled;
342}
343
344void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group) 264void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
345{ 265{
346 mLastTabGroup = tab_group; 266 mLastTabGroup = tab_group;
@@ -355,83 +275,90 @@ void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
355 LLView::addCtrlAtEnd(ctrl, tab_group); 275 LLView::addCtrlAtEnd(ctrl, tab_group);
356} 276}
357 277
358BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) 278BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
359{ 279{
360 BOOL handled = FALSE; 280 BOOL handled = FALSE;
361 281
362 if( getVisible() && getEnabled() && 282 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
363 gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent )
364 {
365 // handle user hitting ESC to defocus
366 if (key == KEY_ESCAPE)
367 {
368 gFocusMgr.setKeyboardFocus(NULL);
369 return TRUE;
370 }
371 283
372 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); 284 // handle user hitting ESC to defocus
373 // If we have a default button, click it when 285 if (key == KEY_ESCAPE)
374 // return is pressed, unless current focus is a return-capturing button 286 {
375 // in which case *that* button will handle the return key 287 gFocusMgr.setKeyboardFocus(NULL);
376 if (cur_focus && !(cur_focus->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(cur_focus)->getCommitOnReturn())) 288 return TRUE;
289 }
290 else if( (mask == MASK_SHIFT) && (KEY_TAB == key))
291 {
292 //SHIFT-TAB
293 if (cur_focus)
377 { 294 {
378 // RETURN key means hit default button in this case 295 LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
379 if (key == KEY_RETURN && mask == MASK_NONE 296 if (focus_root)
380 && mDefaultBtn != NULL
381 && mDefaultBtn->getVisible()
382 && mDefaultBtn->getEnabled())
383 { 297 {
384 mDefaultBtn->onCommit(); 298 handled = focus_root->focusPrevItem(FALSE);
385 handled = TRUE;
386 } 299 }
387 } 300 }
388 301 }
389 if (key == KEY_RETURN && mask == MASK_NONE) 302 else if( (mask == MASK_NONE ) && (KEY_TAB == key))
303 {
304 //TAB
305 if (cur_focus)
390 { 306 {
391 // set keyboard focus to self to trigger commitOnFocusLost behavior on current ctrl 307 LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
392 if (cur_focus && cur_focus->acceptsTextInput()) 308 if (focus_root)
393 { 309 {
394 cur_focus->onCommit(); 310 handled = focus_root->focusNextItem(FALSE);
395 handled = TRUE;
396 } 311 }
397 } 312 }
398 } 313 }
399 314
400 return handled; 315 // If we have a default button, click it when
401} 316 // return is pressed, unless current focus is a return-capturing button
402 317 // in which case *that* button will handle the return key
403void LLPanel::requires(LLString name, EWidgetType type) 318 LLButton* focused_button = dynamic_cast<LLButton*>(cur_focus);
404{ 319 if (cur_focus && !(focused_button && focused_button->getCommitOnReturn()))
405 mRequirements[name] = type; 320 {
406} 321 // RETURN key means hit default button in this case
407 322 if (key == KEY_RETURN && mask == MASK_NONE
408BOOL LLPanel::checkRequirements() const 323 && mDefaultBtn != NULL
409{ 324 && mDefaultBtn->getVisible()
410 BOOL retval = TRUE; 325 && mDefaultBtn->getEnabled())
411 LLString message; 326 {
327 mDefaultBtn->onCommit();
328 handled = TRUE;
329 }
330 }
412 331
413 for (requirements_map_t::const_iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) 332 if (key == KEY_RETURN && mask == MASK_NONE)
414 { 333 {
415 if (!this->getCtrlByNameAndType(i->first, i->second)) 334 // set keyboard focus to self to trigger commitOnFocusLost behavior on current ctrl
335 if (cur_focus && cur_focus->acceptsTextInput())
416 { 336 {
417 retval = FALSE; 337 cur_focus->onCommit();
418 message += i->first + " " + LLUICtrlFactory::getWidgetType(i->second) + "\n"; 338 handled = TRUE;
419 } 339 }
420 } 340 }
421 341
422 if (!retval) 342 return handled;
343}
344
345BOOL LLPanel::checkRequirements()
346{
347 if (!mRequirementsError.empty())
423 { 348 {
424 LLString::format_map_t args; 349 LLString::format_map_t args;
425 args["[COMPONENTS]"] = message; 350 args["[COMPONENTS]"] = mRequirementsError;
426 args["[FLOATER]"] = getName(); 351 args["[FLOATER]"] = getName();
427 352
428 llwarns << getName() << " failed requirements check on: \n" 353 llwarns << getName() << " failed requirements check on: \n"
429 << message << llendl; 354 << mRequirementsError << llendl;
430 355
431 alertXml("FailedRequirementsCheck", args); 356 alertXml("FailedRequirementsCheck", args);
357 mRequirementsError.clear();
358 return FALSE;
432 } 359 }
433 360
434 return retval; 361 return TRUE;
435} 362}
436 363
437//static 364//static
@@ -494,30 +421,6 @@ void LLPanel::setBorderVisible(BOOL b)
494 } 421 }
495} 422}
496 423
497LLUICtrl* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) const
498{
499 LLView* view = getChildByName(name, TRUE);
500 if (view && view->isCtrl())
501 {
502 if (type == WIDGET_TYPE_DONTCARE || view->getWidgetType() == type)
503 {
504 return (LLUICtrl*)view;
505 }
506 else
507 {
508 llwarns << "Widget " << name << " has improper type in panel " << getName() << "\n"
509 << "Is: \t\t" << view->getWidgetType() << "\n"
510 << "Should be: \t" << type
511 << llendl;
512 }
513 }
514 else
515 {
516 childNotFound(name);
517 }
518 return NULL;
519}
520
521// virtual 424// virtual
522LLXMLNodePtr LLPanel::getXML(bool save_children) const 425LLXMLNodePtr LLPanel::getXML(bool save_children) const
523{ 426{
@@ -973,7 +876,7 @@ BOOL LLPanel::childSetLabelArg(const LLString& id, const LLString& key, const LL
973 876
974BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text) 877BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text)
975{ 878{
976 LLView* child = getChildByName(id, true); 879 LLView* child = getChildView(id, true, FALSE);
977 if (child) 880 if (child)
978 { 881 {
979 return child->setToolTipArg(key, text); 882 return child->setToolTipArg(key, text);
@@ -1001,7 +904,7 @@ void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value)
1001 904
1002void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible) 905void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible)
1003{ 906{
1004 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 907 LLTabContainer* child = getChild<LLTabContainer>(id);
1005 if (child) 908 if (child)
1006 { 909 {
1007 child->selectTabByName(tabname); 910 child->selectTabByName(tabname);
@@ -1010,7 +913,7 @@ void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool vis
1010 913
1011LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const 914LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const
1012{ 915{
1013 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 916 LLTabContainer* child = getChild<LLTabContainer>(id);
1014 if (child) 917 if (child)
1015 { 918 {
1016 return child->getCurrentPanel(); 919 return child->getCurrentPanel();
@@ -1020,7 +923,7 @@ LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const
1020 923
1021void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata) 924void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata)
1022{ 925{
1023 LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); 926 LLTabContainer* child = getChild<LLTabContainer>(id);
1024 if (child) 927 if (child)
1025 { 928 {
1026 LLPanel *panel = child->getPanelByName(tabname); 929 LLPanel *panel = child->getPanelByName(tabname);
@@ -1034,7 +937,7 @@ void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabn
1034 937
1035void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data) 938void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data)
1036{ 939{
1037 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); 940 LLLineEditor* child = getChild<LLLineEditor>(id);
1038 if (child) 941 if (child)
1039 { 942 {
1040 child->setKeystrokeCallback(keystroke_callback); 943 child->setKeystrokeCallback(keystroke_callback);
@@ -1047,7 +950,7 @@ void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_cal
1047 950
1048void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) ) 951void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) )
1049{ 952{
1050 LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); 953 LLLineEditor* child = getChild<LLLineEditor>(id);
1051 if (child) 954 if (child)
1052 { 955 {
1053 child->setPrevalidate(func); 956 child->setPrevalidate(func);
@@ -1056,7 +959,7 @@ void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWStri
1056 959
1057void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible) 960void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible)
1058{ 961{
1059 LLTextBox* child = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); 962 LLTextBox* child = getChild<LLTextBox>(id);
1060 if (child) 963 if (child)
1061 { 964 {
1062 child->setVisible(visible); 965 child->setVisible(visible);
@@ -1066,7 +969,7 @@ void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool
1066 969
1067void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value) 970void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value)
1068{ 971{
1069 LLButton* button = (LLButton*)getCtrlByNameAndType(id, WIDGET_TYPE_BUTTON); 972 LLButton* button = getChild<LLButton>(id);
1070 if (button) 973 if (button)
1071 { 974 {
1072 button->setClickedCallback(function, value); 975 button->setClickedCallback(function, value);
@@ -1075,7 +978,7 @@ void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* v
1075 978
1076void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*)) 979void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*))
1077{ 980{
1078 LLTextBox* textbox = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); 981 LLTextBox* textbox = getChild<LLTextBox>(id);
1079 if (textbox) 982 if (textbox)
1080 { 983 {
1081 textbox->setClickedCallback(function); 984 textbox->setClickedCallback(function);
@@ -1092,13 +995,18 @@ void LLPanel::childSetControlName(const LLString& id, const LLString& control_na
1092} 995}
1093 996
1094//virtual 997//virtual
1095LLView* LLPanel::getChildByName(const LLString& name, BOOL recurse) const 998LLView* LLPanel::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const
1096{ 999{
1097 LLView* view = LLUICtrl::getChildByName(name, recurse); 1000 // just get child, don't try to create a dummy one
1001 LLView* view = LLUICtrl::getChildView(name, recurse, FALSE);
1098 if (!view && !recurse) 1002 if (!view && !recurse)
1099 { 1003 {
1100 childNotFound(name); 1004 childNotFound(name);
1101 } 1005 }
1006 if (!view && create_if_missing)
1007 {
1008 view = createDummyWidget<LLView>(name);
1009 }
1102 return view; 1010 return view;
1103} 1011}
1104 1012
@@ -1191,6 +1099,8 @@ struct LLLayoutStack::LLEmbeddedPanel
1191 F32 mVisibleAmt; 1099 F32 mVisibleAmt;
1192}; 1100};
1193 1101
1102static LLRegisterWidget<LLLayoutStack> r2("layout_stack");
1103
1194LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) : 1104LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
1195 mOrientation(orientation), 1105 mOrientation(orientation),
1196 mMinWidth(0), 1106 mMinWidth(0),
@@ -1204,19 +1114,6 @@ LLLayoutStack::~LLLayoutStack()
1204 std::for_each(mPanels.begin(), mPanels.end(), DeletePointer()); 1114 std::for_each(mPanels.begin(), mPanels.end(), DeletePointer());
1205} 1115}
1206 1116
1207// virtual
1208EWidgetType LLLayoutStack::getWidgetType() const
1209{
1210 return WIDGET_TYPE_LAYOUT_STACK;
1211}
1212
1213// virtual
1214LLString LLLayoutStack::getWidgetTag() const
1215{
1216 return LL_LAYOUT_STACK_TAG;
1217}
1218
1219
1220void LLLayoutStack::draw() 1117void LLLayoutStack::draw()
1221{ 1118{
1222 updateLayout(); 1119 updateLayout();
@@ -1304,18 +1201,18 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
1304 LLXMLNodePtr child; 1201 LLXMLNodePtr child;
1305 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) 1202 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
1306 { 1203 {
1204 S32 min_width = 0;
1205 S32 min_height = 0;
1206 BOOL auto_resize = TRUE;
1207
1208 child->getAttributeS32("min_width", min_width);
1209 child->getAttributeS32("min_height", min_height);
1210 child->getAttributeBOOL("auto_resize", auto_resize);
1211
1307 if (child->hasName("layout_panel")) 1212 if (child->hasName("layout_panel"))
1308 { 1213 {
1309 S32 min_width = 0;
1310 S32 min_height = 0;
1311 BOOL auto_resize = TRUE;
1312 BOOL user_resize = TRUE; 1214 BOOL user_resize = TRUE;
1313
1314 child->getAttributeS32("min_width", min_width);
1315 child->getAttributeS32("min_height", min_height);
1316 child->getAttributeBOOL("auto_resize", auto_resize);
1317 child->getAttributeBOOL("user_resize", user_resize); 1215 child->getAttributeBOOL("user_resize", user_resize);
1318
1319 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory); 1216 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
1320 if (panelp) 1217 if (panelp)
1321 { 1218 {
@@ -1323,6 +1220,26 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
1323 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize); 1220 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
1324 } 1221 }
1325 } 1222 }
1223 else
1224 {
1225 BOOL user_resize = FALSE;
1226 child->getAttributeBOOL("user_resize", user_resize);
1227
1228 LLPanel* panelp = new LLPanel("auto_panel");
1229 LLView* new_child = factory->createWidget(panelp, child);
1230 if (new_child)
1231 {
1232 // put child in new embedded panel
1233 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
1234 // resize panel to contain widget and move widget to be contained in panel
1235 panelp->setRect(new_child->getRect());
1236 new_child->setOrigin(0, 0);
1237 }
1238 else
1239 {
1240 panelp->die();
1241 }
1242 }
1326 } 1243 }
1327 layout_stackp->updateLayout(); 1244 layout_stackp->updateLayout();
1328 1245
@@ -1411,6 +1328,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1411 1328
1412 if (mOrientation == HORIZONTAL) 1329 if (mOrientation == HORIZONTAL)
1413 { 1330 {
1331 // enforce minimize size constraint by default
1332 if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth)
1333 {
1334 panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
1335 }
1414 total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt); 1336 total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
1415 // want n-1 panel gaps for n panels 1337 // want n-1 panel gaps for n panels
1416 if (panel_it != mPanels.begin()) 1338 if (panel_it != mPanels.begin())
@@ -1420,6 +1342,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1420 } 1342 }
1421 else //VERTICAL 1343 else //VERTICAL
1422 { 1344 {
1345 // enforce minimize size constraint by default
1346 if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight)
1347 {
1348 panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
1349 }
1423 total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt); 1350 total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
1424 if (panel_it != mPanels.begin()) 1351 if (panel_it != mPanels.begin())
1425 { 1352 {
@@ -1438,6 +1365,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1438 { 1365 {
1439 continue; 1366 continue;
1440 } 1367 }
1368
1441 // if currently resizing a panel or the panel is flagged as not automatically resizing 1369 // if currently resizing a panel or the panel is flagged as not automatically resizing
1442 // only track total available headroom, but don't use it for automatic resize logic 1370 // only track total available headroom, but don't use it for automatic resize logic
1443 if ((*panel_it)->mResizeBar->hasMouseCapture() 1371 if ((*panel_it)->mResizeBar->hasMouseCapture()
@@ -1469,6 +1397,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1469 } 1397 }
1470 } 1398 }
1471 1399
1400 // calculate how many pixels need to be distributed among layout panels
1472 // positive means panels need to grow, negative means shrink 1401 // positive means panels need to grow, negative means shrink
1473 S32 pixels_to_distribute; 1402 S32 pixels_to_distribute;
1474 if (mOrientation == HORIZONTAL) 1403 if (mOrientation == HORIZONTAL)
@@ -1480,6 +1409,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1480 pixels_to_distribute = getRect().getHeight() - total_height; 1409 pixels_to_distribute = getRect().getHeight() - total_height;
1481 } 1410 }
1482 1411
1412 // now we distribute the pixels...
1483 S32 cur_x = 0; 1413 S32 cur_x = 0;
1484 S32 cur_y = getRect().getHeight(); 1414 S32 cur_y = getRect().getHeight();
1485 1415
@@ -1505,13 +1435,17 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1505 if (pixels_to_distribute < 0) 1435 if (pixels_to_distribute < 0)
1506 { 1436 {
1507 // shrink proportionally to amount over minimum 1437 // shrink proportionally to amount over minimum
1508 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available) : 0; 1438 // so we can do this in one pass
1439 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0;
1440 shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth);
1509 } 1441 }
1510 else 1442 else
1511 { 1443 {
1512 // grow all elements equally 1444 // grow all elements equally
1513 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); 1445 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1446 num_resizable_panels--;
1514 } 1447 }
1448 pixels_to_distribute -= delta_size;
1515 new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size); 1449 new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size);
1516 } 1450 }
1517 else 1451 else
@@ -1524,12 +1458,16 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
1524 if (pixels_to_distribute < 0) 1458 if (pixels_to_distribute < 0)
1525 { 1459 {
1526 // shrink proportionally to amount over minimum 1460 // shrink proportionally to amount over minimum
1527 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available) : 0; 1461 // so we can do this in one pass
1462 delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0;
1463 shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight);
1528 } 1464 }
1529 else 1465 else
1530 { 1466 {
1531 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); 1467 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1468 num_resizable_panels--;
1532 } 1469 }
1470 pixels_to_distribute -= delta_size;
1533 new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size); 1471 new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size);
1534 } 1472 }
1535 else 1473 else