| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 bool animate_; | 143 bool animate_; |
| 144 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); | 144 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); |
| 145 }; | 145 }; |
| 146 | 146 |
| 147 } // namespace | 147 } // namespace |
| 148 | 148 |
| 149 @interface TabStripController (Private) | 149 @interface TabStripController (Private) |
| 150 - (void)addSubviewToPermanentList:(NSView*)aView; | 150 - (void)addSubviewToPermanentList:(NSView*)aView; |
| 151 - (void)regenerateSubviewList; | 151 - (void)regenerateSubviewList; |
| 152 - (NSInteger)indexForContentsView:(NSView*)view; | 152 - (NSInteger)indexForContentsView:(NSView*)view; |
| 153 - (void)updateFaviconForContents:(TabContents*)contents | 153 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents; |
| 154 - (void)updateFaviconForContents:(content::WebContents*)contents |
| 154 atIndex:(NSInteger)modelIndex; | 155 atIndex:(NSInteger)modelIndex; |
| 155 - (void)layoutTabsWithAnimation:(BOOL)animate | 156 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 156 regenerateSubviews:(BOOL)doUpdate; | 157 regenerateSubviews:(BOOL)doUpdate; |
| 157 - (void)animationDidStopForController:(TabController*)controller | 158 - (void)animationDidStopForController:(TabController*)controller |
| 158 finished:(BOOL)finished; | 159 finished:(BOOL)finished; |
| 159 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 160 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 160 - (void)clickNewTabButton:(id)sender; | 161 - (void)clickNewTabButton:(id)sender; |
| 161 - (NSInteger)numberOfOpenTabs; | 162 - (NSInteger)numberOfOpenTabs; |
| 162 - (NSInteger)numberOfOpenMiniTabs; | 163 - (NSInteger)numberOfOpenMiniTabs; |
| 163 - (NSInteger)numberOfOpenNonMiniTabs; | 164 - (NSInteger)numberOfOpenNonMiniTabs; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 // Set accessibility descriptions. http://openradar.appspot.com/7496255 | 454 // Set accessibility descriptions. http://openradar.appspot.com/7496255 |
| 454 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); | 455 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); |
| 455 [[newTabButton_ cell] | 456 [[newTabButton_ cell] |
| 456 accessibilitySetOverrideValue:description | 457 accessibilitySetOverrideValue:description |
| 457 forAttribute:NSAccessibilityDescriptionAttribute]; | 458 forAttribute:NSAccessibilityDescriptionAttribute]; |
| 458 | 459 |
| 459 // Controller may have been (re-)created by switching layout modes, which | 460 // Controller may have been (re-)created by switching layout modes, which |
| 460 // means the tab model is already fully formed with tabs. Need to walk the | 461 // means the tab model is already fully formed with tabs. Need to walk the |
| 461 // list and create the UI for each. | 462 // list and create the UI for each. |
| 462 const int existingTabCount = tabStripModel_->count(); | 463 const int existingTabCount = tabStripModel_->count(); |
| 463 const TabContents* selection = tabStripModel_->GetActiveTabContents(); | 464 const content::WebContents* selection = |
| 465 tabStripModel_->GetActiveWebContents(); |
| 464 for (int i = 0; i < existingTabCount; ++i) { | 466 for (int i = 0; i < existingTabCount; ++i) { |
| 465 TabContents* currentContents = tabStripModel_->GetTabContentsAt(i); | 467 content::WebContents* currentContents = |
| 468 tabStripModel_->GetWebContentsAt(i); |
| 466 [self insertTabWithContents:currentContents | 469 [self insertTabWithContents:currentContents |
| 467 atIndex:i | 470 atIndex:i |
| 468 inForeground:NO]; | 471 inForeground:NO]; |
| 469 if (selection == currentContents) { | 472 if (selection == currentContents) { |
| 470 // Must manually force a selection since the model won't send | 473 // Must manually force a selection since the model won't send |
| 471 // selection messages in this scenario. | 474 // selection messages in this scenario. |
| 472 [self activateTabWithContents:currentContents | 475 [self activateTabWithContents:currentContents |
| 473 previousContents:NULL | 476 previousContents:NULL |
| 474 atIndex:i | 477 atIndex:i |
| 475 userGesture:NO]; | 478 userGesture:NO]; |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 if (contents) | 1163 if (contents) |
| 1161 titleString = base::SysUTF16ToNSString(contents->GetTitle()); | 1164 titleString = base::SysUTF16ToNSString(contents->GetTitle()); |
| 1162 if (![titleString length]) { | 1165 if (![titleString length]) { |
| 1163 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); | 1166 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); |
| 1164 } | 1167 } |
| 1165 [tab setTitle:titleString]; | 1168 [tab setTitle:titleString]; |
| 1166 } | 1169 } |
| 1167 | 1170 |
| 1168 // Called when a notification is received from the model to insert a new tab | 1171 // Called when a notification is received from the model to insert a new tab |
| 1169 // at |modelIndex|. | 1172 // at |modelIndex|. |
| 1170 - (void)insertTabWithContents:(TabContents*)contents | 1173 - (void)insertTabWithContents:(content::WebContents*)contents |
| 1171 atIndex:(NSInteger)modelIndex | 1174 atIndex:(NSInteger)modelIndex |
| 1172 inForeground:(bool)inForeground { | 1175 inForeground:(bool)inForeground { |
| 1173 DCHECK(contents); | 1176 DCHECK(contents); |
| 1174 DCHECK(modelIndex == TabStripModel::kNoTab || | 1177 DCHECK(modelIndex == TabStripModel::kNoTab || |
| 1175 tabStripModel_->ContainsIndex(modelIndex)); | 1178 tabStripModel_->ContainsIndex(modelIndex)); |
| 1176 | 1179 |
| 1177 // Cancel any pending tab transition. | 1180 // Cancel any pending tab transition. |
| 1178 hoverTabSelector_->CancelTabTransition(); | 1181 hoverTabSelector_->CancelTabTransition(); |
| 1179 | 1182 |
| 1180 // Take closing tabs into account. | 1183 // Take closing tabs into account. |
| 1181 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1184 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1182 | 1185 |
| 1183 // Make a new tab. Load the contents of this tab from the nib and associate | 1186 // Make a new tab. Load the contents of this tab from the nib and associate |
| 1184 // the new controller with |contents| so it can be looked up later. | 1187 // the new controller with |contents| so it can be looked up later. |
| 1185 scoped_nsobject<TabContentsController> contentsController( | 1188 scoped_nsobject<TabContentsController> contentsController( |
| 1186 [[TabContentsController alloc] | 1189 [[TabContentsController alloc] initWithContents:contents]); |
| 1187 initWithContents:contents->web_contents()]); | |
| 1188 [tabContentsArray_ insertObject:contentsController atIndex:index]; | 1190 [tabContentsArray_ insertObject:contentsController atIndex:index]; |
| 1189 | 1191 |
| 1190 // Make a new tab and add it to the strip. Keep track of its controller. | 1192 // Make a new tab and add it to the strip. Keep track of its controller. |
| 1191 TabController* newController = [self newTab]; | 1193 TabController* newController = [self newTab]; |
| 1192 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1194 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1193 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1195 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1194 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1196 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1195 [newController setUrl:contents->web_contents()->GetURL()]; | 1197 [newController setUrl:contents->GetURL()]; |
| 1196 [tabArray_ insertObject:newController atIndex:index]; | 1198 [tabArray_ insertObject:newController atIndex:index]; |
| 1197 NSView* newView = [newController view]; | 1199 NSView* newView = [newController view]; |
| 1198 | 1200 |
| 1199 // Set the originating frame to just below the strip so that it animates | 1201 // Set the originating frame to just below the strip so that it animates |
| 1200 // upwards as it's being initially layed out. Oddly, this works while doing | 1202 // upwards as it's being initially layed out. Oddly, this works while doing |
| 1201 // something similar in |-layoutTabs| confuses the window server. | 1203 // something similar in |-layoutTabs| confuses the window server. |
| 1202 [newView setFrame:NSOffsetRect([newView frame], | 1204 [newView setFrame:NSOffsetRect([newView frame], |
| 1203 0, -[[self class] defaultTabHeight])]; | 1205 0, -[[self class] defaultTabHeight])]; |
| 1204 | 1206 |
| 1205 [self setTabTitle:newController withContents:contents->web_contents()]; | 1207 [self setTabTitle:newController withContents:contents]; |
| 1206 | 1208 |
| 1207 // If a tab is being inserted, we can again use the entire tab strip width | 1209 // If a tab is being inserted, we can again use the entire tab strip width |
| 1208 // for layout. | 1210 // for layout. |
| 1209 availableResizeWidth_ = kUseFullAvailableWidth; | 1211 availableResizeWidth_ = kUseFullAvailableWidth; |
| 1210 | 1212 |
| 1211 // We don't need to call |-layoutTabs| if the tab will be in the foreground | 1213 // We don't need to call |-layoutTabs| if the tab will be in the foreground |
| 1212 // because it will get called when the new tab is selected by the tab model. | 1214 // because it will get called when the new tab is selected by the tab model. |
| 1213 // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1215 // Whenever |-layoutTabs| is called, it'll also add the new subview. |
| 1214 if (!inForeground) { | 1216 if (!inForeground) { |
| 1215 [self layoutTabs]; | 1217 [self layoutTabs]; |
| 1216 } | 1218 } |
| 1217 | 1219 |
| 1218 // During normal loading, we won't yet have a favicon and we'll get | 1220 // During normal loading, we won't yet have a favicon and we'll get |
| 1219 // subsequent state change notifications to show the throbber, but when we're | 1221 // subsequent state change notifications to show the throbber, but when we're |
| 1220 // dragging a tab out into a new window, we have to put the tab's favicon | 1222 // dragging a tab out into a new window, we have to put the tab's favicon |
| 1221 // into the right state up front as we won't be told to do it from anywhere | 1223 // into the right state up front as we won't be told to do it from anywhere |
| 1222 // else. | 1224 // else. |
| 1223 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1225 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1224 } | 1226 } |
| 1225 | 1227 |
| 1226 // Called when a notification is received from the model to select a particular | 1228 // Called when a notification is received from the model to select a particular |
| 1227 // tab. Swaps in the toolbar and content area associated with |newContents|. | 1229 // tab. Swaps in the toolbar and content area associated with |newContents|. |
| 1228 - (void)activateTabWithContents:(TabContents*)newContents | 1230 - (void)activateTabWithContents:(content::WebContents*)newContents |
| 1229 previousContents:(TabContents*)oldContents | 1231 previousContents:(content::WebContents*)oldContents |
| 1230 atIndex:(NSInteger)modelIndex | 1232 atIndex:(NSInteger)modelIndex |
| 1231 userGesture:(bool)wasUserGesture { | 1233 userGesture:(bool)wasUserGesture { |
| 1232 // Take closing tabs into account. | 1234 // Take closing tabs into account. |
| 1233 NSInteger activeIndex = [self indexFromModelIndex:modelIndex]; | 1235 NSInteger activeIndex = [self indexFromModelIndex:modelIndex]; |
| 1234 | 1236 |
| 1235 if (oldContents) { | 1237 if (oldContents) { |
| 1236 int oldModelIndex = | 1238 int oldModelIndex = chrome::GetIndexOfTab(browser_, oldContents); |
| 1237 chrome::GetIndexOfTab(browser_, oldContents->web_contents()); | |
| 1238 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. | 1239 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. |
| 1239 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; | 1240 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; |
| 1240 TabContentsController* oldController = | 1241 TabContentsController* oldController = |
| 1241 [tabContentsArray_ objectAtIndex:oldIndex]; | 1242 [tabContentsArray_ objectAtIndex:oldIndex]; |
| 1242 [oldController willBecomeUnselectedTab]; | 1243 [oldController willBecomeUnselectedTab]; |
| 1243 oldContents->web_contents()->GetView()->StoreFocus(); | 1244 oldContents->GetView()->StoreFocus(); |
| 1244 oldContents->web_contents()->WasHidden(); | 1245 oldContents->WasHidden(); |
| 1245 } | 1246 } |
| 1246 } | 1247 } |
| 1247 | 1248 |
| 1248 // First get the vector of indices, which is allays sorted in ascending order. | 1249 // First get the vector of indices, which is allays sorted in ascending order. |
| 1249 TabStripSelectionModel::SelectedIndices selection( | 1250 TabStripSelectionModel::SelectedIndices selection( |
| 1250 tabStripModel_->selection_model().selected_indices()); | 1251 tabStripModel_->selection_model().selected_indices()); |
| 1251 // Iterate through all of the tabs, selecting each as necessary. | 1252 // Iterate through all of the tabs, selecting each as necessary. |
| 1252 TabStripSelectionModel::SelectedIndices::iterator iter = selection.begin(); | 1253 TabStripSelectionModel::SelectedIndices::iterator iter = selection.begin(); |
| 1253 int i = 0; | 1254 int i = 0; |
| 1254 for (TabController* current in tabArray_.get()) { | 1255 for (TabController* current in tabArray_.get()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1269 | 1270 |
| 1270 // Relayout for new tabs and to let the selected tab grow to be larger in | 1271 // Relayout for new tabs and to let the selected tab grow to be larger in |
| 1271 // size than surrounding tabs if the user has many. This also raises the | 1272 // size than surrounding tabs if the user has many. This also raises the |
| 1272 // selected tab to the top. | 1273 // selected tab to the top. |
| 1273 [self layoutTabs]; | 1274 [self layoutTabs]; |
| 1274 | 1275 |
| 1275 // Swap in the contents for the new tab. | 1276 // Swap in the contents for the new tab. |
| 1276 [self swapInTabAtIndex:modelIndex]; | 1277 [self swapInTabAtIndex:modelIndex]; |
| 1277 | 1278 |
| 1278 if (newContents) { | 1279 if (newContents) { |
| 1279 newContents->web_contents()->WasShown(); | 1280 newContents->WasShown(); |
| 1280 newContents->web_contents()->GetView()->RestoreFocus(); | 1281 newContents->GetView()->RestoreFocus(); |
| 1281 | 1282 |
| 1282 FindTabHelper* findTabHelper = | 1283 FindTabHelper* findTabHelper = FindTabHelper::FromWebContents(newContents); |
| 1283 FindTabHelper::FromWebContents(newContents->web_contents()); | |
| 1284 if (findTabHelper->find_ui_active()) | 1284 if (findTabHelper->find_ui_active()) |
| 1285 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 1285 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); |
| 1286 } | 1286 } |
| 1287 } | 1287 } |
| 1288 | 1288 |
| 1289 - (void)tabReplacedWithContents:(TabContents*)newContents | 1289 - (void)tabReplacedWithContents:(content::WebContents*)newContents |
| 1290 previousContents:(TabContents*)oldContents | 1290 previousContents:(content::WebContents*)oldContents |
| 1291 atIndex:(NSInteger)modelIndex { | 1291 atIndex:(NSInteger)modelIndex { |
| 1292 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1292 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1293 TabContentsController* oldController = | 1293 TabContentsController* oldController = |
| 1294 [tabContentsArray_ objectAtIndex:index]; | 1294 [tabContentsArray_ objectAtIndex:index]; |
| 1295 DCHECK_EQ(oldContents->web_contents(), [oldController webContents]); | 1295 DCHECK_EQ(oldContents, [oldController webContents]); |
| 1296 | 1296 |
| 1297 // Simply create a new TabContentsController for |newContents| and place it | 1297 // Simply create a new TabContentsController for |newContents| and place it |
| 1298 // into the array, replacing |oldContents|. A ActiveTabChanged notification | 1298 // into the array, replacing |oldContents|. A ActiveTabChanged notification |
| 1299 // will follow, at which point we will install the new view. | 1299 // will follow, at which point we will install the new view. |
| 1300 scoped_nsobject<TabContentsController> newController( | 1300 scoped_nsobject<TabContentsController> newController( |
| 1301 [[TabContentsController alloc] | 1301 [[TabContentsController alloc] initWithContents:newContents]); |
| 1302 initWithContents:newContents->web_contents()]); | |
| 1303 | 1302 |
| 1304 // Bye bye, |oldController|. | 1303 // Bye bye, |oldController|. |
| 1305 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; | 1304 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; |
| 1306 | 1305 |
| 1307 // Fake a tab changed notification to force tab titles and favicons to update. | 1306 // Fake a tab changed notification to force tab titles and favicons to update. |
| 1308 [self tabChangedWithContents:newContents | 1307 [self tabChangedWithContents:newContents |
| 1309 atIndex:modelIndex | 1308 atIndex:modelIndex |
| 1310 changeType:TabStripModelObserver::ALL]; | 1309 changeType:TabStripModelObserver::ALL]; |
| 1311 } | 1310 } |
| 1312 | 1311 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 NSRect newFrame = [tabView frame]; | 1391 NSRect newFrame = [tabView frame]; |
| 1393 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); | 1392 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); |
| 1394 ScopedNSAnimationContextGroup animationGroup(true); | 1393 ScopedNSAnimationContextGroup animationGroup(true); |
| 1395 animationGroup.SetCurrentContextDuration(kAnimationDuration); | 1394 animationGroup.SetCurrentContextDuration(kAnimationDuration); |
| 1396 [[tabView animator] setFrame:newFrame]; | 1395 [[tabView animator] setFrame:newFrame]; |
| 1397 } | 1396 } |
| 1398 | 1397 |
| 1399 // Called when a notification is received from the model that the given tab | 1398 // Called when a notification is received from the model that the given tab |
| 1400 // has gone away. Start an animation then force a layout to put everything | 1399 // has gone away. Start an animation then force a layout to put everything |
| 1401 // in motion. | 1400 // in motion. |
| 1402 - (void)tabDetachedWithContents:(TabContents*)contents | 1401 - (void)tabDetachedWithContents:(content::WebContents*)contents |
| 1403 atIndex:(NSInteger)modelIndex { | 1402 atIndex:(NSInteger)modelIndex { |
| 1404 // Take closing tabs into account. | 1403 // Take closing tabs into account. |
| 1405 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1404 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1406 | 1405 |
| 1407 // Cancel any pending tab transition. | 1406 // Cancel any pending tab transition. |
| 1408 hoverTabSelector_->CancelTabTransition(); | 1407 hoverTabSelector_->CancelTabTransition(); |
| 1409 | 1408 |
| 1410 TabController* tab = [tabArray_ objectAtIndex:index]; | 1409 TabController* tab = [tabArray_ objectAtIndex:index]; |
| 1411 if (tabStripModel_->count() > 0) { | 1410 if (tabStripModel_->count() > 0) { |
| 1412 [self startClosingTabWithAnimation:tab]; | 1411 [self startClosingTabWithAnimation:tab]; |
| 1413 [self layoutTabs]; | 1412 [self layoutTabs]; |
| 1414 } else { | 1413 } else { |
| 1415 [self removeTab:tab]; | 1414 [self removeTab:tab]; |
| 1416 } | 1415 } |
| 1417 | 1416 |
| 1418 [delegate_ onTabDetachedWithContents:contents->web_contents()]; | 1417 [delegate_ onTabDetachedWithContents:contents]; |
| 1419 } | 1418 } |
| 1420 | 1419 |
| 1421 // A helper routine for creating an NSImageView to hold the favicon or app icon | 1420 // A helper routine for creating an NSImageView to hold the favicon or app icon |
| 1422 // for |contents|. | 1421 // for |contents|. |
| 1423 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 1422 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents { |
| 1424 extensions::TabHelper* extensions_tab_helper = | 1423 extensions::TabHelper* extensions_tab_helper = |
| 1425 extensions::TabHelper::FromWebContents(contents->web_contents()); | 1424 extensions::TabHelper::FromWebContents(contents); |
| 1426 BOOL isApp = extensions_tab_helper->is_app(); | 1425 BOOL isApp = extensions_tab_helper->is_app(); |
| 1427 NSImage* image = nil; | 1426 NSImage* image = nil; |
| 1428 // Favicons come from the renderer, and the renderer draws everything in the | 1427 // Favicons come from the renderer, and the renderer draws everything in the |
| 1429 // system color space. | 1428 // system color space. |
| 1430 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); | 1429 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); |
| 1431 if (isApp) { | 1430 if (isApp) { |
| 1432 SkBitmap* icon = extensions_tab_helper->GetExtensionAppIcon(); | 1431 SkBitmap* icon = extensions_tab_helper->GetExtensionAppIcon(); |
| 1433 if (icon) | 1432 if (icon) |
| 1434 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); | 1433 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); |
| 1435 } else { | 1434 } else { |
| 1436 image = mac::FaviconForTabContents(contents); | 1435 image = mac::FaviconForWebContents(contents); |
| 1437 } | 1436 } |
| 1438 | 1437 |
| 1439 // Either we don't have a valid favicon or there was some issue converting it | 1438 // Either we don't have a valid favicon or there was some issue converting it |
| 1440 // from an SkBitmap. Either way, just show the default. | 1439 // from an SkBitmap. Either way, just show the default. |
| 1441 if (!image) | 1440 if (!image) |
| 1442 image = defaultFavicon_.get(); | 1441 image = defaultFavicon_.get(); |
| 1443 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1442 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
| 1444 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | 1443 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; |
| 1445 [view setImage:image]; | 1444 [view setImage:image]; |
| 1446 return view; | 1445 return view; |
| 1447 } | 1446 } |
| 1448 | 1447 |
| 1449 // Updates the current loading state, replacing the icon view with a favicon, | 1448 // Updates the current loading state, replacing the icon view with a favicon, |
| 1450 // a throbber, the default icon, or nothing at all. | 1449 // a throbber, the default icon, or nothing at all. |
| 1451 - (void)updateFaviconForContents:(TabContents*)contents | 1450 - (void)updateFaviconForContents:(content::WebContents*)contents |
| 1452 atIndex:(NSInteger)modelIndex { | 1451 atIndex:(NSInteger)modelIndex { |
| 1453 if (!contents) | 1452 if (!contents) |
| 1454 return; | 1453 return; |
| 1455 | 1454 |
| 1456 static NSImage* throbberWaitingImage = | 1455 static NSImage* throbberWaitingImage = |
| 1457 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1456 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1458 IDR_THROBBER_WAITING).CopyNSImage(); | 1457 IDR_THROBBER_WAITING).CopyNSImage(); |
| 1459 static NSImage* throbberLoadingImage = | 1458 static NSImage* throbberLoadingImage = |
| 1460 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1459 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1461 IDR_THROBBER).CopyNSImage(); | 1460 IDR_THROBBER).CopyNSImage(); |
| 1462 static NSImage* sadFaviconImage = | 1461 static NSImage* sadFaviconImage = |
| 1463 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1462 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1464 IDR_SAD_FAVICON).CopyNSImage(); | 1463 IDR_SAD_FAVICON).CopyNSImage(); |
| 1465 | 1464 |
| 1466 // Take closing tabs into account. | 1465 // Take closing tabs into account. |
| 1467 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1466 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1468 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1467 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1469 | 1468 |
| 1470 FaviconTabHelper* favicon_tab_helper = | 1469 FaviconTabHelper* favicon_tab_helper = |
| 1471 FaviconTabHelper::FromWebContents(contents->web_contents()); | 1470 FaviconTabHelper::FromWebContents(contents); |
| 1472 bool oldHasIcon = [tabController iconView] != nil; | 1471 bool oldHasIcon = [tabController iconView] != nil; |
| 1473 bool newHasIcon = favicon_tab_helper->ShouldDisplayFavicon() || | 1472 bool newHasIcon = favicon_tab_helper->ShouldDisplayFavicon() || |
| 1474 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. | 1473 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. |
| 1475 | 1474 |
| 1476 TabLoadingState oldState = [tabController loadingState]; | 1475 TabLoadingState oldState = [tabController loadingState]; |
| 1477 TabLoadingState newState = kTabDone; | 1476 TabLoadingState newState = kTabDone; |
| 1478 NSImage* throbberImage = nil; | 1477 NSImage* throbberImage = nil; |
| 1479 if (contents->web_contents()->IsCrashed()) { | 1478 if (contents->IsCrashed()) { |
| 1480 newState = kTabCrashed; | 1479 newState = kTabCrashed; |
| 1481 newHasIcon = true; | 1480 newHasIcon = true; |
| 1482 } else if (contents->web_contents()->IsWaitingForResponse()) { | 1481 } else if (contents->IsWaitingForResponse()) { |
| 1483 newState = kTabWaiting; | 1482 newState = kTabWaiting; |
| 1484 throbberImage = throbberWaitingImage; | 1483 throbberImage = throbberWaitingImage; |
| 1485 } else if (contents->web_contents()->IsLoading()) { | 1484 } else if (contents->IsLoading()) { |
| 1486 newState = kTabLoading; | 1485 newState = kTabLoading; |
| 1487 throbberImage = throbberLoadingImage; | 1486 throbberImage = throbberLoadingImage; |
| 1488 } | 1487 } |
| 1489 | 1488 |
| 1490 if (oldState != newState) | 1489 if (oldState != newState) |
| 1491 [tabController setLoadingState:newState]; | 1490 [tabController setLoadingState:newState]; |
| 1492 | 1491 |
| 1493 // While loading, this function is called repeatedly with the same state. | 1492 // While loading, this function is called repeatedly with the same state. |
| 1494 // To avoid expensive unnecessary view manipulation, only make changes when | 1493 // To avoid expensive unnecessary view manipulation, only make changes when |
| 1495 // the state is actually changing. When loading is complete (kTabDone), | 1494 // the state is actually changing. When loading is complete (kTabDone), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1523 // some tests. | 1522 // some tests. |
| 1524 //DCHECK_LE(NSMaxX([iconView frame]), | 1523 //DCHECK_LE(NSMaxX([iconView frame]), |
| 1525 // NSWidth([[tabController view] frame]) - kTabOverlap); | 1524 // NSWidth([[tabController view] frame]) - kTabOverlap); |
| 1526 } | 1525 } |
| 1527 } | 1526 } |
| 1528 } | 1527 } |
| 1529 | 1528 |
| 1530 // Called when a notification is received from the model that the given tab | 1529 // Called when a notification is received from the model that the given tab |
| 1531 // has been updated. |loading| will be YES when we only want to update the | 1530 // has been updated. |loading| will be YES when we only want to update the |
| 1532 // throbber state, not anything else about the (partially) loading tab. | 1531 // throbber state, not anything else about the (partially) loading tab. |
| 1533 - (void)tabChangedWithContents:(TabContents*)contents | 1532 - (void)tabChangedWithContents:(content::WebContents*)contents |
| 1534 atIndex:(NSInteger)modelIndex | 1533 atIndex:(NSInteger)modelIndex |
| 1535 changeType:(TabStripModelObserver::TabChangeType)change { | 1534 changeType:(TabStripModelObserver::TabChangeType)change { |
| 1536 // Take closing tabs into account. | 1535 // Take closing tabs into account. |
| 1537 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1536 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1538 | 1537 |
| 1539 if (modelIndex == tabStripModel_->active_index()) | 1538 if (modelIndex == tabStripModel_->active_index()) |
| 1540 [delegate_ onTabChanged:change withContents:contents->web_contents()]; | 1539 [delegate_ onTabChanged:change withContents:contents]; |
| 1541 | 1540 |
| 1542 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { | 1541 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { |
| 1543 // TODO(sky): make this work. | 1542 // TODO(sky): make this work. |
| 1544 // We'll receive another notification of the change asynchronously. | 1543 // We'll receive another notification of the change asynchronously. |
| 1545 return; | 1544 return; |
| 1546 } | 1545 } |
| 1547 | 1546 |
| 1548 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1547 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1549 | 1548 |
| 1550 if (change != TabStripModelObserver::LOADING_ONLY) | 1549 if (change != TabStripModelObserver::LOADING_ONLY) |
| 1551 [self setTabTitle:tabController withContents:contents->web_contents()]; | 1550 [self setTabTitle:tabController withContents:contents]; |
| 1552 | 1551 |
| 1553 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1552 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1554 | 1553 |
| 1555 TabContentsController* updatedController = | 1554 TabContentsController* updatedController = |
| 1556 [tabContentsArray_ objectAtIndex:index]; | 1555 [tabContentsArray_ objectAtIndex:index]; |
| 1557 [updatedController tabDidChange:contents->web_contents()]; | 1556 [updatedController tabDidChange:contents]; |
| 1558 } | 1557 } |
| 1559 | 1558 |
| 1560 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1559 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
| 1561 // in sync with the tab strip model. It can also be pinned/unpinned | 1560 // in sync with the tab strip model. It can also be pinned/unpinned |
| 1562 // simultaneously, so we need to take care of that. | 1561 // simultaneously, so we need to take care of that. |
| 1563 - (void)tabMovedWithContents:(TabContents*)contents | 1562 - (void)tabMovedWithContents:(content::WebContents*)contents |
| 1564 fromIndex:(NSInteger)modelFrom | 1563 fromIndex:(NSInteger)modelFrom |
| 1565 toIndex:(NSInteger)modelTo { | 1564 toIndex:(NSInteger)modelTo { |
| 1566 // Take closing tabs into account. | 1565 // Take closing tabs into account. |
| 1567 NSInteger from = [self indexFromModelIndex:modelFrom]; | 1566 NSInteger from = [self indexFromModelIndex:modelFrom]; |
| 1568 NSInteger to = [self indexFromModelIndex:modelTo]; | 1567 NSInteger to = [self indexFromModelIndex:modelTo]; |
| 1569 | 1568 |
| 1570 // Cancel any pending tab transition. | 1569 // Cancel any pending tab transition. |
| 1571 hoverTabSelector_->CancelTabTransition(); | 1570 hoverTabSelector_->CancelTabTransition(); |
| 1572 | 1571 |
| 1573 scoped_nsobject<TabContentsController> movedTabContentsController( | 1572 scoped_nsobject<TabContentsController> movedTabContentsController( |
| 1574 [[tabContentsArray_ objectAtIndex:from] retain]); | 1573 [[tabContentsArray_ objectAtIndex:from] retain]); |
| 1575 [tabContentsArray_ removeObjectAtIndex:from]; | 1574 [tabContentsArray_ removeObjectAtIndex:from]; |
| 1576 [tabContentsArray_ insertObject:movedTabContentsController.get() | 1575 [tabContentsArray_ insertObject:movedTabContentsController.get() |
| 1577 atIndex:to]; | 1576 atIndex:to]; |
| 1578 scoped_nsobject<TabController> movedTabController( | 1577 scoped_nsobject<TabController> movedTabController( |
| 1579 [[tabArray_ objectAtIndex:from] retain]); | 1578 [[tabArray_ objectAtIndex:from] retain]); |
| 1580 DCHECK([movedTabController isKindOfClass:[TabController class]]); | 1579 DCHECK([movedTabController isKindOfClass:[TabController class]]); |
| 1581 [tabArray_ removeObjectAtIndex:from]; | 1580 [tabArray_ removeObjectAtIndex:from]; |
| 1582 [tabArray_ insertObject:movedTabController.get() atIndex:to]; | 1581 [tabArray_ insertObject:movedTabController.get() atIndex:to]; |
| 1583 | 1582 |
| 1584 // The tab moved, which means that the mini-tab state may have changed. | 1583 // The tab moved, which means that the mini-tab state may have changed. |
| 1585 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) | 1584 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) |
| 1586 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; | 1585 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; |
| 1587 | 1586 |
| 1588 [self layoutTabs]; | 1587 [self layoutTabs]; |
| 1589 } | 1588 } |
| 1590 | 1589 |
| 1591 // Called when a tab is pinned or unpinned without moving. | 1590 // Called when a tab is pinned or unpinned without moving. |
| 1592 - (void)tabMiniStateChangedWithContents:(TabContents*)contents | 1591 - (void)tabMiniStateChangedWithContents:(content::WebContents*)contents |
| 1593 atIndex:(NSInteger)modelIndex { | 1592 atIndex:(NSInteger)modelIndex { |
| 1594 // Take closing tabs into account. | 1593 // Take closing tabs into account. |
| 1595 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1594 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1596 | 1595 |
| 1597 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1596 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1598 DCHECK([tabController isKindOfClass:[TabController class]]); | 1597 DCHECK([tabController isKindOfClass:[TabController class]]); |
| 1599 | 1598 |
| 1600 // Don't do anything if the change was already picked up by the move event. | 1599 // Don't do anything if the change was already picked up by the move event. |
| 1601 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1600 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) |
| 1602 return; | 1601 return; |
| 1603 | 1602 |
| 1604 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1603 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1605 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1604 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1606 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1605 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1607 [tabController setUrl:contents->web_contents()->GetURL()]; | 1606 [tabController setUrl:contents->GetURL()]; |
| 1608 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1607 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1609 // If the tab is being restored and it's pinned, the mini state is set after | 1608 // If the tab is being restored and it's pinned, the mini state is set after |
| 1610 // the tab has already been rendered, so re-layout the tabstrip. In all other | 1609 // the tab has already been rendered, so re-layout the tabstrip. In all other |
| 1611 // cases, the state is set before the tab is rendered so this isn't needed. | 1610 // cases, the state is set before the tab is rendered so this isn't needed. |
| 1612 [self layoutTabs]; | 1611 [self layoutTabs]; |
| 1613 } | 1612 } |
| 1614 | 1613 |
| 1615 - (void)setFrameOfActiveTab:(NSRect)frame { | 1614 - (void)setFrameOfActiveTab:(NSRect)frame { |
| 1616 NSView* view = [self activeTabView]; | 1615 NSView* view = [self activeTabView]; |
| 1617 NSValue* identifier = [NSValue valueWithPointer:view]; | 1616 NSValue* identifier = [NSValue valueWithPointer:view]; |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { | 2106 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { |
| 2108 // View hierarchy of the contents view: | 2107 // View hierarchy of the contents view: |
| 2109 // NSView -- switchView, same for all tabs | 2108 // NSView -- switchView, same for all tabs |
| 2110 // +- NSView -- TabContentsController's view | 2109 // +- NSView -- TabContentsController's view |
| 2111 // +- TabContentsViewCocoa | 2110 // +- TabContentsViewCocoa |
| 2112 // | 2111 // |
| 2113 // Changing it? Do not forget to modify | 2112 // Changing it? Do not forget to modify |
| 2114 // -[TabStripController swapInTabAtIndex:] too. | 2113 // -[TabStripController swapInTabAtIndex:] too. |
| 2115 return [web_contents->GetNativeView() superview]; | 2114 return [web_contents->GetNativeView() superview]; |
| 2116 } | 2115 } |
| OLD | NEW |