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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h"
7 #include "base/logging.h"
8 #include "base/strings/sys_string_conversions.h"
9 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
10 #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
11 #include "chrome/common/url_constants.h"
12 #include "grit/generated_resources.h"
13 #include "grit/theme_resources.h"
14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/l10n/l10n_util_mac.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/image/image.h"
20 // Offset above vertical middle of page where contents of page start.
21 static const CGFloat kSadTabOffset = -64;
22 // Padding between icon and title.
23 static const CGFloat kIconTitleSpacing = 20;
24 // Padding between title and message.
25 static const CGFloat kTitleMessageSpacing = 15;
26 // Padding between message and link.
27 static const CGFloat kMessageLinkSpacing = 15;
28 // Paddings on left and right of page.
29 static const CGFloat kTabHorzMargin = 13;
31 @implementation SadTabView
33 - (void)awakeFromNib {
34 // Load resource for image and set it.
35 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
36 NSImage* image = rb.GetNativeImageNamed(IDR_SAD_TAB).ToNSImage();
37 [image_ setImage:image];
39 // Set font for title.
40 NSFont* titleFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
41 [title_ setFont:titleFont];
43 // Set font for message.
44 NSFont* messageFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
45 [message_ setFont:messageFont];
48 [self initializeHelpText];
50 // Initialize background color.
51 NSColor* backgroundColor = [[NSColor colorWithCalibratedRed:(35.0f/255.0f)
55 backgroundColor_.reset(backgroundColor);
58 - (void)drawRect:(NSRect)dirtyRect {
60 [backgroundColor_ set];
61 NSRectFill(dirtyRect);
64 - (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
65 NSRect newBounds = [self bounds];
66 CGFloat maxWidth = NSWidth(newBounds) - (kTabHorzMargin * 2);
67 BOOL callSizeToFit = (messageSize_.width == 0);
69 // Set new frame origin for image.
70 NSRect iconFrame = [image_ frame];
71 CGFloat iconX = (maxWidth - NSWidth(iconFrame)) / 2;
73 MIN(((NSHeight(newBounds) - NSHeight(iconFrame)) / 2) - kSadTabOffset,
74 NSHeight(newBounds) - NSHeight(iconFrame));
77 [image_ setFrameOrigin:NSMakePoint(iconX, iconY)];
79 // Set new frame origin for title.
82 NSRect titleFrame = [title_ frame];
83 CGFloat titleX = (maxWidth - NSWidth(titleFrame)) / 2;
84 CGFloat titleY = iconY - kIconTitleSpacing - NSHeight(titleFrame);
85 [title_ setFrameOrigin:NSMakePoint(titleX, titleY)];
87 // Set new frame for message, wrapping or unwrapping the text if necessary.
90 messageSize_ = [message_ frame].size;
92 NSRect messageFrame = [message_ frame];
93 if (messageSize_.width > maxWidth) { // Need to wrap message.
94 [message_ setFrameSize:NSMakeSize(maxWidth, messageSize_.height)];
95 CGFloat heightChange =
96 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_];
97 messageFrame.size.width = maxWidth;
98 messageFrame.size.height = messageSize_.height + heightChange;
99 messageFrame.origin.x = kTabHorzMargin;
101 if (!callSizeToFit) {
102 [message_ sizeToFit];
103 messageFrame = [message_ frame];
105 messageFrame.origin.x = (maxWidth - NSWidth(messageFrame)) / 2;
107 messageFrame.origin.y =
108 titleY - kTitleMessageSpacing - NSHeight(messageFrame);
109 [message_ setFrame:messageFrame];
111 // Set new frame for help text and link.
114 [help_.get() sizeToFit];
115 CGFloat helpHeight = [help_.get() frame].size.height;
116 [help_.get() setFrameSize:NSMakeSize(maxWidth, helpHeight)];
117 // Set new frame origin for link.
118 NSRect helpFrame = [help_.get() frame];
119 CGFloat helpX = (maxWidth - NSWidth(helpFrame)) / 2;
121 NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(helpFrame);
122 [help_.get() setFrameOrigin:NSMakePoint(helpX, helpY)];
126 - (void)removeHelpText {
128 [help_.get() removeFromSuperview];
133 - (void)initializeHelpText {
134 // Replace the help placeholder NSTextField with the real help NSTextView.
135 // The former doesn't show links in a nice way, but the latter can't be added
136 // in IB without a containing scroll view, so create the NSTextView
137 // programmatically. Taken from -[InfoBarController initializeLabel].
139 [[HyperlinkTextView alloc] initWithFrame:[helpPlaceholder_ frame]]);
140 [help_.get() setAutoresizingMask:[helpPlaceholder_ autoresizingMask]];
141 [[helpPlaceholder_ superview]
142 replaceSubview:helpPlaceholder_ with:help_.get()];
143 helpPlaceholder_ = nil; // Now released.
144 [help_.get() setDelegate:self];
145 [help_.get() setAlignment:NSCenterTextAlignment];
147 // Get the help text and link.
148 size_t linkOffset = 0;
149 NSString* helpMessage(base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(
150 IDS_SAD_TAB_HELP_MESSAGE, base::string16(), &linkOffset)));
151 NSString* helpLink = l10n_util::GetNSString(IDS_SAD_TAB_HELP_LINK);
152 NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
153 [help_.get() setMessageAndLink:helpMessage
157 messageColor:[NSColor whiteColor]
158 linkColor:[NSColor whiteColor]];
161 // Called when someone clicks on the embedded link.
162 - (BOOL)textView:(NSTextView*)textView
163 clickedOnLink:(id)link
164 atIndex:(NSUInteger)charIndex {
166 [controller_ openLearnMoreAboutCrashLink:nil];