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..67e79870dcd81ce914e925639abc345030f6ec16 |
--- /dev/null |
+++ b/chrome/browser/ui/cocoa/draggable_button_mixin.h |
@@ -0,0 +1,128 @@ |
+// 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. |
+ |
Mark Mentovai
2011/08/11 00:51:17
#include guards and #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 |
Mark Mentovai
2011/08/11 00:51:17
I thought you were a one-space-after-period kind o
Robert Sesek
2011/08/11 16:06:00
I am. I just didn't feel like fixing all the old c
|
+// called by DraggableButtonImpl when the beginDrag call returns. |
+- (DraggableButtonResult)endDrag; |
+ |
+// Decides whether we should treat the click as a cue to start dragging, or |
Mark Mentovai
2011/08/11 00:51:17
We, and on line 70.
|
+// 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 |
Mark Mentovai
2011/08/11 00:51:17
Seems like you could have lined up the colons here
Robert Sesek
2011/08/11 16:06:00
Eh. Methods that fly off to the right like that ar
|
+ xHysteresis:(float)xHysteresis |
+ yHysteresis:(float)yHysteresis |
+ indicates:(BOOL*)result; |
+ |
+// Decides if we now have 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 |
Mark Mentovai
2011/08/11 00:51:17
Not too bad so far.
|
+ |
+// Impl Interface ////////////////////////////////////////////////////////////// |
+ |
+// Class for buttons that can be drag sources. If the mouse is clicked and moved |
+// more than a given distance, this class will call |-beginDrag:| instead of |
+// |-performClick:|. Subclasses should override these two methods. |
+@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 NSTimeInterval durationMouseWasDown; |
Mark Mentovai
2011/08/11 00:51:17
atomic? 107 too.
|
+ |
+@property 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; |
Mark Mentovai
2011/08/11 00:51:17
Hmm. I guess this is technically unportable, but i
Robert Sesek
2011/08/11 16:06:00
Why wouldn't this be "portable"? This inherits fro
Mark Mentovai
2011/08/11 16:11:45
rsesek wrote:
|
+- (DraggableButtonResult)mouseUp:(NSEvent*)event; |
+ |
+@end |