diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llui/llview.cpp | 440 |
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 | ||
239 | void LLView::setToolTipArgs( const LLString::format_map_t& args ) | ||
240 | { | ||
241 | mToolTipMsg.setArgList(args); | ||
242 | } | ||
243 | |||
238 | // virtual | 244 | // virtual |
239 | void LLView::setRect(const LLRect& rect) | 245 | void 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 | ||
290 | void LLView::setSpanChildren( BOOL span_children ) | 297 | void LLView::setUseBoundingRect( BOOL use_bounding_rect ) |
298 | { | ||
299 | if (mUseBoundingRect != use_bounding_rect) | ||
300 | { | ||
301 | mUseBoundingRect = use_bounding_rect; | ||
302 | updateBoundingRect(); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | BOOL LLView::getUseBoundingRect() | ||
291 | { | 307 | { |
292 | mSpanChildren = span_children; updateRect(); | 308 | return mUseBoundingRect; |
293 | } | 309 | } |
294 | 310 | ||
295 | const LLString& LLView::getToolTip() | 311 | const LLString& LLView::getToolTip() |
@@ -306,7 +322,7 @@ const LLString& LLView::getName() const | |||
306 | 322 | ||
307 | void LLView::sendChildToFront(LLView* child) | 323 | void 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 | ||
316 | void LLView::sendChildToBack(LLView* child) | 332 | void 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 | ||
349 | void LLView::moveChildToBackOfTabGroup(LLUICtrl* child) | ||
350 | { | ||
351 | if(mCtrlOrder.find(child) != mCtrlOrder.end()) | ||
352 | { | ||
353 | mCtrlOrder[child].second = mNextInsertionOrdinal++; | ||
354 | } | ||
355 | } | ||
356 | |||
333 | void LLView::addChild(LLView* child, S32 tab_group) | 357 | void 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 | ||
408 | void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) | 433 | void 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 ) | |||
815 | void LLView::translate(S32 x, S32 y) | 841 | void 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) | |||
831 | BOOL LLView::handleHover(S32 x, S32 y, MASK mask) | 858 | BOOL 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() | |||
1081 | BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask) | 1110 | BOOL 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) | |||
1118 | BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) | 1147 | BOOL 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) | |||
1143 | BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) | 1172 | BOOL 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) | |||
1153 | BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) | 1182 | BOOL 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. |
1468 | void LLView::drawDebugRect() | 1497 | void 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 | ||
1516 | void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw) | 1556 | void 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 | ||
1538 | void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) | 1578 | void 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 | ||
1613 | LLRect LLView::getRequiredRect() | 1652 | LLRect LLView::getRequiredRect() |
@@ -1615,6 +1654,53 @@ LLRect LLView::getRequiredRect() | |||
1615 | return mRect; | 1654 | return mRect; |
1616 | } | 1655 | } |
1617 | 1656 | ||
1657 | void 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 | |||
1618 | const LLRect LLView::getScreenRect() const | 1704 | const 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 | ||
1713 | const 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 | |||
1627 | const LLRect LLView::getLocalRect() const | 1722 | const 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 | ||
1640 | void LLView::updateRect() | 1735 | BOOL 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 | |||
1671 | BOOL 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 | 1810 | BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const |
1747 | void 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 | 1817 | BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const |
1752 | void 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 | |||
1824 | BOOL 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; | |||
2593 | U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect) | 2667 | U32 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 | ||
2894 | void 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 |
2848 | LLFontGL* LLView::selectFont(LLXMLNodePtr node) | 2938 | LLFontGL* LLView::selectFont(LLXMLNodePtr node) |
2849 | { | 2939 | { |