aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llmenugl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/llmenugl.cpp166
1 files changed, 100 insertions, 66 deletions
diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp
index 4766267..907777d 100644
--- a/linden/indra/llui/llmenugl.cpp
+++ b/linden/indra/llui/llmenugl.cpp
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$ 5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2001-2008, Linden Research, Inc. 7 * Copyright (c) 2001-2009, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -1033,30 +1033,47 @@ void LLMenuItemToggleGL::doIt( void )
1033} 1033}
1034 1034
1035 1035
1036LLMenuItemBranchGL::LLMenuItemBranchGL( const std::string& name, const std::string& label, LLMenuGL* branch, 1036LLMenuItemBranchGL::LLMenuItemBranchGL( const std::string& name, const std::string& label, LLHandle<LLView> branch,
1037 KEY key, MASK mask ) : 1037 KEY key, MASK mask ) :
1038 LLMenuItemGL( name, label, key, mask ), 1038 LLMenuItemGL( name, label, key, mask ),
1039 mBranch( branch ) 1039 mBranch( branch )
1040{ 1040{
1041 mBranch->setVisible( FALSE ); 1041 if(!dynamic_cast<LLMenuGL*>(branch.get()))
1042 mBranch->setParentMenuItem(this); 1042 {
1043 llerrs << "Non-menu handle passed as branch reference." << llendl;
1044 }
1045
1046 if(getBranch())
1047 {
1048 getBranch()->setVisible( FALSE );
1049 getBranch()->setParentMenuItem(this);
1050 }
1051}
1052
1053LLMenuItemBranchGL::~LLMenuItemBranchGL()
1054{
1055 LLView::deleteViewByHandle(mBranch);
1043} 1056}
1044 1057
1045// virtual 1058// virtual
1046LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const 1059LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
1047{ 1060{
1048 // richard: this is redundant with parent, remove 1061 // richard: this is redundant with parent, remove
1049 if (mBranch->getName() == name) 1062 if (getBranch())
1050 {
1051 return mBranch;
1052 }
1053 // Always recurse on branches
1054 LLView* child = mBranch->getChildView(name, recurse, FALSE);
1055 if (!child)
1056 { 1063 {
1057 child = LLView::getChildView(name, recurse, create_if_missing); 1064 if(getBranch()->getName() == name)
1065 {
1066 return getBranch();
1067 }
1068
1069 // Always recurse on branches
1070 LLView* child = getBranch()->getChildView(name, recurse, FALSE);
1071 if(child)
1072 {
1073 return child;
1074 }
1058 } 1075 }
1059 return child; 1076 return LLView::getChildView(name, recurse, create_if_missing);;
1060} 1077}
1061 1078
1062// virtual 1079// virtual
@@ -1072,15 +1089,19 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
1072 1089
1073BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) 1090BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
1074{ 1091{
1075 return mBranch->handleAcceleratorKey(key, mask); 1092 if(getBranch())
1093 {
1094 return getBranch()->handleAcceleratorKey(key, mask);
1095 }
1096 return FALSE;
1076} 1097}
1077 1098
1078// virtual 1099// virtual
1079LLXMLNodePtr LLMenuItemBranchGL::getXML(bool save_children) const 1100LLXMLNodePtr LLMenuItemBranchGL::getXML(bool save_children) const
1080{ 1101{
1081 if (mBranch) 1102 if (getBranch())
1082 { 1103 {
1083 return mBranch->getXML(); 1104 return getBranch()->getXML();
1084 } 1105 }
1085 1106
1086 return LLMenuItemGL::getXML(); 1107 return LLMenuItemGL::getXML();
@@ -1091,14 +1112,17 @@ LLXMLNodePtr LLMenuItemBranchGL::getXML(bool save_children) const
1091// if not, it will be added to the list 1112// if not, it will be added to the list
1092BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp) 1113BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp)
1093{ 1114{
1094 U32 item_count = mBranch->getItemCount(); 1115 if(getBranch())
1095 LLMenuItemGL *item;
1096
1097 while (item_count--)
1098 { 1116 {
1099 if ((item = mBranch->getItem(item_count))) 1117 U32 item_count = getBranch()->getItemCount();
1118 LLMenuItemGL *item;
1119
1120 while (item_count--)
1100 { 1121 {
1101 return item->addToAcceleratorList(listp); 1122 if ((item = getBranch()->getItem(item_count)))
1123 {
1124 return item->addToAcceleratorList(listp);
1125 }
1102 } 1126 }
1103 } 1127 }
1104 return FALSE; 1128 return FALSE;
@@ -1122,18 +1146,18 @@ void LLMenuItemBranchGL::doIt( void )
1122 1146
1123 // keyboard navigation automatically propagates highlight to sub-menu 1147 // keyboard navigation automatically propagates highlight to sub-menu
1124 // to facilitate fast menu control via jump keys 1148 // to facilitate fast menu control via jump keys
1125 if (LLMenuGL::getKeyboardMode() && !mBranch->getHighlightedItem()) 1149 if (getBranch() && LLMenuGL::getKeyboardMode() && !getBranch()->getHighlightedItem())
1126 { 1150 {
1127 mBranch->highlightNextItem(NULL); 1151 getBranch()->highlightNextItem(NULL);
1128 } 1152 }
1129} 1153}
1130 1154
1131BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) 1155BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
1132{ 1156{
1133 BOOL handled = FALSE; 1157 BOOL handled = FALSE;
1134 if (called_from_parent) 1158 if (called_from_parent && getBranch())
1135 { 1159 {
1136 handled = mBranch->handleKey(key, mask, called_from_parent); 1160 handled = getBranch()->handleKey(key, mask, called_from_parent);
1137 } 1161 }
1138 1162
1139 if (!handled) 1163 if (!handled)
@@ -1147,9 +1171,9 @@ BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
1147BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) 1171BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
1148{ 1172{
1149 BOOL handled = FALSE; 1173 BOOL handled = FALSE;
1150 if (called_from_parent) 1174 if (called_from_parent && getBranch())
1151 { 1175 {
1152 handled = mBranch->handleUnicodeChar(uni_char, TRUE); 1176 handled = getBranch()->handleUnicodeChar(uni_char, TRUE);
1153 } 1177 }
1154 1178
1155 if (!handled) 1179 if (!handled)
@@ -1165,14 +1189,19 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
1165{ 1189{
1166 if (highlight == getHighlight()) return; 1190 if (highlight == getHighlight()) return;
1167 1191
1168 BOOL auto_open = getEnabled() && (!mBranch->getVisible() || mBranch->getTornOff()); 1192 if(!getBranch())
1193 {
1194 return;
1195 }
1196
1197 BOOL auto_open = getEnabled() && (!getBranch()->getVisible() || getBranch()->getTornOff());
1169 // torn off menus don't open sub menus on hover unless they have focus 1198 // torn off menus don't open sub menus on hover unless they have focus
1170 if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) 1199 if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus())
1171 { 1200 {
1172 auto_open = FALSE; 1201 auto_open = FALSE;
1173 } 1202 }
1174 // don't auto open torn off sub-menus (need to explicitly active menu item to give them focus) 1203 // don't auto open torn off sub-menus (need to explicitly active menu item to give them focus)
1175 if (mBranch->getTornOff()) 1204 if (getBranch()->getTornOff())
1176 { 1205 {
1177 auto_open = FALSE; 1206 auto_open = FALSE;
1178 } 1207 }
@@ -1186,14 +1215,14 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
1186 } 1215 }
1187 else 1216 else
1188 { 1217 {
1189 if (mBranch->getTornOff()) 1218 if (getBranch()->getTornOff())
1190 { 1219 {
1191 ((LLFloater*)mBranch->getParent())->setFocus(FALSE); 1220 ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
1192 mBranch->clearHoverItem(); 1221 getBranch()->clearHoverItem();
1193 } 1222 }
1194 else 1223 else
1195 { 1224 {
1196 mBranch->setVisible( FALSE ); 1225 getBranch()->setVisible( FALSE );
1197 } 1226 }
1198 } 1227 }
1199} 1228}
@@ -1201,7 +1230,7 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
1201void LLMenuItemBranchGL::draw() 1230void LLMenuItemBranchGL::draw()
1202{ 1231{
1203 LLMenuItemGL::draw(); 1232 LLMenuItemGL::draw();
1204 if (mBranch->getVisible() && !mBranch->getTornOff()) 1233 if (getBranch() && getBranch()->getVisible() && !getBranch()->getTornOff())
1205 { 1234 {
1206 setHighlight(TRUE); 1235 setHighlight(TRUE);
1207 } 1236 }
@@ -1209,33 +1238,33 @@ void LLMenuItemBranchGL::draw()
1209 1238
1210void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) 1239void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)
1211{ 1240{
1212 if (mBranch->getParent() == NULL) 1241 if (getBranch() && getBranch()->getParent() == NULL)
1213 { 1242 {
1214 // make the branch menu a sibling of my parent menu 1243 // make the branch menu a sibling of my parent menu
1215 mBranch->updateParent(parentp); 1244 getBranch()->updateParent(parentp);
1216 } 1245 }
1217} 1246}
1218 1247
1219void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility ) 1248void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )
1220{ 1249{
1221 if (new_visibility == FALSE && !mBranch->getTornOff()) 1250 if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff())
1222 { 1251 {
1223 mBranch->setVisible(FALSE); 1252 getBranch()->setVisible(FALSE);
1224 } 1253 }
1225 LLMenuItemGL::onVisibilityChange(new_visibility); 1254 LLMenuItemGL::onVisibilityChange(new_visibility);
1226} 1255}
1227 1256
1228BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) 1257BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
1229{ 1258{
1230 if (getMenu()->getVisible() && mBranch->getVisible() && key == KEY_LEFT) 1259 if (getMenu()->getVisible() && getBranch() && getBranch()->getVisible() && key == KEY_LEFT)
1231 { 1260 {
1232 // switch to keyboard navigation mode 1261 // switch to keyboard navigation mode
1233 LLMenuGL::setKeyboardMode(TRUE); 1262 LLMenuGL::setKeyboardMode(TRUE);
1234 1263
1235 BOOL handled = mBranch->clearHoverItem(); 1264 BOOL handled = getBranch()->clearHoverItem();
1236 if (mBranch->getTornOff()) 1265 if (getBranch()->getTornOff())
1237 { 1266 {
1238 ((LLFloater*)mBranch->getParent())->setFocus(FALSE); 1267 ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
1239 } 1268 }
1240 if (handled && getMenu()->getTornOff()) 1269 if (handled && getMenu()->getTornOff())
1241 { 1270 {
@@ -1246,12 +1275,12 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
1246 1275
1247 if (getHighlight() && 1276 if (getHighlight() &&
1248 getMenu()->isOpen() && 1277 getMenu()->isOpen() &&
1249 key == KEY_RIGHT && !mBranch->getHighlightedItem()) 1278 key == KEY_RIGHT && getBranch() && !getBranch()->getHighlightedItem())
1250 { 1279 {
1251 // switch to keyboard navigation mode 1280 // switch to keyboard navigation mode
1252 LLMenuGL::setKeyboardMode(TRUE); 1281 LLMenuGL::setKeyboardMode(TRUE);
1253 1282
1254 LLMenuItemGL* itemp = mBranch->highlightNextItem(NULL); 1283 LLMenuItemGL* itemp = getBranch()->highlightNextItem(NULL);
1255 if (itemp) 1284 if (itemp)
1256 { 1285 {
1257 return TRUE; 1286 return TRUE;
@@ -1263,37 +1292,39 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
1263 1292
1264void LLMenuItemBranchGL::openMenu() 1293void LLMenuItemBranchGL::openMenu()
1265{ 1294{
1266 if (mBranch->getTornOff()) 1295 if(!getBranch()) return;
1296
1297 if (getBranch()->getTornOff())
1267 { 1298 {
1268 gFloaterView->bringToFront((LLFloater*)mBranch->getParent()); 1299 gFloaterView->bringToFront((LLFloater*)getBranch()->getParent());
1269 // this might not be necessary, as torn off branches don't get focus and hence no highligth 1300 // this might not be necessary, as torn off branches don't get focus and hence no highligth
1270 mBranch->highlightNextItem(NULL); 1301 getBranch()->highlightNextItem(NULL);
1271 } 1302 }
1272 else if( !mBranch->getVisible() ) 1303 else if( !getBranch()->getVisible() )
1273 { 1304 {
1274 // get valid rectangle for menus 1305 // get valid rectangle for menus
1275 const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); 1306 const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
1276 1307
1277 mBranch->arrange(); 1308 getBranch()->arrange();
1278 1309
1279 LLRect rect = mBranch->getRect(); 1310 LLRect rect = getBranch()->getRect();
1280 // calculate root-view relative position for branch menu 1311 // calculate root-view relative position for branch menu
1281 S32 left = getRect().mRight; 1312 S32 left = getRect().mRight;
1282 S32 top = getRect().mTop - getRect().mBottom; 1313 S32 top = getRect().mTop - getRect().mBottom;
1283 1314
1284 localPointToOtherView(left, top, &left, &top, mBranch->getParent()); 1315 localPointToOtherView(left, top, &left, &top, getBranch()->getParent());
1285 1316
1286 rect.setLeftTopAndSize( left, top, 1317 rect.setLeftTopAndSize( left, top,
1287 rect.getWidth(), rect.getHeight() ); 1318 rect.getWidth(), rect.getHeight() );
1288 1319
1289 if (mBranch->getCanTearOff()) 1320 if (getBranch()->getCanTearOff())
1290 { 1321 {
1291 rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS); 1322 rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS);
1292 } 1323 }
1293 mBranch->setRect( rect ); 1324 getBranch()->setRect( rect );
1294 S32 x = 0; 1325 S32 x = 0;
1295 S32 y = 0; 1326 S32 y = 0;
1296 mBranch->localPointToOtherView( 0, 0, &x, &y, mBranch->getParent() ); 1327 getBranch()->localPointToOtherView( 0, 0, &x, &y, getBranch()->getParent() );
1297 S32 delta_x = 0; 1328 S32 delta_x = 0;
1298 S32 delta_y = 0; 1329 S32 delta_y = 0;
1299 if( y < menu_region_rect.mBottom ) 1330 if( y < menu_region_rect.mBottom )
@@ -1307,9 +1338,9 @@ void LLMenuItemBranchGL::openMenu()
1307 // move sub-menu over to left side 1338 // move sub-menu over to left side
1308 delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth()))); 1339 delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth())));
1309 } 1340 }
1310 mBranch->translate( delta_x, delta_y ); 1341 getBranch()->translate( delta_x, delta_y );
1311 mBranch->setVisible( TRUE ); 1342 getBranch()->setVisible( TRUE );
1312 mBranch->getParent()->sendChildToFront(mBranch); 1343 getBranch()->getParent()->sendChildToFront(getBranch());
1313 } 1344 }
1314} 1345}
1315 1346
@@ -1326,7 +1357,7 @@ class LLMenuItemBranchDownGL : public LLMenuItemBranchGL
1326protected: 1357protected:
1327 1358
1328public: 1359public:
1329 LLMenuItemBranchDownGL( const std::string& name, const std::string& label, LLMenuGL* branch, 1360 LLMenuItemBranchDownGL( const std::string& name, const std::string& label, LLHandle<LLView> branch,
1330 KEY key = KEY_NONE, MASK mask = MASK_NONE ); 1361 KEY key = KEY_NONE, MASK mask = MASK_NONE );
1331 1362
1332 virtual std::string getType() const { return "menu"; } 1363 virtual std::string getType() const { return "menu"; }
@@ -1359,7 +1390,7 @@ public:
1359 1390
1360LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const std::string& name, 1391LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const std::string& name,
1361 const std::string& label, 1392 const std::string& label,
1362 LLMenuGL* branch, 1393 LLHandle<LLView> branch,
1363 KEY key, MASK mask ) : 1394 KEY key, MASK mask ) :
1364 LLMenuItemBranchGL( name, label, branch, key, mask ) 1395 LLMenuItemBranchGL( name, label, branch, key, mask )
1365{ 1396{
@@ -2257,7 +2288,7 @@ void LLMenuGL::createSpilloverBranch()
2257 mSpilloverMenu->setBackgroundColor( mBackgroundColor ); 2288 mSpilloverMenu->setBackgroundColor( mBackgroundColor );
2258 mSpilloverMenu->setCanTearOff(FALSE); 2289 mSpilloverMenu->setCanTearOff(FALSE);
2259 2290
2260 mSpilloverBranch = new LLMenuItemBranchGL(std::string("More"), std::string("More"), mSpilloverMenu); 2291 mSpilloverBranch = new LLMenuItemBranchGL(std::string("More"), std::string("More"), mSpilloverMenu->getHandle());
2261 mSpilloverBranch->setFontStyle(LLFontGL::ITALIC); 2292 mSpilloverBranch->setFontStyle(LLFontGL::ITALIC);
2262 } 2293 }
2263} 2294}
@@ -2277,9 +2308,6 @@ void LLMenuGL::cleanupSpilloverBranch()
2277 mItems.erase(found_iter); 2308 mItems.erase(found_iter);
2278 } 2309 }
2279 2310
2280 delete mSpilloverBranch;
2281 mSpilloverBranch = NULL;
2282
2283 // pop off spillover items 2311 // pop off spillover items
2284 while (mSpilloverMenu->getItemCount()) 2312 while (mSpilloverMenu->getItemCount())
2285 { 2313 {
@@ -2290,6 +2318,12 @@ void LLMenuGL::cleanupSpilloverBranch()
2290 mItems.push_back(itemp); 2318 mItems.push_back(itemp);
2291 addChild(itemp); 2319 addChild(itemp);
2292 } 2320 }
2321
2322 // Delete the branch, and since the branch will delete the menu,
2323 // set the menu* to null.
2324 delete mSpilloverBranch;
2325 mSpilloverBranch = NULL;
2326 mSpilloverMenu = NULL;
2293 } 2327 }
2294} 2328}
2295 2329
@@ -2462,7 +2496,7 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
2462 BOOL success = TRUE; 2496 BOOL success = TRUE;
2463 2497
2464 LLMenuItemBranchGL* branch = NULL; 2498 LLMenuItemBranchGL* branch = NULL;
2465 branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu ); 2499 branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() );
2466 branch->setJumpKey(menu->getJumpKey()); 2500 branch->setJumpKey(menu->getJumpKey());
2467 success &= append( branch ); 2501 success &= append( branch );
2468 2502
@@ -4071,7 +4105,7 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )
4071 BOOL success = TRUE; 4105 BOOL success = TRUE;
4072 4106
4073 LLMenuItemBranchGL* branch = NULL; 4107 LLMenuItemBranchGL* branch = NULL;
4074 branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu ); 4108 branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu->getHandle());
4075 success &= branch->addToAcceleratorList(&mAccelerators); 4109 success &= branch->addToAcceleratorList(&mAccelerators);
4076 success &= append( branch ); 4110 success &= append( branch );
4077 branch->setJumpKey(branch->getJumpKey()); 4111 branch->setJumpKey(branch->getJumpKey());