diff options
author | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
commit | ce28e056c20bf2723f565bbf464b87781ec248a2 (patch) | |
tree | ef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llui/llpanel.cpp | |
parent | Second Life viewer sources 1.19.1.4b (diff) | |
download | meta-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.cpp | 320 |
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; | |||
65 | const S32 RESIZE_BAR_OVERLAP = 1; | 65 | const S32 RESIZE_BAR_OVERLAP = 1; |
66 | const S32 RESIZE_BAR_HEIGHT = 3; | 66 | const S32 RESIZE_BAR_HEIGHT = 3; |
67 | 67 | ||
68 | static LLRegisterWidget<LLPanel> r1("panel"); | ||
69 | |||
68 | void LLPanel::init() | 70 | void LLPanel::init() |
69 | { | 71 | { |
70 | // mRectControl | 72 | // mRectControl |
@@ -126,18 +128,6 @@ LLPanel::~LLPanel() | |||
126 | } | 128 | } |
127 | 129 | ||
128 | // virtual | 130 | // virtual |
129 | EWidgetType LLPanel::getWidgetType() const | ||
130 | { | ||
131 | return WIDGET_TYPE_PANEL; | ||
132 | } | ||
133 | |||
134 | // virtual | ||
135 | LLString LLPanel::getWidgetTag() const | ||
136 | { | ||
137 | return LL_PANEL_TAG; | ||
138 | } | ||
139 | |||
140 | // virtual | ||
141 | BOOL LLPanel::isPanel() const | 131 | BOOL 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 | ||
260 | void LLPanel::setDefaultBtn(const LLString& id) | 251 | void 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 | ||
273 | BOOL 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 | |||
344 | void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group) | 264 | void 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 | ||
358 | BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) | 278 | BOOL 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 | |
403 | void 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 | |
408 | BOOL 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 | |||
345 | BOOL 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 | ||
497 | LLUICtrl* 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 |
522 | LLXMLNodePtr LLPanel::getXML(bool save_children) const | 425 | LLXMLNodePtr 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 | ||
974 | BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text) | 877 | BOOL 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 | ||
1002 | void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible) | 905 | void 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 | ||
1011 | LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const | 914 | LLPanel *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 | ||
1021 | void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata) | 924 | void 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 | ||
1035 | void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data) | 938 | void 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 | ||
1048 | void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWString &) ) | 951 | void 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 | ||
1057 | void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible) | 960 | void 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 | ||
1067 | void LLPanel::childSetAction(const LLString& id, void(*function)(void*), void* value) | 970 | void 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 | ||
1076 | void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*)) | 979 | void 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 |
1095 | LLView* LLPanel::getChildByName(const LLString& name, BOOL recurse) const | 998 | LLView* 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 | ||
1102 | static LLRegisterWidget<LLLayoutStack> r2("layout_stack"); | ||
1103 | |||
1194 | LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) : | 1104 | LLLayoutStack::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 | ||
1208 | EWidgetType LLLayoutStack::getWidgetType() const | ||
1209 | { | ||
1210 | return WIDGET_TYPE_LAYOUT_STACK; | ||
1211 | } | ||
1212 | |||
1213 | // virtual | ||
1214 | LLString LLLayoutStack::getWidgetTag() const | ||
1215 | { | ||
1216 | return LL_LAYOUT_STACK_TAG; | ||
1217 | } | ||
1218 | |||
1219 | |||
1220 | void LLLayoutStack::draw() | 1117 | void 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 |