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 @interface SadTabTextView : NSTextField
33 - (id)initWithView:(SadTabView*)view withText:(int)textIds;
37 @implementation SadTabTextView
39 - (id)initWithView:(SadTabView*)view withText:(int)textIds {
40 if (self = [super init]) {
41 [self setTextColor:[NSColor whiteColor]];
42 [self setAlignment:NSCenterTextAlignment];
43 [self setStringValue:l10n_util::GetNSString(textIds)];
44 [self setEditable:NO];
46 [self setAutoresizingMask:
47 NSViewMinXMargin|NSViewWidthSizable|NSViewMaxXMargin|NSViewMinYMargin];
48 [view addSubview:self];
59 @implementation SadTabView
61 - (void)awakeFromNib {
62 // Load resource for image and set it.
63 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
64 NSImage* image = rb.GetNativeImageNamed(IDR_SAD_TAB).ToNSImage();
65 [image_ setImage:image];
68 // Initialize background color.
69 NSColor* backgroundColor = [[NSColor colorWithCalibratedRed:(35.0f/255.0f)
73 backgroundColor_.reset(backgroundColor);
76 title_.reset([[SadTabTextView alloc]
77 initWithView:self withText:IDS_SAD_TAB_TITLE]);
78 [title_ setFont:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]]];
79 [title_ setBackgroundColor:backgroundColor];
81 // Set up the message.
82 message_.reset([[SadTabTextView alloc]
83 initWithView:self withText:IDS_SAD_TAB_MESSAGE]);
84 [message_ setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
85 [message_ setBackgroundColor:backgroundColor];
88 [self initializeHelpText];
91 - (void)drawRect:(NSRect)dirtyRect {
93 [backgroundColor_ set];
94 NSRectFill(dirtyRect);
97 - (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
98 NSRect newBounds = [self bounds];
99 CGFloat maxWidth = NSWidth(newBounds) - (kTabHorzMargin * 2);
100 BOOL callSizeToFit = (messageSize_.width == 0);
102 // Set new frame origin for image.
103 NSRect iconFrame = [image_ frame];
104 CGFloat iconX = floorf((maxWidth - NSWidth(iconFrame)) / 2);
106 MIN(floorf((NSHeight(newBounds) - NSHeight(iconFrame)) / 2) -
108 NSHeight(newBounds) - NSHeight(iconFrame));
109 iconX = floorf(iconX);
110 iconY = floorf(iconY);
111 [image_ setFrameOrigin:NSMakePoint(iconX, iconY)];
113 // Set new frame origin for title.
116 NSRect titleFrame = [title_ frame];
117 CGFloat titleX = floorf((maxWidth - NSWidth(titleFrame)) / 2);
118 CGFloat titleY = iconY - kIconTitleSpacing - NSHeight(titleFrame);
119 [title_ setFrameOrigin:NSMakePoint(titleX, titleY)];
121 // Set new frame for message, wrapping or unwrapping the text if necessary.
123 [message_ sizeToFit];
124 messageSize_ = [message_ frame].size;
126 NSRect messageFrame = [message_ frame];
127 if (messageSize_.width > maxWidth) { // Need to wrap message.
128 [message_ setFrameSize:NSMakeSize(maxWidth, messageSize_.height)];
129 CGFloat heightChange =
130 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_];
131 messageFrame.size.width = maxWidth;
132 messageFrame.size.height = messageSize_.height + heightChange;
133 messageFrame.origin.x = kTabHorzMargin;
135 if (!callSizeToFit) {
136 [message_ sizeToFit];
137 messageFrame = [message_ frame];
139 messageFrame.origin.x = floorf((maxWidth - NSWidth(messageFrame)) / 2);
141 messageFrame.origin.y =
142 titleY - kTitleMessageSpacing - NSHeight(messageFrame);
143 [message_ setFrame:messageFrame];
145 // Set new frame for help text and link.
149 CGFloat helpHeight = [help_ frame].size.height;
150 [help_ setFrameSize:NSMakeSize(maxWidth, helpHeight)];
151 // Set new frame origin for link.
152 NSRect helpFrame = [help_ frame];
153 CGFloat helpX = floorf((maxWidth - NSWidth(helpFrame)) / 2);
155 NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(helpFrame);
156 [help_ setFrameOrigin:NSMakePoint(helpX, helpY)];
160 - (void)removeHelpText {
162 [help_ removeFromSuperview];
167 - (void)initializeHelpText {
168 // Programmatically create the help link. Note that the frame's initial
169 // height must be set for the programmatic resizing to work.
171 [[HyperlinkTextView alloc] initWithFrame:NSMakeRect(0, 0, 1, 17)]);
172 [help_ setAutoresizingMask:
173 NSViewMinXMargin|NSViewWidthSizable|NSViewMaxXMargin|NSViewMinYMargin];
174 [self addSubview:help_];
175 [help_ setDelegate:self];
176 [help_ setAlignment:NSCenterTextAlignment];
178 // Get the help text and link.
179 size_t linkOffset = 0;
180 NSString* helpMessage(base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(
181 IDS_SAD_TAB_HELP_MESSAGE, base::string16(), &linkOffset)));
182 NSString* helpLink = l10n_util::GetNSString(IDS_SAD_TAB_HELP_LINK);
183 NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
184 [help_ setMessageAndLink:helpMessage
188 messageColor:[NSColor whiteColor]
189 linkColor:[NSColor whiteColor]];
192 // Called when someone clicks on the embedded link.
193 - (BOOL)textView:(NSTextView*)textView
194 clickedOnLink:(id)link
195 atIndex:(NSUInteger)charIndex {
197 [controller_ openLearnMoreAboutCrashLink:nil];