summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandresantoso <andresantoso@chromium.org>2015-06-01 18:01:00 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-02 01:01:45 +0000
commite59a7b6cbad6b0aa04e01d9f3c0021ee1ee03e8a (patch)
tree677e9a4109f2813695274a5dd316e8e93c9d31c7
parent298d6b7b03f7383d51e4792be8b1d2d162281e6a (diff)
downloadchromium_src-e59a7b6cbad6b0aa04e01d9f3c0021ee1ee03e8a.zip
chromium_src-e59a7b6cbad6b0aa04e01d9f3c0021ee1ee03e8a.tar.gz
chromium_src-e59a7b6cbad6b0aa04e01d9f3c0021ee1ee03e8a.tar.bz2
Mac: Update sad tab layout to new design
Update sad tab layout to new design and match the other platforms. Add a button for reloading the page. Fixed BlueLabelButton to enable LCD font smoothing when layer backed. BUG=490139 Review URL: https://codereview.chromium.org/1145063005 Cr-Commit-Position: refs/heads/master@{#332284}
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller.mm17
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm9
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm23
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h23
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm247
-rw-r--r--ui/base/cocoa/controls/blue_label_button.mm8
6 files changed, 178 insertions, 149 deletions
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index d2c81e5..06b489a 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -63,7 +63,6 @@
#import "chrome/browser/ui/cocoa/profiles/avatar_icon_controller.h"
#import "chrome/browser/ui/cocoa/status_bubble_mac.h"
#import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h"
-#import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
#import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
@@ -1931,19 +1930,15 @@ using content::WebContents;
[self layoutSubviews];
}
-// Handle the openLearnMoreAboutCrashLink: action from SadTabController when
+// Handle the openLearnMoreAboutCrashLink: action from SadTabView when
// "Learn more" link in "Aw snap" page (i.e. crash page or sad tab) is
// clicked. Decoupling the action from its target makes unit testing possible.
- (void)openLearnMoreAboutCrashLink:(id)sender {
- if (SadTabController* sadTab =
- base::mac::ObjCCast<SadTabController>(sender)) {
- WebContents* webContents = [sadTab webContents];
- if (webContents) {
- OpenURLParams params(
- GURL(chrome::kCrashReasonURL), Referrer(), CURRENT_TAB,
- ui::PAGE_TRANSITION_LINK, false);
- webContents->OpenURL(params);
- }
+ if (WebContents* webContents =
+ browser_->tab_strip_model()->GetActiveWebContents()) {
+ OpenURLParams params(GURL(chrome::kCrashReasonURL), Referrer(), CURRENT_TAB,
+ ui::PAGE_TRANSITION_LINK, false);
+ webContents->OpenURL(params);
}
}
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
index a2073e1..6e49e8e 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
@@ -36,6 +36,7 @@ void SadTabCocoa::Close() {
- (id)initWithWebContents:(content::WebContents*)webContents {
if ((self = [super init])) {
+ DCHECK(webContents);
webContents_ = webContents;
if (webContents_) { // NULL in unit_tests.
@@ -52,8 +53,8 @@ void SadTabCocoa::Close() {
- (void)loadView {
base::scoped_nsobject<SadTabView> sadView([[SadTabView alloc] init]);
- if (!webContents_)
- [sadView removeHelpText];
+ [[sadView reloadButton] setTarget:self];
+ [[sadView reloadButton] setAction:@selector(reloadPage:)];
[self setView:sadView];
}
@@ -61,4 +62,8 @@ void SadTabCocoa::Close() {
return webContents_;
}
+- (IBAction)reloadPage:(id)sender {
+ webContents_->GetController().Reload(true);
+}
+
@end
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm
index 4ef94a1..08168aa 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/debug/debugger.h"
+#import "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
@@ -18,7 +19,12 @@
@implementation SadTabView (ExposedForTesting)
- (HyperlinkTextView*)helpTextView {
- return help_.get();
+ NSView* containerView = [[self subviews] lastObject];
+ for (NSView* view in [containerView subviews]) {
+ if (auto textView = base::mac::ObjCCast<HyperlinkTextView>(view))
+ return textView;
+ }
+ return nil;
}
@end
@@ -74,21 +80,6 @@ class SadTabControllerTest : public ChromeRenderViewHostTestHarness {
// static
bool SadTabControllerTest::link_clicked_;
-TEST_F(SadTabControllerTest, WithTabContents) {
- base::scoped_nsobject<SadTabController> controller(CreateController());
- EXPECT_TRUE(controller);
- HyperlinkTextView* help = GetHelpTextView(controller);
- EXPECT_TRUE(help);
-}
-
-TEST_F(SadTabControllerTest, WithoutTabContents) {
- DeleteContents();
- base::scoped_nsobject<SadTabController> controller(CreateController());
- EXPECT_TRUE(controller);
- HyperlinkTextView* help = GetHelpTextView(controller);
- EXPECT_FALSE(help);
-}
-
TEST_F(SadTabControllerTest, ClickOnLink) {
base::scoped_nsobject<SadTabController> controller(CreateController());
HyperlinkTextView* help = GetHelpTextView(controller);
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h
index 306ad4c..e5f420a 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h
@@ -9,26 +9,19 @@
#import <Cocoa/Cocoa.h>
-@class HyperlinkTextView;
+namespace content {
+class WebContents;
+}
+
+@class SadTabContainerView;
// A view that displays the "sad tab" (aka crash page).
-@interface SadTabView : NSView<NSTextViewDelegate> {
+@interface SadTabView : NSView {
@private
- base::scoped_nsobject<NSImageView> image_;
- base::scoped_nsobject<NSTextField> title_;
- base::scoped_nsobject<NSTextField> message_;
- base::scoped_nsobject<HyperlinkTextView> help_;
-
- NSSize messageSize_;
+ base::scoped_nsobject<SadTabContainerView> container_;
}
-// Designated initializer is -initWithFrame: .
-
-// Called by SadTabController to remove the help text and link.
-- (void)removeHelpText;
-
-// Sets |help_| based on |helpPlaceholder_|, sets |helpPlaceholder_| to nil.
-- (void)initializeHelpText;
+@property(readonly,nonatomic) NSButton* reloadButton;
@end
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm
index 3a32f1f..c831e68 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.mm
@@ -10,6 +10,7 @@
#include "chrome/grit/generated_resources.h"
#include "grit/theme_resources.h"
#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#import "ui/base/cocoa/controls/blue_label_button.h"
#import "ui/base/cocoa/controls/hyperlink_text_view.h"
#import "ui/base/cocoa/nscolor_additions.h"
#include "ui/base/l10n/l10n_util.h"
@@ -17,36 +18,43 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
-// Offset above vertical middle of page where contents of page start.
-static const CGFloat kSadTabOffset = -64;
+// Maximum width used by page contents.
+static const CGFloat kMaxContainerWidth = 600;
// Padding between icon and title.
-static const CGFloat kIconTitleSpacing = 20;
+static const CGFloat kIconTitleSpacing = 40;
// Padding between title and message.
-static const CGFloat kTitleMessageSpacing = 15;
+static const CGFloat kTitleMessageSpacing = 18;
// Padding between message and link.
-static const CGFloat kMessageLinkSpacing = 15;
-// Paddings on left and right of page.
-static const CGFloat kTabHorzMargin = 13;
-// The width and height of the icon image view.
-static const CGFloat kIconViewSize = 66;
+static const CGFloat kMessageLinkSpacing = 21;
+// Padding between link and button.
+static const CGFloat kLinkButtonSpacing = 55;
+// Minimum margins on all sides.
+static const CGFloat kTabMargin = 13;
+// Maximum margin on top.
+static const CGFloat kMaxTopMargin = 100;
@interface SadTabTextView : NSTextField
-- (id)initWithView:(SadTabView*)view withText:(int)textIds;
+- (id)initWithStringResourceID:(int)stringResourceID;
@end
@implementation SadTabTextView
-- (id)initWithView:(SadTabView*)view withText:(int)textIds {
+- (id)initWithStringResourceID:(int)stringResourceID {
if (self = [super init]) {
- [self setAlignment:NSCenterTextAlignment];
- [self setStringValue:l10n_util::GetNSString(textIds)];
+ base::scoped_nsobject<NSMutableParagraphStyle> style(
+ [[NSMutableParagraphStyle alloc] init]);
+ [style setLineSpacing:6];
+ base::scoped_nsobject<NSAttributedString> title([[NSAttributedString alloc]
+ initWithString:l10n_util::GetNSString(stringResourceID)
+ attributes:@{ NSParagraphStyleAttributeName : style }]);
+ [self setAttributedStringValue:title];
+
+ [self setAlignment:NSLeftTextAlignment];
[self setEditable:NO];
[self setBezeled:NO];
- [self setAutoresizingMask:
- NSViewMinXMargin|NSViewWidthSizable|NSViewMaxXMargin|NSViewMinYMargin];
- [view addSubview:self];
+ [self setAutoresizingMask:NSViewWidthSizable|NSViewMaxYMargin];
}
return self;
}
@@ -57,112 +65,97 @@ static const CGFloat kIconViewSize = 66;
@end
-@implementation SadTabView
+@interface SadTabContainerView : NSView<NSTextViewDelegate> {
+ @private
+ base::scoped_nsobject<NSImageView> image_;
+ base::scoped_nsobject<NSTextField> title_;
+ base::scoped_nsobject<NSTextField> message_;
+ base::scoped_nsobject<HyperlinkTextView> help_;
+ base::scoped_nsobject<NSButton> button_;
+}
-- (instancetype)initWithFrame:(NSRect)frame {
- if ((self = [super initWithFrame:frame])) {
+- (instancetype)initWithBackgroundColor:(NSColor*)backgroundColor;
+
+@property(readonly,nonatomic) NSButton* reloadButton;
+
+// The height to fit the content elements within the current width.
+@property(readonly,nonatomic) CGFloat contentHeight;
+
+@end
+
+@implementation SadTabContainerView
+
+- (instancetype)initWithBackgroundColor:(NSColor*)backgroundColor {
+ if ((self = [super initWithFrame:NSZeroRect])) {
// Load resource for image and set it.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- image_.reset([[NSImageView alloc]
- initWithFrame:NSMakeRect(0, 0, kIconViewSize, kIconViewSize)]);
- [image_ setImage:rb.GetNativeImageNamed(IDR_SAD_TAB).ToNSImage()];
+ NSImage* iconImage = rb.GetNativeImageNamed(IDR_SAD_TAB).ToNSImage();
+ NSRect imageFrame = NSZeroRect;
+ imageFrame.size = [iconImage size];
+ image_.reset([[NSImageView alloc] initWithFrame:imageFrame]);
+ [image_ setImage:iconImage];
+ [image_ setAutoresizingMask:NSViewMaxXMargin|NSViewMaxYMargin];
[self addSubview:image_];
- // Initialize background color.
- NSColor* backgroundColor = [NSColor colorWithCalibratedWhite:247.0f/255.0f
- alpha:1.0];
- [self setWantsLayer:YES];
- [[self layer] setBackgroundColor:[backgroundColor cr_CGColor]];
-
// Set up the title.
- title_.reset([[SadTabTextView alloc]
- initWithView:self withText:IDS_SAD_TAB_TITLE]);
+ title_.reset(
+ [[SadTabTextView alloc] initWithStringResourceID:IDS_SAD_TAB_TITLE]);
[title_ setFont:[NSFont systemFontOfSize:24]];
[title_ setBackgroundColor:backgroundColor];
- [title_ setTextColor:[NSColor colorWithCalibratedWhite:51.0f/255.0f
+ [title_ setTextColor:[NSColor colorWithCalibratedWhite:38.0f/255.0f
alpha:1.0]];
+ [title_ sizeToFit];
+ [title_ setFrameOrigin:
+ NSMakePoint(0, NSMaxY(imageFrame) + kIconTitleSpacing)];
+ [self addSubview:title_];
// Set up the message.
- message_.reset([[SadTabTextView alloc]
- initWithView:self withText:IDS_SAD_TAB_MESSAGE]);
- [message_ setFont:[NSFont systemFontOfSize:15]];
+ message_.reset(
+ [[SadTabTextView alloc] initWithStringResourceID:IDS_SAD_TAB_MESSAGE]);
+ [message_ setFont:[NSFont systemFontOfSize:14]];
[message_ setBackgroundColor:backgroundColor];
- [message_ setTextColor:[NSColor colorWithCalibratedWhite:100.0f/255.0f
+ [message_ setTextColor:[NSColor colorWithCalibratedWhite:81.0f/255.0f
alpha:1.0]];
+ [message_ setFrameOrigin:
+ NSMakePoint(0, NSMaxY([title_ frame]) + kTitleMessageSpacing)];
+ [self addSubview:message_];
[self initializeHelpText];
+
+ button_.reset([[BlueLabelButton alloc] init]);
+ [button_ setTitle:l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_LABEL)];
+ [button_ sizeToFit];
+ [button_ setTarget:self];
+ [button_ setAction:@selector(reloadPage:)];
+ [self addSubview:button_];
}
return self;
}
-- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
- NSRect newBounds = [self bounds];
- CGFloat maxWidth = NSWidth(newBounds) - (kTabHorzMargin * 2);
- BOOL callSizeToFit = (messageSize_.width == 0);
-
- // Set new frame origin for image.
- NSRect iconFrame = [image_ frame];
- CGFloat iconX = floorf((maxWidth - NSWidth(iconFrame)) / 2);
- CGFloat iconY =
- MIN(floorf((NSHeight(newBounds) - NSHeight(iconFrame)) / 2) -
- kSadTabOffset,
- NSHeight(newBounds) - NSHeight(iconFrame));
- iconX = floorf(iconX);
- iconY = floorf(iconY);
- [image_ setFrameOrigin:NSMakePoint(iconX, iconY)];
-
- // Set new frame origin for title.
- if (callSizeToFit)
- [title_ sizeToFit];
- NSRect titleFrame = [title_ frame];
- CGFloat titleX = floorf((maxWidth - NSWidth(titleFrame)) / 2);
- CGFloat titleY = iconY - kIconTitleSpacing - NSHeight(titleFrame);
- [title_ setFrameOrigin:NSMakePoint(titleX, titleY)];
-
- // Set new frame for message, wrapping or unwrapping the text if necessary.
- if (callSizeToFit) {
- [message_ sizeToFit];
- messageSize_ = [message_ frame].size;
- }
- NSRect messageFrame = [message_ frame];
- if (messageSize_.width > maxWidth) { // Need to wrap message.
- [message_ setFrameSize:NSMakeSize(maxWidth, messageSize_.height)];
- CGFloat heightChange =
- [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_];
- messageFrame.size.width = maxWidth;
- messageFrame.size.height = messageSize_.height + heightChange;
- messageFrame.origin.x = kTabHorzMargin;
- } else {
- if (!callSizeToFit) {
- [message_ sizeToFit];
- messageFrame = [message_ frame];
- }
- messageFrame.origin.x = floorf((maxWidth - NSWidth(messageFrame)) / 2);
- }
- messageFrame.origin.y =
- titleY - kTitleMessageSpacing - NSHeight(messageFrame);
- [message_ setFrame:messageFrame];
-
- // Set new frame for help text and link.
- if (help_) {
- if (callSizeToFit)
- [help_ sizeToFit];
- CGFloat helpHeight = [help_ frame].size.height;
- [help_ setFrameSize:NSMakeSize(maxWidth, helpHeight)];
- // Set new frame origin for link.
- NSRect helpFrame = [help_ frame];
- CGFloat helpX = floorf((maxWidth - NSWidth(helpFrame)) / 2);
- CGFloat helpY =
- NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(helpFrame);
- [help_ setFrameOrigin:NSMakePoint(helpX, helpY)];
- }
+- (BOOL)isFlipped {
+ return YES;
}
-- (void)removeHelpText {
- if (help_) {
- [help_ removeFromSuperview];
- help_.reset(nil);
- }
+- (NSButton*)reloadButton {
+ return button_;
+}
+
+- (CGFloat)contentHeight {
+ return NSMaxY([button_ frame]);
+}
+
+- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
+ [super resizeSubviewsWithOldSize:oldSize];
+
+ // |message_| can wrap to variable number of lines.
+ [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_];
+
+ [help_ setFrameOrigin:
+ NSMakePoint(0, NSMaxY([message_ frame]) + kMessageLinkSpacing)];
+
+ [button_ setFrameOrigin:
+ NSMakePoint(NSMaxX([self bounds]) - NSWidth([button_ frame]),
+ NSMaxY([help_ frame]) + kLinkButtonSpacing)];
}
- (void)initializeHelpText {
@@ -171,10 +164,10 @@ static const CGFloat kIconViewSize = 66;
NSFont* helpFont = [message_ font];
NSRect helpFrame = NSMakeRect(0, 0, 1, [helpFont pointSize] + 4);
help_.reset([[HyperlinkTextView alloc] initWithFrame:helpFrame]);
- [help_ setAutoresizingMask:
- NSViewMinXMargin|NSViewWidthSizable|NSViewMaxXMargin|NSViewMinYMargin];
+ [help_ setAutoresizingMask:NSViewWidthSizable|NSViewMaxYMargin];
[help_ setDrawsBackground:YES];
[help_ setBackgroundColor:[message_ backgroundColor]];
+ [[help_ textContainer] setLineFragmentPadding:2]; // To align with message_.
[self addSubview:help_];
[help_ setDelegate:self];
@@ -190,7 +183,8 @@ static const CGFloat kIconViewSize = 66;
[help_ addLinkRange:NSMakeRange(linkOffset, helpLink.length())
withName:@""
linkColor:[message_ textColor]];
- [help_ setAlignment:NSCenterTextAlignment];
+ [help_ setAlignment:NSLeftTextAlignment];
+ [help_ sizeToFit];
}
// Called when someone clicks on the embedded link.
@@ -202,3 +196,48 @@ static const CGFloat kIconViewSize = 66;
}
@end
+
+@implementation SadTabView
+
+- (instancetype)initWithFrame:(NSRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+ [self setWantsLayer:YES];
+
+ NSColor* backgroundColor = [NSColor colorWithCalibratedWhite:245.0f/255.0f
+ alpha:1.0];
+ [[self layer] setBackgroundColor:[backgroundColor cr_CGColor]];
+
+ container_.reset(
+ [[SadTabContainerView alloc] initWithBackgroundColor:backgroundColor]);
+ [self addSubview:container_];
+ }
+ return self;
+}
+
+- (BOOL)isFlipped {
+ return YES;
+}
+
+- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
+ NSRect bounds = [self bounds];
+
+ // Set the container size first because its contentHeight will depend on its
+ // width.
+ NSSize frameSize = NSMakeSize(
+ std::min(NSWidth(bounds) - 2 * kTabMargin, kMaxContainerWidth),
+ NSHeight(bounds));
+ [container_ setFrameSize:frameSize];
+
+ // Center horizontally.
+ // Top margin is at least kTabMargin and at most kMaxTopMargin.
+ [container_ setFrameOrigin:NSMakePoint(
+ floor((NSWidth(bounds) - frameSize.width) / 2),
+ std::min(kMaxTopMargin, std::max(kTabMargin,
+ NSHeight(bounds) - [container_ contentHeight] - kTabMargin)))];
+}
+
+- (NSButton*)reloadButton {
+ return [container_ reloadButton];
+}
+
+@end
diff --git a/ui/base/cocoa/controls/blue_label_button.mm b/ui/base/cocoa/controls/blue_label_button.mm
index fad0a01..d602146 100644
--- a/ui/base/cocoa/controls/blue_label_button.mm
+++ b/ui/base/cocoa/controls/blue_label_button.mm
@@ -93,9 +93,15 @@ const SkColor kPressOuterRingColor = SkColorSetRGB(0x23, 0x52, 0xa2);
// Fuzz factor to adjust for the drop shadow. Based on visual inspection.
frame.origin.y -= 1;
+ // Ensure LCD font smoothing is enabled when layer backed.
+ // This is safe to do because we know we are drawing on an opaque background.
+ gfx::ScopedNSGraphicsContextSaveGState scopedGState;
+ NSGraphicsContext* context = [NSGraphicsContext currentContext];
+ CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]);
+ CGContextSetShouldSmoothFonts(cgContext, true);
+
NSAttributedString* attributedTitle =
[[self class] generateAttributedString:[self title]];
- gfx::ScopedNSGraphicsContextSaveGState context;
[attributedTitle drawInRect:frame];
return frame;
}