scroll_view_with_no_scrollbars.mm revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright 2013 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#include "ui/app_list/cocoa/scroll_view_with_no_scrollbars.h" 6 7#include "base/mac/mac_util.h" 8#include "base/mac/scoped_cftyperef.h" 9#include "base/mac/scoped_nsobject.h" 10 11#if !defined(MAC_OS_X_VERSION_10_7) || \ 12 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 13 14enum { 15 NSEventPhaseNone = 0, 16 NSEventPhaseBegan = 0x1 << 0, 17 NSEventPhaseStationary = 0x1 << 1, 18 NSEventPhaseChanged = 0x1 << 2, 19 NSEventPhaseEnded = 0x1 << 3, 20 NSEventPhaseCancelled = 0x1 << 4, 21}; 22typedef NSUInteger NSEventPhase; 23 24@interface NSEvent (LionAPI) 25 26- (NSEventPhase)momentumPhase; 27- (NSEventPhase)phase; 28 29@end 30 31#endif // 10.7 32 33@interface InvisibleScroller : NSScroller; 34@end 35 36@implementation InvisibleScroller 37 38// Makes it non-interactive (and invisible) on Lion with both 10.6 and 10.7 39// SDKs. TODO(tapted): Find a way to make it non-interactive on Snow Leopard. 40// TODO(tapted): Find a way to make it take up no space on Lion with a 10.6 SDK. 41- (NSRect)rectForPart:(NSScrollerPart)aPart { 42 return NSZeroRect; 43} 44 45@end 46 47@implementation ScrollViewWithNoScrollbars 48 49@synthesize delegate = delegate_; 50 51- (id)initWithFrame:(NSRect)frame { 52 if ((self = [super initWithFrame:frame])) { 53 [self setHasHorizontalScroller:base::mac::IsOSLionOrLater()]; 54 NSRect horizontalScrollerRect = [self bounds]; 55 horizontalScrollerRect.size.height = 0; 56 base::scoped_nsobject<InvisibleScroller> horizontalScroller( 57 [[InvisibleScroller alloc] initWithFrame:horizontalScrollerRect]); 58 [self setHorizontalScroller:horizontalScroller]; 59 } 60 return self; 61} 62 63- (void)endGestureWithEvent:(NSEvent*)event { 64 [super endGestureWithEvent:event]; 65 if (!base::mac::IsOSLionOrLater()) 66 [delegate_ userScrolling:NO]; 67} 68 69- (void)scrollWheel:(NSEvent*)event { 70 if ([event subtype] == NSMouseEventSubtype) { 71 // Since the scroll view has no vertical scroller, regular up and down mouse 72 // wheel events would be ignored. This maps mouse wheel events to a 73 // horizontal scroll event of one line, to turn pages. 74 BOOL downOrRight; 75 if ([event deltaX] != 0) 76 downOrRight = [event deltaX] > 0; 77 else if ([event deltaY] != 0) 78 downOrRight = [event deltaY] > 0; 79 else 80 return; 81 82 base::ScopedCFTypeRef<CGEventRef> cgEvent(CGEventCreateScrollWheelEvent( 83 NULL, kCGScrollEventUnitLine, 2, 0, downOrRight ? 1 : -1)); 84 [super scrollWheel:[NSEvent eventWithCGEvent:cgEvent]]; 85 return; 86 } 87 88 [super scrollWheel:event]; 89 if (![event respondsToSelector:@selector(momentumPhase)]) 90 return; 91 92 BOOL scrollComplete = [event momentumPhase] == NSEventPhaseEnded || 93 ([event momentumPhase] == NSEventPhaseNone && 94 [event phase] == NSEventPhaseEnded); 95 96 [delegate_ userScrolling:!scrollComplete]; 97} 98 99@end 100