Index: chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm |
diff --git a/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm |
deleted file mode 100644 |
index 0815179af2e4d4bbbcbb1d2389e94a6e32ad7228..0000000000000000000000000000000000000000 |
--- a/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm |
+++ /dev/null |
@@ -1,575 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#import "chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.h" |
- |
-#import <Cocoa/Cocoa.h> |
- |
-#include "base/logging.h" |
-#include "base/mac/scoped_nsautorelease_pool.h" |
-#import "chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.h" |
-#import "chrome/browser/ui/panels/panel_constants.h" |
-#include "chrome/grit/generated_resources.h" |
-#include "grit/theme_resources.h" |
-#include "ui/base/cocoa/cocoa_base_utils.h" |
-#import "ui/base/cocoa/hover_image_button.h" |
-#import "ui/base/cocoa/nsview_additions.h" |
-#include "ui/base/l10n/l10n_util_mac.h" |
-#include "ui/base/resource/resource_bundle.h" |
-#include "ui/gfx/image/image.h" |
-#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
- |
-// 'Glint' is a glowing light animation on the titlebar to attract user's |
-// attention. Numbers are arbitrary, based on several tries. |
-const double kGlintAnimationDuration = 1.5; |
-const double kGlintRepeatIntervalSeconds = 1.0; |
-const int kNumberOfGlintRepeats = 4; // 5 total, including initial flash. |
- |
-// Used to implement TestingAPI |
-static NSEvent* MakeMouseEvent(NSEventType type, |
- NSPoint point, |
- int modifierFlags, |
- int clickCount) { |
- return [NSEvent mouseEventWithType:type |
- location:point |
- modifierFlags:modifierFlags |
- timestamp:0 |
- windowNumber:0 |
- context:nil |
- eventNumber:0 |
- clickCount:clickCount |
- pressure:0.0]; |
-} |
- |
-// Test drag controller - does not contain a nested message loop, directly |
-// invokes the dragStarted/dragProgress instead. |
-@interface TestDragController : MouseDragController { |
- @private |
- BOOL dragStarted_; |
-} |
-- (void)mouseDragged:(NSEvent*)event; |
-@end |
- |
-@implementation TestDragController |
-// Bypass nested message loop for tests. There is no need to check for |
-// threshold here as the base class does because tests only simulate a single |
-// 'mouse drag' to the destination point. |
-- (void)mouseDragged:(NSEvent*)event { |
- if (!dragStarted_) { |
- [[self client] dragStarted:[self initialMouseLocation]]; |
- dragStarted_ = YES; |
- } |
- |
- [[self client] dragProgress:[event locationInWindow]]; |
-} |
-@end |
- |
-@implementation PanelTitlebarOverlayView |
-// Sometimes we do not want to bring chrome window to foreground when we click |
-// on any part of the titlebar. To do this, we first postpone the window |
-// reorder here (shouldDelayWindowOrderingForEvent is called during when mouse |
-// button is pressed but before mouseDown: is dispatched) and then complete |
-// canceling the reorder by [NSApp preventWindowOrdering] in mouseDown handler |
-// of this view. |
-- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent*)theEvent { |
- disableReordering_ = ![controller_ canBecomeKeyWindow]; |
- return disableReordering_; |
-} |
- |
-- (void)mouseDown:(NSEvent*)event { |
- if (disableReordering_) |
- [NSApp preventWindowOrdering]; |
- disableReordering_ = NO; |
- // Continue bubbling the event up the chain of responders. |
- [super mouseDown:event]; |
-} |
- |
-- (BOOL)acceptsFirstMouse:(NSEvent*)event { |
- return YES; |
-} |
-@end |
- |
-@implementation RepaintAnimation |
-- (id)initWithView:(NSView*)targetView duration:(double) duration { |
- if ((self = [super initWithDuration:duration |
- animationCurve:NSAnimationEaseInOut])) { |
- [self setAnimationBlockingMode:NSAnimationNonblocking]; |
- targetView_ = targetView; |
- } |
- return self; |
-} |
- |
-- (void)setCurrentProgress:(NSAnimationProgress)progress { |
- [super setCurrentProgress:progress]; |
- [targetView_ setNeedsDisplay:YES]; |
-} |
-@end |
- |
- |
-@implementation PanelTitlebarViewCocoa |
- |
-- (id)initWithFrame:(NSRect)frame { |
- if ((self = [super initWithFrame:frame])) |
- dragController_.reset([[MouseDragController alloc] initWithClient:self]); |
- return self; |
-} |
- |
-- (void)dealloc { |
- [[NSNotificationCenter defaultCenter] removeObserver:self]; |
- [self stopGlintAnimation]; |
- [super dealloc]; |
-} |
- |
-- (void)onCloseButtonClick:(id)sender { |
- [controller_ closePanel]; |
-} |
- |
-- (void)onMinimizeButtonClick:(id)sender { |
- [controller_ minimizeButtonClicked:[[NSApp currentEvent] modifierFlags]]; |
-} |
- |
-- (void)onRestoreButtonClick:(id)sender { |
- [controller_ restoreButtonClicked:[[NSApp currentEvent] modifierFlags]]; |
-} |
- |
-- (void)drawRect:(NSRect)rect { |
- if (isDrawingAttention_) { |
- NSColor* attentionColor = [NSColor colorWithCalibratedRed:0x53/255.0 |
- green:0xa9/255.0 |
- blue:0x3f/255.0 |
- alpha:1.0]; |
- [attentionColor set]; |
- NSRectFillUsingOperation([self bounds], NSCompositeSourceOver); |
- |
- if ([glintAnimation_ isAnimating]) { |
- base::scoped_nsobject<NSGradient> glint([NSGradient alloc]); |
- float currentAlpha = 0.8 * [glintAnimation_ currentValue]; |
- NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 |
- alpha:currentAlpha]; |
- NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 |
- alpha:0.0]; |
- [glint initWithColorsAndLocations: |
- startColor, 0.0, startColor, 0.3, endColor, 1.0, nil]; |
- NSRect bounds = [self bounds]; |
- [glint drawInRect:bounds relativeCenterPosition:NSZeroPoint]; |
- } |
- } else { |
- BOOL isActive = [[self window] isMainWindow]; |
- |
- // If titlebar is close to minimized state or is at minimized state and only |
- // shows a few pixels, change the color to something light and add border. |
- NSRect windowFrame = [[self window] frame]; |
- if (NSHeight(windowFrame) < 8) { |
- NSColor* lightBackgroundColor = |
- [NSColor colorWithCalibratedRed:0xf5/255.0 |
- green:0xf4/255.0 |
- blue:0xf0/255.0 |
- alpha:1.0]; |
- [lightBackgroundColor set]; |
- NSRectFill([self bounds]); |
- |
- NSColor* borderColor = |
- [NSColor colorWithCalibratedRed:0xc9/255.0 |
- green:0xc9/255.0 |
- blue:0xc9/255.0 |
- alpha:1.0]; |
- [borderColor set]; |
- NSFrameRect([self bounds]); |
- } else { |
- // use solid black-ish colors. |
- NSColor* backgroundColor = isActive ? |
- [NSColor colorWithCalibratedRed:0x3a/255.0 |
- green:0x3d/255.0 |
- blue:0x3d/255.0 |
- alpha:1.0] : |
- [NSColor colorWithCalibratedRed:0x7a/255.0 |
- green:0x7c/255.0 |
- blue:0x7c/255.0 |
- alpha:1.0]; |
- |
- [backgroundColor set]; |
- NSRectFill([self bounds]); |
- } |
- } |
- |
- NSColor* titleColor = [NSColor colorWithCalibratedRed:0xf9/255.0 |
- green:0xf9/255.0 |
- blue:0xf9/255.0 |
- alpha:1.0]; |
- [title_ setTextColor:titleColor]; |
-} |
- |
-- (void)attach { |
- // Interface Builder can not put a view as a sibling of contentView, |
- // so need to do it here. Placing ourself as the last child of the |
- // internal view allows us to draw on top of the titlebar. |
- // Note we must use [controller_ window] here since we have not been added |
- // to the view hierarchy yet. |
- NSView* contentView = [[controller_ window] contentView]; |
- NSView* rootView = [contentView superview]; |
- [rootView addSubview:self]; |
- |
- // Figure out the rectangle of the titlebar and set us on top of it. |
- // The titlebar covers window's root view where not covered by contentView. |
- // Compute the titlebar frame in coordinate system of the window's root view. |
- // NSWindow |
- // | |
- // ___root_view____ |
- // | | |
- // contentView titlebar |
- NSSize titlebarSize = NSMakeSize(0, panel::kTitlebarHeight); |
- titlebarSize = [contentView convertSize:titlebarSize toView:rootView]; |
- NSRect rootViewBounds = [[self superview] bounds]; |
- NSRect titlebarFrame = |
- NSMakeRect(NSMinX(rootViewBounds), |
- NSMaxY(rootViewBounds) - titlebarSize.height, |
- NSWidth(rootViewBounds), |
- titlebarSize.height); |
- [self setFrame:titlebarFrame]; |
- |
- [title_ setFont:[[NSFontManager sharedFontManager] |
- fontWithFamily:@"Arial" |
- traits:NSBoldFontMask |
- weight:0 |
- size:14.0]]; |
- [title_ setDrawsBackground:NO]; |
- |
- ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
- |
- [self initializeImageButton:customCloseButton_ |
- image:rb.GetNativeImageNamed(IDR_PANEL_CLOSE).ToNSImage() |
- hoverImage:rb.GetNativeImageNamed(IDR_PANEL_CLOSE_H).ToNSImage() |
- pressedImage:rb.GetNativeImageNamed(IDR_PANEL_CLOSE_C).ToNSImage() |
- toolTip:l10n_util::GetNSStringWithFixup(IDS_PANEL_CLOSE_TOOLTIP)]; |
- |
- // Iniitalize the minimize and restore buttons. |
- [self initializeImageButton:minimizeButton_ |
- image:rb.GetNativeImageNamed(IDR_PANEL_MINIMIZE).ToNSImage() |
- hoverImage:rb.GetNativeImageNamed(IDR_PANEL_MINIMIZE_H).ToNSImage() |
- pressedImage:rb.GetNativeImageNamed(IDR_PANEL_MINIMIZE_C).ToNSImage() |
- toolTip:l10n_util::GetNSStringWithFixup(IDS_PANEL_MINIMIZE_TOOLTIP)]; |
- |
- [self initializeImageButton:restoreButton_ |
- image:rb.GetNativeImageNamed(IDR_PANEL_RESTORE).ToNSImage() |
- hoverImage:rb.GetNativeImageNamed(IDR_PANEL_RESTORE_H).ToNSImage() |
- pressedImage:rb.GetNativeImageNamed(IDR_PANEL_RESTORE_C).ToNSImage() |
- toolTip:l10n_util::GetNSStringWithFixup(IDS_PANEL_RESTORE_TOOLTIP)]; |
- |
- [controller_ updateTitleBarMinimizeRestoreButtonVisibility]; |
- |
- [self updateCustomButtonsLayout]; |
- |
- // Set autoresizing behavior: glued to edges on left, top and right. |
- [self setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)]; |
- |
- [[NSNotificationCenter defaultCenter] |
- addObserver:self |
- selector:@selector(didChangeFrame:) |
- name:NSViewFrameDidChangeNotification |
- object:self]; |
- [[NSNotificationCenter defaultCenter] |
- addObserver:self |
- selector:@selector(didChangeMainWindow:) |
- name:NSWindowDidBecomeMainNotification |
- object:[self window]]; |
- [[NSNotificationCenter defaultCenter] |
- addObserver:self |
- selector:@selector(didChangeMainWindow:) |
- name:NSWindowDidResignMainNotification |
- object:[self window]]; |
-} |
- |
-- (void)initializeImageButton:(HoverImageButton*)button |
- image:(NSImage*)image |
- hoverImage:(NSImage*)hoverImage |
- pressedImage:(NSImage*)pressedImage |
- toolTip:(NSString*)toolTip { |
- [button setDefaultImage:image]; |
- [button setHoverImage:hoverImage]; |
- [button setPressedImage:pressedImage]; |
- [button setToolTip:toolTip]; |
- [[button cell] setHighlightsBy:NSNoCellMask]; |
-} |
- |
-- (void)setTitle:(NSString*)newTitle { |
- [title_ setStringValue:newTitle]; |
- [self updateIconAndTitleLayout]; |
-} |
- |
-- (void)setIcon:(NSView*)newIcon { |
- [icon_ removeFromSuperview]; |
- icon_ = newIcon; |
- if (icon_) { |
- [self addSubview:icon_ positioned:NSWindowBelow relativeTo:overlay_]; |
- [icon_ setWantsLayer:YES]; |
- } |
- [self updateIconAndTitleLayout]; |
-} |
- |
-- (NSView*)icon { |
- return icon_; |
-} |
- |
-- (void)setMinimizeButtonVisibility:(BOOL)visible { |
- [minimizeButton_ setHidden:!visible]; |
-} |
- |
-- (void)setRestoreButtonVisibility:(BOOL)visible { |
- [restoreButton_ setHidden:!visible]; |
-} |
- |
-- (void)updateCustomButtonsLayout { |
- NSRect bounds = [self bounds]; |
- NSRect closeButtonFrame = [customCloseButton_ frame]; |
- closeButtonFrame.size.width = panel::kPanelButtonSize; |
- closeButtonFrame.size.height = panel::kPanelButtonSize; |
- closeButtonFrame.origin.x = |
- NSWidth(bounds) - NSWidth(closeButtonFrame) - panel::kButtonPadding; |
- closeButtonFrame.origin.y = |
- (NSHeight(bounds) - NSHeight(closeButtonFrame)) / 2; |
- [customCloseButton_ setFrame:closeButtonFrame]; |
- |
- NSRect buttonFrame = [minimizeButton_ frame]; |
- buttonFrame.size.width = panel::kPanelButtonSize; |
- buttonFrame.size.height = panel::kPanelButtonSize; |
- buttonFrame.origin.x = |
- closeButtonFrame.origin.x - NSWidth(buttonFrame) - panel::kButtonPadding; |
- buttonFrame.origin.y = (NSHeight(bounds) - NSHeight(buttonFrame)) / 2; |
- [minimizeButton_ setFrame:buttonFrame]; |
- [restoreButton_ setFrame:buttonFrame]; |
-} |
- |
-- (void)updateIconAndTitleLayout { |
- NSRect iconFrame = [icon_ frame]; |
- // NSTextField for title_ is set to Layout:Truncate, LineBreaks:TruncateTail |
- // in Interface Builder so it is sized in a single-line mode. |
- [title_ sizeToFit]; |
- NSRect titleFrame = [title_ frame]; |
- // Only one of minimize/restore button is visible at a time so just allow for |
- // the width of one of them. |
- NSRect minimizeRestoreButtonFrame = [minimizeButton_ frame]; |
- NSRect bounds = [self bounds]; |
- |
- // Place the icon and title at the left edge of the titlebar. |
- int iconWidth = NSWidth(iconFrame); |
- int titleWidth = NSWidth(titleFrame); |
- int availableWidth = minimizeRestoreButtonFrame.origin.x - |
- panel::kTitleAndButtonPadding; |
- |
- int paddings = panel::kTitlebarLeftPadding + panel::kIconAndTitlePadding; |
- if (paddings + iconWidth + titleWidth > availableWidth) |
- titleWidth = availableWidth - iconWidth - paddings; |
- if (titleWidth < 0) |
- titleWidth = 0; |
- |
- iconFrame.origin.x = panel::kTitlebarLeftPadding; |
- iconFrame.origin.y = (NSHeight(bounds) - NSHeight(iconFrame)) / 2; |
- [icon_ setFrame:iconFrame]; |
- |
- titleFrame.origin.x = paddings + iconWidth; |
- // In bottom-heavy text labels, let's compensate for occasional integer |
- // rounding to avoid text label to feel too low. |
- titleFrame.origin.y = (NSHeight(bounds) - NSHeight(titleFrame)) / 2 + 2; |
- titleFrame.size.width = titleWidth; |
- [title_ setFrame:titleFrame]; |
-} |
- |
-// PanelManager controls size/position of the window. |
-- (BOOL)mouseDownCanMoveWindow { |
- return NO; |
-} |
- |
-- (BOOL)acceptsFirstMouse:(NSEvent*)event { |
- return YES; |
-} |
- |
-- (void)didChangeFrame:(NSNotification*)notification { |
- // Update buttons first because title layout depends on buttons layout. |
- [self updateCustomButtonsLayout]; |
- [self updateIconAndTitleLayout]; |
-} |
- |
-- (void)didChangeMainWindow:(NSNotification*)notification { |
- [self setNeedsDisplay:YES]; |
-} |
- |
-- (void)mouseDown:(NSEvent*)event { |
- [dragController_ mouseDown:event]; |
-} |
- |
-- (void)mouseUp:(NSEvent*)event { |
- [dragController_ mouseUp:event]; |
- |
- if ([event clickCount] == 1) |
- [controller_ onTitlebarMouseClicked:[event modifierFlags]]; |
- else if ([event clickCount] == 2) |
- [controller_ onTitlebarDoubleClicked:[event modifierFlags]]; |
-} |
- |
-- (void)mouseDragged:(NSEvent*)event { |
- [dragController_ mouseDragged:event]; |
-} |
- |
-// MouseDragControllerClient implementaiton |
- |
-- (void)prepareForDrag { |
-} |
- |
-- (void)dragStarted:(NSPoint)initialMouseLocation { |
- NSPoint initialMouseLocationScreen = ui::ConvertPointFromWindowToScreen( |
- [self window], initialMouseLocation); |
- [controller_ startDrag:initialMouseLocationScreen]; |
-} |
- |
-- (void)dragEnded:(BOOL)cancelled { |
- [controller_ endDrag:cancelled]; |
-} |
- |
-- (void)dragProgress:(NSPoint)mouseLocation { |
- NSPoint mouseLocationScreen = ui::ConvertPointFromWindowToScreen( |
- [self window], mouseLocation); |
- [controller_ drag:mouseLocationScreen]; |
-} |
- |
-- (void)cleanupAfterDrag { |
-} |
- |
-// End of MouseDragControllerClient implementaiton |
- |
-- (void)drawAttention { |
- if (isDrawingAttention_) |
- return; |
- isDrawingAttention_ = YES; |
- |
- [self startGlintAnimation]; |
-} |
- |
-- (void)stopDrawingAttention { |
- if (!isDrawingAttention_) |
- return; |
- isDrawingAttention_ = NO; |
- |
- [self stopGlintAnimation]; |
- [self setNeedsDisplay:YES]; |
-} |
- |
-- (BOOL)isDrawingAttention { |
- return isDrawingAttention_; |
-} |
- |
-- (void)startGlintAnimation { |
- glintCounter_ = 0; |
- [self restartGlintAnimation:nil]; |
-} |
- |
-- (void)stopGlintAnimation { |
- if (glintAnimationTimer_.get()) { |
- [glintAnimationTimer_ invalidate]; |
- glintAnimationTimer_.reset(); |
- } |
- if ([glintAnimation_ isAnimating]) |
- [glintAnimation_ stopAnimation]; |
-} |
- |
-- (void)restartGlintAnimation:(NSTimer*)timer { |
- if (!glintAnimation_.get()) { |
- glintAnimation_.reset( |
- [[RepaintAnimation alloc] initWithView:self |
- duration:kGlintAnimationDuration]); |
- [glintAnimation_ setDelegate:self]; |
- } |
- [glintAnimation_ startAnimation]; |
-} |
- |
-// NSAnimationDelegate method. |
-- (void)animationDidEnd:(NSAnimation*)animation { |
- if (animation != glintAnimation_.get()) |
- return; |
- if (glintCounter_ >= kNumberOfGlintRepeats) |
- return; |
- glintCounter_++; |
- // Restart after a timeout. |
- glintAnimationTimer_.reset([[NSTimer |
- scheduledTimerWithTimeInterval:kGlintRepeatIntervalSeconds |
- target:self |
- selector:@selector(restartGlintAnimation:) |
- userInfo:nil |
- repeats:NO] retain]); |
-} |
- |
-// NSAnimationDelegate method. |
-- (float)animation:(NSAnimation *)animation |
- valueForProgress:(NSAnimationProgress)progress { |
- if (animation != glintAnimation_.get()) |
- return progress; |
- |
- // Converts 0..1 progression into a sharper raise/fall. |
- float result = progress < 0.5 ? progress : 1.0 - progress; |
- result = 4.0 * result * result; |
- return result; |
-} |
- |
-// (Private/TestingAPI) |
-- (PanelWindowControllerCocoa*)controller { |
- return controller_; |
-} |
- |
-- (NSTextField*)title { |
- return title_; |
-} |
- |
-- (void)simulateCloseButtonClick { |
- [[customCloseButton_ cell] performClick:customCloseButton_]; |
-} |
- |
-- (void)pressLeftMouseButtonTitlebar:(NSPoint)mouseLocation |
- modifiers:(int)modifierFlags { |
- // Override the drag controller. It's ok to create a new one for each drag. |
- dragController_.reset([[TestDragController alloc] initWithClient:self]); |
- // Convert from Cocoa's screen coordinates to base coordinates since the mouse |
- // event takes base (NSWindow) coordinates. |
- NSPoint mouseLocationWindow = ui::ConvertPointFromScreenToWindow( |
- [self window], mouseLocation); |
- NSEvent* event = MakeMouseEvent(NSLeftMouseDown, mouseLocationWindow, |
- modifierFlags, 0); |
- [self mouseDown:event]; |
-} |
- |
-- (void)releaseLeftMouseButtonTitlebar:(int)modifierFlags { |
- NSEvent* event = MakeMouseEvent(NSLeftMouseUp, NSZeroPoint, modifierFlags, 1); |
- [self mouseUp:event]; |
-} |
- |
-- (void)dragTitlebar:(NSPoint)mouseLocation { |
- // Convert from Cocoa's screen coordinates to base coordinates since the mouse |
- // event takes base (NSWindow) coordinates. |
- NSPoint mouseLocationWindow = ui::ConvertPointFromScreenToWindow( |
- [self window], mouseLocation); |
- NSEvent* event = |
- MakeMouseEvent(NSLeftMouseDragged, mouseLocationWindow, 0, 0); |
- [self mouseDragged:event]; |
-} |
- |
-- (void)cancelDragTitlebar { |
- [self dragEnded:YES]; |
-} |
- |
-- (void)finishDragTitlebar { |
- [self dragEnded:NO]; |
-} |
- |
-- (NSButton*)closeButton { |
- return closeButton_; |
-} |
- |
-- (NSButton*)minimizeButton { |
- return minimizeButton_; |
-} |
- |
-- (NSButton*)restoreButton { |
- return restoreButton_; |
-} |
- |
-@end |
- |