summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/bookmark_bar_folder_view.mm
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 23:26:27 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 23:26:27 +0000
commitd27fd0e73b0620cc3af740d2dd2138c20ca4372a (patch)
treee97bc4d580ed7893b035168f2380b3b2f28908bb /chrome/browser/cocoa/bookmark_bar_folder_view.mm
parent38eb08a5fd1ea4f529b9d4651a2f2eb31b0d2192 (diff)
downloadchromium_src-d27fd0e73b0620cc3af740d2dd2138c20ca4372a.zip
chromium_src-d27fd0e73b0620cc3af740d2dd2138c20ca4372a.tar.gz
chromium_src-d27fd0e73b0620cc3af740d2dd2138c20ca4372a.tar.bz2
Custom "menus" for the bookmark bar folders.
Full behavior: http://JRG_WRITE_FULL_DOC_AND_TEST_PLAN_TOMORROW BUG=17608 (and a slew of others) Brief details on how to test: - add some bookmarks and bookmark folders. - at a basic level, make sure bookmark folders feel like menus e.g. -- click to open -- can open "submenus" and sub-sub-menus -- can open (click on) bookmarks in any of these submenus - click-drag does NOT open a menu (different than Mac menus); it initiates a Drag - click on folder in bookmark bar initiates "hover open"; moving mouse over other folders will pop them open immediately (much like Mac menus) - Bookmark bar non-drag hover-open is immediate, but bookmark folder hover-open has a brief delay so quick "move down" a folder does not trigger them all to open while you travel (much like Mac menus). - DnD of bookmarks and folders on bookmark bar. - While doing DnD of bookmark, "hover" over a folder and see it open. - Bookmark folder menus have normal DnD "drop indicators" like the bookmark bar. - Can "hover open" a nested subfolder. - Can drag a bookmark from one deep sub-sub-folder to a different deep one. - Confirm buttons and folders in submenus are themed, both with the theme set at launch time and the theme we change to after launch. - Empty folders have an "(empty)" item which is not selectable. - Intentional delay in closing a sub-sub-folder when hovering over another one. E.g. When moving to a sub-sub-menu, 'brief' travel over a different submenu does not close the destination sub-menu. - can use bookmark context menus in folder "menus". - confirm DnD from "Other bookmarks" to any other random folder and vice versa. - While non-drag hover open is active, clicking anywhere other than the bookmark bar or folder (e.g. the main web view) turns it off. TODO: - random bugs (e.g. "add folder" over a folder doesn't put it in there) - (empty) needs to be revisited, both visually and for a drop indication - core animations instead of drop indicators - ... Review URL: http://codereview.chromium.org/551226 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39947 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/bookmark_bar_folder_view.mm')
-rw-r--r--chrome/browser/cocoa/bookmark_bar_folder_view.mm185
1 files changed, 185 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_folder_view.mm b/chrome/browser/cocoa/bookmark_bar_folder_view.mm
new file mode 100644
index 0000000..e8e91dd
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_bar_folder_view.mm
@@ -0,0 +1,185 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/bookmark_bar_folder_view.h"
+
+#import "chrome/browser/browser_theme_provider.h"
+#import "chrome/browser/cocoa/bookmark_bar_controller.h"
+
+@implementation BookmarkBarFolderView
+
+- (id<BookmarkButtonControllerProtocol>)controller {
+ return [[self window] windowController];
+}
+
+- (void)awakeFromNib {
+ [super awakeFromNib];
+
+ // BackgroundGradientView's awakeFromNib does a |showsDivider_ = YES|.
+ // Make sure we turn it off.
+ [self setShowsDivider:NO];
+
+ NSArray* types = [NSArray arrayWithObject:kBookmarkButtonDragType];
+ [self registerForDraggedTypes:types];
+}
+
+- (void)dealloc {
+ [self unregisterDraggedTypes];
+ [super dealloc];
+}
+
+- (void)drawRect:(NSRect)rect {
+ [self drawBackground];
+
+ // TODO(jrg): copied from bookmark_bar_view but orientation changed.
+ // Code dup sucks but I'm not sure I can take 16 lines and make it
+ // generic for horiz vs vertical while keeping things simple.
+ // TODO(jrg): when throwing it all away and using animations, try
+ // hard to make a common routine for both.
+ // http://crbug.com/35966, http://crbug.com/35968
+
+ // Draw the bookmark-button-dragging drop indicator if necessary.
+ if (dropIndicatorShown_) {
+ const CGFloat kBarHeight = 1;
+ const CGFloat kBarHorizPad = 4;
+ const CGFloat kBarOpacity = 0.85;
+
+ NSRect uglyBlackBar =
+ NSMakeRect(kBarHorizPad, dropIndicatorPosition_,
+ NSWidth([self bounds]) - 2*kBarHorizPad,
+ kBarHeight);
+ // themeProvider is nil in unit tests.
+ ThemeProvider* themeProvider = [[self controller] themeProvider];
+ if (themeProvider) {
+ NSColor* uglyBlackBarColor = themeProvider->
+ GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, true);
+ [[uglyBlackBarColor colorWithAlphaComponent:kBarOpacity] setFill];
+ [[NSBezierPath bezierPathWithRect:uglyBlackBar] fill];
+ }
+ }
+}
+
+// Virtually identical to [BookmarkBarView draggingEntered:].
+// TODO(jrg): find a way to share code. Lack of multiple inheritance
+// makes things more of a pain but there should be no excuse for laziness.
+// http://crbug.com/35966
+- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
+ inDrag_ = YES;
+
+ NSData* data = [[info draggingPasteboard]
+ dataForType:kBookmarkButtonDragType];
+ // [info draggingSource] is nil if not the same application.
+ if (data && [info draggingSource]) {
+ // Find the position of the drop indicator.
+ BookmarkButton* button = nil;
+ [data getBytes:&button length:sizeof(button)];
+
+ BOOL showIt = [[self controller]
+ shouldShowIndicatorShownForPoint:[info draggingLocation]];
+ if (!showIt) {
+ if (dropIndicatorShown_) {
+ dropIndicatorShown_ = NO;
+ [self setNeedsDisplay:YES];
+ }
+ } else {
+ CGFloat y =
+ [[self controller]
+ indicatorPosForDragOfButton:button
+ toPoint:[info draggingLocation]];
+
+ // Need an update if the indicator wasn't previously shown or if it has
+ // moved.
+ if (!dropIndicatorShown_ || dropIndicatorPosition_ != y) {
+ dropIndicatorShown_ = YES;
+ dropIndicatorPosition_ = y;
+ [self setNeedsDisplay:YES];
+ }
+ }
+
+ [[self controller] draggingEntered:info]; // allow hover-open to work
+ return NSDragOperationMove;
+ }
+
+ return NSDragOperationNone;
+}
+
+- (void)draggingExited:(id<NSDraggingInfo>)info {
+ [[self controller] draggingExited:info];
+
+ // Regardless of the type of dragging which ended, we need to get rid of the
+ // drop indicator if one was shown.
+ if (dropIndicatorShown_) {
+ dropIndicatorShown_ = NO;
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (void)draggingEnded:(id<NSDraggingInfo>)info {
+ // Awkwardness since views open and close out from under us.
+ if (inDrag_) {
+ inDrag_ = NO;
+
+ // This line makes sure menus get closed when a drag isn't
+ // completed.
+ [[self controller] closeAllBookmarkFolders];
+ }
+
+ [self draggingExited:info];
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates {
+ // TODO(jrg): This should probably return |YES| and the controller should
+ // slide the existing bookmark buttons interactively to the side to make
+ // room for the about-to-be-dropped bookmark.
+ // http://crbug.com/35968
+ return NO;
+}
+
+- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
+ // For now it's the same as draggingEntered:.
+ // TODO(jrg): once we return YES for wantsPeriodicDraggingUpdates,
+ // this should ping the [self controller] to perform animations.
+ // http://crbug.com/35968
+ return [self draggingEntered:info];
+}
+
+- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
+ return YES;
+}
+
+// Implement NSDraggingDestination protocol method
+// performDragOperation: for bookmarks.
+- (BOOL)performDragOperationForBookmark:(id<NSDraggingInfo>)info {
+ BOOL doDrag = NO;
+ NSData* data = [[info draggingPasteboard]
+ dataForType:kBookmarkButtonDragType];
+ // [info draggingSource] is nil if not the same application.
+ if (data && [info draggingSource]) {
+ BookmarkButton* button = nil;
+ [data getBytes:&button length:sizeof(button)];
+ doDrag = [[self controller] dragButton:button to:[info draggingLocation]];
+ }
+ return doDrag;
+}
+
+- (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
+ NSPasteboard* pboard = [info draggingPasteboard];
+ if ([pboard dataForType:kBookmarkButtonDragType]) {
+ if ([self performDragOperationForBookmark:info])
+ return YES;
+ // Fall through....
+ }
+ return NO;
+}
+
+@end // BookmarkBarFolderView
+
+
+@implementation BookmarkBarFolderView(TestingAPI)
+
+- (void)setDropIndicatorShown:(BOOL)shown {
+ dropIndicatorShown_ = shown;
+}
+
+@end