| Index: chrome/browser/ui/cocoa/draggable_button_mixin.h
|
| diff --git a/chrome/browser/ui/cocoa/draggable_button_mixin.h b/chrome/browser/ui/cocoa/draggable_button_mixin.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c769bcd55c2869a5289d12465f5b9831a92a65a8
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/cocoa/draggable_button_mixin.h
|
| @@ -0,0 +1,134 @@
|
| +// Copyright (c) 2011 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.
|
| +
|
| +#ifndef CHROME_BROWSER_UI_COCOA_DRAGGABLE_BUTTON_MIXIN_H_
|
| +#define CHROME_BROWSER_UI_COCOA_DRAGGABLE_BUTTON_MIXIN_H_
|
| +#pragma once
|
| +
|
| +#import <Cocoa/Cocoa.h>
|
| +
|
| +// The design of this class is extraordinarily poor. Apologies to all clients in
|
| +// advance. Unfortunately, the lack of multiple inheritance and our desire to
|
| +// avoid runtime hacks makes this convoluted dance necessary.
|
| +//
|
| +// Buttons that want to be draggable should implement the Mixin protocol below
|
| +// and keep an instance of the Impl as an ivar. The button should forward mouse
|
| +// events to the impl, which will tell the button whether or not to call super
|
| +// and let the event be handled normally.
|
| +//
|
| +// If the impl decides to do work on the event, methods of the mixin protocol
|
| +// may be called. Some of the methods declared in that protocol have base
|
| +// implementations. If the method is not implemented by the button, that base
|
| +// implementation will be called. Otherwise, the button's implementation will
|
| +// be called first and the DraggableButtonResult will be used to determine
|
| +// whether the base implementation should be called. This requires the client to
|
| +// understand what the base does.
|
| +
|
| +enum DraggableButtonResult {
|
| + // Return values for Impl methods.
|
| + kDraggableButtonImplDidWork,
|
| + kDraggableButtonMixinCallSuper,
|
| +
|
| + // Return values for Mixin methods.
|
| + kDraggableButtonMixinDidWork,
|
| + kDraggableButtonImplUseBase,
|
| +};
|
| +
|
| +// Mixin Protocol //////////////////////////////////////////////////////////////
|
| +
|
| +// Buttons that make use of the below impl need to conform to this protocol.
|
| +@protocol DraggableButtonMixin
|
| +
|
| +@required
|
| +
|
| +// Called when a drag should start. Implement this to do any pasteboard
|
| +// manipulation and begin the drag, usually with
|
| +// -dragImage:at:offset:event:. Subclasses must call one of the blocking
|
| +// -drag* methods of NSView when implementing this method.
|
| +- (void)beginDrag:(NSEvent*)dragEvent;
|
| +
|
| +@optional
|
| +
|
| +// Called if the actsOnMouseDown property is set. Fires the button's action and
|
| +// tracks the click.
|
| +- (DraggableButtonResult)performMouseDownAction:(NSEvent*)theEvent;
|
| +
|
| +// Implement if you want to do any extra work on mouseUp, after a mouseDown
|
| +// action has already fired.
|
| +- (DraggableButtonResult)secondaryMouseUpAction:(BOOL)wasInside;
|
| +
|
| +// Resets the draggable state of the button after dragging is finished. This is
|
| +// called by DraggableButtonImpl when the beginDrag call returns.
|
| +- (DraggableButtonResult)endDrag;
|
| +
|
| +// Decides whether to treat the click as a cue to start dragging, or to instead
|
| +// call the mouseDown/mouseUp handler as appropriate. Implement if you want to
|
| +// do something tricky when making the decision.
|
| +- (DraggableButtonResult)deltaIndicatesDragStartWithXDelta:(float)xDelta
|
| + yDelta:(float)yDelta
|
| + xHysteresis:(float)xHysteresis
|
| + yHysteresis:(float)yHysteresis
|
| + indicates:(BOOL*)result;
|
| +
|
| +// Decides if there is enough information to stop tracking the mouse.
|
| +// It's deltaIndicatesDragStartWithXDelta, however, that decides whether it's a
|
| +// drag or not. Implement if you want to do something tricky when making the
|
| +// decision.
|
| +- (DraggableButtonResult)deltaIndicatesConclusionReachedWithXDelta:(float)xDelta
|
| + yDelta:(float)yDelta
|
| + xHysteresis:(float)xHysteresis
|
| + yHysteresis:(float)yHysteresis
|
| + indicates:(BOOL*)result;
|
| +
|
| +@end
|
| +
|
| +// Impl Interface //////////////////////////////////////////////////////////////
|
| +
|
| +// Implementation of the drag and drop logic. NSButton Mixin subclasses should
|
| +// forward their mouse events to this, which in turn will call out to the mixin
|
| +// protocol.
|
| +@interface DraggableButtonImpl : NSObject {
|
| + @private
|
| + // The button for which this class is implementing stuff.
|
| + NSButton<DraggableButtonMixin>* button_;
|
| +
|
| + // Is this a draggable type of button?
|
| + BOOL draggable_;
|
| +
|
| + // Has the action already fired for this click?
|
| + BOOL actionHasFired_;
|
| +
|
| + // Does button action happen on mouse down when possible?
|
| + BOOL actsOnMouseDown_;
|
| +
|
| + NSTimeInterval durationMouseWasDown_;
|
| + NSTimeInterval whenMouseDown_;
|
| +}
|
| +
|
| +@property(nonatomic) NSTimeInterval durationMouseWasDown;
|
| +
|
| +@property(nonatomic) NSTimeInterval whenMouseDown;
|
| +
|
| +// Whether the action has already fired for this click.
|
| +@property(nonatomic) BOOL actionHasFired;
|
| +
|
| +// Enable or disable dragability for special buttons like "Other Bookmarks".
|
| +@property(nonatomic) BOOL draggable;
|
| +
|
| +// If it has a popup menu, for example, we want to perform the action on mouse
|
| +// down, if possible (as long as user still gets chance to drag, if
|
| +// appropriate).
|
| +@property(nonatomic) BOOL actsOnMouseDown;
|
| +
|
| +// Designated initializer.
|
| +- (id)initWithButton:(NSButton<DraggableButtonMixin>*)button;
|
| +
|
| +// NSResponder implementation. NSButton subclasses should invoke these methods
|
| +// and only call super if the return value indicates such.
|
| +- (DraggableButtonResult)mouseDown:(NSEvent*)event;
|
| +- (DraggableButtonResult)mouseUp:(NSEvent*)event;
|
| +
|
| +@end
|
| +
|
| +#endif // CHROME_BROWSER_UI_COCOA_DRAGGABLE_BUTTON_MIXIN_H_
|
|
|