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 18 matching lines...) Expand all Loading... | |
29 #include "chrome/browser/ui/browser.h" | 29 #include "chrome/browser/ui/browser.h" |
30 #include "chrome/browser/ui/browser_navigator.h" | 30 #include "chrome/browser/ui/browser_navigator.h" |
31 #include "chrome/browser/ui/browser_tabstrip.h" | 31 #include "chrome/browser/ui/browser_tabstrip.h" |
32 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 32 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
33 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con troller.h" | 33 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con troller.h" |
34 #include "chrome/browser/ui/cocoa/drag_util.h" | 34 #include "chrome/browser/ui/cocoa/drag_util.h" |
35 #import "chrome/browser/ui/cocoa/image_button_cell.h" | 35 #import "chrome/browser/ui/cocoa/image_button_cell.h" |
36 #import "chrome/browser/ui/cocoa/new_tab_button.h" | 36 #import "chrome/browser/ui/cocoa/new_tab_button.h" |
37 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" | 37 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" |
38 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 38 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
39 #import "chrome/browser/ui/cocoa/tabs/tab_audio_indicator_view_mac.h" | |
40 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 39 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
41 #import "chrome/browser/ui/cocoa/tabs/tab_projecting_image_view.h" | 40 #import "chrome/browser/ui/cocoa/tabs/tab_projecting_image_view.h" |
42 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" | 41 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" |
43 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" | 42 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" |
44 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 43 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
45 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" | 44 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
46 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" | 45 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" |
47 #import "chrome/browser/ui/cocoa/tabs/throbbing_image_view.h" | 46 #import "chrome/browser/ui/cocoa/tabs/throbbing_image_view.h" |
48 #include "chrome/browser/ui/find_bar/find_bar.h" | 47 #include "chrome/browser/ui/find_bar/find_bar.h" |
49 #include "chrome/browser/ui/find_bar/find_bar_controller.h" | 48 #include "chrome/browser/ui/find_bar/find_bar_controller.h" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 }) autorelease]; | 274 }) autorelease]; |
276 } | 275 } |
277 | 276 |
278 } // namespace | 277 } // namespace |
279 | 278 |
280 @interface TabStripController (Private) | 279 @interface TabStripController (Private) |
281 - (void)addSubviewToPermanentList:(NSView*)aView; | 280 - (void)addSubviewToPermanentList:(NSView*)aView; |
282 - (void)regenerateSubviewList; | 281 - (void)regenerateSubviewList; |
283 - (NSInteger)indexForContentsView:(NSView*)view; | 282 - (NSInteger)indexForContentsView:(NSView*)view; |
284 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents; | 283 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents; |
284 - (NSView*)audioIndicatorViewForContents:(content::WebContents*)contents; | |
285 - (void)updateFaviconForContents:(content::WebContents*)contents | 285 - (void)updateFaviconForContents:(content::WebContents*)contents |
286 atIndex:(NSInteger)modelIndex; | 286 atIndex:(NSInteger)modelIndex; |
287 - (void)layoutTabsWithAnimation:(BOOL)animate | 287 - (void)layoutTabsWithAnimation:(BOOL)animate |
288 regenerateSubviews:(BOOL)doUpdate; | 288 regenerateSubviews:(BOOL)doUpdate; |
289 - (void)animationDidStopForController:(TabController*)controller | 289 - (void)animationDidStopForController:(TabController*)controller |
290 finished:(BOOL)finished; | 290 finished:(BOOL)finished; |
291 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 291 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
292 - (void)clickNewTabButton:(id)sender; | 292 - (void)clickNewTabButton:(id)sender; |
293 - (NSInteger)numberOfOpenTabs; | 293 - (NSInteger)numberOfOpenTabs; |
294 - (NSInteger)numberOfOpenMiniTabs; | 294 - (NSInteger)numberOfOpenMiniTabs; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 animationContainer_ = new ui::AnimationContainer; | 505 animationContainer_ = new ui::AnimationContainer; |
506 NSWindow* browserWindow = [view window]; | 506 NSWindow* browserWindow = [view window]; |
507 | 507 |
508 // Important note: any non-tab subviews not added to |permanentSubviews_| | 508 // Important note: any non-tab subviews not added to |permanentSubviews_| |
509 // (see |-addSubviewToPermanentList:|) will be wiped out. | 509 // (see |-addSubviewToPermanentList:|) will be wiped out. |
510 permanentSubviews_.reset([[NSMutableArray alloc] init]); | 510 permanentSubviews_.reset([[NSMutableArray alloc] init]); |
511 | 511 |
512 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 512 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
513 defaultFavicon_.reset( | 513 defaultFavicon_.reset( |
514 rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage()); | 514 rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage()); |
515 audioIndicatorImage_.reset( | |
516 rb.GetNativeImageNamed(IDR_TAB_AUDIO_INDICATOR).CopyNSImage()); | |
sail
2013/09/11 19:18:37
no need to cache this in a member variable, also n
miu
2013/09/11 21:35:06
Done.
| |
515 | 517 |
516 [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]]; | 518 [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]]; |
517 [self setRightIndentForControls:0]; | 519 [self setRightIndentForControls:0]; |
518 | 520 |
519 newTabButton_ = [view getNewTabButton]; | 521 newTabButton_ = [view getNewTabButton]; |
520 [self addSubviewToPermanentList:newTabButton_]; | 522 [self addSubviewToPermanentList:newTabButton_]; |
521 [newTabButton_ setTarget:self]; | 523 [newTabButton_ setTarget:self]; |
522 [newTabButton_ setAction:@selector(clickNewTabButton:)]; | 524 [newTabButton_ setAction:@selector(clickNewTabButton:)]; |
523 | 525 |
524 [self setNewTabImages]; | 526 [self setNewTabImages]; |
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1554 // Either we don't have a valid favicon or there was some issue converting it | 1556 // Either we don't have a valid favicon or there was some issue converting it |
1555 // from an SkBitmap. Either way, just show the default. | 1557 // from an SkBitmap. Either way, just show the default. |
1556 if (!image) | 1558 if (!image) |
1557 image = defaultFavicon_.get(); | 1559 image = defaultFavicon_.get(); |
1558 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1560 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
1559 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | 1561 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; |
1560 [view setImage:image]; | 1562 [view setImage:image]; |
1561 return view; | 1563 return view; |
1562 } | 1564 } |
1563 | 1565 |
1566 // A helper routine for creating an NSImageView to hold the audio indicator icon | |
1567 // for |contents|. Returns nil when the audio indicator should not be shown. | |
1568 - (NSView*)audioIndicatorViewForContents:(content::WebContents*)contents { | |
sail
2013/09/11 19:18:37
This code is hard to follow with one set of condit
miu
2013/09/11 21:35:06
Done.
| |
1569 if (!chrome::IsPlayingAudio(contents) || !audioIndicatorImage_) | |
sail
2013/09/11 19:18:37
don't need the !audioIndicatorImage_ check
| |
1570 return nil; | |
1571 NSRect frame; | |
1572 frame.size = [audioIndicatorImage_ size]; | |
1573 NSImageView* const image_view = | |
1574 [[[NSImageView alloc] initWithFrame:frame] autorelease]; | |
1575 [image_view setImage:audioIndicatorImage_.get()]; | |
1576 return image_view; | |
1577 } | |
1578 | |
1564 // Updates the current loading state, replacing the icon view with a favicon, | 1579 // Updates the current loading state, replacing the icon view with a favicon, |
1565 // a throbber, the default icon, or nothing at all. | 1580 // a throbber, the default icon, or nothing at all. |
1566 - (void)updateFaviconForContents:(content::WebContents*)contents | 1581 - (void)updateFaviconForContents:(content::WebContents*)contents |
1567 atIndex:(NSInteger)modelIndex { | 1582 atIndex:(NSInteger)modelIndex { |
1568 if (!contents) | 1583 if (!contents) |
1569 return; | 1584 return; |
1570 | 1585 |
1571 static NSImage* throbberWaitingImage = | 1586 static NSImage* throbberWaitingImage = |
1572 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1587 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
1573 IDR_THROBBER_WAITING).CopyNSImage(); | 1588 IDR_THROBBER_WAITING).CopyNSImage(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1605 if (oldState != newState) | 1620 if (oldState != newState) |
1606 [tabController setLoadingState:newState]; | 1621 [tabController setLoadingState:newState]; |
1607 | 1622 |
1608 // While loading, this function is called repeatedly with the same state. | 1623 // While loading, this function is called repeatedly with the same state. |
1609 // To avoid expensive unnecessary view manipulation, only make changes when | 1624 // To avoid expensive unnecessary view manipulation, only make changes when |
1610 // the state is actually changing. When loading is complete (kTabDone), | 1625 // the state is actually changing. When loading is complete (kTabDone), |
1611 // every call to this function is significant. | 1626 // every call to this function is significant. |
1612 if (newState == kTabDone || oldState != newState || | 1627 if (newState == kTabDone || oldState != newState || |
1613 oldHasIcon != newHasIcon) { | 1628 oldHasIcon != newHasIcon) { |
1614 NSView* iconView = nil; | 1629 NSView* iconView = nil; |
1630 BOOL disallowAudioIndicatorView = YES; | |
1615 if (newHasIcon) { | 1631 if (newHasIcon) { |
1616 if (newState == kTabDone) { | 1632 if (newState == kTabDone) { |
1617 NSImageView* imageView = [self iconImageViewForContents:contents]; | 1633 NSImageView* imageView = [self iconImageViewForContents:contents]; |
1618 TabAudioIndicatorViewMac* tabAudioIndicatorViewMac = | |
1619 base::mac::ObjCCast<TabAudioIndicatorViewMac>( | |
1620 [tabController iconView]); | |
1621 | 1634 |
1622 ui::ThemeProvider* theme = [[tabStripView_ window] themeProvider]; | 1635 ui::ThemeProvider* theme = [[tabStripView_ window] themeProvider]; |
1623 if (theme && [tabController projecting]) { | 1636 if (theme && [tabController projecting]) { |
1624 NSImage* projectorGlow = | 1637 NSImage* projectorGlow = |
1625 theme->GetNSImageNamed(IDR_TAB_CAPTURE_GLOW); | 1638 theme->GetNSImageNamed(IDR_TAB_CAPTURE_GLOW); |
1626 NSImage* projector = theme->GetNSImageNamed(IDR_TAB_CAPTURE); | 1639 NSImage* projector = theme->GetNSImageNamed(IDR_TAB_CAPTURE); |
1627 | 1640 |
1628 NSRect frame = NSMakeRect(0, | 1641 NSRect frame = NSMakeRect(0, |
1629 0, | 1642 0, |
1630 kProjectingIconWidthAndHeight, | 1643 kProjectingIconWidthAndHeight, |
(...skipping 20 matching lines...) Expand all Loading... | |
1651 ThrobbingImageView* recordingView = | 1664 ThrobbingImageView* recordingView = |
1652 [[[ThrobbingImageView alloc] | 1665 [[[ThrobbingImageView alloc] |
1653 initWithFrame:frame | 1666 initWithFrame:frame |
1654 backgroundImage:favIconMasked | 1667 backgroundImage:favIconMasked |
1655 throbImage:recording | 1668 throbImage:recording |
1656 durationMS:kRecordingDurationMs | 1669 durationMS:kRecordingDurationMs |
1657 throbPosition:kThrobPositionBottomRight | 1670 throbPosition:kThrobPositionBottomRight |
1658 animationContainer:animationContainer_.get()] autorelease]; | 1671 animationContainer:animationContainer_.get()] autorelease]; |
1659 | 1672 |
1660 iconView = recordingView; | 1673 iconView = recordingView; |
1661 } else if (chrome::IsPlayingAudio(contents) || | |
1662 [tabAudioIndicatorViewMac isAnimating]) { | |
1663 if (!tabAudioIndicatorViewMac) { | |
1664 NSRect frame = | |
1665 NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | |
1666 tabAudioIndicatorViewMac = [[[TabAudioIndicatorViewMac alloc] | |
1667 initWithFrame:frame] autorelease]; | |
1668 [tabAudioIndicatorViewMac | |
1669 setAnimationContainer:animationContainer_.get()]; | |
1670 } | |
1671 [tabAudioIndicatorViewMac | |
1672 setIsPlayingAudio:chrome::IsPlayingAudio(contents)]; | |
1673 [tabAudioIndicatorViewMac setBackgroundImage:[imageView image]]; | |
1674 iconView = tabAudioIndicatorViewMac; | |
1675 } else { | 1674 } else { |
1676 iconView = imageView; | 1675 iconView = imageView; |
1676 disallowAudioIndicatorView = NO; | |
1677 } | 1677 } |
1678 } else if (newState == kTabCrashed) { | 1678 } else if (newState == kTabCrashed) { |
1679 NSImage* oldImage = [[self iconImageViewForContents:contents] image]; | 1679 NSImage* oldImage = [[self iconImageViewForContents:contents] image]; |
1680 NSRect frame = | 1680 NSRect frame = |
1681 NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1681 NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
1682 iconView = [ThrobberView toastThrobberViewWithFrame:frame | 1682 iconView = [ThrobberView toastThrobberViewWithFrame:frame |
1683 beforeImage:oldImage | 1683 beforeImage:oldImage |
1684 afterImage:sadFaviconImage]; | 1684 afterImage:sadFaviconImage]; |
1685 } else { | 1685 } else { |
1686 NSRect frame = | 1686 NSRect frame = |
1687 NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1687 NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
1688 iconView = [ThrobberView filmstripThrobberViewWithFrame:frame | 1688 iconView = [ThrobberView filmstripThrobberViewWithFrame:frame |
1689 image:throbberImage]; | 1689 image:throbberImage]; |
1690 } | 1690 } |
1691 } | 1691 } |
1692 | 1692 |
1693 [tabController setIconView:iconView]; | 1693 [tabController setIconView:iconView]; |
1694 if (iconView && ![tabController projecting]) { | 1694 if (iconView && ![tabController projecting]) { |
1695 // See the comment above kTabOverlap for why these DCHECKs exist. | 1695 // See the comment above kTabOverlap for why these DCHECKs exist. |
1696 DCHECK_GE(NSMinX([iconView frame]), kTabOverlap); | 1696 DCHECK_GE(NSMinX([iconView frame]), kTabOverlap); |
1697 // TODO(thakis): Ideally, this would be true too, but it's not true in | 1697 // TODO(thakis): Ideally, this would be true too, but it's not true in |
1698 // some tests. | 1698 // some tests. |
1699 //DCHECK_LE(NSMaxX([iconView frame]), | 1699 //DCHECK_LE(NSMaxX([iconView frame]), |
1700 // NSWidth([[tabController view] frame]) - kTabOverlap); | 1700 // NSWidth([[tabController view] frame]) - kTabOverlap); |
1701 } | 1701 } |
1702 | |
1703 NSView* audioIndicatorView = disallowAudioIndicatorView ? | |
1704 nil : [self audioIndicatorViewForContents:contents]; | |
1705 [tabController setAudioIndicatorView:audioIndicatorView]; | |
sail
2013/09/11 19:18:37
does this have to be done after setIconView:? It w
miu
2013/09/11 21:35:06
Good point. I got rid of |disallowAudioIndicatorV
| |
1702 } | 1706 } |
1703 } | 1707 } |
1704 | 1708 |
1705 // Called when a notification is received from the model that the given tab | 1709 // Called when a notification is received from the model that the given tab |
1706 // has been updated. |loading| will be YES when we only want to update the | 1710 // has been updated. |loading| will be YES when we only want to update the |
1707 // throbber state, not anything else about the (partially) loading tab. | 1711 // throbber state, not anything else about the (partially) loading tab. |
1708 - (void)tabChangedWithContents:(content::WebContents*)contents | 1712 - (void)tabChangedWithContents:(content::WebContents*)contents |
1709 atIndex:(NSInteger)modelIndex | 1713 atIndex:(NSInteger)modelIndex |
1710 changeType:(TabStripModelObserver::TabChangeType)change { | 1714 changeType:(TabStripModelObserver::TabChangeType)change { |
1711 // Take closing tabs into account. | 1715 // Take closing tabs into account. |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2301 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { | 2305 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { |
2302 // View hierarchy of the contents view: | 2306 // View hierarchy of the contents view: |
2303 // NSView -- switchView, same for all tabs | 2307 // NSView -- switchView, same for all tabs |
2304 // +- NSView -- TabContentsController's view | 2308 // +- NSView -- TabContentsController's view |
2305 // +- TabContentsViewCocoa | 2309 // +- TabContentsViewCocoa |
2306 // | 2310 // |
2307 // Changing it? Do not forget to modify | 2311 // Changing it? Do not forget to modify |
2308 // -[TabStripController swapInTabAtIndex:] too. | 2312 // -[TabStripController swapInTabAtIndex:] too. |
2309 return [web_contents->GetView()->GetNativeView() superview]; | 2313 return [web_contents->GetView()->GetNativeView() superview]; |
2310 } | 2314 } |
OLD | NEW |