1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import <Cocoa/Cocoa.h> 6#include <vector> 7#import "chrome/browser/ui/cocoa/draggable_button.h" 8#include "webkit/glue/window_open_disposition.h" 9 10@class BookmarkBarFolderController; 11@class BookmarkButton; 12struct BookmarkNodeData; 13class BookmarkModel; 14class BookmarkNode; 15@class BrowserWindowController; 16 17namespace ui { 18class ThemeProvider; 19} 20 21// Protocol for a BookmarkButton's delegate, responsible for doing 22// things on behalf of a bookmark button. 23@protocol BookmarkButtonDelegate 24 25// Fill the given pasteboard with appropriate data when the given button is 26// dragged. Since the delegate has no way of providing pasteboard data later, 27// all data must actually be put into the pasteboard and not merely promised. 28- (void)fillPasteboard:(NSPasteboard*)pboard 29 forDragOfButton:(BookmarkButton*)button; 30 31// Bookmark buttons pass mouseEntered: and mouseExited: events to 32// their delegate. This allows the delegate to decide (for example) 33// which one, if any, should perform a hover-open. 34- (void)mouseEnteredButton:(id)button event:(NSEvent*)event; 35- (void)mouseExitedButton:(id)button event:(NSEvent*)event; 36 37// Returns YES if a drag operation should lock the fullscreen overlay bar 38// visibility before starting. For example, dragging a bookmark button should 39// not lock the overlay if the bookmark bar is currently showing in detached 40// mode on the NTP. 41- (BOOL)dragShouldLockBarVisibility; 42 43// Returns the top-level window for this button. 44- (NSWindow*)browserWindow; 45 46// Returns YES if the bookmark button can be dragged to the trash, NO otherwise. 47- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button; 48 49// This is called after the user has dropped the bookmark button on the trash. 50// The delegate can use this event to delete the bookmark. 51- (void)didDragBookmarkToTrash:(BookmarkButton*)button; 52 53// This is called after the drag has finished, for any reason. 54// We particularly need this so we can hide bookmark folder menus and stop 55// doing that hover thing. 56- (void)bookmarkDragDidEnd:(BookmarkButton*)button 57 operation:(NSDragOperation)operation; 58 59@end 60 61 62// Protocol to be implemented by controllers that logically own 63// bookmark buttons. The controller may be either an NSViewController 64// or NSWindowController. The BookmarkButton doesn't use this 65// protocol directly; it is used when BookmarkButton controllers talk 66// to each other. 67// 68// Other than the top level owner (the bookmark bar), all bookmark 69// button controllers have a parent controller. 70@protocol BookmarkButtonControllerProtocol 71 72// Close all bookmark folders, walking up the ownership chain. 73- (void)closeAllBookmarkFolders; 74 75// Close just my bookmark folder. 76- (void)closeBookmarkFolder:(id)sender; 77 78// Return the bookmark model for this controller. 79- (BookmarkModel*)bookmarkModel; 80 81// Perform drag enter/exit operations, such as hover-open and hover-close. 82- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info; 83- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info; 84- (void)draggingExited:(id<NSDraggingInfo>)info; 85 86// Returns YES if a drag operation should lock the fullscreen overlay bar 87// visibility before starting. For example, dragging a bookmark button should 88// not lock the overlay if the bookmark bar is currently showing in detached 89// mode on the NTP. 90- (BOOL)dragShouldLockBarVisibility; 91 92// Perform the actual DnD of a bookmark or bookmark button. 93 94// |point| is in the base coordinate system of the destination window; 95// |it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be 96// made and inserted into the new location while leaving the bookmark in 97// the old location, otherwise move the bookmark by removing from its old 98// location and inserting into the new location. 99- (BOOL)dragButton:(BookmarkButton*)sourceButton 100 to:(NSPoint)point 101 copy:(BOOL)copy; 102 103// Determine if the pasteboard from |info| has dragging data containing 104// bookmark(s) and perform the drag and return YES, otherwise return NO. 105- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info; 106 107// Determine if the drag pasteboard has any drag data of type 108// kBookmarkDictionaryListPboardType and, if so, return those elements 109// otherwise return an empty vector. 110- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData; 111 112// Return YES if we should show the drop indicator, else NO. In some 113// cases (e.g. hover open) we don't want to show the drop indicator. 114// |point| is in the base coordinate system of the destination window; 115// |it comes from an id<NSDraggingInfo>. 116- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point; 117 118// The x or y coordinate of (the middle of) the indicator to draw for 119// a drag of the source button to the given point (given in window 120// coordinates). 121// |point| is in the base coordinate system of the destination window; 122// |it comes from an id<NSDraggingInfo>. 123// TODO(viettrungluu,jrg): instead of this, make buttons move around. 124// http://crbug.com/35968 125- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point; 126 127// Used to tell the controller that room should be made for a drop. 128- (void)setDropInsertionPos:(CGFloat)where; 129 130// Used to tell the controller to stop making room for a drop. 131- (void)clearDropInsertionPos; 132 133// Return the theme provider associated with this browser window. 134- (ui::ThemeProvider*)themeProvider; 135 136// Called just before a child folder puts itself on screen. 137- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child; 138 139// Called just before a child folder closes. 140- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child; 141 142// Return a controller's folder controller for a subfolder, or nil. 143- (BookmarkBarFolderController*)folderController; 144 145// Add a new folder controller as triggered by the given folder button. 146// If there is a current folder controller, close it. 147- (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton; 148 149// Open all of the nodes for the given node with disposition. 150- (void)openAll:(const BookmarkNode*)node 151 disposition:(WindowOpenDisposition)disposition; 152 153// There are several operations which may affect the contents of a bookmark 154// button controller after it has been created, primary of which are 155// cut/paste/delete and drag/drop. Such changes may involve coordinating 156// the bookmark button contents of two controllers (such as when a bookmark is 157// dragged from one folder to another). The bookmark bar controller 158// coordinates in response to notifications propagated by the bookmark model 159// through BookmarkBarBridge calls. The following three functions are 160// implemented by the controllers and are dispatched by the bookmark bar 161// controller in response to notifications coming in from the BookmarkBarBridge. 162 163// Add a button for the given node to the bar or folder menu. This is safe 164// to call when a folder menu window is open as that window will be updated. 165// And index of -1 means to append to the end (bottom). 166- (void)addButtonForNode:(const BookmarkNode*)node 167 atIndex:(NSInteger)buttonIndex; 168 169// Given a list or |urls| and |titles|, create new bookmark nodes and add 170// them to the bookmark model such that they will be 1) added to the folder 171// represented by the button at |point| if it is a folder, or 2) inserted 172// into the parent of the non-folder bookmark at |point| in front of that 173// button. Returns YES if at least one bookmark was added. 174// TODO(mrossetti): Change function to use a pair-like structure for 175// URLs and titles. http://crbug.com/44411 176- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point; 177 178// Move a button from one place in the menu to another. This is safe 179// to call when a folder menu window is open as that window will be updated. 180- (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex; 181 182// Remove the bookmark button at the given index. Show the poof animation 183// if |animate:| is YES. It may be obvious, but this is safe 184// to call when a folder menu window is open as that window will be updated. 185- (void)removeButton:(NSInteger)buttonIndex animate:(BOOL)poof; 186 187// Determine the controller containing the button representing |node|, if any. 188- (id<BookmarkButtonControllerProtocol>)controllerForNode: 189 (const BookmarkNode*)node; 190 191@end // @protocol BookmarkButtonControllerProtocol 192 193 194// Class for bookmark bar buttons that can be drag sources. 195@interface BookmarkButton : DraggableButton { 196 @private 197 IBOutlet NSObject<BookmarkButtonDelegate>* delegate_; // Weak. 198 199 // Saved pointer to the BWC for the browser window that contains this button. 200 // Used to lock and release bar visibility during a drag. The pointer is 201 // saved because the bookmark button is no longer a part of a window at the 202 // end of a drag operation (or, in fact, can be dragged to a completely 203 // different window), so there is no way to retrieve the same BWC object after 204 // a drag. 205 BrowserWindowController* visibilityDelegate_; // weak 206 207 NSPoint dragMouseOffset_; 208 NSPoint dragEndScreenLocation_; 209 BOOL dragPending_; 210 BOOL acceptsTrackIn_; 211 NSTrackingArea* area_; 212} 213 214@property(assign, nonatomic) NSObject<BookmarkButtonDelegate>* delegate; 215@property(assign, nonatomic) BOOL acceptsTrackIn; 216 217// Return the bookmark node associated with this button, or NULL. 218- (const BookmarkNode*)bookmarkNode; 219 220// Return YES if this is a folder button (the node has subnodes). 221- (BOOL)isFolder; 222 223- (void)mouseDragged:(NSEvent*)theEvent; 224 225- (BOOL)acceptsTrackInFrom:(id)sender; 226 227// At this time we represent an empty folder (e.g. the string 228// '(empty)') as a disabled button with no associated node. 229// 230// TODO(jrg): improve; things work but are slightly ugly since "empty" 231// and "one disabled button" are not the same thing. 232// http://crbug.com/35967 233- (BOOL)isEmpty; 234 235// Turn on or off pulsing of a bookmark button. 236// Triggered by the bookmark bubble. 237- (void)setIsContinuousPulsing:(BOOL)flag; 238 239// Return continuous pulse state. 240- (BOOL)isContinuousPulsing; 241 242// Return the location in screen coordinates where the remove animation should 243// be displayed. 244- (NSPoint)screenLocationForRemoveAnimation; 245 246// The BookmarkButton which is currently being dragged, if any. 247+ (BookmarkButton*)draggedButton; 248 249 250@end // @interface BookmarkButton 251 252 253@interface BookmarkButton(TestingAPI) 254- (void)beginDrag:(NSEvent*)event; 255@end 256 257namespace bookmark_button { 258 259// Notifications for pulsing of bookmarks. 260extern NSString* const kPulseBookmarkButtonNotification; 261 262// Key for userInfo dict of a kPulseBookmarkButtonNotification. 263// Value is a [NSValue valueWithPointer:]; pointer is a (const BookmarkNode*). 264extern NSString* const kBookmarkKey; 265 266// Key for userInfo dict of a kPulseBookmarkButtonNotification. 267// Value is a [NSNumber numberWithBool:] to turn pulsing on or off. 268extern NSString* const kBookmarkPulseFlagKey; 269 270}; 271