OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/ui/cocoa/fast_resize_view.h" | 5 #import "chrome/browser/ui/cocoa/fast_resize_view.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/scoped_nsobject.h" | 10 #include "base/mac/scoped_nsobject.h" |
11 #include "ui/base/cocoa/animation_utils.h" | 11 #include "ui/base/cocoa/animation_utils.h" |
12 | 12 |
13 namespace { | |
14 | |
15 // The radius of the rounded corners. | |
16 const CGFloat kRoundedCornerRadius = 4; | |
17 | |
18 } // namespace | |
19 | |
20 @interface FastResizeView (PrivateMethods) | |
21 // Creates a path whose bottom two corners are rounded. | |
22 // Caller takes ownership of the path. | |
23 - (CGPathRef)createRoundedBottomCornersPath:(NSSize)size; | |
24 | |
25 // Updates the path of the layer mask to reflect the current value of | |
26 // roundedBottomCorners_. | |
27 - (void)updateLayerMask; | |
28 @end | |
29 | |
30 @implementation FastResizeView | 13 @implementation FastResizeView |
31 | 14 |
32 - (id)initWithFrame:(NSRect)frameRect { | 15 - (id)initWithFrame:(NSRect)frameRect { |
33 if ((self = [super initWithFrame:frameRect])) { | 16 if ((self = [super initWithFrame:frameRect])) { |
34 ScopedCAActionDisabler disabler; | 17 ScopedCAActionDisabler disabler; |
35 base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]); | 18 base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]); |
36 [layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; | 19 [layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; |
37 [self setLayer:layer]; | 20 [self setLayer:layer]; |
38 [self setWantsLayer:YES]; | 21 [self setWantsLayer:YES]; |
39 | |
40 roundedBottomCorners_ = YES; | |
41 [self updateLayerMask]; | |
42 } | 22 } |
43 return self; | 23 return self; |
44 } | 24 } |
45 | 25 |
46 - (BOOL)isOpaque { | 26 - (BOOL)isOpaque { |
47 return YES; | 27 return YES; |
48 } | 28 } |
49 | 29 |
50 - (void)setRoundedBottomCorners:(BOOL)roundedBottomCorners { | |
51 if (roundedBottomCorners == roundedBottomCorners_) | |
52 return; | |
53 | |
54 roundedBottomCorners_ = roundedBottomCorners; | |
55 [self updateLayerMask]; | |
56 } | |
57 | |
58 // Every time the frame's size changes, the layer mask needs to be updated. | |
59 - (void)setFrameSize:(NSSize)newSize { | |
60 [super setFrameSize:newSize]; | |
61 [self updateLayerMask]; | |
62 } | |
63 | |
64 @end | 30 @end |
65 | 31 |
66 @implementation FastResizeView (PrivateMethods) | |
67 | |
68 - (CGPathRef)createRoundedBottomCornersPath:(NSSize)size { | |
69 CGMutablePathRef path = CGPathCreateMutable(); | |
70 CGFloat width = size.width; | |
71 CGFloat height = size.height; | |
72 CGFloat cornerRadius = kRoundedCornerRadius; | |
73 | |
74 // Top left corner. | |
75 CGPathMoveToPoint(path, NULL, 0, height); | |
76 | |
77 // Top right corner. | |
78 CGPathAddLineToPoint(path, NULL, width, height); | |
79 | |
80 // Bottom right corner. | |
81 CGPathAddArc(path, | |
82 NULL, | |
83 width - cornerRadius, | |
84 cornerRadius, | |
85 cornerRadius, | |
86 0, | |
87 -M_PI_2, | |
88 true); | |
89 | |
90 // Bottom left corner. | |
91 CGPathAddArc(path, | |
92 NULL, | |
93 cornerRadius, | |
94 cornerRadius, | |
95 cornerRadius, | |
96 -M_PI_2, | |
97 -M_PI, | |
98 true); | |
99 | |
100 // Draw line back to top-left corner. | |
101 CGPathAddLineToPoint(path, NULL, 0, height); | |
102 CGPathCloseSubpath(path); | |
103 return path; | |
104 } | |
105 | |
106 - (void)updateLayerMask { | |
107 if (!roundedBottomCorners_) { | |
108 [self layer].mask = nil; | |
109 layerMask_ = nil; | |
110 return; | |
111 } | |
112 | |
113 if (![self layer].mask) { | |
114 layerMask_ = [CAShapeLayer layer]; | |
115 [self layer].mask = layerMask_; | |
116 } | |
117 | |
118 CGPathRef path = [self createRoundedBottomCornersPath:self.bounds.size]; | |
119 layerMask_.path = path; | |
120 CGPathRelease(path); | |
121 } | |
122 | |
123 @end | |
OLD | NEW |