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

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

Issue 260009: Several background pattern fixes on the Mac.... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 2 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
Property Changes:
Name: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "chrome/browser/cocoa/browser_frame_view.h"
6
7 #import <objc/runtime.h>
8 #import <Carbon/Carbon.h>
9
10 #include "base/logging.h"
11 #include "base/scoped_nsobject.h"
12 #import "chrome/browser/cocoa/chrome_browser_window.h"
13 #import "third_party/GTM/AppKit/GTMTheme.h"
14
15 // To line up our background pattern with the patterns in the tabs we need
16 // to move our background patterns in the window frame up by two pixels.
17 // This will make the themes look slightly different than in Windows/Linux
18 // because of the differing heights between window top and tab top, but this
19 // has been approved by UI.
20 static const NSInteger kBrowserFrameViewPatternPhaseOffset = 2;
21
22 @interface NSView (Swizzles)
23 - (void)drawRectOriginal:(NSRect)rect;
24 - (BOOL)_mouseInGroup:(NSButton*)widget;
25 - (void)updateTrackingAreas;
26 @end
27
28 @implementation BrowserFrameView
29
30 + (void)load {
31 // This is where we swizzle drawRect, and add in two methods that we
32 // need. If any of these fail it shouldn't affect the functionality of the
33 // others. If they all fail, we will lose window frame theming and
34 // roll overs for our close widgets, but things should still function
35 // correctly.
36 scoped_nsobject<NSAutoreleasePool> pool([[NSAutoreleasePool alloc] init]);
37 Class grayFrameClass = NSClassFromString(@"NSGrayFrame");
38 DCHECK(grayFrameClass);
39 if (!grayFrameClass) return;
40
41 // Exchange draw rect
42 Method m0 = class_getInstanceMethod([self class], @selector(drawRect:));
43 DCHECK(m0);
44 if (m0) {
45 BOOL didAdd = class_addMethod(grayFrameClass,
46 @selector(drawRectOriginal:),
47 method_getImplementation(m0),
48 method_getTypeEncoding(m0));
49 DCHECK(didAdd);
50 if (didAdd) {
51 Method m1 = class_getInstanceMethod(grayFrameClass, @selector(drawRect:));
52 Method m2 = class_getInstanceMethod(grayFrameClass,
53 @selector(drawRectOriginal:));
54 DCHECK(m1 && m2);
55 if (m1 && m2) {
56 method_exchangeImplementations(m1, m2);
57 }
58 }
59 }
60
61 // Add _mouseInGroup
62 m0 = class_getInstanceMethod([self class], @selector(_mouseInGroup:));
63 DCHECK(m0);
64 if (m0) {
65 BOOL didAdd = class_addMethod(grayFrameClass,
66 @selector(_mouseInGroup:),
67 method_getImplementation(m0),
68 method_getTypeEncoding(m0));
69 DCHECK(didAdd);
70 }
71 // Add updateTrackingArea
72 m0 = class_getInstanceMethod([self class], @selector(updateTrackingAreas));
73 DCHECK(m0);
74 if (m0) {
75 BOOL didAdd = class_addMethod(grayFrameClass,
76 @selector(updateTrackingAreas),
77 method_getImplementation(m0),
78 method_getTypeEncoding(m0));
79 DCHECK(didAdd);
80 }
81 }
82
83 - (id)initWithFrame:(NSRect)frame {
84 // This class is not for instantiating.
85 [self doesNotRecognizeSelector:_cmd];
86 return nil;
87 }
88
89 - (id)initWithCoder:(NSCoder*)coder {
90 // This class is not for instantiating.
91 [self doesNotRecognizeSelector:_cmd];
92 return nil;
93 }
94
95 // Here is our custom drawing for our frame.
96 - (void)drawRect:(NSRect)rect {
97 // If this isn't the window class we expect, then pass it on to the
98 // original implementation.
99 if (![[self window] isKindOfClass:[ChromeBrowserWindow class]]) {
100 [self drawRectOriginal:rect];
101 return;
102 }
103
104 // Clear out everything
105 [[NSColor clearColor] set];
106 NSRectFillUsingOperation(rect, NSCompositeSourceOver);
107
108 // Set up our clip
109 NSWindow* window = [self window];
110 NSRect windowRect = [window frame];
111 windowRect.origin = NSMakePoint(0, 0);
112 [[NSBezierPath bezierPathWithRoundedRect:windowRect
113 xRadius:4
114 yRadius:4] addClip];
115 [[NSBezierPath bezierPathWithRect:rect] addClip];
116
117 // Draw our background color if we have one, otherwise fall back on
118 // system drawing.
119 GTMTheme* theme = [self gtm_theme];
120 GTMThemeState state = [window isMainWindow] ? GTMThemeStateActiveWindow
121 : GTMThemeStateInactiveWindow;
122 NSColor* color = [theme backgroundPatternColorForStyle:GTMThemeStyleWindow
123 state:state];
124 if (color) {
125 // If we have a theme pattern, draw it here.
126 NSPoint phase = NSMakePoint(0, (NSHeight(windowRect) +
127 kBrowserFrameViewPatternPhaseOffset));
128 [[NSGraphicsContext currentContext] setPatternPhase:phase];
129 [color set];
130 NSRectFill(rect);
131 } else {
132 [self drawRectOriginal:rect];
133 }
134
135 // Check to see if we have an overlay image.
136 NSImage* overlayImage = [theme valueForAttribute:@"overlay"
137 style:GTMThemeStyleWindow
138 state:state];
139 if (overlayImage) {
140 NSSize overlaySize = [overlayImage size];
141 NSRect windowFrame = NSMakeRect(0,
142 NSHeight(windowRect) - overlaySize.height,
143 NSWidth(windowRect),
144 overlaySize.height);
145 NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height);
146 [overlayImage drawInRect:windowFrame
147 fromRect:imageFrame
148 operation:NSCompositeSourceOver
149 fraction:1.0];
150 }
151 }
152
153 // Check to see if the mouse is currently in one of our window widgets.
154 - (BOOL)_mouseInGroup:(NSButton*)widget {
155 BOOL mouseInGroup = NO;
156 if ([[self window] isKindOfClass:[ChromeBrowserWindow class]]) {
157 ChromeBrowserWindow* window =
158 static_cast<ChromeBrowserWindow*>([self window]);
159 mouseInGroup = [window mouseInGroup:widget];
160 } else {
161 mouseInGroup = [super _mouseInGroup:widget];
162 }
163 return mouseInGroup;
164 }
165
166 // Let our window handle updating the window widget tracking area.
167 - (void)updateTrackingAreas {
168 [super updateTrackingAreas];
169 if ([[self window] isKindOfClass:[ChromeBrowserWindow class]]) {
170 ChromeBrowserWindow* window =
171 static_cast<ChromeBrowserWindow*>([self window]);
172 [window updateTrackingAreas];
173 }
174 }
175
176 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/browser_frame_view.h ('k') | chrome/browser/cocoa/browser_frame_view_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698