[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / nsview_additions.mm
blob6d8ed4b10b3f4dd83d11fff6d1290032b6b56432
1 // Copyright (c) 2012 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 "base/command_line.h"
6 #include "base/mac/mac_util.h"
7 #import "chrome/browser/ui/cocoa/nsview_additions.h"
8 #include "chrome/common/chrome_switches.h"
9 #include "ui/base/ui_base_switches.h"
10 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
12 #include "base/logging.h"
14 #if !defined(MAC_OS_X_VERSION_10_7) || \
15     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
17 @interface NSView (LionAPI)
18 - (NSSize)convertSizeFromBacking:(NSSize)size;
19 @end
21 #endif  // 10.7
23 // Replicate specific 10.9 SDK declarations for building with prior SDKs.
24 #if !defined(MAC_OS_X_VERSION_10_9) || \
25     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
27 @interface NSView (MavericksAPI)
28 // Flatten all child views that did not call setWantsLayer:YES into this
29 // view's CALayer.
30 - (void)setCanDrawSubviewsIntoLayer:(BOOL)flag;
31 @end
33 #endif  // MAC_OS_X_VERSION_10_9
35 @implementation NSView (ChromeAdditions)
37 - (CGFloat)cr_lineWidth {
38   // All shipping retina macs run at least 10.7.
39   if (![self respondsToSelector:@selector(convertSizeFromBacking:)])
40     return 1;
41   return [self convertSizeFromBacking:NSMakeSize(1, 1)].width;
44 - (BOOL)cr_isMouseInView {
45   NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
46   mouseLoc = [[self superview] convertPoint:mouseLoc fromView:nil];
47   return [self hitTest:mouseLoc] == self;
50 - (BOOL)cr_isBelowView:(NSView*)otherView {
51   NSArray* subviews = [[self superview] subviews];
53   NSUInteger selfIndex = [subviews indexOfObject:self];
54   DCHECK_NE(NSNotFound, selfIndex);
56   NSUInteger otherIndex = [subviews indexOfObject:otherView];
57   DCHECK_NE(NSNotFound, otherIndex);
59   return selfIndex < otherIndex;
62 - (BOOL)cr_isAboveView:(NSView*)otherView {
63   return ![self cr_isBelowView:otherView];
66 - (void)cr_ensureSubview:(NSView*)subview
67             isPositioned:(NSWindowOrderingMode)place
68               relativeTo:(NSView *)otherView {
69   DCHECK(place == NSWindowAbove || place == NSWindowBelow);
70   BOOL isAbove = place == NSWindowAbove;
71   if ([[subview superview] isEqual:self] &&
72       [subview cr_isAboveView:otherView] == isAbove) {
73     return;
74   }
76   [subview removeFromSuperview];
77   [self addSubview:subview
78         positioned:place
79         relativeTo:otherView];
82 - (NSColor*)cr_keyboardFocusIndicatorColor {
83   return [[NSColor keyboardFocusIndicatorColor]
84       colorWithAlphaComponent:0.5 / [self cr_lineWidth]];
87 - (void)cr_recursivelySetNeedsDisplay:(BOOL)flag {
88   [self setNeedsDisplay:YES];
89   for (NSView* child in [self subviews])
90     [child cr_recursivelySetNeedsDisplay:flag];
93 - (void)cr_setWantsLayer:(BOOL)wantsLayer {
94   if (CommandLine::ForCurrentProcess()->HasSwitch(
95           switches::kDisableCoreAnimation))
96     return;
98   // Dynamically removing layers on SnowLeopard will sometimes result in
99   // crashes. Once a view has a layer on SnowLeopard, it is stuck with it.
100   // http://crbug.com/348328
101   if (!wantsLayer && base::mac::IsOSSnowLeopard())
102     return;
104   [self setWantsLayer:wantsLayer];
107 static NSView* g_ancestorBeingDrawnFrom = nil;
108 static NSView* g_childBeingDrawnTo = nil;
110 - (void)cr_drawUsingAncestor:(NSView*)ancestorView inRect:(NSRect)rect {
111   gfx::ScopedNSGraphicsContextSaveGState scopedGSState;
112   NSRect frame = [self convertRect:[self bounds] toView:ancestorView];
113   NSAffineTransform* transform = [NSAffineTransform transform];
114   if ([self isFlipped] == [ancestorView isFlipped]) {
115     [transform translateXBy:-NSMinX(frame) yBy:-NSMinY(frame)];
116   } else {
117     [transform translateXBy:-NSMinX(frame) yBy:NSMaxY(frame)];
118     [transform scaleXBy:1.0 yBy:-1.0];
119   }
120   [transform concat];
122   // This can be made robust to recursive calls, but is as of yet unneeded.
123   DCHECK(!g_ancestorBeingDrawnFrom && !g_childBeingDrawnTo);
124   g_ancestorBeingDrawnFrom = ancestorView;
125   g_childBeingDrawnTo = self;
126   [ancestorView drawRect:[ancestorView bounds]];
127   g_childBeingDrawnTo = nil;
128   g_ancestorBeingDrawnFrom = nil;
131 - (NSView*)cr_viewBeingDrawnTo {
132   if (!g_ancestorBeingDrawnFrom)
133     return self;
134   DCHECK(g_ancestorBeingDrawnFrom == self);
135   return g_childBeingDrawnTo;
138 @end