Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / screen_capture_notification_ui_cocoa.mm
blobcabe8cb2a93a037ff4ab2050147b939405308dfa
1 // Copyright 2013 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/screen_capture_notification_ui_cocoa.h"
7 #import <Cocoa/Cocoa.h>
9 #include "base/compiler_specific.h"
10 #include "base/i18n/rtl.h"
11 #include "base/mac/mac_util.h"
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "grit/generated_resources.h"
16 #include "grit/theme_resources.h"
17 #include "skia/ext/skia_utils_mac.h"
18 #import "ui/base/cocoa/controls/blue_label_button.h"
19 #include "ui/base/cocoa/window_size_constants.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/font_list.h"
23 #include "ui/gfx/image/image_skia.h"
24 #include "ui/gfx/image/image_skia_util_mac.h"
25 #include "ui/gfx/text_elider.h"
26 #include "ui/native_theme/native_theme.h"
28 const CGFloat kMinimumWidth = 460;
29 const CGFloat kMaximumWidth = 1000;
30 const CGFloat kHorizontalMargin = 10;
31 const CGFloat kPadding = 5;
32 const CGFloat kPaddingLeft = 10;
33 const CGFloat kWindowCornerRadius = 2;
35 @interface ScreenCaptureNotificationController()
36 - (void)hide;
37 - (void)populateWithText:(const base::string16&)text;
38 @end
40 @interface ScreenCaptureNotificationView : NSView
41 @end
43 @interface WindowGripView : NSImageView
44 - (WindowGripView*)init;
45 @end
48 ScreenCaptureNotificationUICocoa::ScreenCaptureNotificationUICocoa(
49     const base::string16& text)
50     : text_(text) {
53 ScreenCaptureNotificationUICocoa::~ScreenCaptureNotificationUICocoa() {}
55 void ScreenCaptureNotificationUICocoa::OnStarted(
56     const base::Closure& stop_callback) {
57   DCHECK(!stop_callback.is_null());
58   DCHECK(!windowController_);
60   windowController_.reset([[ScreenCaptureNotificationController alloc]
61       initWithCallback:stop_callback
62                   text:text_]);
63   [windowController_ showWindow:nil];
66 scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create(
67     const base::string16& text) {
68   return scoped_ptr<ScreenCaptureNotificationUI>(
69       new ScreenCaptureNotificationUICocoa(text));
72 @implementation ScreenCaptureNotificationController
73 - (id)initWithCallback:(const base::Closure&)stop_callback
74                   text:(const base::string16&)text {
75   base::scoped_nsobject<NSWindow> window(
76       [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
77                                   styleMask:NSBorderlessWindowMask
78                                     backing:NSBackingStoreBuffered
79                                       defer:NO]);
80   [window setReleasedWhenClosed:NO];
81   [window setBackgroundColor:[NSColor clearColor]];
82   [window setOpaque:NO];
83   [window setHasShadow:YES];
84   [window setLevel:NSStatusWindowLevel];
85   [window setMovableByWindowBackground:YES];
86   [window setDelegate:self];
88   self = [super initWithWindow:window];
89   if (self) {
90     stop_callback_ = stop_callback;
91     [self populateWithText:text];
93     // Center the window at the bottom of the screen, above the dock (if
94     // present).
95     NSRect desktopRect = [[NSScreen mainScreen] visibleFrame];
96     NSRect contentRect = [[window contentView] frame];
97     NSRect windowRect =
98         NSMakeRect((NSWidth(desktopRect) - NSWidth(contentRect)) / 2,
99                    NSMinY(desktopRect),
100                    NSWidth(contentRect),
101                    NSHeight(contentRect));
102     [window setFrame:windowRect display:YES];
103   }
104   return self;
107 - (void)stopSharing:(id)sender {
108   if (!stop_callback_.is_null()) {
109     base::Closure callback = stop_callback_;
110     stop_callback_.Reset();
111     callback.Run();  // Deletes |self|.
112   }
115 - (void)hide {
116   stop_callback_.Reset();
117   [self close];
120 - (void)populateWithText:(const base::string16&)text {
121   base::scoped_nsobject<ScreenCaptureNotificationView> content(
122       [[ScreenCaptureNotificationView alloc]
123           initWithFrame:ui::kWindowSizeDeterminedLater]);
124   [[self window] setContentView:content];
126   // Create button.
127   stopButton_.reset([[BlueLabelButton alloc] initWithFrame:NSZeroRect]);
128   [stopButton_ setTitle:l10n_util::GetNSString(
129                   IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP)];
130   [stopButton_ setTarget:self];
131   [stopButton_ setAction:@selector(stopSharing:)];
132   [stopButton_ sizeToFit];
133   [content addSubview:stopButton_];
135   CGFloat buttonWidth = NSWidth([stopButton_ frame]);
136   CGFloat totalHeight = kPadding + NSHeight([stopButton_ frame]) + kPadding;
138   // Create grip icon.
139   base::scoped_nsobject<WindowGripView> gripView([[WindowGripView alloc] init]);
140   [content addSubview:gripView];
141   CGFloat gripWidth = NSWidth([gripView frame]);
142   CGFloat gripHeight = NSHeight([gripView frame]);
143   [gripView
144       setFrameOrigin:NSMakePoint(kPaddingLeft, (totalHeight - gripHeight) / 2)];
146   // Create text label.
147   int maximumWidth =
148       std::min(kMaximumWidth, NSWidth([[NSScreen mainScreen] visibleFrame]));
149   int maxLabelWidth = maximumWidth - kPaddingLeft - kPadding -
150                       kHorizontalMargin * 2 - gripWidth - buttonWidth;
151   gfx::FontList font_list;
152   base::string16 elidedText =
153       ElideText(text, font_list, maxLabelWidth, gfx::ELIDE_IN_MIDDLE);
154   NSString* statusText = base::SysUTF16ToNSString(elidedText);
155   base::scoped_nsobject<NSTextField> statusTextField(
156       [[NSTextField alloc] initWithFrame:ui::kWindowSizeDeterminedLater]);
157   [statusTextField setEditable:NO];
158   [statusTextField setSelectable:NO];
159   [statusTextField setDrawsBackground:NO];
160   [statusTextField setBezeled:NO];
161   [statusTextField setStringValue:statusText];
162   [statusTextField setFont:font_list.GetPrimaryFont().GetNativeFont()];
163   [statusTextField sizeToFit];
164   [statusTextField setFrameOrigin:NSMakePoint(
165                        kPaddingLeft + kHorizontalMargin + gripWidth,
166                        (totalHeight - NSHeight([statusTextField frame])) / 2)];
167   [content addSubview:statusTextField];
169   // Resize content view to fit controls.
170   CGFloat minimumLableWidth = kMinimumWidth - kPaddingLeft - kPadding -
171                               kHorizontalMargin * 2 - gripWidth - buttonWidth;
172   CGFloat lableWidth =
173       std::max(NSWidth([statusTextField frame]), minimumLableWidth);
174   CGFloat totalWidth = kPaddingLeft + kPadding + kHorizontalMargin * 2 +
175                        gripWidth + lableWidth + buttonWidth;
176   [content setFrame:NSMakeRect(0, 0, totalWidth, totalHeight)];
178   // Move the button to the right place.
179   NSPoint buttonOrigin =
180       NSMakePoint(totalWidth - kPadding - buttonWidth, kPadding);
181   [stopButton_ setFrameOrigin:buttonOrigin];
183   if (base::i18n::IsRTL()) {
184     [stopButton_
185         setFrameOrigin:NSMakePoint(totalWidth - NSMaxX([stopButton_ frame]),
186                                    NSMinY([stopButton_ frame]))];
187     [statusTextField
188         setFrameOrigin:NSMakePoint(totalWidth - NSMaxX([statusTextField frame]),
189                                    NSMinY([statusTextField frame]))];
190     [gripView setFrameOrigin:NSMakePoint(totalWidth - NSMaxX([gripView frame]),
191                                          NSMinY([gripView frame]))];
192   }
195 - (void)windowWillClose:(NSNotification*)notification {
196   [self stopSharing:nil];
199 @end
201 @implementation ScreenCaptureNotificationView
203 - (void)drawRect:(NSRect)dirtyRect {
204   [gfx::SkColorToSRGBNSColor(ui::NativeTheme::instance()->GetSystemColor(
205       ui::NativeTheme::kColorId_DialogBackground)) set];
206   [[NSBezierPath bezierPathWithRoundedRect:[self bounds]
207                                    xRadius:kWindowCornerRadius
208                                    yRadius:kWindowCornerRadius] fill];
211 @end
213 @implementation WindowGripView
214 - (WindowGripView*)init {
215   gfx::Image gripImage =
216       ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
217           IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP,
218           ui::ResourceBundle::RTL_DISABLED);
219   self = [super
220       initWithFrame:NSMakeRect(0, 0, gripImage.Width(), gripImage.Height())];
221   [self setImage:gripImage.ToNSImage()];
222   return self;
225 - (BOOL)mouseDownCanMoveWindow {
226   return YES;
228 @end