summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/clickhold_button_cell.mm
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-07 18:34:55 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-07 18:34:55 +0000
commit630559915695886f8239fc0748aad03c9596bb9e (patch)
tree60737a2f1983ec8bd5b678a473721efa142f8d72 /chrome/browser/cocoa/clickhold_button_cell.mm
parente91a617485ddf9fa6fd151a777f012a1ab5f43eb (diff)
downloadchromium_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.mm136
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