Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import <Cocoa/Cocoa.h> | |
| 6 | |
| 7 #include "base/logging.h" // for NOTREACHED() | |
| 8 #include "base/mac/mac_util.h" | |
| 9 #include "base/sys_string_conversions.h" | |
| 10 #include "chrome/app/chrome_command_ids.h" | |
| 11 #include "chrome/browser/ui/browser.h" | |
| 12 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
| 13 #import "chrome/browser/ui/cocoa/animatable_view.h" | |
| 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | |
| 15 #include "chrome/browser/ui/cocoa/event_utils.h" | |
| 16 #import "chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h" | |
| 17 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | |
| 18 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | |
| 19 #include "ui/base/models/accelerator_cocoa.h" | |
| 20 #include "ui/base/l10n/l10n_util_mac.h" | |
| 21 #include "chrome/app/chrome_command_ids.h" | |
|
Nico
2011/09/15 04:37:32
alphabetize includes
jeremya
2011/09/15 06:33:28
Done.
| |
| 22 #include "grit/generated_resources.h" | |
| 23 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" | |
| 24 | |
| 25 namespace { | |
|
Nico
2011/09/15 04:37:32
const has implicit internal linkage, no need for a
jeremya
2011/09/15 06:33:28
Done.
| |
| 26 const int kPaddingPx = 8; | |
| 27 const int kInitialDelayMs = 3800; | |
| 28 const int kSlideOutDurationMs = 700; | |
| 29 } | |
| 30 | |
| 31 @interface FullscreenExitBubbleController (PrivateMethods) | |
| 32 // Sets |exitLabel_| based on |exitLabelPlaceholder_|, sets | |
|
Nico
2011/09/15 04:37:32
nit: break after ,
jeremya
2011/09/15 06:33:28
Done.
| |
| 33 // |exitLabelPlaceholder_| to nil. | |
| 34 - (void)initializeLabel; | |
| 35 | |
| 36 - (void)hideSoon; | |
| 37 | |
| 38 // Returns the Accelerator for the Toggle Fullscreen menu item. | |
| 39 + (ui::AcceleratorCocoa)toggleFullscreenAccelerator; | |
| 40 | |
| 41 // Returns a string representation fit for display of | |
| 42 // |+toggleFullscreenAccelerator|. | |
|
Nico
2011/09/15 04:37:32
objc methods don't need || since they have a prefi
jeremya
2011/09/15 06:33:28
Done.
| |
| 43 + (NSString*)keyCommandString; | |
| 44 | |
| 45 + (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item; | |
| 46 @end | |
| 47 | |
| 48 @implementation FullscreenExitBubbleController | |
| 49 | |
| 50 - (id)initWithOwner:(BrowserWindowController*)owner browser:(Browser*)browser { | |
| 51 if ((self = [super initWithNibName:@"FullscreenExitBubble" | |
| 52 bundle:base::mac::MainAppBundle()])) { | |
| 53 browser_ = browser; | |
| 54 owner_ = owner; | |
| 55 } | |
| 56 return self; | |
| 57 } | |
| 58 | |
| 59 - (void)awakeFromNib { | |
| 60 [self initializeLabel]; | |
| 61 [self hideSoon]; | |
| 62 } | |
| 63 | |
| 64 // Called when someone clicks on the embedded link. | |
| 65 - (BOOL) textView:(NSTextView*)textView | |
| 66 clickedOnLink:(id)link | |
| 67 atIndex:(NSUInteger)charIndex { | |
| 68 // TODO there's probably a better way to invoke this. | |
|
Nico
2011/09/15 04:37:32
Remove TODO. this is good as is
jeremya
2011/09/15 06:33:28
Done.
| |
| 69 browser_->ExecuteCommand(IDC_FULLSCREEN); | |
| 70 return YES; | |
| 71 } | |
| 72 | |
| 73 - (void)hideTimerFire:(NSTimer*)timer { | |
|
Nico
2011/09/15 04:37:32
hideTimerFired?
jeremya
2011/09/15 06:33:28
Done.
| |
| 74 NSRect endFrame = [[self view] frame]; | |
| 75 endFrame.origin.y += endFrame.size.height; | |
| 76 endFrame.size.height = 0; | |
| 77 NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: | |
| 78 [self view], NSViewAnimationTargetKey, | |
| 79 [NSValue valueWithRect:endFrame], NSViewAnimationEndFrameKey, nil]; | |
| 80 | |
| 81 NSViewAnimation* animation = | |
| 82 [[NSViewAnimation alloc] | |
| 83 initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]]; | |
| 84 [animation gtm_setDuration:kSlideOutDurationMs/1000.0 | |
| 85 eventMask:NSLeftMouseUpMask]; | |
| 86 [animation setDelegate:self]; | |
| 87 [animation startAnimation]; | |
| 88 hideAnimation_ = animation; | |
| 89 } | |
| 90 | |
| 91 - (void)animationDidEnd:(NSAnimation*)animation { | |
| 92 if (animation == hideAnimation_) { | |
| 93 [hideAnimation_ autorelease]; | |
|
Nico
2011/09/15 04:37:32
.reset()?
jeremya
2011/09/15 06:33:28
Done.
| |
| 94 hideAnimation_ = nil; | |
| 95 } | |
| 96 | |
| 97 [owner_ setShowFloatingChrome:YES]; | |
| 98 } | |
| 99 | |
| 100 - (AnimatableView*)animatableView { | |
| 101 return static_cast<AnimatableView*>([self view]); | |
| 102 } | |
| 103 | |
| 104 - (void)dealloc { | |
| 105 // TODO one or more of these things may be unnecessary. | |
|
Nico
2011/09/15 04:37:32
Don't add non-actionable TODOs, see the TODO secti
jeremya
2011/09/15 06:33:28
Forgot to remove this. Oops.
| |
| 106 [[self animatableView] stopAnimation]; | |
| 107 [hideAnimation_ stopAnimation]; | |
| 108 [hideTimer_ invalidate]; | |
| 109 [super dealloc]; | |
| 110 } | |
| 111 | |
| 112 @end | |
| 113 | |
| 114 @implementation FullscreenExitBubbleController (PrivateMethods) | |
| 115 | |
| 116 - (void)initializeLabel { | |
| 117 // Replace the label placeholder NSTextField with the real label NSTextView. | |
| 118 // The former doesn't show links in a nice way, but the latter can't be added | |
| 119 // in IB without a containing scroll view, so create the NSTextView | |
| 120 // programmatically. | |
| 121 exitLabel_.reset([[HyperlinkTextView alloc] | |
| 122 initWithFrame:[exitLabelPlaceholder_ frame]]); | |
| 123 [exitLabel_.get() setAutoresizingMask: | |
| 124 [exitLabelPlaceholder_ autoresizingMask]]; | |
| 125 [[exitLabelPlaceholder_ superview] | |
| 126 replaceSubview:exitLabelPlaceholder_ with:exitLabel_.get()]; | |
| 127 exitLabelPlaceholder_ = nil; // Now released. | |
| 128 [exitLabel_.get() setDelegate:self]; | |
| 129 | |
| 130 NSString *message = l10n_util::GetNSStringF(IDS_EXIT_FULLSCREEN_MODE, | |
| 131 base::SysNSStringToUTF16([[self class] keyCommandString])); | |
| 132 | |
| 133 HyperlinkTextView* view = (HyperlinkTextView*)exitLabel_.get(); | |
| 134 [view setMessageAndLink:@"" | |
|
Nico
2011/09/15 04:37:32
Just say [exitLabel_.get() setFoo] here and get ri
jeremya
2011/09/15 06:33:28
Done.
| |
| 135 withLink:message | |
| 136 atOffset:0 | |
| 137 font:[NSFont systemFontOfSize:18] | |
| 138 messageColor:[NSColor whiteColor] | |
| 139 linkColor:[NSColor whiteColor]]; | |
| 140 | |
| 141 [exitLabel_.get() sizeToFit]; | |
| 142 NSLayoutManager* lm = [exitLabel_.get() layoutManager]; | |
|
Nico
2011/09/15 04:37:32
no abbreviations
jeremya
2011/09/15 06:33:28
Done.
| |
| 143 NSTextContainer* tc = [exitLabel_.get() textContainer]; | |
| 144 [lm ensureLayoutForTextContainer:tc]; | |
| 145 NSRect tcFrame = [lm usedRectForTextContainer:tc]; | |
|
Nico
2011/09/15 04:37:32
yikes. just sizeForAttributes is too far off?
jeremya
2011/09/15 06:33:28
It's consistently 10px off; it seems to add space
| |
| 146 NSRect frame = [[self view] frame]; | |
| 147 NSSize textSize = tcFrame.size; | |
| 148 frame.size.width = textSize.width + 2 * kPaddingPx; | |
|
Nico
2011/09/15 04:37:32
NSInsetRect
jeremya
2011/09/15 06:33:28
How should I use that function?
Nico
2011/09/15 20:09:14
frame = NSInsetRect(frame, -kPaddingPx, 0) I think
| |
| 149 [[self view] setFrame:frame]; | |
| 150 frame = tcFrame; | |
| 151 frame.origin.x = frame.origin.y = kPaddingPx; | |
| 152 [exitLabel_.get() setFrame:frame]; | |
| 153 } | |
| 154 | |
| 155 // This looks at the Main Menu and determines what the user has set as the | |
| 156 // key combination for quit. It then gets the modifiers and builds an object | |
| 157 // to hold the data. | |
| 158 + (ui::AcceleratorCocoa)toggleFullscreenAccelerator { | |
|
Nico
2011/09/15 04:37:32
This parses like "toggle fullscreen accelerator".
jeremya
2011/09/15 06:33:28
Done.
| |
| 159 NSMenu* mainMenu = [NSApp mainMenu]; | |
| 160 // Get the application menu (i.e. Chromium). | |
| 161 for (NSMenuItem* menu in [mainMenu itemArray]) { | |
| 162 for (NSMenuItem* item in [[menu submenu] itemArray]) { | |
| 163 // Find the toggle presentation mode item. | |
| 164 if ([item tag] == IDC_PRESENTATION_MODE) { | |
| 165 return ui::AcceleratorCocoa([item keyEquivalent], | |
| 166 [item keyEquivalentModifierMask]); | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 // Default to Cmd+Shift+F. | |
| 171 return ui::AcceleratorCocoa(@"f", NSCommandKeyMask|NSShiftKeyMask); | |
| 172 } | |
| 173 | |
| 174 // This looks at the Main Menu and determines what the user has set as the | |
| 175 // key combination for quit. It then gets the modifiers and builds a string | |
| 176 // to display them. | |
| 177 + (NSString*)keyCommandString { | |
| 178 ui::AcceleratorCocoa accelerator = [[self class] toggleFullscreenAccelerator]; | |
| 179 return [[self class] keyCombinationForAccelerator:accelerator]; | |
| 180 } | |
| 181 | |
| 182 + (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item { | |
| 183 NSMutableString* string = [NSMutableString string]; | |
| 184 NSUInteger modifiers = item.modifiers(); | |
| 185 | |
| 186 if (modifiers & NSCommandKeyMask) | |
| 187 [string appendString:@"\u2318"]; | |
| 188 if (modifiers & NSControlKeyMask) | |
| 189 [string appendString:@"\u2303"]; | |
| 190 if (modifiers & NSAlternateKeyMask) | |
| 191 [string appendString:@"\u2325"]; | |
| 192 BOOL isUpperCase = [[NSCharacterSet uppercaseLetterCharacterSet] | |
| 193 characterIsMember:[item.characters() characterAtIndex:0]]; | |
| 194 if (modifiers & NSShiftKeyMask || isUpperCase) | |
| 195 [string appendString:@"\u21E7"]; | |
| 196 | |
| 197 [string appendString:[item.characters() uppercaseString]]; | |
| 198 return string; | |
| 199 } | |
| 200 | |
| 201 - (void)hideSoon { | |
| 202 hideTimer_.reset( | |
| 203 [[NSTimer scheduledTimerWithTimeInterval:kInitialDelayMs/1000.0 | |
| 204 target:self | |
| 205 selector:@selector(hideTimerFire:) | |
| 206 userInfo:nil | |
| 207 repeats:NO] retain]); | |
| 208 } | |
| 209 | |
| 210 @end | |
| OLD | NEW |