aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llview.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/llview.cpp440
1 files changed, 265 insertions, 175 deletions
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp
index e18dbb0..04d33a6 100644
--- a/linden/indra/llui/llview.cpp
+++ b/linden/indra/llui/llview.cpp
@@ -13,12 +13,12 @@
13 * ("GPL"), unless you have obtained a separate licensing agreement 13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of 14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or 15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2 16 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
17 * 17 *
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception 21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 22 *
23 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -113,7 +113,7 @@ LLView::LLView() :
113 mSaveToXML(TRUE), 113 mSaveToXML(TRUE),
114 mIsFocusRoot(FALSE), 114 mIsFocusRoot(FALSE),
115 mLastVisible(TRUE), 115 mLastVisible(TRUE),
116 mSpanChildren(FALSE), 116 mUseBoundingRect(FALSE),
117 mVisible(TRUE), 117 mVisible(TRUE),
118 mHidden(FALSE), 118 mHidden(FALSE),
119 mNextInsertionOrdinal(0) 119 mNextInsertionOrdinal(0)
@@ -133,7 +133,7 @@ LLView::LLView(const LLString& name, BOOL mouse_opaque) :
133 mSaveToXML(TRUE), 133 mSaveToXML(TRUE),
134 mIsFocusRoot(FALSE), 134 mIsFocusRoot(FALSE),
135 mLastVisible(TRUE), 135 mLastVisible(TRUE),
136 mSpanChildren(FALSE), 136 mUseBoundingRect(FALSE),
137 mVisible(TRUE), 137 mVisible(TRUE),
138 mHidden(FALSE), 138 mHidden(FALSE),
139 mNextInsertionOrdinal(0) 139 mNextInsertionOrdinal(0)
@@ -148,6 +148,7 @@ LLView::LLView(
148 mParentView(NULL), 148 mParentView(NULL),
149 mName(name), 149 mName(name),
150 mRect(rect), 150 mRect(rect),
151 mBoundingRect(rect),
151 mReshapeFlags(reshape), 152 mReshapeFlags(reshape),
152 mDefaultTabGroup(0), 153 mDefaultTabGroup(0),
153 mEnabled(TRUE), 154 mEnabled(TRUE),
@@ -156,7 +157,7 @@ LLView::LLView(
156 mSaveToXML(TRUE), 157 mSaveToXML(TRUE),
157 mIsFocusRoot(FALSE), 158 mIsFocusRoot(FALSE),
158 mLastVisible(TRUE), 159 mLastVisible(TRUE),
159 mSpanChildren(FALSE), 160 mUseBoundingRect(FALSE),
160 mVisible(TRUE), 161 mVisible(TRUE),
161 mHidden(FALSE), 162 mHidden(FALSE),
162 mNextInsertionOrdinal(0) 163 mNextInsertionOrdinal(0)
@@ -235,10 +236,16 @@ BOOL LLView::setToolTipArg(const LLStringExplicit& key, const LLStringExplicit&
235 return TRUE; 236 return TRUE;
236} 237}
237 238
239void LLView::setToolTipArgs( const LLString::format_map_t& args )
240{
241 mToolTipMsg.setArgList(args);
242}
243
238// virtual 244// virtual
239void LLView::setRect(const LLRect& rect) 245void LLView::setRect(const LLRect& rect)
240{ 246{
241 mRect = rect; 247 mRect = rect;
248 updateBoundingRect();
242} 249}
243 250
244 251
@@ -287,9 +294,18 @@ void LLView::setName(LLString name)
287 mName = name; 294 mName = name;
288} 295}
289 296
290void LLView::setSpanChildren( BOOL span_children ) 297void LLView::setUseBoundingRect( BOOL use_bounding_rect )
298{
299 if (mUseBoundingRect != use_bounding_rect)
300 {
301 mUseBoundingRect = use_bounding_rect;
302 updateBoundingRect();
303 }
304}
305
306BOOL LLView::getUseBoundingRect()
291{ 307{
292 mSpanChildren = span_children; updateRect(); 308 return mUseBoundingRect;
293} 309}
294 310
295const LLString& LLView::getToolTip() 311const LLString& LLView::getToolTip()
@@ -306,7 +322,7 @@ const LLString& LLView::getName() const
306 322
307void LLView::sendChildToFront(LLView* child) 323void LLView::sendChildToFront(LLView* child)
308{ 324{
309 if (child->mParentView == this) 325 if (child && child->getParent() == this)
310 { 326 {
311 mChildList.remove( child ); 327 mChildList.remove( child );
312 mChildList.push_front(child); 328 mChildList.push_front(child);
@@ -315,7 +331,7 @@ void LLView::sendChildToFront(LLView* child)
315 331
316void LLView::sendChildToBack(LLView* child) 332void LLView::sendChildToBack(LLView* child)
317{ 333{
318 if (child->mParentView == this) 334 if (child && child->getParent() == this)
319 { 335 {
320 mChildList.remove( child ); 336 mChildList.remove( child );
321 mChildList.push_back(child); 337 mChildList.push_back(child);
@@ -330,6 +346,14 @@ void LLView::moveChildToFrontOfTabGroup(LLUICtrl* child)
330 } 346 }
331} 347}
332 348
349void LLView::moveChildToBackOfTabGroup(LLUICtrl* child)
350{
351 if(mCtrlOrder.find(child) != mCtrlOrder.end())
352 {
353 mCtrlOrder[child].second = mNextInsertionOrdinal++;
354 }
355}
356
333void LLView::addChild(LLView* child, S32 tab_group) 357void LLView::addChild(LLView* child, S32 tab_group)
334{ 358{
335 if (mParentView == child) 359 if (mParentView == child)
@@ -353,7 +377,7 @@ void LLView::addChild(LLView* child, S32 tab_group)
353 } 377 }
354 378
355 child->mParentView = this; 379 child->mParentView = this;
356 updateRect(); 380 updateBoundingRect();
357} 381}
358 382
359 383
@@ -380,7 +404,7 @@ void LLView::addChildAtEnd(LLView* child, S32 tab_group)
380 } 404 }
381 405
382 child->mParentView = this; 406 child->mParentView = this;
383 updateRect(); 407 updateBoundingRect();
384} 408}
385 409
386// remove the specified child from the view, and set it's parent to NULL. 410// remove the specified child from the view, and set it's parent to NULL.
@@ -403,6 +427,7 @@ void LLView::removeChild(LLView* child, BOOL deleteIt)
403 { 427 {
404 llerrs << "LLView::removeChild called with non-child" << llendl; 428 llerrs << "LLView::removeChild called with non-child" << llendl;
405 } 429 }
430 updateBoundingRect();
406} 431}
407 432
408void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) 433void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group)
@@ -782,6 +807,7 @@ void LLView::setVisible(BOOL visible)
782 // tell all children of this view that the visibility may have changed 807 // tell all children of this view that the visibility may have changed
783 onVisibilityChange( visible ); 808 onVisibilityChange( visible );
784 } 809 }
810 updateBoundingRect();
785 } 811 }
786} 812}
787 813
@@ -815,6 +841,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility )
815void LLView::translate(S32 x, S32 y) 841void LLView::translate(S32 x, S32 y)
816{ 842{
817 mRect.translate(x, y); 843 mRect.translate(x, y);
844 updateBoundingRect();
818} 845}
819 846
820// virtual 847// virtual
@@ -831,7 +858,8 @@ void LLView::snappedTo(LLView* snap_view)
831BOOL LLView::handleHover(S32 x, S32 y, MASK mask) 858BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
832{ 859{
833 BOOL handled = childrenHandleHover( x, y, mask ) != NULL; 860 BOOL handled = childrenHandleHover( x, y, mask ) != NULL;
834 if( !handled && mMouseOpaque && pointInView( x, y ) ) 861 if( !handled
862 && blockMouseEvent(x, y) )
835 { 863 {
836 LLUI::sWindow->setCursor(UI_CURSOR_ARROW); 864 LLUI::sWindow->setCursor(UI_CURSOR_ARROW);
837 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; 865 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
@@ -876,45 +904,46 @@ BOOL LLView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_scre
876 904
877 LLString tool_tip; 905 LLString tool_tip;
878 906
879 if ( getVisible() && getEnabled()) 907 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
880 { 908 {
881 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) 909 LLView* viewp = *child_it;
910 S32 local_x = x - viewp->mRect.mLeft;
911 S32 local_y = y - viewp->mRect.mBottom;
912 if( viewp->pointInView(local_x, local_y)
913 && viewp->getVisible()
914 && viewp->getEnabled()
915 && viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ))
882 { 916 {
883 LLView* viewp = *child_it; 917 handled = TRUE;
884 S32 local_x = x - viewp->mRect.mLeft; 918 break;
885 S32 local_y = y - viewp->mRect.mBottom;
886 if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) )
887 {
888 handled = TRUE;
889 break;
890 }
891 } 919 }
920 }
892 921
893 tool_tip = mToolTipMsg.getString(); 922 tool_tip = mToolTipMsg.getString();
894 if (LLUI::sShowXUINames && (tool_tip.find(".xml", 0) == LLString::npos) && 923 if (
895 (mName.find("Drag", 0) == LLString::npos)) 924 LLUI::sShowXUINames &&
896 { 925 (tool_tip.find(".xml", 0) == LLString::npos) &&
897 tool_tip = getShowNamesToolTip(); 926 (mName.find("Drag", 0) == LLString::npos))
898 } 927 {
899 928 tool_tip = getShowNamesToolTip();
929 }
900 930
901 BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX); 931 BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX);
902 932
903 if( !handled && (mMouseOpaque || showNamesTextBox) && pointInView( x, y ) && !tool_tip.empty()) 933 if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty())
904 { 934 {
905 935
906 msg = tool_tip; 936 msg = tool_tip;
907 937
908 // Convert rect local to screen coordinates 938 // Convert rect local to screen coordinates
909 localPointToScreen( 939 localPointToScreen(
910 0, 0, 940 0, 0,
911 &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); 941 &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
912 localPointToScreen( 942 localPointToScreen(
913 mRect.getWidth(), mRect.getHeight(), 943 mRect.getWidth(), mRect.getHeight(),
914 &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); 944 &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
915 945
916 handled = TRUE; 946 handled = TRUE;
917 }
918 } 947 }
919 948
920 return handled; 949 return handled;
@@ -1025,7 +1054,7 @@ BOOL LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
1025 cargo_data, 1054 cargo_data,
1026 accept, 1055 accept,
1027 tooltip_msg) != NULL; 1056 tooltip_msg) != NULL;
1028 if( !handled && mMouseOpaque ) 1057 if( !handled && blockMouseEvent(x, y) )
1029 { 1058 {
1030 *accept = ACCEPT_NO; 1059 *accept = ACCEPT_NO;
1031 handled = TRUE; 1060 handled = TRUE;
@@ -1081,7 +1110,7 @@ BOOL LLView::hasMouseCapture()
1081BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask) 1110BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
1082{ 1111{
1083 BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL; 1112 BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL;
1084 if( !handled && mMouseOpaque ) 1113 if( !handled && blockMouseEvent(x, y) )
1085 { 1114 {
1086 handled = TRUE; 1115 handled = TRUE;
1087 } 1116 }
@@ -1092,7 +1121,7 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
1092{ 1121{
1093 LLView* handled_view = childrenHandleMouseDown( x, y, mask ); 1122 LLView* handled_view = childrenHandleMouseDown( x, y, mask );
1094 BOOL handled = (handled_view != NULL); 1123 BOOL handled = (handled_view != NULL);
1095 if( !handled && mMouseOpaque ) 1124 if( !handled && blockMouseEvent(x, y) )
1096 { 1125 {
1097 handled = TRUE; 1126 handled = TRUE;
1098 handled_view = this; 1127 handled_view = this;
@@ -1118,7 +1147,7 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
1118BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) 1147BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
1119{ 1148{
1120 BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL; 1149 BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
1121 if( !handled && mMouseOpaque ) 1150 if( !handled && blockMouseEvent(x, y) )
1122 { 1151 {
1123 handleMouseDown(x, y, mask); 1152 handleMouseDown(x, y, mask);
1124 handled = TRUE; 1153 handled = TRUE;
@@ -1132,7 +1161,7 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
1132 if( getVisible() && mEnabled ) 1161 if( getVisible() && mEnabled )
1133 { 1162 {
1134 handled = childrenHandleScrollWheel( x, y, clicks ) != NULL; 1163 handled = childrenHandleScrollWheel( x, y, clicks ) != NULL;
1135 if( !handled && mMouseOpaque ) 1164 if( !handled && blockMouseEvent(x, y) )
1136 { 1165 {
1137 handled = TRUE; 1166 handled = TRUE;
1138 } 1167 }
@@ -1143,7 +1172,7 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
1143BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) 1172BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
1144{ 1173{
1145 BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; 1174 BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
1146 if( !handled && mMouseOpaque ) 1175 if( !handled && blockMouseEvent(x, y) )
1147 { 1176 {
1148 handled = TRUE; 1177 handled = TRUE;
1149 } 1178 }
@@ -1153,7 +1182,7 @@ BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
1153BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) 1182BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask)
1154{ 1183{
1155 BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL; 1184 BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL;
1156 if( !handled && mMouseOpaque ) 1185 if( !handled && blockMouseEvent(x, y) )
1157 { 1186 {
1158 handled = TRUE; 1187 handled = TRUE;
1159 } 1188 }
@@ -1428,10 +1457,10 @@ void LLView::draw()
1428 focus_view = NULL; 1457 focus_view = NULL;
1429 } 1458 }
1430 1459
1460 ++sDepth;
1431 for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter) 1461 for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
1432 { 1462 {
1433 LLView *viewp = *child_iter; 1463 LLView *viewp = *child_iter;
1434 ++sDepth;
1435 1464
1436 if (viewp->getVisible() && viewp != focus_view) 1465 if (viewp->getVisible() && viewp != focus_view)
1437 { 1466 {
@@ -1449,8 +1478,8 @@ void LLView::draw()
1449 } 1478 }
1450 } 1479 }
1451 1480
1452 --sDepth;
1453 } 1481 }
1482 --sDepth;
1454 1483
1455 if (focus_view && focus_view->getVisible()) 1484 if (focus_view && focus_view->getVisible())
1456 { 1485 {
@@ -1467,50 +1496,61 @@ void LLView::draw()
1467//Draw a box for debugging. 1496//Draw a box for debugging.
1468void LLView::drawDebugRect() 1497void LLView::drawDebugRect()
1469{ 1498{
1470 // drawing solids requires texturing be disabled 1499 LLUI::pushMatrix();
1471 LLGLSNoTexture no_texture;
1472
1473 // draw red rectangle for the border
1474 LLColor4 border_color(0.f, 0.f, 0.f, 1.f);
1475 if (sEditingUI)
1476 { 1500 {
1477 border_color.mV[0] = 1.f; 1501 // drawing solids requires texturing be disabled
1478 } 1502 LLGLSNoTexture no_texture;
1479 else
1480 {
1481 border_color.mV[sDepth%3] = 1.f;
1482 }
1483 1503
1484 glColor4fv( border_color.mV ); 1504 if (mUseBoundingRect)
1505 {
1506 LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom, 0.f);
1507 }
1485 1508
1486 glBegin(GL_LINES); 1509 LLRect debug_rect = mUseBoundingRect ? mBoundingRect : mRect;
1487 glVertex2i(0, mRect.getHeight() - 1);
1488 glVertex2i(0, 0);
1489 1510
1490 glVertex2i(0, 0); 1511 // draw red rectangle for the border
1491 glVertex2i(mRect.getWidth() - 1, 0); 1512 LLColor4 border_color(0.f, 0.f, 0.f, 1.f);
1513 if (sEditingUI)
1514 {
1515 border_color.mV[0] = 1.f;
1516 }
1517 else
1518 {
1519 border_color.mV[sDepth%3] = 1.f;
1520 }
1492 1521
1493 glVertex2i(mRect.getWidth() - 1, 0); 1522 glColor4fv( border_color.mV );
1494 glVertex2i(mRect.getWidth() - 1, mRect.getHeight() - 1);
1495 1523
1496 glVertex2i(mRect.getWidth() - 1, mRect.getHeight() - 1); 1524 glBegin(GL_LINES);
1497 glVertex2i(0, mRect.getHeight() - 1); 1525 glVertex2i(0, debug_rect.getHeight() - 1);
1498 glEnd(); 1526 glVertex2i(0, 0);
1499 1527
1500 // Draw the name if it's not a leaf node 1528 glVertex2i(0, 0);
1501 if (mChildList.size() && !sEditingUI) 1529 glVertex2i(debug_rect.getWidth() - 1, 0);
1502 { 1530
1503 //char temp[256]; 1531 glVertex2i(debug_rect.getWidth() - 1, 0);
1504 S32 x, y; 1532 glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1);
1505 glColor4fv( border_color.mV ); 1533
1506 x = mRect.getWidth()/2; 1534 glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1);
1507 y = mRect.getHeight()/2; 1535 glVertex2i(0, debug_rect.getHeight() - 1);
1508 LLString debug_text = llformat("%s (%d x %d)", getName().c_str(), 1536 glEnd();
1509 mRect.getWidth(), mRect.getHeight()); 1537
1510 LLFontGL::sSansSerifSmall->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color, 1538 // Draw the name if it's not a leaf node
1511 LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, 1539 if (mChildList.size() && !sEditingUI)
1512 S32_MAX, S32_MAX, NULL, FALSE); 1540 {
1541 //char temp[256];
1542 S32 x, y;
1543 glColor4fv( border_color.mV );
1544 x = debug_rect.getWidth()/2;
1545 y = debug_rect.getHeight()/2;
1546 LLString debug_text = llformat("%s (%d x %d)", getName().c_str(),
1547 debug_rect.getWidth(), debug_rect.getHeight());
1548 LLFontGL::sSansSerifSmall->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
1549 LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL,
1550 S32_MAX, S32_MAX, NULL, FALSE);
1551 }
1513 } 1552 }
1553 LLUI::popMatrix();
1514} 1554}
1515 1555
1516void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw) 1556void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw)
@@ -1537,9 +1577,6 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr
1537 1577
1538void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) 1578void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
1539{ 1579{
1540 // make sure this view contains all its children
1541 updateRect();
1542
1543 // compute how much things changed and apply reshape logic to children 1580 // compute how much things changed and apply reshape logic to children
1544 S32 delta_width = width - mRect.getWidth(); 1581 S32 delta_width = width - mRect.getWidth();
1545 S32 delta_height = height - mRect.getHeight(); 1582 S32 delta_height = height - mRect.getHeight();
@@ -1608,6 +1645,8 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
1608 mParentView->reshape(mParentView->getRect().getWidth(), mParentView->getRect().getHeight(), FALSE); 1645 mParentView->reshape(mParentView->getRect().getWidth(), mParentView->getRect().getHeight(), FALSE);
1609 } 1646 }
1610 } 1647 }
1648
1649 updateBoundingRect();
1611} 1650}
1612 1651
1613LLRect LLView::getRequiredRect() 1652LLRect LLView::getRequiredRect()
@@ -1615,6 +1654,53 @@ LLRect LLView::getRequiredRect()
1615 return mRect; 1654 return mRect;
1616} 1655}
1617 1656
1657void LLView::updateBoundingRect()
1658{
1659 if (isDead()) return;
1660
1661 if (mUseBoundingRect)
1662 {
1663 LLRect local_bounding_rect = LLRect::null;
1664
1665 child_list_const_iter_t child_it;
1666 for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
1667 {
1668 LLView* childp = *child_it;
1669 if (!childp->getVisible()) continue;
1670
1671 LLRect child_bounding_rect = childp->getBoundingRect();
1672
1673 if (local_bounding_rect.isNull())
1674 {
1675 // start out with bounding rect equal to first visible child's bounding rect
1676 local_bounding_rect = child_bounding_rect;
1677 }
1678 else
1679 {
1680 // accumulate non-null children rectangles
1681 if (!child_bounding_rect.isNull())
1682 {
1683 local_bounding_rect.unionWith(child_bounding_rect);
1684 }
1685 }
1686 }
1687
1688 mBoundingRect = local_bounding_rect;
1689 // translate into parent-relative coordinates
1690 mBoundingRect.translate(mRect.mLeft, mRect.mBottom);
1691 }
1692 else
1693 {
1694 mBoundingRect = mRect;
1695 }
1696
1697 // give parent view a chance to resize, in case we just moved, for example
1698 if (getParent() && getParent()->mUseBoundingRect)
1699 {
1700 getParent()->updateBoundingRect();
1701 }
1702}
1703
1618const LLRect LLView::getScreenRect() const 1704const LLRect LLView::getScreenRect() const
1619{ 1705{
1620 // *FIX: check for one-off error 1706 // *FIX: check for one-off error
@@ -1624,6 +1710,15 @@ const LLRect LLView::getScreenRect() const
1624 return screen_rect; 1710 return screen_rect;
1625} 1711}
1626 1712
1713const LLRect LLView::getLocalBoundingRect() const
1714{
1715 LLRect local_bounding_rect = getBoundingRect();
1716 local_bounding_rect.translate(-mRect.mLeft, -mRect.mBottom);
1717
1718 return local_bounding_rect;
1719}
1720
1721
1627const LLRect LLView::getLocalRect() const 1722const LLRect LLView::getLocalRect() const
1628{ 1723{
1629 LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0); 1724 LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0);
@@ -1637,38 +1732,7 @@ const LLRect LLView::getLocalSnapRect() const
1637 return local_snap_rect; 1732 return local_snap_rect;
1638} 1733}
1639 1734
1640void LLView::updateRect() 1735BOOL LLView::hasAncestor(const LLView* parentp)
1641{
1642 if (mSpanChildren && mChildList.size())
1643 {
1644 LLView* first_child = (*mChildList.begin());
1645 LLRect child_spanning_rect = first_child->mRect;
1646
1647 for ( child_list_iter_t child_it = ++mChildList.begin(); child_it != mChildList.end(); ++child_it)
1648 {
1649 LLView* viewp = *child_it;
1650 if (viewp->getVisible())
1651 {
1652 child_spanning_rect.unionWith(viewp->mRect);
1653 }
1654 }
1655
1656 S32 translate_x = llmin(0, child_spanning_rect.mLeft);
1657 S32 translate_y = llmin(0, child_spanning_rect.mBottom);
1658 S32 new_width = llmax(mRect.getWidth() + translate_x, child_spanning_rect.getWidth());
1659 S32 new_height = llmax(mRect.getHeight() + translate_y, child_spanning_rect.getHeight());
1660
1661 mRect.setOriginAndSize(mRect.mLeft + translate_x, mRect.mBottom + translate_y, new_width, new_height);
1662
1663 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
1664 {
1665 LLView* viewp = *child_it;
1666 viewp->mRect.translate(-translate_x, -translate_y);
1667 }
1668 }
1669}
1670
1671BOOL LLView::hasAncestor(LLView* parentp)
1672{ 1736{
1673 if (!parentp) 1737 if (!parentp)
1674 { 1738 {
@@ -1743,14 +1807,23 @@ LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const
1743 return NULL; 1807 return NULL;
1744} 1808}
1745 1809
1746// virtual 1810BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const
1747void LLView::onFocusLost() 1811{
1748{ 1812 return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
1813 ? mBoundingRect.pointInRect( x, y )
1814 : mRect.pointInRect( x, y );
1749} 1815}
1750 1816
1751// virtual 1817BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const
1752void LLView::onFocusReceived() 1818{
1819 return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
1820 ? mBoundingRect.pointInRect( x + mRect.mLeft, y + mRect.mBottom )
1821 : mRect.localPointInRect( x, y );
1822}
1823
1824BOOL LLView::blockMouseEvent(S32 x, S32 y) const
1753{ 1825{
1826 return mMouseOpaque && pointInView(x, y, HIT_TEST_IGNORE_BOUNDING_RECT);
1754} 1827}
1755 1828
1756// virtual 1829// virtual
@@ -2024,9 +2097,9 @@ LLXMLNodePtr LLView::getXML(bool save_children) const
2024 // Export all widgets as enabled and visible - code must disable. 2097 // Export all widgets as enabled and visible - code must disable.
2025 node->createChild("hidden", TRUE)->setBoolValue(mHidden); 2098 node->createChild("hidden", TRUE)->setBoolValue(mHidden);
2026 node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque ); 2099 node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque );
2027 if (!mToolTipMsg.empty()) 2100 if (!mToolTipMsg.getString().empty())
2028 { 2101 {
2029 node->createChild("tool_tip", TRUE)->setStringValue(mToolTipMsg); 2102 node->createChild("tool_tip", TRUE)->setStringValue(mToolTipMsg.getString());
2030 } 2103 }
2031 if (mSoundFlags != MOUSE_UP) 2104 if (mSoundFlags != MOUSE_UP)
2032 { 2105 {
@@ -2116,7 +2189,7 @@ const LLCtrlQuery & LLView::getTabOrderQuery()
2116 query.addPreFilter(LLVisibleFilter::getInstance()); 2189 query.addPreFilter(LLVisibleFilter::getInstance());
2117 query.addPreFilter(LLEnabledFilter::getInstance()); 2190 query.addPreFilter(LLEnabledFilter::getInstance());
2118 query.addPreFilter(LLTabStopFilter::getInstance()); 2191 query.addPreFilter(LLTabStopFilter::getInstance());
2119 query.addPostFilter(LLUICtrl::LLTabStopPostFilter::getInstance()); 2192 query.addPostFilter(LLLeavesFilter::getInstance());
2120 } 2193 }
2121 return query; 2194 return query;
2122} 2195}
@@ -2129,6 +2202,7 @@ const LLCtrlQuery & LLView::getFocusRootsQuery()
2129 query.addPreFilter(LLVisibleFilter::getInstance()); 2202 query.addPreFilter(LLVisibleFilter::getInstance());
2130 query.addPreFilter(LLEnabledFilter::getInstance()); 2203 query.addPreFilter(LLEnabledFilter::getInstance());
2131 query.addPreFilter(LLView::LLFocusRootsFilter::getInstance()); 2204 query.addPreFilter(LLView::LLFocusRootsFilter::getInstance());
2205 query.addPostFilter(LLRootsFilter::getInstance());
2132 } 2206 }
2133 return query; 2207 return query;
2134} 2208}
@@ -2593,10 +2667,10 @@ const S32 VPAD = 4;
2593U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect) 2667U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect)
2594{ 2668{
2595 U32 follows = 0; 2669 U32 follows = 0;
2596 S32 x = FLOATER_H_MARGIN; 2670 S32 x = rect.mLeft;
2597 S32 y = 0; 2671 S32 y = rect.mBottom;
2598 S32 w = 0; 2672 S32 w = rect.getWidth();
2599 S32 h = 0; 2673 S32 h = rect.getHeight();
2600 2674
2601 U32 last_x = 0; 2675 U32 last_x = 0;
2602 U32 last_y = 0; 2676 U32 last_y = 0;
@@ -2639,8 +2713,15 @@ U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, con
2639 // view if you don't specify a width. 2713 // view if you don't specify a width.
2640 if (parent_view) 2714 if (parent_view)
2641 { 2715 {
2642 w = llmax(required_rect.getWidth(), parent_view->getRect().getWidth() - (FLOATER_H_MARGIN) - x); 2716 if(w == 0)
2643 h = llmax(MIN_WIDGET_HEIGHT, required_rect.getHeight()); 2717 {
2718 w = llmax(required_rect.getWidth(), parent_view->getRect().getWidth() - (FLOATER_H_MARGIN) - x);
2719 }
2720
2721 if(h == 0)
2722 {
2723 h = llmax(MIN_WIDGET_HEIGHT, required_rect.getHeight());
2724 }
2644 } 2725 }
2645 2726
2646 if (node->hasAttribute("width")) 2727 if (node->hasAttribute("width"))
@@ -2765,44 +2846,7 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent)
2765 setRect(view_rect); 2846 setRect(view_rect);
2766 setFollows(follows_flags); 2847 setFollows(follows_flags);
2767 2848
2768 if (node->hasAttribute("follows")) 2849 parseFollowsFlags(node);
2769 {
2770 setFollowsNone();
2771
2772 LLString follows;
2773 node->getAttributeString("follows", follows);
2774
2775 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
2776 boost::char_separator<char> sep("|");
2777 tokenizer tokens(follows, sep);
2778 tokenizer::iterator token_iter = tokens.begin();
2779
2780 while(token_iter != tokens.end())
2781 {
2782 const std::string& token_str = *token_iter;
2783 if (token_str == "left")
2784 {
2785 setFollowsLeft();
2786 }
2787 else if (token_str == "right")
2788 {
2789 setFollowsRight();
2790 }
2791 else if (token_str == "top")
2792 {
2793 setFollowsTop();
2794 }
2795 else if (token_str == "bottom")
2796 {
2797 setFollowsBottom();
2798 }
2799 else if (token_str == "all")
2800 {
2801 setFollowsAll();
2802 }
2803 ++token_iter;
2804 }
2805 }
2806 2850
2807 if (node->hasAttribute("control_name")) 2851 if (node->hasAttribute("control_name"))
2808 { 2852 {
@@ -2839,11 +2883,57 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent)
2839 setHidden(hidden); 2883 setHidden(hidden);
2840 } 2884 }
2841 2885
2886 node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect);
2887 node->getAttributeBOOL("mouse_opaque", mMouseOpaque);
2888
2842 node->getAttributeS32("default_tab_group", mDefaultTabGroup); 2889 node->getAttributeS32("default_tab_group", mDefaultTabGroup);
2843 2890
2844 reshape(view_rect.getWidth(), view_rect.getHeight()); 2891 reshape(view_rect.getWidth(), view_rect.getHeight());
2845} 2892}
2846 2893
2894void LLView::parseFollowsFlags(LLXMLNodePtr node)
2895{
2896 if (node->hasAttribute("follows"))
2897 {
2898 setFollowsNone();
2899
2900 LLString follows;
2901 node->getAttributeString("follows", follows);
2902
2903 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
2904 boost::char_separator<char> sep("|");
2905 tokenizer tokens(follows, sep);
2906 tokenizer::iterator token_iter = tokens.begin();
2907
2908 while(token_iter != tokens.end())
2909 {
2910 const std::string& token_str = *token_iter;
2911 if (token_str == "left")
2912 {
2913 setFollowsLeft();
2914 }
2915 else if (token_str == "right")
2916 {
2917 setFollowsRight();
2918 }
2919 else if (token_str == "top")
2920 {
2921 setFollowsTop();
2922 }
2923 else if (token_str == "bottom")
2924 {
2925 setFollowsBottom();
2926 }
2927 else if (token_str == "all")
2928 {
2929 setFollowsAll();
2930 }
2931 ++token_iter;
2932 }
2933 }
2934}
2935
2936
2847// static 2937// static
2848LLFontGL* LLView::selectFont(LLXMLNodePtr node) 2938LLFontGL* LLView::selectFont(LLXMLNodePtr node)
2849{ 2939{