OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/cocoa/tab_strip_controller.h" | 5 #import "chrome/browser/cocoa/tab_strip_controller.h" |
6 | 6 |
7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 #include <string> | 10 #include <string> |
(...skipping 19 matching lines...) Expand all Loading... |
30 #import "chrome/browser/cocoa/tab_view.h" | 30 #import "chrome/browser/cocoa/tab_view.h" |
31 #import "chrome/browser/cocoa/throbber_view.h" | 31 #import "chrome/browser/cocoa/throbber_view.h" |
32 #include "chrome/browser/debugger/devtools_window.h" | 32 #include "chrome/browser/debugger/devtools_window.h" |
33 #include "chrome/browser/net/url_fixer_upper.h" | 33 #include "chrome/browser/net/url_fixer_upper.h" |
34 #include "chrome/browser/sidebar/sidebar_container.h" | 34 #include "chrome/browser/sidebar/sidebar_container.h" |
35 #include "chrome/browser/sidebar/sidebar_manager.h" | 35 #include "chrome/browser/sidebar/sidebar_manager.h" |
36 #include "chrome/browser/tab_contents/navigation_controller.h" | 36 #include "chrome/browser/tab_contents/navigation_controller.h" |
37 #include "chrome/browser/tab_contents/navigation_entry.h" | 37 #include "chrome/browser/tab_contents/navigation_entry.h" |
38 #include "chrome/browser/tab_contents/tab_contents.h" | 38 #include "chrome/browser/tab_contents/tab_contents.h" |
39 #include "chrome/browser/tab_contents/tab_contents_view.h" | 39 #include "chrome/browser/tab_contents/tab_contents_view.h" |
| 40 #include "chrome/browser/tab_contents_wrapper.h" |
40 #include "chrome/browser/tabs/tab_strip_model.h" | 41 #include "chrome/browser/tabs/tab_strip_model.h" |
41 #include "chrome/browser/ui/browser_navigator.h" | 42 #include "chrome/browser/ui/browser_navigator.h" |
42 #include "grit/app_resources.h" | 43 #include "grit/app_resources.h" |
43 #include "grit/generated_resources.h" | 44 #include "grit/generated_resources.h" |
44 #include "grit/theme_resources.h" | 45 #include "grit/theme_resources.h" |
45 #include "skia/ext/skia_utils_mac.h" | 46 #include "skia/ext/skia_utils_mac.h" |
46 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | 47 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" |
47 | 48 |
48 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; | 49 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; |
49 | 50 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // Set accessibility descriptions. http://openradar.appspot.com/7496255 | 370 // Set accessibility descriptions. http://openradar.appspot.com/7496255 |
370 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); | 371 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); |
371 [[newTabButton_ cell] | 372 [[newTabButton_ cell] |
372 accessibilitySetOverrideValue:description | 373 accessibilitySetOverrideValue:description |
373 forAttribute:NSAccessibilityDescriptionAttribute]; | 374 forAttribute:NSAccessibilityDescriptionAttribute]; |
374 | 375 |
375 // Controller may have been (re-)created by switching layout modes, which | 376 // Controller may have been (re-)created by switching layout modes, which |
376 // means the tab model is already fully formed with tabs. Need to walk the | 377 // means the tab model is already fully formed with tabs. Need to walk the |
377 // list and create the UI for each. | 378 // list and create the UI for each. |
378 const int existingTabCount = tabStripModel_->count(); | 379 const int existingTabCount = tabStripModel_->count(); |
379 const TabContents* selection = tabStripModel_->GetSelectedTabContents(); | 380 const TabContentsWrapper* selection = |
| 381 tabStripModel_->GetSelectedTabContents(); |
380 for (int i = 0; i < existingTabCount; ++i) { | 382 for (int i = 0; i < existingTabCount; ++i) { |
381 TabContents* currentContents = tabStripModel_->GetTabContentsAt(i); | 383 TabContentsWrapper* currentContents = tabStripModel_->GetTabContentsAt(i); |
382 [self insertTabWithContents:currentContents | 384 [self insertTabWithContents:currentContents |
383 atIndex:i | 385 atIndex:i |
384 inForeground:NO]; | 386 inForeground:NO]; |
385 if (selection == currentContents) { | 387 if (selection == currentContents) { |
386 // Must manually force a selection since the model won't send | 388 // Must manually force a selection since the model won't send |
387 // selection messages in this scenario. | 389 // selection messages in this scenario. |
388 [self selectTabWithContents:currentContents | 390 [self selectTabWithContents:currentContents |
389 previousContents:NULL | 391 previousContents:NULL |
390 atIndex:i | 392 atIndex:i |
391 userGesture:NO]; | 393 userGesture:NO]; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 469 } |
468 | 470 |
469 // New content is in place, delegate should adjust itself accordingly. | 471 // New content is in place, delegate should adjust itself accordingly. |
470 [delegate_ onSelectTabWithContents:[controller tabContents]]; | 472 [delegate_ onSelectTabWithContents:[controller tabContents]]; |
471 | 473 |
472 // It also restores content autoresizing properties. | 474 // It also restores content autoresizing properties. |
473 [controller ensureContentsVisible]; | 475 [controller ensureContentsVisible]; |
474 | 476 |
475 // Make sure the new tabs's sheets are visible (necessary when a background | 477 // Make sure the new tabs's sheets are visible (necessary when a background |
476 // tab opened a sheet while it was in the background and now becomes active). | 478 // tab opened a sheet while it was in the background and now becomes active). |
477 TabContents* newTab = tabStripModel_->GetTabContentsAt(modelIndex); | 479 TabContentsWrapper* newTab = tabStripModel_->GetTabContentsAt(modelIndex); |
478 DCHECK(newTab); | 480 DCHECK(newTab); |
479 if (newTab) { | 481 if (newTab) { |
480 TabContents::ConstrainedWindowList::iterator it, end; | 482 TabContents::ConstrainedWindowList::iterator it, end; |
481 end = newTab->constrained_window_end(); | 483 end = newTab->tab_contents()->constrained_window_end(); |
482 NSWindowController* controller = [[newView window] windowController]; | 484 NSWindowController* controller = [[newView window] windowController]; |
483 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 485 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); |
484 | 486 |
485 for (it = newTab->constrained_window_begin(); it != end; ++it) { | 487 for (it = newTab->tab_contents()->constrained_window_begin(); |
| 488 it != end; |
| 489 ++it) { |
486 ConstrainedWindow* constrainedWindow = *it; | 490 ConstrainedWindow* constrainedWindow = *it; |
487 static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( | 491 static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( |
488 static_cast<BrowserWindowController*>(controller)); | 492 static_cast<BrowserWindowController*>(controller)); |
489 } | 493 } |
490 } | 494 } |
491 | 495 |
492 // Tell per-tab sheet manager about currently selected tab. | 496 // Tell per-tab sheet manager about currently selected tab. |
493 if (sheetController_.get()) { | 497 if (sheetController_.get()) { |
494 [sheetController_ setActiveView:newView]; | 498 [sheetController_ setActiveView:newView]; |
495 } | 499 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 - (void)closeTab:(id)sender { | 624 - (void)closeTab:(id)sender { |
621 DCHECK([sender isKindOfClass:[TabView class]]); | 625 DCHECK([sender isKindOfClass:[TabView class]]); |
622 if ([hoveredTab_ isEqual:sender]) { | 626 if ([hoveredTab_ isEqual:sender]) { |
623 hoveredTab_ = nil; | 627 hoveredTab_ = nil; |
624 } | 628 } |
625 | 629 |
626 NSInteger index = [self modelIndexForTabView:sender]; | 630 NSInteger index = [self modelIndexForTabView:sender]; |
627 if (!tabStripModel_->ContainsIndex(index)) | 631 if (!tabStripModel_->ContainsIndex(index)) |
628 return; | 632 return; |
629 | 633 |
630 TabContents* contents = tabStripModel_->GetTabContentsAt(index); | 634 TabContentsWrapper* contents = tabStripModel_->GetTabContentsAt(index); |
631 if (contents) | 635 if (contents) |
632 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Mouse"), | 636 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Mouse"), |
633 contents->profile()); | 637 contents->tab_contents()->profile()); |
634 const NSInteger numberOfOpenTabs = [self numberOfOpenTabs]; | 638 const NSInteger numberOfOpenTabs = [self numberOfOpenTabs]; |
635 if (numberOfOpenTabs > 1) { | 639 if (numberOfOpenTabs > 1) { |
636 bool isClosingLastTab = index == numberOfOpenTabs - 1; | 640 bool isClosingLastTab = index == numberOfOpenTabs - 1; |
637 if (!isClosingLastTab) { | 641 if (!isClosingLastTab) { |
638 // Limit the width available for laying out tabs so that tabs are not | 642 // Limit the width available for laying out tabs so that tabs are not |
639 // resized until a later time (when the mouse leaves the tab strip). | 643 // resized until a later time (when the mouse leaves the tab strip). |
640 // However, if the tab being closed is a pinned tab, break out of | 644 // However, if the tab being closed is a pinned tab, break out of |
641 // rapid-closure mode since the mouse is almost guaranteed not to be over | 645 // rapid-closure mode since the mouse is almost guaranteed not to be over |
642 // the closebox of the adjacent tab (due to the difference in widths). | 646 // the closebox of the adjacent tab (due to the difference in widths). |
643 // TODO(pinkerton): re-visit when handling tab overflow. | 647 // TODO(pinkerton): re-visit when handling tab overflow. |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 if (contents) | 957 if (contents) |
954 titleString = base::SysUTF16ToNSString(contents->GetTitle()); | 958 titleString = base::SysUTF16ToNSString(contents->GetTitle()); |
955 if (![titleString length]) { | 959 if (![titleString length]) { |
956 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); | 960 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); |
957 } | 961 } |
958 [tab setTitle:titleString]; | 962 [tab setTitle:titleString]; |
959 } | 963 } |
960 | 964 |
961 // Called when a notification is received from the model to insert a new tab | 965 // Called when a notification is received from the model to insert a new tab |
962 // at |modelIndex|. | 966 // at |modelIndex|. |
963 - (void)insertTabWithContents:(TabContents*)contents | 967 - (void)insertTabWithContents:(TabContentsWrapper*)contents |
964 atIndex:(NSInteger)modelIndex | 968 atIndex:(NSInteger)modelIndex |
965 inForeground:(bool)inForeground { | 969 inForeground:(bool)inForeground { |
966 DCHECK(contents); | 970 DCHECK(contents); |
967 DCHECK(modelIndex == TabStripModel::kNoTab || | 971 DCHECK(modelIndex == TabStripModel::kNoTab || |
968 tabStripModel_->ContainsIndex(modelIndex)); | 972 tabStripModel_->ContainsIndex(modelIndex)); |
969 | 973 |
970 // Take closing tabs into account. | 974 // Take closing tabs into account. |
971 NSInteger index = [self indexFromModelIndex:modelIndex]; | 975 NSInteger index = [self indexFromModelIndex:modelIndex]; |
972 | 976 |
973 // Make a new tab. Load the contents of this tab from the nib and associate | 977 // Make a new tab. Load the contents of this tab from the nib and associate |
974 // the new controller with |contents| so it can be looked up later. | 978 // the new controller with |contents| so it can be looked up later. |
975 scoped_nsobject<TabContentsController> contentsController( | 979 scoped_nsobject<TabContentsController> contentsController( |
976 [[TabContentsController alloc] initWithContents:contents delegate:self]); | 980 [[TabContentsController alloc] initWithContents:contents->tab_contents() |
| 981 delegate:self]); |
977 [tabContentsArray_ insertObject:contentsController atIndex:index]; | 982 [tabContentsArray_ insertObject:contentsController atIndex:index]; |
978 | 983 |
979 // Make a new tab and add it to the strip. Keep track of its controller. | 984 // Make a new tab and add it to the strip. Keep track of its controller. |
980 TabController* newController = [self newTab]; | 985 TabController* newController = [self newTab]; |
981 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 986 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
982 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 987 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
983 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 988 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
984 [tabArray_ insertObject:newController atIndex:index]; | 989 [tabArray_ insertObject:newController atIndex:index]; |
985 NSView* newView = [newController view]; | 990 NSView* newView = [newController view]; |
986 | 991 |
987 // Set the originating frame to just below the strip so that it animates | 992 // Set the originating frame to just below the strip so that it animates |
988 // upwards as it's being initially layed out. Oddly, this works while doing | 993 // upwards as it's being initially layed out. Oddly, this works while doing |
989 // something similar in |-layoutTabs| confuses the window server. | 994 // something similar in |-layoutTabs| confuses the window server. |
990 [newView setFrame:NSOffsetRect([newView frame], | 995 [newView setFrame:NSOffsetRect([newView frame], |
991 0, -[[self class] defaultTabHeight])]; | 996 0, -[[self class] defaultTabHeight])]; |
992 | 997 |
993 [self setTabTitle:newController withContents:contents]; | 998 [self setTabTitle:newController withContents:contents->tab_contents()]; |
994 | 999 |
995 // If a tab is being inserted, we can again use the entire tab strip width | 1000 // If a tab is being inserted, we can again use the entire tab strip width |
996 // for layout. | 1001 // for layout. |
997 availableResizeWidth_ = kUseFullAvailableWidth; | 1002 availableResizeWidth_ = kUseFullAvailableWidth; |
998 | 1003 |
999 // We don't need to call |-layoutTabs| if the tab will be in the foreground | 1004 // We don't need to call |-layoutTabs| if the tab will be in the foreground |
1000 // because it will get called when the new tab is selected by the tab model. | 1005 // because it will get called when the new tab is selected by the tab model. |
1001 // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1006 // Whenever |-layoutTabs| is called, it'll also add the new subview. |
1002 if (!inForeground) { | 1007 if (!inForeground) { |
1003 [self layoutTabs]; | 1008 [self layoutTabs]; |
1004 } | 1009 } |
1005 | 1010 |
1006 // During normal loading, we won't yet have a favicon and we'll get | 1011 // During normal loading, we won't yet have a favicon and we'll get |
1007 // subsequent state change notifications to show the throbber, but when we're | 1012 // subsequent state change notifications to show the throbber, but when we're |
1008 // dragging a tab out into a new window, we have to put the tab's favicon | 1013 // dragging a tab out into a new window, we have to put the tab's favicon |
1009 // into the right state up front as we won't be told to do it from anywhere | 1014 // into the right state up front as we won't be told to do it from anywhere |
1010 // else. | 1015 // else. |
1011 [self updateFavIconForContents:contents atIndex:modelIndex]; | 1016 [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; |
1012 | 1017 |
1013 // Send a broadcast that the number of tabs have changed. | 1018 // Send a broadcast that the number of tabs have changed. |
1014 [[NSNotificationCenter defaultCenter] | 1019 [[NSNotificationCenter defaultCenter] |
1015 postNotificationName:kTabStripNumberOfTabsChanged | 1020 postNotificationName:kTabStripNumberOfTabsChanged |
1016 object:self]; | 1021 object:self]; |
1017 } | 1022 } |
1018 | 1023 |
1019 // Called when a notification is received from the model to select a particular | 1024 // Called when a notification is received from the model to select a particular |
1020 // tab. Swaps in the toolbar and content area associated with |newContents|. | 1025 // tab. Swaps in the toolbar and content area associated with |newContents|. |
1021 - (void)selectTabWithContents:(TabContents*)newContents | 1026 - (void)selectTabWithContents:(TabContentsWrapper*)newContents |
1022 previousContents:(TabContents*)oldContents | 1027 previousContents:(TabContentsWrapper*)oldContents |
1023 atIndex:(NSInteger)modelIndex | 1028 atIndex:(NSInteger)modelIndex |
1024 userGesture:(bool)wasUserGesture { | 1029 userGesture:(bool)wasUserGesture { |
1025 // Take closing tabs into account. | 1030 // Take closing tabs into account. |
1026 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1031 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1027 | 1032 |
1028 if (oldContents) { | 1033 if (oldContents) { |
1029 int oldModelIndex = | 1034 int oldModelIndex = |
1030 browser_->GetIndexOfController(&(oldContents->controller())); | 1035 browser_->GetIndexOfController(&(oldContents->controller())); |
1031 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. | 1036 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. |
1032 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; | 1037 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; |
1033 TabContentsController* oldController = | 1038 TabContentsController* oldController = |
1034 [tabContentsArray_ objectAtIndex:oldIndex]; | 1039 [tabContentsArray_ objectAtIndex:oldIndex]; |
1035 [oldController willBecomeUnselectedTab]; | 1040 [oldController willBecomeUnselectedTab]; |
1036 oldContents->view()->StoreFocus(); | 1041 oldContents->view()->StoreFocus(); |
1037 oldContents->WasHidden(); | 1042 oldContents->tab_contents()->WasHidden(); |
1038 } | 1043 } |
1039 } | 1044 } |
1040 | 1045 |
1041 // De-select all other tabs and select the new tab. | 1046 // De-select all other tabs and select the new tab. |
1042 int i = 0; | 1047 int i = 0; |
1043 for (TabController* current in tabArray_.get()) { | 1048 for (TabController* current in tabArray_.get()) { |
1044 [current setSelected:(i == index) ? YES : NO]; | 1049 [current setSelected:(i == index) ? YES : NO]; |
1045 ++i; | 1050 ++i; |
1046 } | 1051 } |
1047 | 1052 |
1048 // Tell the new tab contents it is about to become the selected tab. Here it | 1053 // Tell the new tab contents it is about to become the selected tab. Here it |
1049 // can do things like make sure the toolbar is up to date. | 1054 // can do things like make sure the toolbar is up to date. |
1050 TabContentsController* newController = | 1055 TabContentsController* newController = |
1051 [tabContentsArray_ objectAtIndex:index]; | 1056 [tabContentsArray_ objectAtIndex:index]; |
1052 [newController willBecomeSelectedTab]; | 1057 [newController willBecomeSelectedTab]; |
1053 | 1058 |
1054 // Relayout for new tabs and to let the selected tab grow to be larger in | 1059 // Relayout for new tabs and to let the selected tab grow to be larger in |
1055 // size than surrounding tabs if the user has many. This also raises the | 1060 // size than surrounding tabs if the user has many. This also raises the |
1056 // selected tab to the top. | 1061 // selected tab to the top. |
1057 [self layoutTabs]; | 1062 [self layoutTabs]; |
1058 | 1063 |
1059 // Swap in the contents for the new tab. | 1064 // Swap in the contents for the new tab. |
1060 [self swapInTabAtIndex:modelIndex]; | 1065 [self swapInTabAtIndex:modelIndex]; |
1061 | 1066 |
1062 if (newContents) { | 1067 if (newContents) { |
1063 newContents->DidBecomeSelected(); | 1068 newContents->tab_contents()->DidBecomeSelected(); |
1064 newContents->view()->RestoreFocus(); | 1069 newContents->view()->RestoreFocus(); |
1065 | 1070 |
1066 if (newContents->find_ui_active()) | 1071 if (newContents->tab_contents()->find_ui_active()) |
1067 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 1072 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); |
1068 } | 1073 } |
1069 } | 1074 } |
1070 | 1075 |
1071 - (void)tabReplacedWithContents:(TabContents*)newContents | 1076 - (void)tabReplacedWithContents:(TabContentsWrapper*)newContents |
1072 previousContents:(TabContents*)oldContents | 1077 previousContents:(TabContentsWrapper*)oldContents |
1073 atIndex:(NSInteger)modelIndex { | 1078 atIndex:(NSInteger)modelIndex { |
1074 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1079 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1075 TabContentsController* oldController = | 1080 TabContentsController* oldController = |
1076 [tabContentsArray_ objectAtIndex:index]; | 1081 [tabContentsArray_ objectAtIndex:index]; |
1077 DCHECK_EQ(oldContents, [oldController tabContents]); | 1082 DCHECK_EQ(oldContents->tab_contents(), [oldController tabContents]); |
1078 | 1083 |
1079 // Simply create a new TabContentsController for |newContents| and place it | 1084 // Simply create a new TabContentsController for |newContents| and place it |
1080 // into the array, replacing |oldContents|. A TabSelectedAt notification will | 1085 // into the array, replacing |oldContents|. A TabSelectedAt notification will |
1081 // follow, at which point we will install the new view. | 1086 // follow, at which point we will install the new view. |
1082 scoped_nsobject<TabContentsController> newController( | 1087 scoped_nsobject<TabContentsController> newController( |
| 1088 <<<<<<< .mine |
| 1089 [[TabContentsController alloc] |
| 1090 initWithContents:newContents->tab_contents()]); |
| 1091 ======= |
1083 [[TabContentsController alloc] initWithContents:newContents | 1092 [[TabContentsController alloc] initWithContents:newContents |
1084 delegate:self]); | 1093 delegate:self]); |
| 1094 >>>>>>> .r66339 |
1085 | 1095 |
1086 // Bye bye, |oldController|. | 1096 // Bye bye, |oldController|. |
1087 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; | 1097 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; |
1088 | 1098 |
1089 [delegate_ onReplaceTabWithContents:newContents]; | 1099 [delegate_ onReplaceTabWithContents:newContents->tab_contents()]; |
1090 } | 1100 } |
1091 | 1101 |
1092 // Remove all knowledge about this tab and its associated controller, and remove | 1102 // Remove all knowledge about this tab and its associated controller, and remove |
1093 // the view from the strip. | 1103 // the view from the strip. |
1094 - (void)removeTab:(TabController*)controller { | 1104 - (void)removeTab:(TabController*)controller { |
1095 NSUInteger index = [tabArray_ indexOfObject:controller]; | 1105 NSUInteger index = [tabArray_ indexOfObject:controller]; |
1096 | 1106 |
1097 // Release the tab contents controller so those views get destroyed. This | 1107 // Release the tab contents controller so those views get destroyed. This |
1098 // will remove all the tab content Cocoa views from the hierarchy. A | 1108 // will remove all the tab content Cocoa views from the hierarchy. A |
1099 // subsequent "select tab" notification will follow from the model. To | 1109 // subsequent "select tab" notification will follow from the model. To |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 NSRect newFrame = [tabView frame]; | 1174 NSRect newFrame = [tabView frame]; |
1165 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); | 1175 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); |
1166 ScopedNSAnimationContextGroup animationGroup(true); | 1176 ScopedNSAnimationContextGroup animationGroup(true); |
1167 animationGroup.SetCurrentContextDuration(kAnimationDuration); | 1177 animationGroup.SetCurrentContextDuration(kAnimationDuration); |
1168 [[tabView animator] setFrame:newFrame]; | 1178 [[tabView animator] setFrame:newFrame]; |
1169 } | 1179 } |
1170 | 1180 |
1171 // Called when a notification is received from the model that the given tab | 1181 // Called when a notification is received from the model that the given tab |
1172 // has gone away. Start an animation then force a layout to put everything | 1182 // has gone away. Start an animation then force a layout to put everything |
1173 // in motion. | 1183 // in motion. |
1174 - (void)tabDetachedWithContents:(TabContents*)contents | 1184 - (void)tabDetachedWithContents:(TabContentsWrapper*)contents |
1175 atIndex:(NSInteger)modelIndex { | 1185 atIndex:(NSInteger)modelIndex { |
1176 // Take closing tabs into account. | 1186 // Take closing tabs into account. |
1177 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1187 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1178 | 1188 |
1179 TabController* tab = [tabArray_ objectAtIndex:index]; | 1189 TabController* tab = [tabArray_ objectAtIndex:index]; |
1180 if (tabStripModel_->count() > 0) { | 1190 if (tabStripModel_->count() > 0) { |
1181 [self startClosingTabWithAnimation:tab]; | 1191 [self startClosingTabWithAnimation:tab]; |
1182 [self layoutTabs]; | 1192 [self layoutTabs]; |
1183 } else { | 1193 } else { |
1184 [self removeTab:tab]; | 1194 [self removeTab:tab]; |
1185 } | 1195 } |
1186 | 1196 |
1187 // Send a broadcast that the number of tabs have changed. | 1197 // Send a broadcast that the number of tabs have changed. |
1188 [[NSNotificationCenter defaultCenter] | 1198 [[NSNotificationCenter defaultCenter] |
1189 postNotificationName:kTabStripNumberOfTabsChanged | 1199 postNotificationName:kTabStripNumberOfTabsChanged |
1190 object:self]; | 1200 object:self]; |
1191 | 1201 |
1192 [delegate_ onTabDetachedWithContents:contents]; | 1202 [delegate_ onTabDetachedWithContents:contents->tab_contents()]; |
1193 } | 1203 } |
1194 | 1204 |
1195 // A helper routine for creating an NSImageView to hold the fav icon or app icon | 1205 // A helper routine for creating an NSImageView to hold the fav icon or app icon |
1196 // for |contents|. | 1206 // for |contents|. |
1197 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 1207 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { |
1198 BOOL isApp = contents->is_app(); | 1208 BOOL isApp = contents->is_app(); |
1199 NSImage* image = nil; | 1209 NSImage* image = nil; |
1200 if (isApp) { | 1210 if (isApp) { |
1201 SkBitmap* icon = contents->GetExtensionAppIcon(); | 1211 SkBitmap* icon = contents->GetExtensionAppIcon(); |
1202 if (icon) | 1212 if (icon) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 } | 1292 } |
1283 } | 1293 } |
1284 | 1294 |
1285 [tabController setIconView:iconView]; | 1295 [tabController setIconView:iconView]; |
1286 } | 1296 } |
1287 } | 1297 } |
1288 | 1298 |
1289 // Called when a notification is received from the model that the given tab | 1299 // Called when a notification is received from the model that the given tab |
1290 // has been updated. |loading| will be YES when we only want to update the | 1300 // has been updated. |loading| will be YES when we only want to update the |
1291 // throbber state, not anything else about the (partially) loading tab. | 1301 // throbber state, not anything else about the (partially) loading tab. |
1292 - (void)tabChangedWithContents:(TabContents*)contents | 1302 - (void)tabChangedWithContents:(TabContentsWrapper*)contents |
1293 atIndex:(NSInteger)modelIndex | 1303 atIndex:(NSInteger)modelIndex |
1294 changeType:(TabStripModelObserver::TabChangeType)change { | 1304 changeType:(TabStripModelObserver::TabChangeType)change { |
1295 // Take closing tabs into account. | 1305 // Take closing tabs into account. |
1296 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1306 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1297 | 1307 |
1298 if (modelIndex == tabStripModel_->selected_index()) | 1308 if (modelIndex == tabStripModel_->selected_index()) |
1299 [delegate_ onSelectedTabChange:change]; | 1309 [delegate_ onSelectedTabChange:change]; |
1300 | 1310 |
1301 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { | 1311 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { |
1302 // TODO(sky): make this work. | 1312 // TODO(sky): make this work. |
1303 // We'll receive another notification of the change asynchronously. | 1313 // We'll receive another notification of the change asynchronously. |
1304 return; | 1314 return; |
1305 } | 1315 } |
1306 | 1316 |
1307 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1317 TabController* tabController = [tabArray_ objectAtIndex:index]; |
1308 | 1318 |
1309 if (change != TabStripModelObserver::LOADING_ONLY) | 1319 if (change != TabStripModelObserver::LOADING_ONLY) |
1310 [self setTabTitle:tabController withContents:contents]; | 1320 [self setTabTitle:tabController withContents:contents->tab_contents()]; |
1311 | 1321 |
1312 [self updateFavIconForContents:contents atIndex:modelIndex]; | 1322 [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; |
1313 | 1323 |
1314 TabContentsController* updatedController = | 1324 TabContentsController* updatedController = |
1315 [tabContentsArray_ objectAtIndex:index]; | 1325 [tabContentsArray_ objectAtIndex:index]; |
1316 [updatedController tabDidChange:contents]; | 1326 [updatedController tabDidChange:contents->tab_contents()]; |
1317 } | 1327 } |
1318 | 1328 |
1319 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1329 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
1320 // in sync with the tab strip model. It can also be pinned/unpinned | 1330 // in sync with the tab strip model. It can also be pinned/unpinned |
1321 // simultaneously, so we need to take care of that. | 1331 // simultaneously, so we need to take care of that. |
1322 - (void)tabMovedWithContents:(TabContents*)contents | 1332 - (void)tabMovedWithContents:(TabContentsWrapper*)contents |
1323 fromIndex:(NSInteger)modelFrom | 1333 fromIndex:(NSInteger)modelFrom |
1324 toIndex:(NSInteger)modelTo { | 1334 toIndex:(NSInteger)modelTo { |
1325 // Take closing tabs into account. | 1335 // Take closing tabs into account. |
1326 NSInteger from = [self indexFromModelIndex:modelFrom]; | 1336 NSInteger from = [self indexFromModelIndex:modelFrom]; |
1327 NSInteger to = [self indexFromModelIndex:modelTo]; | 1337 NSInteger to = [self indexFromModelIndex:modelTo]; |
1328 | 1338 |
1329 scoped_nsobject<TabContentsController> movedTabContentsController( | 1339 scoped_nsobject<TabContentsController> movedTabContentsController( |
1330 [[tabContentsArray_ objectAtIndex:from] retain]); | 1340 [[tabContentsArray_ objectAtIndex:from] retain]); |
1331 [tabContentsArray_ removeObjectAtIndex:from]; | 1341 [tabContentsArray_ removeObjectAtIndex:from]; |
1332 [tabContentsArray_ insertObject:movedTabContentsController.get() | 1342 [tabContentsArray_ insertObject:movedTabContentsController.get() |
1333 atIndex:to]; | 1343 atIndex:to]; |
1334 scoped_nsobject<TabController> movedTabController( | 1344 scoped_nsobject<TabController> movedTabController( |
1335 [[tabArray_ objectAtIndex:from] retain]); | 1345 [[tabArray_ objectAtIndex:from] retain]); |
1336 DCHECK([movedTabController isKindOfClass:[TabController class]]); | 1346 DCHECK([movedTabController isKindOfClass:[TabController class]]); |
1337 [tabArray_ removeObjectAtIndex:from]; | 1347 [tabArray_ removeObjectAtIndex:from]; |
1338 [tabArray_ insertObject:movedTabController.get() atIndex:to]; | 1348 [tabArray_ insertObject:movedTabController.get() atIndex:to]; |
1339 | 1349 |
1340 // The tab moved, which means that the mini-tab state may have changed. | 1350 // The tab moved, which means that the mini-tab state may have changed. |
1341 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) | 1351 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) |
1342 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; | 1352 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; |
1343 | 1353 |
1344 [self layoutTabs]; | 1354 [self layoutTabs]; |
1345 } | 1355 } |
1346 | 1356 |
1347 // Called when a tab is pinned or unpinned without moving. | 1357 // Called when a tab is pinned or unpinned without moving. |
1348 - (void)tabMiniStateChangedWithContents:(TabContents*)contents | 1358 - (void)tabMiniStateChangedWithContents:(TabContentsWrapper*)contents |
1349 atIndex:(NSInteger)modelIndex { | 1359 atIndex:(NSInteger)modelIndex { |
1350 // Take closing tabs into account. | 1360 // Take closing tabs into account. |
1351 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1361 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1352 | 1362 |
1353 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1363 TabController* tabController = [tabArray_ objectAtIndex:index]; |
1354 DCHECK([tabController isKindOfClass:[TabController class]]); | 1364 DCHECK([tabController isKindOfClass:[TabController class]]); |
1355 | 1365 |
1356 // Don't do anything if the change was already picked up by the move event. | 1366 // Don't do anything if the change was already picked up by the move event. |
1357 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1367 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) |
1358 return; | 1368 return; |
1359 | 1369 |
1360 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1370 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
1361 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1371 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
1362 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1372 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
1363 [self updateFavIconForContents:contents atIndex:modelIndex]; | 1373 [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; |
1364 // If the tab is being restored and it's pinned, the mini state is set after | 1374 // If the tab is being restored and it's pinned, the mini state is set after |
1365 // the tab has already been rendered, so re-layout the tabstrip. In all other | 1375 // the tab has already been rendered, so re-layout the tabstrip. In all other |
1366 // cases, the state is set before the tab is rendered so this isn't needed. | 1376 // cases, the state is set before the tab is rendered so this isn't needed. |
1367 [self layoutTabs]; | 1377 [self layoutTabs]; |
1368 } | 1378 } |
1369 | 1379 |
1370 - (void)setFrameOfSelectedTab:(NSRect)frame { | 1380 - (void)setFrameOfSelectedTab:(NSRect)frame { |
1371 NSView* view = [self selectedTabView]; | 1381 NSView* view = [self selectedTabView]; |
1372 NSValue* identifier = [NSValue valueWithPointer:view]; | 1382 NSValue* identifier = [NSValue valueWithPointer:view]; |
1373 [targetFrames_ setObject:[NSValue valueWithRect:frame] | 1383 [targetFrames_ setObject:[NSValue valueWithRect:frame] |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 | 1437 |
1428 // Drop a given TabContents at the location of the current placeholder. If there | 1438 // Drop a given TabContents at the location of the current placeholder. If there |
1429 // is no placeholder, it will go at the end. Used when dragging from another | 1439 // is no placeholder, it will go at the end. Used when dragging from another |
1430 // window when we don't have access to the TabContents as part of our strip. | 1440 // window when we don't have access to the TabContents as part of our strip. |
1431 // |frame| is in the coordinate system of the tab strip view and represents | 1441 // |frame| is in the coordinate system of the tab strip view and represents |
1432 // where the user dropped the new tab so it can be animated into its correct | 1442 // where the user dropped the new tab so it can be animated into its correct |
1433 // location when the tab is added to the model. If the tab was pinned in its | 1443 // location when the tab is added to the model. If the tab was pinned in its |
1434 // previous window, setting |pinned| to YES will propagate that state to the | 1444 // previous window, setting |pinned| to YES will propagate that state to the |
1435 // new window. Mini-tabs are either app or pinned tabs; the app state is stored | 1445 // new window. Mini-tabs are either app or pinned tabs; the app state is stored |
1436 // by the |contents|, but the |pinned| state is the caller's responsibility. | 1446 // by the |contents|, but the |pinned| state is the caller's responsibility. |
1437 - (void)dropTabContents:(TabContents*)contents | 1447 - (void)dropTabContents:(TabContentsWrapper*)contents |
1438 withFrame:(NSRect)frame | 1448 withFrame:(NSRect)frame |
1439 asPinnedTab:(BOOL)pinned { | 1449 asPinnedTab:(BOOL)pinned { |
1440 int modelIndex = [self indexOfPlaceholder]; | 1450 int modelIndex = [self indexOfPlaceholder]; |
1441 | 1451 |
1442 // Mark that the new tab being created should start at |frame|. It will be | 1452 // Mark that the new tab being created should start at |frame|. It will be |
1443 // reset as soon as the tab has been positioned. | 1453 // reset as soon as the tab has been positioned. |
1444 droppedTabFrame_ = frame; | 1454 droppedTabFrame_ = frame; |
1445 | 1455 |
1446 // Insert it into this tab strip. We want it in the foreground and to not | 1456 // Insert it into this tab strip. We want it in the foreground and to not |
1447 // inherit the current tab's group. | 1457 // inherit the current tab's group. |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 params.disposition = disposition; | 1718 params.disposition = disposition; |
1709 params.tabstrip_index = index; | 1719 params.tabstrip_index = index; |
1710 params.tabstrip_add_types = | 1720 params.tabstrip_add_types = |
1711 TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; | 1721 TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; |
1712 browser::Navigate(¶ms); | 1722 browser::Navigate(¶ms); |
1713 break; | 1723 break; |
1714 } | 1724 } |
1715 case CURRENT_TAB: | 1725 case CURRENT_TAB: |
1716 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), | 1726 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), |
1717 browser_->profile()); | 1727 browser_->profile()); |
1718 tabStripModel_->GetTabContentsAt(index)->OpenURL(url, GURL(), CURRENT_TAB, | 1728 tabStripModel_->GetTabContentsAt(index) |
1719 PageTransition::TYPED); | 1729 ->tab_contents()->OpenURL(url, GURL(), CURRENT_TAB, |
| 1730 PageTransition::TYPED); |
1720 tabStripModel_->SelectTabContentsAt(index, true); | 1731 tabStripModel_->SelectTabContentsAt(index, true); |
1721 break; | 1732 break; |
1722 default: | 1733 default: |
1723 NOTIMPLEMENTED(); | 1734 NOTIMPLEMENTED(); |
1724 } | 1735 } |
1725 } | 1736 } |
1726 | 1737 |
1727 // (URLDropTargetController protocol) | 1738 // (URLDropTargetController protocol) |
1728 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { | 1739 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { |
1729 DCHECK_EQ(view, tabStripView_.get()); | 1740 DCHECK_EQ(view, tabStripView_.get()); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1869 NSInteger index = [self indexFromModelIndex:modelIndex]; |
1859 BrowserWindowController* controller = | 1870 BrowserWindowController* controller = |
1860 (BrowserWindowController*)[[switchView_ window] windowController]; | 1871 (BrowserWindowController*)[[switchView_ window] windowController]; |
1861 DCHECK(index >= 0); | 1872 DCHECK(index >= 0); |
1862 if (index >= 0) { | 1873 if (index >= 0) { |
1863 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; | 1874 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; |
1864 } | 1875 } |
1865 } | 1876 } |
1866 | 1877 |
1867 @end | 1878 @end |
OLD | NEW |