diff options
10 files changed, 169 insertions, 17 deletions
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h index ae603ee..fddb1c0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h @@ -264,11 +264,15 @@ willAnimateFromState:(bookmarks::VisualState)oldState // The x point on the bar where the left edge of the new item will end // up if it is dropped. CGFloat insertionPos_; + + // YES if the bookmark bar is empty. + BOOL isEmpty_; } @property(readonly, nonatomic) bookmarks::VisualState visualState; @property(readonly, nonatomic) bookmarks::VisualState lastVisualState; @property(assign, nonatomic) id<BookmarkBarControllerDelegate> delegate; +@property(readonly, nonatomic) BOOL isEmpty; // Initializes the bookmark bar controller with the given browser // profile and delegates. @@ -289,10 +293,6 @@ willAnimateFromState:(bookmarks::VisualState)oldState // Hides or shows the bookmark bar depending on the current state. - (void)updateHiddenState; -// Returns YES if the bookmark bar should be shown at the bottom of the content -// view when detached. -- (BOOL)shouldShowAtBottomWhenDetached; - // Turn on or off the bookmark bar and prevent or reallow its appearance. On // disable, toggle off if shown. On enable, show only if needed. App and popup // windows do not show a bookmark bar. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm index 6803ace..897fe3a 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm @@ -233,6 +233,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { @synthesize visualState = visualState_; @synthesize lastVisualState = lastVisualState_; @synthesize delegate = delegate_; +@synthesize isEmpty = isEmpty_; - (id)initWithBrowser:(Browser*)browser initialWidth:(CGFloat)initialWidth @@ -489,10 +490,6 @@ void RecordAppLaunch(Profile* profile, GURL url) { [[self view] setHidden:newHidden]; } -- (BOOL)shouldShowAtBottomWhenDetached { - return chrome::search::IsInstantExtendedAPIEnabled(browser_->profile()); -} - - (void)setBookmarkBarEnabled:(BOOL)enabled { if (enabled != barIsEnabled_) { barIsEnabled_ = enabled; @@ -1015,6 +1012,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // Update everything else. [self layoutSubviews]; [self frameDidChange]; + [self updateNoItemContainerVisibility]; } // (Private) @@ -1266,7 +1264,15 @@ void RecordAppLaunch(Profile* profile, GURL url) { // appropriate) the "no items" container (text which says "bookmarks // go here"). - (void)showOrHideNoItemContainerForNode:(const BookmarkNode*)node { - BOOL hideNoItemWarning = !node->empty(); + isEmpty_ = node->empty(); + [[self view] setNeedsDisplay:YES]; + [self updateNoItemContainerVisibility]; +} + +- (void)updateNoItemContainerVisibility { + BOOL hideNoItemWarning = !isEmpty_ || + ([self shouldShowAtBottomWhenDetached] && + visualState_ == bookmarks::kDetachedState); [[buttonView_ noItemContainer] setHidden:hideNoItemWarning]; } @@ -2372,6 +2378,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return ThemeServiceFactory::GetForProfile(browser_->profile()); } +- (BOOL)shouldShowAtBottomWhenDetached { + return chrome::search::IsInstantExtendedAPIEnabled(browser_->profile()); +} + #pragma mark BookmarkButtonDelegate Protocol - (void)fillPasteboard:(NSPasteboard*)pboard diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_browsertest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_browsertest.mm index cbba0a1..9e34e00 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_browsertest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_browsertest.mm @@ -4,8 +4,12 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" +#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" #include "chrome/browser/ui/search/search.h" @@ -118,3 +122,22 @@ IN_PROC_BROWSER_TEST_F(BottomBookmarkBarControllerTest, MinContentHeight) { [window setFrame:window_frame display:YES]; EXPECT_TRUE([[GetBookmarkBarController() view] isHidden]); } + +IN_PROC_BROWSER_TEST_F(BottomBookmarkBarControllerTest, NoItemContainer) { + EXPECT_TRUE([GetBookmarkBarController() isEmpty]); + BookmarkBarView* button_view = [GetBookmarkBarController() buttonView]; + EXPECT_TRUE([[button_view noItemContainer] isHidden]); + + // Add a bookmark. + BookmarkModel* model = + BookmarkModelFactory::GetForProfile(browser()->profile()); + const BookmarkNode* node = model->bookmark_bar_node(); + model->AddURL(node, + node->child_count(), + ASCIIToUTF16("title"), + GURL("http://www.google.com")); + + // Item container should remain hidden. + EXPECT_FALSE([GetBookmarkBarController() isEmpty]); + EXPECT_TRUE([[button_view noItemContainer] isHidden]); +} diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h index 4535dfd..9df5231 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h @@ -32,6 +32,13 @@ class ThemeProvider; // Current theme provider, passed to the cross platform NtpBackgroundUtil class. - (ui::ThemeProvider*)themeProvider; +// Returns YES if the bookmark bar should be shown at the bottom of the content +// view when detached. +- (BOOL)shouldShowAtBottomWhenDetached; + +// Returns YES if the bookmark bar has no bookmarks. +- (BOOL)isEmpty; + @end @interface BookmarkBarToolbarView : AnimatableView { diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm index 72a3e67..ebd4850 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm @@ -8,8 +8,12 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "chrome/browser/ui/ntp_background_util.h" +#include "chrome/browser/ui/search/search_ui.h" +#include "grit/theme_resources.h" +#include "skia/ext/skia_utils_mac.h" #include "ui/base/theme_provider.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/rect.h" @@ -18,7 +22,8 @@ const CGFloat kBorderRadius = 3.0; @interface BookmarkBarToolbarView (Private) -- (void)drawRectAsBubble:(NSRect)rect; +- (void)drawRectAsTopBubble:(NSRect)rect; +- (void)drawRectAsBottomBubble:(NSRect)rect; @end @implementation BookmarkBarToolbarView @@ -37,7 +42,10 @@ const CGFloat kBorderRadius = 3.0; if ([controller_ isInState:bookmarks::kDetachedState] || [controller_ isAnimatingToState:bookmarks::kDetachedState] || [controller_ isAnimatingFromState:bookmarks::kDetachedState]) { - [self drawRectAsBubble:rect]; + if ([controller_ shouldShowAtBottomWhenDetached]) + [self drawRectAsBottomBubble:rect]; + else + [self drawRectAsTopBubble:rect]; } else { NSPoint phase = [[self window] themePatternPhase]; [[NSGraphicsContext currentContext] setPatternPhase:phase]; @@ -45,7 +53,7 @@ const CGFloat kBorderRadius = 3.0; } } -- (void)drawRectAsBubble:(NSRect)rect { +- (void)drawRectAsTopBubble:(NSRect)rect { // The state of our morph; 1 is total bubble, 0 is the regular bar. We use it // to morph the bubble to a regular bar (shape and colour). CGFloat morph = [controller_ detachedMorphProgress]; @@ -105,7 +113,7 @@ const CGFloat kBorderRadius = 3.0; gfx::ScopedNSGraphicsContextSaveGState bgScopedState; [border setClip]; NSGraphicsContext* context = [NSGraphicsContext currentContext]; - CGContextRef cgContext = (CGContextRef)[context graphicsPort]; + CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); CGContextBeginTransparencyLayer(cgContext, NULL); CGContextSetAlpha(cgContext, 1 - morph); [context setPatternPhase:[[self window] themePatternPhase]]; @@ -137,4 +145,49 @@ const CGFloat kBorderRadius = 3.0; [divider stroke]; } +- (void)drawRectAsBottomBubble:(NSRect)rect { + if ([controller_ isEmpty]) + return; + + ui::ThemeProvider* themeProvider = [controller_ themeProvider]; + if (!themeProvider) + return; + + gfx::ScopedNSGraphicsContextSaveGState scopedGState; + NSRect bounds = [self bounds]; + + // Draw a background if the NTP has a custom background image. Otherwise just + // leave the background transparent. + BOOL useThemeColor = themeProvider->HasCustomImage(IDR_THEME_NTP_BACKGROUND); + if (useThemeColor) { + gfx::ScopedNSGraphicsContextSaveGState bgScopedState; + NSGraphicsContext* context = [NSGraphicsContext currentContext]; + CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); + CGContextBeginTransparencyLayer(cgContext, NULL); + CGContextSetAlpha( + cgContext, chrome::search::kBookmarkBarThemeBackgroundAlphaFactor); + [themeProvider->GetNSColor(ThemeService::COLOR_NTP_BACKGROUND, true) set]; + NSRectFillUsingOperation(bounds, NSCompositeSourceOver); + CGContextEndTransparencyLayer(cgContext); + } + + NSRect dividerRect; + dividerRect.size.width = NSWidth(bounds); + dividerRect.size.height = [self cr_lineWidth]; + dividerRect.origin.x = NSMinX(bounds); + dividerRect.origin.y = NSMaxY(bounds) - NSHeight(dividerRect); + + NSColor* strokeColor = nil; + if (useThemeColor) { + strokeColor = + themeProvider->GetNSColor(ThemeService::COLOR_TOOLBAR_SEPARATOR, true); + } else { + strokeColor = gfx::SkColorToCalibratedNSColor( + chrome::search::GetBookmarkBarNoThemeSeparatorColor()); + } + + [strokeColor set]; + NSRectFillUsingOperation(dividerRect, NSCompositeSourceOver); +} + @end // @implementation BookmarkBarToolbarView diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm index 51e6753..ffbc159 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm @@ -63,10 +63,14 @@ class MockThemeProvider : public ui::ThemeProvider { int currentTabContentsHeight_; ui::ThemeProvider* themeProvider_; bookmarks::VisualState visualState_; + BOOL shouldShowAtBottomWhenDetached_; + BOOL isEmpty_; } @property (nonatomic, assign) int currentTabContentsHeight; @property (nonatomic, assign) ui::ThemeProvider* themeProvider; @property (nonatomic, assign) bookmarks::VisualState visualState; +@property (nonatomic, assign) BOOL shouldShowAtBottomWhenDetached; +@property (nonatomic, assign) BOOL isEmpty; // |BookmarkBarState| protocol: - (BOOL)isVisible; @@ -85,6 +89,8 @@ class MockThemeProvider : public ui::ThemeProvider { @synthesize currentTabContentsHeight = currentTabContentsHeight_; @synthesize themeProvider = themeProvider_; @synthesize visualState = visualState_; +@synthesize shouldShowAtBottomWhenDetached = shouldShowAtBottomWhenDetached_; +@synthesize isEmpty = isEmpty_; - (id)init { if ((self = [super init])) { @@ -192,4 +198,30 @@ TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithBgImage) { [view_ display]; } +TEST_F(BookmarkBarToolbarViewTest, DisplayAsBottomDetachedBar) { + [controller_.get() setVisualState:bookmarks::kDetachedState]; + [controller_.get() setShouldShowAtBottomWhenDetached:YES]; + + // Tests where we don't have a background image, only a color. + NiceMock<MockThemeProvider> provider; + NSColor* color = [NSColor redColor]; + EXPECT_CALL(provider, HasCustomImage(IDR_THEME_NTP_BACKGROUND)) + .WillRepeatedly(Return(true)); + EXPECT_CALL(provider, GetNSColor(ThemeService::COLOR_NTP_BACKGROUND, true)) + .WillRepeatedly(Return(color)); + EXPECT_CALL(provider, + GetNSColor(ThemeService::COLOR_TOOLBAR_SEPARATOR, true)) + .WillRepeatedly(Return(color)); + [controller_.get() setThemeProvider:&provider]; + + [view_ display]; +} + +TEST_F(BookmarkBarToolbarViewTest, DisplayAsEmptyBottomDetachedBar) { + [controller_.get() setVisualState:bookmarks::kDetachedState]; + [controller_.get() setShouldShowAtBottomWhenDetached:YES]; + [controller_.get() setIsEmpty:YES]; + [view_ display]; +} + // TODO(viettrungluu): write more unit tests, especially after my refactoring. diff --git a/chrome/browser/ui/search/search_ui.cc b/chrome/browser/ui/search/search_ui.cc new file mode 100644 index 0000000..fa4db3f --- /dev/null +++ b/chrome/browser/ui/search/search_ui.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/search/search_ui.h" + +namespace chrome { +namespace search { + +SkColor GetBookmarkBarNoThemeSeparatorColor() { + return SkColorSetARGB(25, 0, 0, 0); // 10% black +} + +} // namespace search +} // namespace chrome diff --git a/chrome/browser/ui/search/search_ui.h b/chrome/browser/ui/search/search_ui.h index 3c24887..be578b1 100644 --- a/chrome/browser/ui/search/search_ui.h +++ b/chrome/browser/ui/search/search_ui.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_UI_H_ #define CHROME_BROWSER_UI_SEARCH_SEARCH_UI_H_ +#include "third_party/skia/include/core/SkColor.h" + namespace chrome { namespace search { @@ -20,6 +22,13 @@ static const int kMaxWidthForBottomBookmarkBar = 720; // The left and right padding of the detached bookmark bar. static const int kHorizontalPaddingForBottomBookmarkBar = 130; +// The alpha used to draw the bookmark bar background when themed. +// This value ranges from 0.0 (fully transparent) to 1.0 (fully opaque). +static const float kBookmarkBarThemeBackgroundAlphaFactor = 0.8f; + +// Returns the color to use to draw the bookmark bar separator when not themed. +SkColor GetBookmarkBarNoThemeSeparatorColor(); + } // namespace search } // namespace chrome diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 32ef6de..aa2dc50 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -380,11 +380,12 @@ void BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, int width = host_view_->width() - host_view_->GetRightMargin() - left_margin; canvas->ClipRect(gfx::Rect(left_margin, 0, width, host_view_->height())); - // If a theme is being used, paint the theme background color at maximum - // 80% opacity to make the the bookmark bar more legible; + // If a theme is being used, paint the theme background color with an + // alpha blend to make the the bookmark bar more legible; // otherwise, use a transparent background. if (tp->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { - const U8CPU kBackgroundOpacity = 204; // 80% opacity + const U8CPU kBackgroundOpacity = + 255 * chrome::search::kBookmarkBarThemeBackgroundAlphaFactor; SkColor color = tp->GetColor(ThemeService::COLOR_NTP_BACKGROUND); if (gfx::IsInvertedColorScheme()) color = color_utils::InvertColor(color); @@ -393,7 +394,8 @@ void BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, canvas->DrawColor(color); DetachableToolbarView::PaintHorizontalBorder(canvas, host_view_); } else { - const SkColor kBorderColor = SkColorSetARGB(25, 0, 0, 0); // 10% black + const SkColor kBorderColor = + chrome::search::GetBookmarkBarNoThemeSeparatorColor(); DetachableToolbarView::PaintHorizontalBorderWithColor( canvas, host_view_, kBorderColor); } diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index d0fa49a..11af939 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -1200,6 +1200,7 @@ 'browser/ui/search/search_model_observer.h', 'browser/ui/search/search_tab_helper.cc', 'browser/ui/search/search_tab_helper.h', + 'browser/ui/search/search_ui.cc', 'browser/ui/search/search_ui.h', 'browser/ui/search_engines/edit_search_engine_controller.cc', 'browser/ui/search_engines/edit_search_engine_controller.h', |