Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h" | 5 #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/sys_string_conversions.h" | |
| 8 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" | 9 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.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" | |
| 9 #include "grit/theme_resources.h" | 13 #include "grit/theme_resources.h" |
| 10 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 14 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | |
| 16 #include "ui/base/l10n/l10n_util_mac.h" | |
| 11 #include "ui/base/resource/resource_bundle.h" | 17 #include "ui/base/resource/resource_bundle.h" |
| 12 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" |
| 13 | 19 |
| 14 // Offset above vertical middle of page where contents of page start. | 20 // Offset above vertical middle of page where contents of page start. |
| 15 static const CGFloat kSadTabOffset = -64; | 21 static const CGFloat kSadTabOffset = -64; |
| 16 // Padding between icon and title. | 22 // Padding between icon and title. |
| 17 static const CGFloat kIconTitleSpacing = 20; | 23 static const CGFloat kIconTitleSpacing = 20; |
| 18 // Padding between title and message. | 24 // Padding between title and message. |
| 19 static const CGFloat kTitleMessageSpacing = 15; | 25 static const CGFloat kTitleMessageSpacing = 15; |
| 20 // Padding between message and link. | 26 // Padding between message and link. |
| 21 static const CGFloat kMessageLinkSpacing = 15; | 27 static const CGFloat kMessageLinkSpacing = 15; |
| 22 // Paddings on left and right of page. | 28 // Paddings on left and right of page. |
| 23 static const CGFloat kTabHorzMargin = 13; | 29 static const CGFloat kTabHorzMargin = 13; |
| 24 | 30 |
| 31 // This simple subclass of |NSTextView| just doesn't show the (text) cursor | |
| 32 // (|NSTextView| displays the cursor with full keyboard accessibility enabled). | |
| 33 @interface HelpTextView : NSTextView | |
| 34 - (void)fixupCursor; | |
| 35 @end | |
| 36 | |
| 37 @implementation HelpTextView | |
| 38 | |
| 39 // Never draw the insertion point (otherwise, it shows up without any user | |
| 40 // action if full keyboard accessibility is enabled). | |
| 41 - (BOOL)shouldDrawInsertionPoint { | |
| 42 return NO; | |
| 43 } | |
| 44 | |
| 45 - (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange | |
| 46 granularity:(NSSelectionGranularity)granularity { | |
| 47 // Do not allow selections. | |
| 48 return NSMakeRange(0, 0); | |
| 49 } | |
| 50 | |
| 51 // Convince NSTextView to not show an I-Beam cursor when the cursor is over the | |
| 52 // text view but not over actual text. | |
| 53 // | |
| 54 // http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg10791.html | |
| 55 // "NSTextView sets the cursor over itself dynamically, based on considerations | |
| 56 // including the text under the cursor. It does so in -mouseEntered:, | |
| 57 // -mouseMoved:, and -cursorUpdate:, so those would be points to consider | |
| 58 // overriding." | |
| 59 - (void)mouseMoved:(NSEvent*)e { | |
| 60 [super mouseMoved:e]; | |
| 61 [self fixupCursor]; | |
| 62 } | |
| 63 | |
| 64 - (void)mouseEntered:(NSEvent*)e { | |
| 65 [super mouseEntered:e]; | |
| 66 [self fixupCursor]; | |
| 67 } | |
| 68 | |
| 69 - (void)cursorUpdate:(NSEvent*)e { | |
| 70 [super cursorUpdate:e]; | |
| 71 [self fixupCursor]; | |
| 72 } | |
| 73 | |
| 74 - (void)fixupCursor { | |
| 75 if ([[NSCursor currentCursor] isEqual:[NSCursor IBeamCursor]]) | |
| 76 [[NSCursor arrowCursor] set]; | |
| 77 } | |
| 78 | |
| 79 @end | |
| 80 | |
| 25 @implementation SadTabView | 81 @implementation SadTabView |
| 26 | 82 |
| 27 - (void)awakeFromNib { | 83 - (void)awakeFromNib { |
| 28 // Load resource for image and set it. | 84 // Load resource for image and set it. |
| 29 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 85 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 30 NSImage* image = rb.GetNativeImageNamed(IDR_SAD_TAB); | 86 NSImage* image = rb.GetNativeImageNamed(IDR_SAD_TAB); |
| 31 DCHECK(image); | 87 DCHECK(image); |
| 32 [image_ setImage:image]; | 88 [image_ setImage:image]; |
| 33 | 89 |
| 34 // Set font for title. | 90 // Set font for title. |
| 35 NSFont* titleFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]]; | 91 NSFont* titleFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]]; |
| 36 [title_ setFont:titleFont]; | 92 [title_ setFont:titleFont]; |
| 37 | 93 |
| 38 // Set font for message. | 94 // Set font for message. |
| 39 NSFont* messageFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; | 95 NSFont* messageFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; |
| 40 [message_ setFont:messageFont]; | 96 [message_ setFont:messageFont]; |
| 41 | 97 |
|
Nico
2011/08/12 02:29:56
Instead, you would then DCHECK(controller_) here;
msw
2011/08/30 04:09:06
Done.
| |
| 42 // If necessary, set font and color for link. | 98 [self initializeHelpText]; |
| 43 if (linkButton_) { | |
| 44 [linkButton_ setFont:messageFont]; | |
| 45 [linkCell_ setTextColor:[NSColor whiteColor]]; | |
| 46 } | |
| 47 | 99 |
| 48 // Initialize background color. | 100 // Initialize background color. |
| 49 NSColor* backgroundColor = [[NSColor colorWithCalibratedRed:(35.0f/255.0f) | 101 NSColor* backgroundColor = [[NSColor colorWithCalibratedRed:(35.0f/255.0f) |
| 50 green:(48.0f/255.0f) | 102 green:(48.0f/255.0f) |
| 51 blue:(64.0f/255.0f) | 103 blue:(64.0f/255.0f) |
| 52 alpha:1.0] retain]; | 104 alpha:1.0] retain]; |
| 53 backgroundColor_.reset(backgroundColor); | 105 backgroundColor_.reset(backgroundColor); |
| 54 } | 106 } |
| 55 | 107 |
| 56 - (void)drawRect:(NSRect)dirtyRect { | 108 - (void)drawRect:(NSRect)dirtyRect { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 if (!callSizeToFit) { | 151 if (!callSizeToFit) { |
| 100 [message_ sizeToFit]; | 152 [message_ sizeToFit]; |
| 101 messageFrame = [message_ frame]; | 153 messageFrame = [message_ frame]; |
| 102 } | 154 } |
| 103 messageFrame.origin.x = (maxWidth - NSWidth(messageFrame)) / 2; | 155 messageFrame.origin.x = (maxWidth - NSWidth(messageFrame)) / 2; |
| 104 } | 156 } |
| 105 messageFrame.origin.y = | 157 messageFrame.origin.y = |
| 106 titleY - kTitleMessageSpacing - NSHeight(messageFrame); | 158 titleY - kTitleMessageSpacing - NSHeight(messageFrame); |
| 107 [message_ setFrame:messageFrame]; | 159 [message_ setFrame:messageFrame]; |
| 108 | 160 |
| 109 if (linkButton_) { | 161 // Set new frame for help text and link. |
| 162 if (help_.get()) { | |
|
Nico
2011/08/12 02:29:56
The .get() shouldn't be necessary I think.
msw
2011/08/30 04:09:06
Done.
| |
| 110 if (callSizeToFit) | 163 if (callSizeToFit) |
| 111 [linkButton_ sizeToFit]; | 164 [help_.get() sizeToFit]; |
| 165 CGFloat helpHeight = [help_.get() frame].size.height; | |
| 166 [help_.get() setFrameSize:NSMakeSize(maxWidth, helpHeight)]; | |
| 112 // Set new frame origin for link. | 167 // Set new frame origin for link. |
| 113 NSRect linkFrame = [linkButton_ frame]; | 168 NSRect helpFrame = [help_.get() frame]; |
| 114 CGFloat linkX = (maxWidth - NSWidth(linkFrame)) / 2; | 169 CGFloat helpX = (maxWidth - NSWidth(helpFrame)) / 2; |
| 115 CGFloat linkY = | 170 CGFloat helpY = |
| 116 NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(linkFrame); | 171 NSMinY(messageFrame) - kMessageLinkSpacing - NSHeight(helpFrame); |
| 117 [linkButton_ setFrameOrigin:NSMakePoint(linkX, linkY)]; | 172 [help_.get() setFrameOrigin:NSMakePoint(helpX, helpY)]; |
| 118 } | 173 } |
| 119 } | 174 } |
| 120 | 175 |
| 121 - (void)removeLinkButton { | 176 - (void)setController:(SadTabController*)controller { |
| 122 if (linkButton_) { | 177 controller_ = controller; |
| 123 [linkButton_ removeFromSuperview]; | 178 } |
| 124 linkButton_ = nil; | 179 |
| 180 | |
| 181 - (void)removeHelpText { | |
| 182 if (help_.get()) { | |
| 183 [help_.get() removeFromSuperview]; | |
| 184 help_.reset(nil); | |
| 125 } | 185 } |
| 126 } | 186 } |
| 127 | 187 |
| 188 - (void)initializeHelpText { | |
|
Nico
2011/08/12 02:29:56
For stuff like this, it's very useful to say "Take
msw
2011/08/30 04:09:06
Done.
| |
| 189 // Replace the help placeholder NSTextField with the real help NSTextView. | |
| 190 // The former doesn't show links in a nice way, but the latter can't be added | |
| 191 // in IB without a containing scroll view, so create the NSTextView | |
| 192 // programmatically. | |
| 193 help_.reset([[HelpTextView alloc] initWithFrame:[helpPlaceholder_ frame]]); | |
| 194 [help_.get() setAutoresizingMask:[helpPlaceholder_ autoresizingMask]]; | |
| 195 [[helpPlaceholder_ superview] | |
| 196 replaceSubview:helpPlaceholder_ with:help_.get()]; | |
| 197 helpPlaceholder_ = nil; // Now released. | |
| 198 [help_.get() setDelegate:self]; | |
| 199 [help_.get() setEditable:NO]; | |
| 200 [help_.get() setDrawsBackground:NO]; | |
| 201 [help_.get() setHorizontallyResizable:NO]; | |
| 202 [help_.get() setVerticallyResizable:NO]; | |
| 203 [help_.get() setAlignment:NSCenterTextAlignment]; | |
| 204 | |
| 205 // Get the help text and link. | |
| 206 size_t linkOffset = 0; | |
| 207 NSString* helpMessage(base::SysUTF16ToNSString(l10n_util::GetStringFUTF16( | |
| 208 IDS_SAD_TAB_HELP_MESSAGE, string16(), &linkOffset))); | |
| 209 NSString* helpLink = l10n_util::GetNSString(IDS_SAD_TAB_HELP_LINK); | |
| 210 | |
| 211 // Create an attributes dictionary for the help text and link. | |
| 212 NSMutableDictionary* helpAttributes = [NSMutableDictionary dictionary]; | |
| 213 [helpAttributes setObject:[NSCursor arrowCursor] | |
| 214 forKey:NSCursorAttributeName]; | |
| 215 NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; | |
| 216 [helpAttributes setObject:font | |
| 217 forKey:NSFontAttributeName]; | |
| 218 [helpAttributes setObject:[NSColor whiteColor] | |
| 219 forKey:NSForegroundColorAttributeName]; | |
|
Nico
2011/08/12 02:29:56
This is very similiar to setLabelToMessage:withLin
msw
2011/08/30 04:09:06
Done.
| |
| 220 | |
| 221 // Create the attributed string for the main help message text. | |
| 222 scoped_nsobject<NSMutableAttributedString> helpText( | |
| 223 [[NSMutableAttributedString alloc] initWithString:helpMessage]); | |
| 224 [helpText.get() addAttributes:helpAttributes | |
| 225 range:NSMakeRange(0, [helpText.get() length])]; | |
| 226 | |
| 227 // Add additional attributes to the embedded link. | |
| 228 [helpAttributes setObject:[NSNumber numberWithBool:YES] | |
| 229 forKey:NSUnderlineStyleAttributeName]; | |
| 230 [helpAttributes setObject:[NSCursor pointingHandCursor] | |
| 231 forKey:NSCursorAttributeName]; | |
| 232 [helpAttributes setObject:[NSNumber numberWithInt:NSSingleUnderlineStyle] | |
| 233 forKey:NSUnderlineStyleAttributeName]; | |
| 234 [helpAttributes setObject:[NSString string] // dummy value | |
| 235 forKey:NSLinkAttributeName]; | |
| 236 | |
| 237 // Insert the link text into the string at the appropriate offset. | |
| 238 scoped_nsobject<NSAttributedString> attributedString( | |
| 239 [[NSAttributedString alloc] initWithString:helpLink | |
| 240 attributes:helpAttributes]); | |
| 241 [helpText.get() insertAttributedString:attributedString.get() | |
| 242 atIndex:linkOffset]; | |
| 243 | |
| 244 // Ensure the TextView doesn't override the link style. | |
| 245 [help_.get() setLinkTextAttributes:helpAttributes]; | |
| 246 | |
| 247 // Update the label view with the new text. | |
| 248 [[help_.get() textStorage] setAttributedString:helpText]; | |
| 249 } | |
| 250 | |
| 251 // Called when someone clicks on the embedded link. | |
| 252 - (BOOL) textView:(NSTextView*)textView | |
| 253 clickedOnLink:(id)link | |
| 254 atIndex:(NSUInteger)charIndex { | |
| 255 if (controller_) | |
| 256 [controller_ openLearnMoreAboutCrashLink:nil]; | |
| 257 return YES; | |
| 258 } | |
| 259 | |
| 128 @end | 260 @end |
| OLD | NEW |