| Index: chrome/browser/cocoa/bookmark_bar_folder_controller.mm
|
| ===================================================================
|
| --- chrome/browser/cocoa/bookmark_bar_folder_controller.mm (revision 46002)
|
| +++ chrome/browser/cocoa/bookmark_bar_folder_controller.mm (working copy)
|
| @@ -4,6 +4,7 @@
|
|
|
| #import "chrome/browser/cocoa/bookmark_bar_folder_controller.h"
|
| #include "base/mac_util.h"
|
| +#include "base/nsimage_cache_mac.h"
|
| #include "base/sys_string_conversions.h"
|
| #include "chrome/browser/bookmarks/bookmark_model.h"
|
| #include "chrome/browser/bookmarks/bookmark_utils.h"
|
| @@ -40,7 +41,6 @@
|
| // by at least this much.
|
| const CGFloat kScrollViewContentWidthMargin = 2;
|
|
|
| -
|
| // When constraining a scrolling bookmark bar folder window to the
|
| // screen, shrink the "constrain" by this much vertically. Currently
|
| // this is 0.0 to avoid a problem with tracking areas leaving the
|
| @@ -62,6 +62,9 @@
|
| // Return the new width (so that the window can be adjusted, if necessary).
|
| - (CGFloat)adjustButtonWidths;
|
|
|
| +// Show or hide the scroll arrows at the top/bottom of the window.
|
| +- (void)showOrHideScrollArrows;
|
| +
|
| @end
|
|
|
| @implementation BookmarkBarFolderController
|
| @@ -78,6 +81,9 @@
|
| barController_ = barController; // WEAK
|
| buttons_.reset([[NSMutableArray alloc] init]);
|
| folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);
|
| + NSImage* image = nsimage_cache::ImageNamed(@"menu_overflow_up.pdf");
|
| + DCHECK(image);
|
| + verticalScrollArrowHeight_ = [image size].height;
|
| [self configureWindow];
|
| hoverState_.reset([[BookmarkBarFolderHoverState alloc] init]);
|
| if (scrollable_)
|
| @@ -334,6 +340,11 @@
|
| NSHeight(windowFrame)))];
|
| }
|
|
|
| + // If scrollable, show the arrows.
|
| + if (scrollable_) {
|
| + [self showOrHideScrollArrows];
|
| + }
|
| +
|
| // Finally pop me up.
|
| [self configureWindowLevel];
|
| }
|
| @@ -364,6 +375,81 @@
|
| return width;
|
| }
|
|
|
| +- (BOOL)canScrollUp {
|
| + // If removal of an arrow would make things "finished", state as
|
| + // such.
|
| + CGFloat scrollY = [scrollView_ documentVisibleRect].origin.y;
|
| + if (scrollUpArrowShown_)
|
| + scrollY -= verticalScrollArrowHeight_;
|
| +
|
| + if (scrollY <= 0)
|
| + return NO;
|
| + return YES;
|
| +}
|
| +
|
| +- (BOOL)canScrollDown {
|
| + CGFloat arrowAdjustment = 0.0;
|
| +
|
| + // We do NOT adjust based on the scrollDOWN arrow. This keeps
|
| + // things from "jumping"; if removal of the down arrow (at the top
|
| + // of the window) would cause a scroll to end, we'll end.
|
| + if (scrollUpArrowShown_)
|
| + arrowAdjustment += verticalScrollArrowHeight_;
|
| +
|
| + NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
|
| + NSRect documentRect = [[scrollView_ documentView] frame];
|
| +
|
| + // If we are exactly the right height, return no. We need this
|
| + // extra conditional in the case where we've just scrolled/grown
|
| + // into position.
|
| + if (NSHeight([[self window] frame]) == NSHeight(documentRect))
|
| + return NO;
|
| +
|
| + if ((scrollPosition.y + NSHeight([[self window] frame])) >=
|
| + (NSHeight(documentRect) + arrowAdjustment)) {
|
| + return NO;
|
| + }
|
| + return YES;
|
| +}
|
| +
|
| +- (void)showOrHideScrollArrows {
|
| + NSRect frame = [scrollView_ frame];
|
| + CGFloat scrollDelta = 0.0;
|
| + BOOL canScrollDown = [self canScrollDown];
|
| + BOOL canScrollUp = [self canScrollUp];
|
| +
|
| + if (canScrollUp != scrollUpArrowShown_) {
|
| + if (scrollUpArrowShown_) {
|
| + frame.origin.y -= verticalScrollArrowHeight_;
|
| + frame.size.height += verticalScrollArrowHeight_;
|
| + scrollDelta = verticalScrollArrowHeight_;
|
| + } else {
|
| + frame.origin.y += verticalScrollArrowHeight_;
|
| + frame.size.height -= verticalScrollArrowHeight_;
|
| + scrollDelta = -verticalScrollArrowHeight_;
|
| + }
|
| + }
|
| + if (canScrollDown != scrollDownArrowShown_) {
|
| + if (scrollDownArrowShown_) {
|
| + frame.size.height += verticalScrollArrowHeight_;
|
| + } else {
|
| + frame.size.height -= verticalScrollArrowHeight_;
|
| + }
|
| + }
|
| + scrollUpArrowShown_ = canScrollUp;
|
| + scrollDownArrowShown_ = canScrollDown;
|
| + [scrollView_ setFrame:frame];
|
| +
|
| + // Adjust scroll based on new frame. For example, if we make room
|
| + // for an arrow at the bottom, adjust the scroll so the topmost item
|
| + // is still fully visible.
|
| + if (scrollDelta) {
|
| + NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
|
| + scrollPosition.y -= scrollDelta;
|
| + [[scrollView_ documentView] scrollPoint:scrollPosition];
|
| + }
|
| +}
|
| +
|
| #pragma mark BookmarkButtonControllerProtocol
|
|
|
| - (void)addButtonForNode:(const BookmarkNode*)node
|
| @@ -559,6 +645,10 @@
|
| windowFrame.size.height += growAmount;
|
| windowFrame.size.height = std::min(NSHeight(windowFrame),
|
| screenHeightMinusMargin);
|
| + // Watch out for a finish that isn't the full height of the screen.
|
| + // We get here if using the scroll wheel to scroll by small amounts.
|
| + windowFrame.size.height = std::min(NSHeight(windowFrame),
|
| + NSHeight([mainView_ frame]));
|
| // Don't allow scrolling to make the window smaller, ever. This
|
| // conditional is important when processing scrollWheel events.
|
| if (windowFrame.size.height > [[self window] frame].size.height) {
|
| @@ -575,12 +665,16 @@
|
| (windowFrame.size.height == screenHeightMinusMargin))) {
|
| [self endScroll];
|
|
|
| - // If the entire view is now visible the window is no longer scrollable.
|
| - if (NSHeight([mainView_ visibleRect]) == NSHeight([mainView_ bounds])) {
|
| + // If we can't scroll either up or down we are completely done.
|
| + // For example, perhaps we've scrolled a little and grown the
|
| + // window on-screen until there is now room for everything.
|
| + if (![self canScrollUp] && ![self canScrollDown]) {
|
| scrollable_ = NO;
|
| [self removeScrollTracking];
|
| }
|
| }
|
| +
|
| + [self showOrHideScrollArrows];
|
| }
|
|
|
| // Perform a scroll of the window on the screen.
|
|
|