Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/browser/cocoa/hover_close_button.mm

Issue 2805055: [Mac] Use Core Graphics to draw the close button used within tabs, infobars, ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #import "chrome/browser/cocoa/hover_close_button.h" 5 #import "chrome/browser/cocoa/hover_close_button.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/nsimage_cache_mac.h" 8 #include "base/scoped_nsobject.h"
9 #import "chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.h"
9 #include "grit/generated_resources.h" 10 #include "grit/generated_resources.h"
10 11
11 namespace { 12 namespace {
13 // Convenience function to return the middle point of the given |rect|.
14 static NSPoint MidRect(NSRect rect) {
15 return NSMakePoint(NSMidX(rect), NSMidY(rect));
16 }
12 17
13 NSString* const kNormalImageString = @"close_bar.pdf"; 18 const CGFloat kCircleRadiusPercentage = 0.45;
14 NSString* const kHoverImageString = @"close_bar_h.pdf"; 19 const CGFloat kCircleHoverWhite = 0.565;
15 NSString* const kPressedImageString = @"close_bar_p.pdf"; 20 const CGFloat kCircleClickWhite = 0.396;
21 const CGFloat kXShadowAlpha = 0.6;
22 const CGFloat kXShadowCircleAlpha = 0.1;
23 } // namespace
16 24
17 } // namespace 25 @interface HoverCloseButton(Private)
26 - (void)setUpDrawingPaths;
27 @end
18 28
19 @implementation HoverCloseButton 29 @implementation HoverCloseButton
20 30
21 - (id)initWithFrame:(NSRect)frameRect { 31 - (id)initWithFrame:(NSRect)frameRect {
22 if ((self = [super initWithFrame:frameRect])) { 32 if ((self = [super initWithFrame:frameRect])) {
23 [self commonInit]; 33 [self commonInit];
24 } 34 }
25 return self; 35 return self;
26 } 36 }
27 37
28 - (void)awakeFromNib { 38 - (void)awakeFromNib {
29 [self commonInit]; 39 [self commonInit];
30 } 40 }
31 41
42 - (void)drawRect:(NSRect)rect {
43 if (!circlePath_.get() || !xPath_.get())
44 [self setUpDrawingPaths];
45
46 // If the user is hovering over the button, a light/dark gray circle is drawn
47 // behind the 'x'.
48 if (hoverState_ != kHoverStateNone) {
49 // Adjust the darkness of the circle depending on whether it is being
50 // clicked.
51 CGFloat white = (hoverState_ == kHoverStateMouseOver) ?
52 kCircleHoverWhite : kCircleClickWhite;
53 [[NSColor colorWithCalibratedWhite:white alpha:1.0] set];
54 [circlePath_ fill];
55 }
56
57 [[NSColor whiteColor] set];
58 [xPath_ fill];
59
60 // Give the 'x' an inner shadow for depth. If the button is in a hover state
61 // (circle behind it), then adjust the shadow accordingly (not as harsh).
62 NSShadow* shadow = [[NSShadow alloc] init];
63 CGFloat alpha = (hoverState_ != kHoverStateNone) ?
64 kXShadowCircleAlpha : kXShadowAlpha;
65 [shadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0
66 alpha:alpha]];
67 [shadow setShadowOffset:NSMakeSize(0.0, -1.0)];
68 [shadow setShadowBlurRadius:2.0];
69 [xPath_ fillWithInnerShadow:shadow];
70 }
71
32 - (void)commonInit { 72 - (void)commonInit {
33 [self setTrackingEnabled:YES]; 73 [self setTrackingEnabled:YES];
34 NSImage* alternateImage = nsimage_cache::ImageNamed(kPressedImageString); 74 hoverState_ = kHoverStateNone;
35 [self setAlternateImage:alternateImage];
36 [self updateTrackingAreas]; 75 [self updateTrackingAreas];
37 76
38 // Set accessibility description. 77 // Set accessibility description.
39 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_CLOSE); 78 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_CLOSE);
40 [[self cell] 79 [[self cell]
41 accessibilitySetOverrideValue:description 80 accessibilitySetOverrideValue:description
42 forAttribute:NSAccessibilityDescriptionAttribute]; 81 forAttribute:NSAccessibilityDescriptionAttribute];
43 } 82 }
44 83
84 - (void)setUpDrawingPaths {
85 NSPoint viewCenter = MidRect([self bounds]);
86
87 circlePath_.reset([[NSBezierPath bezierPath] retain]);
88 [circlePath_ moveToPoint:viewCenter];
89 CGFloat radius = kCircleRadiusPercentage * NSWidth([self bounds]);
90 [circlePath_ appendBezierPathWithArcWithCenter:viewCenter
91 radius:radius
92 startAngle:0.0
93 endAngle:365.0];
94
95 // Construct an 'x' by drawing two intersecting rectangles in the shape of a
96 // cross and then rotating the path by 45 degrees.
97 xPath_.reset([[NSBezierPath bezierPath] retain]);
98 [xPath_ appendBezierPathWithRect:NSMakeRect(3.5, 7.0, 9.0, 2.0)];
99 [xPath_ appendBezierPathWithRect:NSMakeRect(7.0, 3.5, 2.0, 9.0)];
100
101 NSPoint pathCenter = MidRect([xPath_ bounds]);
102
103 NSAffineTransform* transform = [NSAffineTransform transform];
104 [transform translateXBy:viewCenter.x yBy:viewCenter.y];
105 [transform rotateByDegrees:45.0];
106 [transform translateXBy:-pathCenter.x yBy:-pathCenter.y];
107
108 [xPath_ transformUsingAffineTransform:transform];
109 }
110
45 - (void)dealloc { 111 - (void)dealloc {
46 [self setTrackingEnabled:NO]; 112 [self setTrackingEnabled:NO];
47 [super dealloc]; 113 [super dealloc];
48 } 114 }
49 115
50 - (void)mouseEntered:(NSEvent*)theEvent { 116 - (void)mouseEntered:(NSEvent*)theEvent {
51 [self setImage:nsimage_cache::ImageNamed(kHoverImageString)]; 117 hoverState_ = kHoverStateMouseOver;
118 [self setNeedsDisplay:YES];
52 } 119 }
53 120
54 - (void)mouseExited:(NSEvent*)theEvent { 121 - (void)mouseExited:(NSEvent*)theEvent {
55 [self setImage:nsimage_cache::ImageNamed(kNormalImageString)]; 122 hoverState_ = kHoverStateNone;
123 [self setNeedsDisplay:YES];
56 } 124 }
57 125
58 - (void)mouseDown:(NSEvent*)theEvent { 126 - (void)mouseDown:(NSEvent*)theEvent {
127 hoverState_ = kHoverStateMouseDown;
128 [self setNeedsDisplay:YES];
59 // The hover button needs to hold onto itself here for a bit. Otherwise, 129 // The hover button needs to hold onto itself here for a bit. Otherwise,
60 // it can be freed while |super mouseDown:| is in it's loop, and the 130 // it can be freed while |super mouseDown:| is in it's loop, and the
61 // |checkImageState| call will crash. 131 // |checkImageState| call will crash.
62 // http://crbug.com/28220 132 // http://crbug.com/28220
63 scoped_nsobject<HoverCloseButton> myself([self retain]); 133 scoped_nsobject<HoverCloseButton> myself([self retain]);
64 134
65 [super mouseDown:theEvent]; 135 [super mouseDown:theEvent];
66 // We need to check the image state after the mouseDown event loop finishes. 136 // We need to check the image state after the mouseDown event loop finishes.
67 // It's possible that we won't get a mouseExited event if the button was 137 // It's possible that we won't get a mouseExited event if the button was
68 // moved under the mouse during tab resize, instead of the mouse moving over 138 // moved under the mouse during tab resize, instead of the mouse moving over
(...skipping 24 matching lines...) Expand all
93 } 163 }
94 } 164 }
95 } 165 }
96 166
97 - (void)updateTrackingAreas { 167 - (void)updateTrackingAreas {
98 [super updateTrackingAreas]; 168 [super updateTrackingAreas];
99 [self checkImageState]; 169 [self checkImageState];
100 } 170 }
101 171
102 - (void)checkImageState { 172 - (void)checkImageState {
103 if (closeTrackingArea_.get()) { 173 if (!closeTrackingArea_.get())
104 // Update the close buttons if the tab has moved. 174 return;
105 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream]; 175
106 mouseLoc = [self convertPoint:mouseLoc fromView:nil]; 176 // Update the close buttons if the tab has moved.
107 NSString* name = NSPointInRect(mouseLoc, [self bounds]) ? 177 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
108 kHoverImageString : kNormalImageString; 178 mouseLoc = [self convertPoint:mouseLoc fromView:nil];
109 NSImage* newImage = nsimage_cache::ImageNamed(name); 179 hoverState_ = NSPointInRect(mouseLoc, [self bounds]) ?
110 NSImage* buttonImage = [self image]; 180 kHoverStateMouseOver : kHoverStateNone;
111 if (![buttonImage isEqual:newImage]) { 181 [self setNeedsDisplay:YES];
112 [self setImage:newImage];
113 }
114 }
115 } 182 }
116 183
117 @end 184 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698