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