diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 18:34:55 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 18:34:55 +0000 |
commit | 630559915695886f8239fc0748aad03c9596bb9e (patch) | |
tree | 60737a2f1983ec8bd5b678a473721efa142f8d72 /chrome/browser/cocoa/clickhold_button_cell.mm | |
parent | e91a617485ddf9fa6fd151a777f012a1ab5f43eb (diff) | |
download | chromium_src-630559915695886f8239fc0748aad03c9596bb9e.zip chromium_src-630559915695886f8239fc0748aad03c9596bb9e.tar.gz chromium_src-630559915695886f8239fc0748aad03c9596bb9e.tar.bz2 |
Implement back/forward toolbar menus on Mac (bug 13203).
Note: The drop-down menu is actually a drag-down (activating on
click-hold or on drag), working much like Safari's (and other Apple
apps, such as Dictionary). This can be changed to a pop-down if that's
what's desired.
TODO: Show keyboard shortcut for "Show Full History".
Patch by viettrungluu.
BUG=http://crbug.com/13203
TEST=Navigate around, check out and use the menus; do so in multiple tabs and
windows.
Review URL: http://codereview.chromium.org/160496
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22740 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/clickhold_button_cell.mm')
-rw-r--r-- | chrome/browser/cocoa/clickhold_button_cell.mm | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/clickhold_button_cell.mm b/chrome/browser/cocoa/clickhold_button_cell.mm new file mode 100644 index 0000000..c65971c --- /dev/null +++ b/chrome/browser/cocoa/clickhold_button_cell.mm @@ -0,0 +1,136 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/clickhold_button_cell.h" + +#include "base/logging.h" + +// Minimum and maximum click-hold timeout. +static const NSTimeInterval kMinTimeout = 0.01; +static const NSTimeInterval kMaxTimeout = 3600.0; + +@implementation ClickHoldButtonCell + +// Overrides: + ++ (BOOL)prefersTrackingUntilMouseUp { + return NO; +} + +- (BOOL)startTrackingAt:(NSPoint)startPoint + inView:(NSView*)controlView { + return enableClickHold_ ? + YES : + [super startTrackingAt:startPoint + inView:controlView]; +} + +- (BOOL)continueTracking:(NSPoint)lastPoint + at:(NSPoint)currentPoint + inView:(NSView*)controlView { + return enableClickHold_ ? + YES : + [super continueTracking:lastPoint + at:currentPoint + inView:controlView]; +} + +- (BOOL)trackMouse:(NSEvent*)originalEvent + inRect:(NSRect)cellFrame + ofView:(NSView*)controlView + untilMouseUp:(BOOL)untilMouseUp { + if (!enableClickHold_) { + return [super trackMouse:originalEvent + inRect:cellFrame + ofView:controlView + untilMouseUp:untilMouseUp]; + } + + // If doing click-hold, track the mouse ourselves. + NSPoint currPoint = [controlView convertPoint:[originalEvent locationInWindow] + fromView:nil]; + NSPoint lastPoint = currPoint; + NSTimeInterval timeout = + MAX(MIN(clickHoldTimeout_, kMaxTimeout), kMinTimeout); + NSDate* clickHoldBailTime = [NSDate dateWithTimeIntervalSinceNow:timeout]; + + if (![self startTrackingAt:currPoint inView:controlView]) + return NO; + + enum { + kContinueTrack, kStopClickHold, kStopMouseUp, kStopLeftRect, kStopNoContinue + } state = kContinueTrack; + do { + NSEvent* event = [NSApp nextEventMatchingMask:(NSLeftMouseDraggedMask | + NSLeftMouseUpMask) + untilDate:clickHoldBailTime + inMode:NSEventTrackingRunLoopMode + dequeue:YES]; + currPoint = [controlView convertPoint:[event locationInWindow] + fromView:nil]; + + // Time-out or drag. + if (!event || (activateOnDrag_ && ([event type] == NSLeftMouseDragged))) { + state = kStopClickHold; + + // Mouse up. + } else if ([event type] == NSLeftMouseUp) { + state = kStopMouseUp; + + // Stop tracking if mouse left frame rectangle (if requested to do so). + } else if (trackOnlyInRect_ && ![controlView mouse:currPoint + inRect:cellFrame]) { + state = kStopLeftRect; + + // Stop tracking if instructed to. + } else if (![self continueTracking:lastPoint + at:currPoint + inView:controlView]) { + state = kStopNoContinue; + } + + lastPoint = currPoint; + } while (state == kContinueTrack); + + [self stopTracking:lastPoint + at:lastPoint + inView:controlView + mouseIsUp:NO]; + + switch (state) { + case kStopClickHold: + if (clickHoldAction_) { + [static_cast<NSControl*>(controlView) sendAction:clickHoldAction_ + to:clickHoldTarget_]; + } + return YES; + + case kStopMouseUp: + if ([self action]) { + [static_cast<NSControl*>(controlView) sendAction:[self action] + to:[self target]]; + } + return YES; + + case kStopLeftRect: + case kStopNoContinue: + return NO; + + default: + NOTREACHED() << "Unknown terminating state!"; + } + + return NO; +} + +// Accessors and mutators: + +@synthesize enableClickHold = enableClickHold_; +@synthesize clickHoldTimeout = clickHoldTimeout_; +@synthesize trackOnlyInRect = trackOnlyInRect_; +@synthesize activateOnDrag = activateOnDrag_; +@synthesize clickHoldTarget = clickHoldTarget_; +@synthesize clickHoldAction = clickHoldAction_; + +@end // @implementation ClickHoldButtonCell |