1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#import <Cocoa/Cocoa.h> 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Class for buttons that can be drag sources. If the mouse is clicked and moved 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// more than a given distance, this class will call |-beginDrag:| instead of 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |-performClick:|. Subclasses should override these two methods. 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch@interface DraggableButton : NSButton { 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch @private 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BOOL draggable_; // Is this a draggable type of button? 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BOOL actionHasFired_; // Has the action already fired for this click? 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BOOL actsOnMouseDown_; // Does button action happen on mouse down when 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // possible? 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NSTimeInterval durationMouseWasDown_; 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NSTimeInterval whenMouseDown_; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen@property NSTimeInterval durationMouseWasDown; 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen@property NSTimeInterval whenMouseDown; 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Whether the action has already fired for this click. 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen@property(nonatomic) BOOL actionHasFired; 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Enable or disable dragability for special buttons like "Other Bookmarks". 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen@property(nonatomic) BOOL draggable; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// If it has a popup menu, for example, we want to perform the action on mouse 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// down, if possible (as long as user still gets chance to drag, if 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// appropriate). 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen@property(nonatomic) BOOL actsOnMouseDown; 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Called when a drag should start. Subclasses must override this to do any 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pasteboard manipulation and begin the drag, usually with 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -dragImage:at:offset:event:. Subclasses must call one of the blocking 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -drag* methods of NSView when overriding this method. 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch- (void)beginDrag:(NSEvent*)dragEvent; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Override if you want to do any extra work on mouseUp, after a mouseDown 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// action has already fired. 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen- (void)secondaryMouseUpAction:(BOOL)wasInside; 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This is called internally. 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Decides if we now have enough information to stop tracking the mouse. 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// It's the function below, deltaIndicatesDragStartWithXDelta. however, that 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// decides whether it's a drag or not. 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Override if you want to do something tricky when making the decision. 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Default impl returns YES if ABS(xDelta) or ABS(yDelta) >= their respective 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// hysteresis limit. 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen- (BOOL)deltaIndicatesConclusionReachedWithXDelta:(float)xDelta 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen yDelta:(float)yDelta 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen xHysteresis:(float)xHysteresis 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen yHysteresis:(float)yHysteresis; 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This is called internally. 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Decides whether we should treat the click as a cue to start dragging, or 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// instead call the mouseDown/mouseUp handler as appropriate. 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Override if you want to do something tricky when making the decision. 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Default impl returns YES if ABS(xDelta) or ABS(yDelta) >= their respective 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// hysteresis limit. 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen- (BOOL)deltaIndicatesDragStartWithXDelta:(float)xDelta 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen yDelta:(float)yDelta 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen xHysteresis:(float)xHysteresis 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen yHysteresis:(float)yHysteresis; 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch@end // @interface DraggableButton 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch@interface DraggableButton (Private) 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Resets the draggable state of the button after dragging is finished. This is 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// called by DraggableButton when the beginDrag call returns, it should not be 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// called by the subclass. 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch- (void)endDrag; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Called internally if the actsOnMouseDown property is set. 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Fires the button's action and tracks the click. 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen- (void)performMouseDownAction:(NSEvent*)theEvent; 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch@end // @interface DraggableButton(Private) 85