diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 23:26:27 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 23:26:27 +0000 |
commit | d27fd0e73b0620cc3af740d2dd2138c20ca4372a (patch) | |
tree | e97bc4d580ed7893b035168f2380b3b2f28908bb /chrome/browser/cocoa/bookmark_bar_folder_view.mm | |
parent | 38eb08a5fd1ea4f529b9d4651a2f2eb31b0d2192 (diff) | |
download | chromium_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.mm | 185 |
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 |