blob: 769ea749a0be9818506da73d6d4ce17b2e03a91d [file] [log] [blame]
// 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/cocoa/tab_contents/sad_tab_view.h"
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
#include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
#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;
// Padding between icon and title.
static const CGFloat kIconTitleSpacing = 20;
// Padding between title and message.
static const CGFloat kTitleMessageSpacing = 15;
// Padding between message and link.
static const CGFloat kMessageLinkSpacing = 15;
// Paddings on left and right of page.
static const CGFloat kTabHorzMargin = 13;
@implementation SadTabView
- (void)awakeFromNib {
// Load resource for image and set it.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
NSImage* image = rb.GetNativeImageNamed(IDR_SAD_TAB).ToNSImage();
[image_ setImage:image];
// Set font for title.
NSFont* titleFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
[title_ setFont:titleFont];
// Set font for message.
NSFont* messageFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
[message_ setFont:messageFont];
DCHECK(controller_);
[self initializeHelpText];
// Initialize background color.
NSColor* backgroundColor = [[NSColor colorWithCalibratedRed:(35.0f/255.0f)
green:(48.0f/255.0f)
blue:(64.0f/255.0f)
alpha:1.0] retain];
backgroundColor_.reset(backgroundColor);
}
- (void)drawRect:(NSRect)dirtyRect {
// Paint background.
[backgroundColor_ set];
NSRectFill(dirtyRect);
}
- (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 = (maxWidth - NSWidth(iconFrame)) / 2;
CGFloat iconY =
MIN(((NSHeight(newBounds) - NSHeight(iconFrame)) / 2) - kSadTabOffset,
NSHeight(newBounds) - NSHeight(iconFrame));
iconX = floor(iconX);
iconY = floor(iconY);
[image_ setFrameOrigin:NSMakePoint(iconX, iconY)];
// Set new frame origin for title.
if (callSizeToFit)
[title_ sizeToFit];
NSRect titleFrame = [title_ frame];
CGFloat titleX = (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 = (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_.get() sizeToFit];
CGFloat helpHeight = [help_.get() frame].size.height;
[help_.get() setFrameSize:NSMakeSize(maxWidth, helpHeight)];
// Set new frame origin for link.
NSRect helpFrame = [help_.get() frame];
CGFloat helpX = (maxWidth - NSWidth(helpFrame)) / 2;
CGFloat helpY =
NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(helpFrame);
[help_.get() setFrameOrigin:NSMakePoint(helpX, helpY)];
}
}
- (void)removeHelpText {
if (help_.get()) {
[help_.get() removeFromSuperview];
help_.reset(nil);
}
}
- (void)initializeHelpText {
// Replace the help placeholder NSTextField with the real help NSTextView.
// The former doesn't show links in a nice way, but the latter can't be added
// in IB without a containing scroll view, so create the NSTextView
// programmatically. Taken from -[InfoBarController initializeLabel].
help_.reset(
[[HyperlinkTextView alloc] initWithFrame:[helpPlaceholder_ frame]]);
[help_.get() setAutoresizingMask:[helpPlaceholder_ autoresizingMask]];
[[helpPlaceholder_ superview]
replaceSubview:helpPlaceholder_ with:help_.get()];
helpPlaceholder_ = nil; // Now released.
[help_.get() setDelegate:self];
[help_.get() setAlignment:NSCenterTextAlignment];
// Get the help text and link.
size_t linkOffset = 0;
NSString* helpMessage(base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(
IDS_SAD_TAB_HELP_MESSAGE, base::string16(), &linkOffset)));
NSString* helpLink = l10n_util::GetNSString(IDS_SAD_TAB_HELP_LINK);
NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
[help_.get() setMessageAndLink:helpMessage
withLink:helpLink
atOffset:linkOffset
font:font
messageColor:[NSColor whiteColor]
linkColor:[NSColor whiteColor]];
}
// Called when someone clicks on the embedded link.
- (BOOL)textView:(NSTextView*)textView
clickedOnLink:(id)link
atIndex:(NSUInteger)charIndex {
if (controller_)
[controller_ openLearnMoreAboutCrashLink:nil];
return YES;
}
@end