15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/mac/mac_util.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/mac/sdk_forward_declarations.h" 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#import "ui/base/cocoa/nsview_additions.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation NSView (ChromeAdditions) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (CGFloat)cr_lineWidth { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All shipping retina macs run at least 10.7. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (![self respondsToSelector:@selector(convertSizeFromBacking:)]) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self convertSizeFromBacking:NSMakeSize(1, 1)].width; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL)cr_isMouseInView { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream]; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouseLoc = [[self superview] convertPoint:mouseLoc fromView:nil]; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self hitTest:mouseLoc] == self; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (BOOL)cr_isBelowView:(NSView*)otherView { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NSArray* subviews = [[self superview] subviews]; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NSUInteger selfIndex = [subviews indexOfObject:self]; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(NSNotFound, selfIndex); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NSUInteger otherIndex = [subviews indexOfObject:otherView]; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(NSNotFound, otherIndex); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return selfIndex < otherIndex; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (BOOL)cr_isAboveView:(NSView*)otherView { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ![self cr_isBelowView:otherView]; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (void)cr_ensureSubview:(NSView*)subview 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isPositioned:(NSWindowOrderingMode)place 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) relativeTo:(NSView *)otherView { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(place == NSWindowAbove || place == NSWindowBelow); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BOOL isAbove = place == NSWindowAbove; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ([[subview superview] isEqual:self] && 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [subview cr_isAboveView:otherView] == isAbove) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [subview removeFromSuperview]; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [self addSubview:subview 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) positioned:place 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) relativeTo:otherView]; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- (NSColor*)cr_keyboardFocusIndicatorColor { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [[NSColor keyboardFocusIndicatorColor] 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) colorWithAlphaComponent:0.5 / [self cr_lineWidth]]; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch- (void)cr_recursivelySetNeedsDisplay:(BOOL)flag { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch [self setNeedsDisplay:YES]; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (NSView* child in [self subviews]) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch [child cr_recursivelySetNeedsDisplay:flag]; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static NSView* g_ancestorBeingDrawnFrom = nil; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static NSView* g_childBeingDrawnTo = nil; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)- (void)cr_drawUsingAncestor:(NSView*)ancestorView inRect:(NSRect)rect { 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::ScopedNSGraphicsContextSaveGState scopedGSState; 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NSRect frame = [self convertRect:[self bounds] toView:ancestorView]; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NSAffineTransform* transform = [NSAffineTransform transform]; 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ([self isFlipped] == [ancestorView isFlipped]) { 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) [transform translateXBy:-NSMinX(frame) yBy:-NSMinY(frame)]; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) [transform translateXBy:-NSMinX(frame) yBy:NSMaxY(frame)]; 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) [transform scaleXBy:1.0 yBy:-1.0]; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) [transform concat]; 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This can be made robust to recursive calls, but is as of yet unneeded. 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!g_ancestorBeingDrawnFrom && !g_childBeingDrawnTo); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_ancestorBeingDrawnFrom = ancestorView; 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_childBeingDrawnTo = self; 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) [ancestorView drawRect:[ancestorView bounds]]; 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_childBeingDrawnTo = nil; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_ancestorBeingDrawnFrom = nil; 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)- (NSView*)cr_viewBeingDrawnTo { 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!g_ancestorBeingDrawnFrom) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return self; 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(g_ancestorBeingDrawnFrom == self); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return g_childBeingDrawnTo; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 102