| Index: chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
|
| ===================================================================
|
| --- chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm (revision 70424)
|
| +++ chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm (working copy)
|
| @@ -4,7 +4,6 @@
|
|
|
| #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h"
|
|
|
| -#include "app/mac/nsimage_cache.h"
|
| #include "base/mac/mac_util.h"
|
| #include "base/sys_string_conversions.h"
|
| #include "chrome/browser/bookmarks/bookmark_model.h"
|
| @@ -15,10 +14,13 @@
|
| #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
|
| #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.h"
|
| #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.h"
|
| +#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h"
|
| #import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h"
|
| #import "chrome/browser/ui/cocoa/browser_window_controller.h"
|
| #import "chrome/browser/ui/cocoa/event_utils.h"
|
|
|
| +using bookmarks::kBookmarkBarMenuCornerRadius;
|
| +
|
| namespace {
|
|
|
| // Frequency of the scrolling timer in seconds.
|
| @@ -29,17 +31,76 @@
|
| const CGFloat kBookmarkBarFolderScrollAmount =
|
| 3 * bookmarks::kBookmarkButtonVerticalSpan;
|
|
|
| -// Amount to scroll for each scroll wheel delta.
|
| +// Amount to scroll for each scroll wheel roll.
|
| const CGFloat kBookmarkBarFolderScrollWheelAmount =
|
| 1 * bookmarks::kBookmarkButtonVerticalSpan;
|
|
|
| -// 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
|
| -// window, but should probably be 8.0 or something.
|
| -// TODO(jrg): http://crbug.com/36225
|
| -const CGFloat kScrollWindowVerticalMargin = 0.0;
|
| +// Determining adjustments to the layout of the folder menu window in response
|
| +// to resizing and scrolling relies on many visual factors. The following
|
| +// struct is used to pass around these factors to the several support
|
| +// functions involved in the adjustment calculations and application.
|
| +struct LayoutMetrics {
|
| + // Metrics applied during the final layout adjustments to the window,
|
| + // the main visible content view, and the menu content view (i.e. the
|
| + // scroll view).
|
| + CGFloat windowLeft;
|
| + NSSize windowSize;
|
| + // The proposed and then final scrolling adjustment made to the scrollable
|
| + // area of the folder menu. This may be modified during the window layout
|
| + // primarily as a result of hiding or showing the scroll arrows.
|
| + CGFloat scrollDelta;
|
| + NSRect windowFrame;
|
| + NSRect visibleFrame;
|
| + NSRect scrollerFrame;
|
| + NSPoint scrollPoint;
|
| + // The difference between 'could' and 'can' in these next four data members
|
| + // is this: 'could' represents the previous condition for scrollability
|
| + // while 'can' represents what the new condition will be for scrollability.
|
| + BOOL couldScrollUp;
|
| + BOOL canScrollUp;
|
| + BOOL couldScrollDown;
|
| + BOOL canScrollDown;
|
| + // Determines the optimal time during folder menu layout when the contents
|
| + // of the button scroll area should be scrolled in order to prevent
|
| + // flickering.
|
| + BOOL preScroll;
|
|
|
| + // Intermediate metrics used in determining window vertical layout changes.
|
| + CGFloat deltaWindowHeight;
|
| + CGFloat deltaWindowY;
|
| + CGFloat deltaVisibleHeight;
|
| + CGFloat deltaVisibleY;
|
| + CGFloat deltaScrollerHeight;
|
| + CGFloat deltaScrollerY;
|
| +
|
| + // Convenience metrics used in multiple functions (carried along here in
|
| + // order to eliminate the need to calculate in multiple places and
|
| + // reduce the possibility of bugs).
|
| + CGFloat minimumY;
|
| + CGFloat oldWindowY;
|
| + CGFloat folderY;
|
| + CGFloat folderTop;
|
| +
|
| + LayoutMetrics(CGFloat windowLeft, NSSize windowSize, CGFloat scrollDelta) :
|
| + windowLeft(windowLeft),
|
| + windowSize(windowSize),
|
| + scrollDelta(scrollDelta),
|
| + couldScrollUp(NO),
|
| + canScrollUp(NO),
|
| + couldScrollDown(NO),
|
| + canScrollDown(NO),
|
| + preScroll(NO),
|
| + deltaWindowHeight(0.0),
|
| + deltaWindowY(0.0),
|
| + deltaVisibleHeight(0.0),
|
| + deltaVisibleY(0.0),
|
| + deltaScrollerHeight(0.0),
|
| + deltaScrollerY(0.0),
|
| + oldWindowY(0.0),
|
| + folderY(0.0),
|
| + folderTop(0.0) {}
|
| +};
|
| +
|
| } // namespace
|
|
|
| @interface BookmarkBarFolderController(Private)
|
| @@ -49,23 +110,83 @@
|
| - (void)endScroll;
|
| - (void)addScrollTimerWithDelta:(CGFloat)delta;
|
|
|
| +// Helper function to configureWindow which performs a basic layout of
|
| +// the window subviews, in particular the menu buttons and the window width.
|
| +- (void)layOutWindowWithHeight:(CGFloat)height;
|
| +
|
| // Determine the best button width (which will be the widest button or the
|
| // maximum allowable button width, whichever is less) and resize all buttons.
|
| -// Return the new width (so that the window can be adjusted, if necessary).
|
| +// Return the new width so that the window can be adjusted.
|
| - (CGFloat)adjustButtonWidths;
|
|
|
| // Returns the total menu height needed to display |buttonCount| buttons.
|
| // Does not do any fancy tricks like trimming the height to fit on the screen.
|
| -- (int)windowHeightForButtonCount:(int)buttonCount;
|
| +- (int)menuHeightForButtonCount:(int)buttonCount;
|
|
|
| -// Adjust the height and horizontal position of the window such that the
|
| -// scroll arrows are shown as needed and the window appears completely
|
| -// on screen.
|
| -- (void)adjustWindowForHeight:(int)windowHeight;
|
| +// Adjust layout of the folder menu window components, showing/hiding the
|
| +// scroll up/down arrows, and resizing as necessary for a proper disaplay.
|
| +// In order to reduce window flicker, all layout changes are deferred until
|
| +// the final step of the adjustment. To accommodate this deferral, window
|
| +// height and width changes needed by callers to this function pass their
|
| +// desired window changes in |size|. When scrolling is to be performed
|
| +// any scrolling change is given by |scrollDelta|. The ultimate amount of
|
| +// scrolling may be different from |scrollDelta| in order to accommodate
|
| +// changes in the scroller view layout. These proposed window adjustments
|
| +// are passed to helper functions using a LayoutMetrics structure.
|
| +//
|
| +// This function should be called when: 1) initially setting up a folder menu
|
| +// window, 2) responding to scrolling of the contents (which may affect the
|
| +// height of the window), 3) addition or removal of bookmark items (such as
|
| +// during cut/paste/delete/drag/drop operations).
|
| +- (void)adjustWindowLeft:(CGFloat)windowLeft
|
| + size:(NSSize)windowSize
|
| + scrollingBy:(CGFloat)scrollDelta;
|
|
|
| -// Show or hide the scroll arrows at the top/bottom of the window.
|
| -- (void)showOrHideScrollArrows;
|
| +// Support function for adjustWindowLeft:size:scrollingBy: which initializes
|
| +// the layout adjustments by gathering current folder menu window and subviews
|
| +// positions and sizes. This information is set in the |layoutMetrics|
|
| +// structure.
|
| +- (void)gatherMetrics:(LayoutMetrics*)layoutMetrics;
|
|
|
| +// Support function for adjustWindowLeft:size:scrollingBy: which calculates
|
| +// the changes which must be applied to the folder menu window and subviews
|
| +// positions and sizes. |layoutMetrics| contains the proposed window size
|
| +// and scrolling along with the other current window and subview layout
|
| +// information. The values in |layoutMetrics| are then adjusted to
|
| +// accommodate scroll arrow presentation and window growth.
|
| +- (void)adjustMetrics:(LayoutMetrics*)layoutMetrics;
|
| +
|
| +// Support function for adjustMetrics: which calculates the layout changes
|
| +// required to accommodate changes in the position and scrollability
|
| +// of the top of the folder menu window.
|
| +- (void)adjustMetricsForMenuTopChanges:(LayoutMetrics*)layoutMetrics;
|
| +
|
| +// Support function for adjustMetrics: which calculates the layout changes
|
| +// required to accommodate changes in the position and scrollability
|
| +// of the bottom of the folder menu window.
|
| +- (void)adjustMetricsForMenuBottomChanges:(LayoutMetrics*)layoutMetrics;
|
| +
|
| +// Support function for adjustWindowLeft:size:scrollingBy: which applies
|
| +// the layout adjustments to the folder menu window and subviews.
|
| +- (void)applyMetrics:(LayoutMetrics*)layoutMetrics;
|
| +
|
| +// This function is called when buttons are added or removed from the folder
|
| +// menu, and which may require a change in the layout of the folder menu
|
| +// window. Such layout changes may include horizontal placement, width,
|
| +// height, and scroller visibility changes. (This function calls through
|
| +// to -[adjustWindowLeft:size:scrollingBy:].)
|
| +// |buttonCount| should contain the updated count of menu buttons.
|
| +- (void)adjustWindowForButtonCount:(NSUInteger)buttonCount;
|
| +
|
| +// A helper function which takes the desired amount to scroll, given by
|
| +// |scrollDelta|, and calculates the actual scrolling change to be applied
|
| +// taking into account the layout of the folder menu window and any
|
| +// changes in it's scrollability. (For example, when scrolling down and the
|
| +// top-most menu item is coming into view we will only scroll enough for
|
| +// that item to be completely presented, which may be less than the
|
| +// scroll amount requested.)
|
| +- (CGFloat)determineFinalScrollDelta:(CGFloat)scrollDelta;
|
| +
|
| // |point| is in the base coordinate system of the destination window;
|
| // it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be
|
| // made and inserted into the new location while leaving the bookmark in
|
| @@ -131,9 +252,6 @@
|
| barController_ = barController; // WEAK
|
| buttons_.reset([[NSMutableArray alloc] init]);
|
| folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);
|
| - NSImage* image = app::mac::GetCachedImageWithName(@"menu_overflow_up.pdf");
|
| - DCHECK(image);
|
| - verticalScrollArrowHeight_ = [image size].height;
|
| [self configureWindow];
|
| hoverState_.reset([[BookmarkBarFolderHoverState alloc] init]);
|
| }
|
| @@ -163,6 +281,13 @@
|
| [super dealloc];
|
| }
|
|
|
| +- (void)awakeFromNib {
|
| + NSRect windowFrame = [[self window] frame];
|
| + NSRect scrollViewFrame = [scrollView_ frame];
|
| + padding_ = NSWidth(windowFrame) - NSWidth(scrollViewFrame);
|
| + verticalScrollArrowHeight_ = NSHeight([scrollUpArrowView_ frame]);
|
| +}
|
| +
|
| // Overriden from NSWindowController to call childFolderWillShow: before showing
|
| // the window.
|
| - (void)showWindow:(id)sender {
|
| @@ -276,11 +401,6 @@
|
| return button;
|
| }
|
|
|
| -// Exposed for testing.
|
| -- (NSView*)mainView {
|
| - return mainView_;
|
| -}
|
| -
|
| - (id)folderTarget {
|
| return folderTarget_.get();
|
| }
|
| @@ -354,7 +474,8 @@
|
| convertBaseToScreen:[[parentButton_ superview]
|
| convertPoint:NSZeroPoint toView:nil]];
|
| newWindowTopLeft = NSMakePoint(buttonBottomLeftInScreen.x,
|
| - bookmarkBarBottomLeftInScreen.y);
|
| + bookmarkBarBottomLeftInScreen.y +
|
| + bookmarks::kBookmarkBarMenuOffset);
|
| // Make sure the window is on-screen; if not, push left. It is
|
| // intentional that top level folders "push left" slightly
|
| // different than subfolders.
|
| @@ -367,12 +488,12 @@
|
| } else {
|
| // Parent is a folder; grow right/left.
|
| newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth];
|
| - NSPoint top = NSMakePoint(0, (NSMaxY([parentButton_ frame]) +
|
| - bookmarks::kBookmarkVerticalPadding));
|
| - NSPoint topOfWindow =
|
| - [[parentButton_ window]
|
| - convertBaseToScreen:[[parentButton_ superview]
|
| - convertPoint:top toView:nil]];
|
| + NSPoint topOfWindow = NSMakePoint(0,
|
| + (NSMaxY([parentButton_ frame]) +
|
| + bookmarks::kBookmarkVerticalPadding));
|
| + topOfWindow = [[parentButton_ window]
|
| + convertBaseToScreen:[[parentButton_ superview]
|
| + convertPoint:topOfWindow toView:nil]];
|
| newWindowTopLeft.y = topOfWindow.y;
|
| }
|
| return newWindowTopLeft;
|
| @@ -384,74 +505,214 @@
|
| [[self window] setLevel:NSPopUpMenuWindowLevel];
|
| }
|
|
|
| -- (int)windowHeightForButtonCount:(int)buttonCount {
|
| +- (int)menuHeightForButtonCount:(int)buttonCount {
|
| + // This does not take into account any padding which may be required at the
|
| + // top and/or bottom of the window.
|
| return (buttonCount * bookmarks::kBookmarkButtonVerticalSpan) +
|
| bookmarks::kBookmarkVerticalPadding;
|
| }
|
|
|
| -- (void)adjustWindowForHeight:(int)windowHeight {
|
| - // Adjust all button widths to be consistent, determine the best size for
|
| - // the window, and set the window frame.
|
| - CGFloat windowWidth =
|
| - [self adjustButtonWidths] +
|
| - (2 * bookmarks::kBookmarkSubMenuHorizontalPadding);
|
| - NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth];
|
| - NSSize windowSize = NSMakeSize(windowWidth, windowHeight);
|
| - windowSize = [scrollView_ convertSize:windowSize toView:nil];
|
| +- (void)adjustWindowLeft:(CGFloat)windowLeft
|
| + size:(NSSize)windowSize
|
| + scrollingBy:(CGFloat)scrollDelta {
|
| + // Callers of this function should make adjustments to the vertical
|
| + // attributes of the folder view only (height, scroll position).
|
| + // This function will then make appropriate layout adjustments in order
|
| + // to accommodate screen/dock margins, scroll-up and scroll-down arrow
|
| + // presentation, etc.
|
| + // The 4 views whose vertical height and origins may be adjusted
|
| + // by this function are:
|
| + // 1) window, 2) visible content view, 3) scroller view, 4) folder view.
|
| +
|
| + LayoutMetrics layoutMetrics(windowLeft, windowSize, scrollDelta);
|
| + [self gatherMetrics:&layoutMetrics];
|
| + [self adjustMetrics:&layoutMetrics];
|
| + [self applyMetrics:&layoutMetrics];
|
| +}
|
| +
|
| +- (void)gatherMetrics:(LayoutMetrics*)layoutMetrics {
|
| + LayoutMetrics& metrics(*layoutMetrics);
|
| NSWindow* window = [self window];
|
| - // If the window is already visible then make sure its top remains stable.
|
| - BOOL windowAlreadyShowing = [window isVisible];
|
| - CGFloat deltaY = windowHeight - NSHeight([mainView_ frame]);
|
| - if (windowAlreadyShowing) {
|
| - NSRect oldFrame = [window frame];
|
| - newWindowTopLeft.y = oldFrame.origin.y + NSHeight(oldFrame);
|
| + metrics.windowFrame = [window frame];
|
| + metrics.visibleFrame = [visibleView_ frame];
|
| + metrics.scrollerFrame = [scrollView_ frame];
|
| + metrics.scrollPoint = [scrollView_ documentVisibleRect].origin;
|
| + metrics.scrollPoint.y -= metrics.scrollDelta;
|
| + metrics.couldScrollUp = ![scrollUpArrowView_ isHidden];
|
| + metrics.couldScrollDown = ![scrollDownArrowView_ isHidden];
|
| +
|
| + metrics.deltaWindowHeight = 0.0;
|
| + metrics.deltaWindowY = 0.0;
|
| + metrics.deltaVisibleHeight = 0.0;
|
| + metrics.deltaVisibleY = 0.0;
|
| + metrics.deltaScrollerHeight = 0.0;
|
| + metrics.deltaScrollerY = 0.0;
|
| +
|
| + metrics.minimumY = NSMinY([[window screen] visibleFrame]) +
|
| + bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.oldWindowY = NSMinY(metrics.windowFrame);
|
| + metrics.folderY =
|
| + metrics.scrollerFrame.origin.y + metrics.visibleFrame.origin.y +
|
| + metrics.oldWindowY - metrics.scrollPoint.y;
|
| + metrics.folderTop = metrics.folderY + NSHeight([folderView_ frame]);
|
| +}
|
| +
|
| +- (void)adjustMetrics:(LayoutMetrics*)layoutMetrics {
|
| + LayoutMetrics& metrics(*layoutMetrics);
|
| + NSScreen* screen = [[self window] screen];
|
| + CGFloat effectiveFolderY = metrics.folderY;
|
| + if (!metrics.couldScrollUp && !metrics.couldScrollDown)
|
| + effectiveFolderY -= metrics.windowSize.height;
|
| + metrics.canScrollUp = effectiveFolderY < metrics.minimumY;
|
| + CGFloat maximumY =
|
| + NSMaxY([screen frame]) - bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.canScrollDown = metrics.folderTop > maximumY;
|
| +
|
| + // Accommodate changes in the bottom of the menu.
|
| + [self adjustMetricsForMenuTopChanges:layoutMetrics];
|
| +
|
| + // Accommodate changes in the top of the menu.
|
| + [self adjustMetricsForMenuBottomChanges:layoutMetrics];
|
| +
|
| + metrics.scrollerFrame.origin.y += metrics.deltaScrollerY;
|
| + metrics.scrollerFrame.size.height += metrics.deltaScrollerHeight;
|
| + metrics.visibleFrame.origin.y += metrics.deltaVisibleY;
|
| + metrics.visibleFrame.size.height += metrics.deltaVisibleHeight;
|
| + metrics.preScroll = metrics.canScrollUp && !metrics.couldScrollUp &&
|
| + metrics.scrollDelta == 0.0 && metrics.deltaWindowHeight >= 0.0;
|
| + metrics.windowFrame.origin.y += metrics.deltaWindowY;
|
| + metrics.windowFrame.origin.x = metrics.windowLeft;
|
| + metrics.windowFrame.size.height += metrics.deltaWindowHeight;
|
| + metrics.windowFrame.size.width = metrics.windowSize.width;
|
| +}
|
| +
|
| +- (void)adjustMetricsForMenuTopChanges:(LayoutMetrics*)layoutMetrics {
|
| + LayoutMetrics& metrics(*layoutMetrics);
|
| + if (metrics.canScrollUp) {
|
| + if (!metrics.couldScrollUp) {
|
| + // Couldn't -> Can
|
| + metrics.deltaWindowY = -metrics.oldWindowY;
|
| + metrics.deltaWindowHeight = -metrics.deltaWindowY;
|
| + metrics.deltaVisibleY = metrics.minimumY;
|
| + metrics.deltaVisibleHeight = -metrics.deltaVisibleY;
|
| + metrics.deltaScrollerY = verticalScrollArrowHeight_;
|
| + metrics.deltaScrollerHeight = -metrics.deltaScrollerY;
|
| + // Adjust the scroll delta if we've grown the window and it is
|
| + // now scroll-up-able, but don't adjust it factor if we've
|
| + // scrolled down and it wasn't scroll-up-able but now is.
|
| + if (metrics.canScrollDown == metrics.couldScrollDown) {
|
| + CGFloat deltaScroll = metrics.deltaWindowY + metrics.deltaScrollerY +
|
| + metrics.deltaVisibleY;
|
| + metrics.scrollPoint.y += deltaScroll + metrics.windowSize.height;
|
| + }
|
| + } else if (!metrics.canScrollDown && metrics.windowSize.height > 0.0) {
|
| + metrics.scrollPoint.y += metrics.windowSize.height;
|
| + }
|
| + } else {
|
| + if (metrics.couldScrollUp) {
|
| + // Could -> Can't
|
| + metrics.deltaWindowY = metrics.folderY - metrics.oldWindowY;
|
| + metrics.deltaWindowHeight = -metrics.deltaWindowY;
|
| + metrics.deltaVisibleY = -bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.deltaVisibleHeight = -metrics.deltaVisibleY;
|
| + metrics.deltaScrollerY = -verticalScrollArrowHeight_;
|
| + metrics.deltaScrollerHeight = -metrics.deltaScrollerY;
|
| + // Adjust the scroll delta if we are no longer scroll-up-able
|
| + // and the scroll-down-able-ness hasn't changed.
|
| + if (metrics.canScrollDown == metrics.couldScrollDown) {
|
| + CGFloat deltaScroll = metrics.deltaWindowY + metrics.deltaScrollerY +
|
| + metrics.deltaVisibleY;
|
| + metrics.scrollPoint.y += deltaScroll;
|
| + }
|
| + } else {
|
| + // Couldn't -> Can't
|
| + // Check for menu height change by looking at the relative tops of the
|
| + // menu folder and the window folder, which previously would have been
|
| + // the same.
|
| + metrics.deltaWindowY = NSMaxY(metrics.windowFrame) - metrics.folderTop;
|
| + metrics.deltaWindowHeight = -metrics.deltaWindowY;
|
| + }
|
| }
|
| - NSRect windowFrame = NSMakeRect(newWindowTopLeft.x,
|
| - newWindowTopLeft.y - windowHeight, windowSize.width, windowHeight);
|
| - // Make the scrolled content be the right size (full size).
|
| - NSRect mainViewFrame = NSMakeRect(0, 0, NSWidth(windowFrame) -
|
| - bookmarks::kScrollViewContentWidthMargin, NSHeight(windowFrame));
|
| - [mainView_ setFrame:mainViewFrame];
|
| - // Make sure the window fits on the screen. If not, constrain.
|
| - // We'll scroll to allow the user to see all the content.
|
| - NSRect screenFrame = [[[self window] screen] frame];
|
| - screenFrame = NSInsetRect(screenFrame, 0, kScrollWindowVerticalMargin);
|
| - BOOL wasScrollable = scrollable_;
|
| - if (!NSContainsRect(screenFrame, windowFrame)) {
|
| - scrollable_ = YES;
|
| - windowFrame = NSIntersectionRect(screenFrame, windowFrame);
|
| +}
|
| +
|
| +- (void)adjustMetricsForMenuBottomChanges:(LayoutMetrics*)layoutMetrics {
|
| + LayoutMetrics& metrics(*layoutMetrics);
|
| + if (metrics.canScrollDown == metrics.couldScrollDown) {
|
| + if (!metrics.canScrollDown) {
|
| + // Not scroll-down-able but the menu top has changed.
|
| + metrics.deltaWindowHeight += metrics.scrollDelta;
|
| + }
|
| } else {
|
| - scrollable_ = NO;
|
| + if (metrics.canScrollDown) {
|
| + // Couldn't -> Can
|
| + metrics.deltaWindowHeight += (NSMaxY([[[self window] screen] frame]) -
|
| + NSMaxY(metrics.windowFrame));
|
| + metrics.deltaVisibleHeight -= bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.deltaScrollerHeight -= verticalScrollArrowHeight_;
|
| + } else {
|
| + // Could -> Can't
|
| + metrics.deltaWindowHeight -= bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.deltaVisibleHeight += bookmarks::kScrollWindowVerticalMargin;
|
| + metrics.deltaScrollerHeight += verticalScrollArrowHeight_;
|
| + }
|
| }
|
| - [window setFrame:windowFrame display:NO];
|
| - if (wasScrollable != scrollable_) {
|
| - // If scrollability changed then rework visibility of the scroll arrows
|
| - // and the scroll offset of the menu view.
|
| - NSSize windowLocalSize =
|
| - [scrollView_ convertSize:windowFrame.size fromView:nil];
|
| - CGFloat scrollPointY = NSHeight(mainViewFrame) - windowLocalSize.height +
|
| - bookmarks::kBookmarkVerticalPadding;
|
| - [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)];
|
| - [self showOrHideScrollArrows];
|
| - [self addOrUpdateScrollTracking];
|
| - } else if (scrollable_ && windowAlreadyShowing) {
|
| - // If the window was already showing and is still scrollable then make
|
| - // sure the main view moves upward, not downward so that the content
|
| - // at the bottom of the menu, not the top, appears to move.
|
| - // The edge case is when the menu is scrolled all the way to top (hence
|
| - // the test of scrollDownArrowShown_) - don't scroll then.
|
| - NSView* superView = [mainView_ superview];
|
| - DCHECK([superView isKindOfClass:[NSClipView class]]);
|
| - NSClipView* clipView = static_cast<NSClipView*>(superView);
|
| - CGFloat scrollPointY = [clipView bounds].origin.y +
|
| - bookmarks::kBookmarkVerticalPadding;
|
| - if (scrollDownArrowShown_ || deltaY > 0.0)
|
| - scrollPointY += deltaY;
|
| - [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)];
|
| +}
|
| +
|
| +- (void)applyMetrics:(LayoutMetrics*)layoutMetrics {
|
| + LayoutMetrics& metrics(*layoutMetrics);
|
| + // Hide or show the scroll arrows.
|
| + if (metrics.canScrollUp != metrics.couldScrollUp)
|
| + [scrollUpArrowView_ setHidden:metrics.couldScrollUp];
|
| + if (metrics.canScrollDown != metrics.couldScrollDown)
|
| + [scrollDownArrowView_ setHidden:metrics.couldScrollDown];
|
| +
|
| + // Adjust the geometry. The order is important because of sizer dependencies.
|
| + [scrollView_ setFrame:metrics.scrollerFrame];
|
| + [visibleView_ setFrame:metrics.visibleFrame];
|
| + // This little bit of trickery handles the one special case where
|
| + // the window is now scroll-up-able _and_ going to be resized -- scroll
|
| + // first in order to prevent flashing.
|
| + if (metrics.preScroll)
|
| + [[scrollView_ documentView] scrollPoint:metrics.scrollPoint];
|
| +
|
| + [[self window] setFrame:metrics.windowFrame display:YES];
|
| +
|
| + // In all other cases we defer scrolling until the window has been resized
|
| + // in order to prevent flashing.
|
| + if (!metrics.preScroll)
|
| + [[scrollView_ documentView] scrollPoint:metrics.scrollPoint];
|
| +
|
| + if (metrics.canScrollUp != metrics.couldScrollUp ||
|
| + metrics.canScrollDown != metrics.couldScrollDown ||
|
| + metrics.scrollDelta != 0.0) {
|
| + if (metrics.canScrollUp || metrics.canScrollDown)
|
| + [self addOrUpdateScrollTracking];
|
| + else
|
| + [self removeScrollTracking];
|
| }
|
| - [window display];
|
| }
|
|
|
| +- (void)adjustWindowForButtonCount:(NSUInteger)buttonCount {
|
| + NSRect folderFrame = [folderView_ frame];
|
| + CGFloat newMenuHeight =
|
| + (CGFloat)[self menuHeightForButtonCount:[buttons_ count]];
|
| + CGFloat deltaMenuHeight = newMenuHeight - NSHeight(folderFrame);
|
| + // If the height has changed then also change the origin, and adjust the
|
| + // scroll (if scrolling).
|
| + if ([self canScrollUp]) {
|
| + NSPoint scrollPoint = [scrollView_ documentVisibleRect].origin;
|
| + scrollPoint.y += deltaMenuHeight;
|
| + [[scrollView_ documentView] scrollPoint:scrollPoint];
|
| + }
|
| + folderFrame.size.height += deltaMenuHeight;
|
| + [folderView_ setFrameSize:folderFrame.size];
|
| + CGFloat windowWidth = [self adjustButtonWidths] + padding_;
|
| + NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth];
|
| + CGFloat left = newWindowTopLeft.x;
|
| + NSSize newSize = NSMakeSize(windowWidth, deltaMenuHeight);
|
| + [self adjustWindowLeft:left size:newSize scrollingBy:0.0];
|
| +}
|
| +
|
| // Determine window size and position.
|
| // Create buttons for all our nodes.
|
| // TODO(jrg): break up into more and smaller routines for easier unit testing.
|
| @@ -464,17 +725,17 @@
|
| int buttons = std::max(node->GetChildCount() - startingIndex, 1);
|
|
|
| // Prelim height of the window. We'll trim later as needed.
|
| - int height = [self windowHeightForButtonCount:buttons];
|
| + int height = [self menuHeightForButtonCount:buttons];
|
| // We'll need this soon...
|
| [self window];
|
|
|
| // TODO(jrg): combine with frame code in bookmark_bar_controller.mm
|
| // http://crbug.com/35966
|
| NSRect buttonsOuterFrame = NSMakeRect(
|
| - bookmarks::kBookmarkSubMenuHorizontalPadding,
|
| - (height - bookmarks::kBookmarkButtonVerticalSpan),
|
| - bookmarks::kDefaultBookmarkWidth,
|
| - bookmarks::kBookmarkButtonHeight);
|
| + 0,
|
| + (height - bookmarks::kBookmarkButtonVerticalSpan),
|
| + bookmarks::kDefaultBookmarkWidth,
|
| + bookmarks::kBookmarkButtonHeight);
|
|
|
| // TODO(jrg): combine with addNodesToButtonList: code from
|
| // bookmark_bar_controller.mm (but use y offset)
|
| @@ -484,7 +745,7 @@
|
| BookmarkButton* button = [self makeButtonForNode:nil
|
| frame:buttonsOuterFrame];
|
| [buttons_ addObject:button];
|
| - [mainView_ addSubview:button];
|
| + [folderView_ addSubview:button];
|
| } else {
|
| for (int i = startingIndex;
|
| i < node->GetChildCount();
|
| @@ -493,13 +754,35 @@
|
| BookmarkButton* button = [self makeButtonForNode:child
|
| frame:buttonsOuterFrame];
|
| [buttons_ addObject:button];
|
| - [mainView_ addSubview:button];
|
| + [folderView_ addSubview:button];
|
| buttonsOuterFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan;
|
| }
|
| }
|
| + [self layOutWindowWithHeight:height];
|
| +}
|
|
|
| - [self adjustWindowForHeight:height];
|
| - // Finally pop me up.
|
| +- (void)layOutWindowWithHeight:(CGFloat)height {
|
| + // Lay out the window by adjusting all button widths to be consistent, then
|
| + // base the window width on this ideal button width.
|
| + CGFloat buttonWidth = [self adjustButtonWidths];
|
| + CGFloat windowWidth = buttonWidth + padding_;
|
| + NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth];
|
| + // Make sure as much of a submenu is exposed (which otherwise would be a
|
| + // problem if the parent button is close to the bottom of the screen).
|
| + if ([parentController_ isKindOfClass:[self class]]) {
|
| + newWindowTopLeft.y = MAX(newWindowTopLeft.y,
|
| + height + bookmarks::kScrollWindowVerticalMargin);
|
| + }
|
| + NSWindow* window = [self window];
|
| + NSRect windowFrame = NSMakeRect(newWindowTopLeft.x,
|
| + newWindowTopLeft.y - height,
|
| + windowWidth, height);
|
| + [window setFrame:windowFrame display:NO];
|
| + NSRect folderFrame = NSMakeRect(0, 0, windowWidth, height);
|
| + [folderView_ setFrame:folderFrame];
|
| + NSSize newSize = NSMakeSize(windowWidth, 0.0);
|
| + [self adjustWindowLeft:newWindowTopLeft.x size:newSize scrollingBy:0.0];
|
| + [window display];
|
| [self configureWindowLevel];
|
| }
|
|
|
| @@ -525,85 +808,6 @@
|
| 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];
|
| - }
|
| -}
|
| -
|
| -- (BOOL)scrollable {
|
| - return scrollable_;
|
| -}
|
| -
|
| // Start a "scroll up" timer.
|
| - (void)beginScrollWindowUp {
|
| [self addScrollTimerWithDelta:kBookmarkBarFolderScrollAmount];
|
| @@ -624,67 +828,55 @@
|
| }
|
|
|
| // Perform a single scroll of the specified amount.
|
| -// Scroll up:
|
| -// Scroll the documentView by the growth amount.
|
| -// If we cannot grow the window, simply scroll the documentView.
|
| -// If we can grow the window up without falling off the screen, do it.
|
| -// Scroll down:
|
| -// Never change the window size; only scroll the documentView.
|
| - (void)performOneScroll:(CGFloat)delta {
|
| - NSRect windowFrame = [[self window] frame];
|
| - NSRect screenFrame = [[[self window] screen] frame];
|
| -
|
| - // First scroll the "document" area.
|
| - NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
|
| - scrollPosition.y -= delta;
|
| - [[scrollView_ documentView] scrollPoint:scrollPosition];
|
| -
|
| - if (buttonThatMouseIsIn_)
|
| - [buttonThatMouseIsIn_ toggleButtonBorderingWhileMouseInside];
|
| -
|
| - // We update the window size after shifting the scroll to avoid a race.
|
| - CGFloat screenHeightMinusMargin = (NSHeight(screenFrame) -
|
| - (2 * kScrollWindowVerticalMargin));
|
| - if (delta) {
|
| - // If we can, grow the window (up).
|
| - if (NSHeight(windowFrame) < screenHeightMinusMargin) {
|
| - CGFloat growAmount = delta;
|
| - // Don't scroll more than enough to "finish".
|
| - if (scrollPosition.y < 0)
|
| - growAmount += scrollPosition.y;
|
| - 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) {
|
| - [[self window] setFrame:windowFrame display:YES];
|
| - [self addOrUpdateScrollTracking];
|
| - }
|
| - }
|
| + CGFloat finalDelta = [self determineFinalScrollDelta:delta];
|
| + if (finalDelta > 0.0 || finalDelta < 0.0) {
|
| + if (buttonThatMouseIsIn_)
|
| + [buttonThatMouseIsIn_ toggleButtonBorderingWhileMouseInside];
|
| + NSRect windowFrame = [[self window] frame];
|
| + NSSize newSize = NSMakeSize(NSWidth(windowFrame), 0.0);
|
| + [self adjustWindowLeft:windowFrame.origin.x
|
| + size:newSize
|
| + scrollingBy:finalDelta];
|
| }
|
| +}
|
|
|
| - // If we're at either end, happiness.
|
| - if ((scrollPosition.y <= 0) ||
|
| - ((scrollPosition.y + NSHeight(windowFrame) >=
|
| - NSHeight([mainView_ frame])) &&
|
| - (windowFrame.size.height == screenHeightMinusMargin))) {
|
| - [self endScroll];
|
| +- (CGFloat)determineFinalScrollDelta:(CGFloat)delta {
|
| + if (delta > 0.0 && ![scrollUpArrowView_ isHidden] ||
|
| + delta < 0.0 && ![scrollDownArrowView_ isHidden]) {
|
| + NSWindow* window = [self window];
|
| + NSRect windowFrame = [window frame];
|
| + NSScreen* screen = [window screen];
|
| + NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
|
| + CGFloat scrollY = scrollPosition.y;
|
| + NSRect scrollerFrame = [scrollView_ frame];
|
| + CGFloat scrollerY = NSMinY(scrollerFrame);
|
| + NSRect visibleFrame = [visibleView_ frame];
|
| + CGFloat visibleY = NSMinY(visibleFrame);
|
| + CGFloat windowY = NSMinY(windowFrame);
|
| + CGFloat offset = scrollerY + visibleY + windowY;
|
|
|
| - // 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];
|
| + if (delta > 0.0) {
|
| + // Scrolling up.
|
| + CGFloat minimumY = NSMinY([screen visibleFrame]) +
|
| + bookmarks::kScrollWindowVerticalMargin;
|
| + CGFloat maxUpDelta = scrollY - offset + minimumY;
|
| + delta = MIN(delta, maxUpDelta);
|
| + } else {
|
| + // Scrolling down.
|
| + NSRect screenFrame = [screen frame];
|
| + CGFloat topOfScreen = NSMaxY(screenFrame);
|
| + NSRect folderFrame = [folderView_ frame];
|
| + CGFloat folderHeight = NSHeight(folderFrame);
|
| + CGFloat folderTop = folderHeight - scrollY + offset;
|
| + CGFloat maxDownDelta =
|
| + topOfScreen - folderTop - bookmarks::kScrollWindowVerticalMargin;
|
| + delta = MAX(delta, maxDownDelta);
|
| }
|
| + } else {
|
| + delta = 0.0;
|
| }
|
| -
|
| - [self showOrHideScrollArrows];
|
| + return delta;
|
| }
|
|
|
| // Perform a scroll of the window on the screen.
|
| @@ -716,22 +908,28 @@
|
| // menubar (to be fixed by setting the proper window level; see
|
| // initializer).
|
| - (void)mouseMoved:(NSEvent*)theEvent {
|
| - DCHECK([theEvent window] == [self window]);
|
| + NSWindow* window = [theEvent window];
|
| + DCHECK(window == [self window]);
|
|
|
| NSPoint eventScreenLocation =
|
| - [[theEvent window] convertBaseToScreen:[theEvent locationInWindow]];
|
| + [window convertBaseToScreen:[theEvent locationInWindow]];
|
|
|
| - // We use frame (not visibleFrame) since our bookmark folder is on
|
| - // TOP of the menubar.
|
| - NSRect visibleRect = [[[self window] screen] frame];
|
| - CGFloat closeToTopOfScreen = NSMaxY(visibleRect) -
|
| - verticalScrollArrowHeight_;
|
| - CGFloat closeToBottomOfScreen = NSMinY(visibleRect) +
|
| - verticalScrollArrowHeight_;
|
| + // Base hot spot calculations on the positions of the scroll arrow views.
|
| + NSRect testRect = [scrollDownArrowView_ frame];
|
| + NSPoint testPoint = [visibleView_ convertPoint:testRect.origin
|
| + toView:nil];
|
| + testPoint = [window convertBaseToScreen:testPoint];
|
| + CGFloat closeToTopOfScreen = testPoint.y;
|
|
|
| - if (eventScreenLocation.y <= closeToBottomOfScreen) {
|
| + testRect = [scrollUpArrowView_ frame];
|
| + testPoint = [visibleView_ convertPoint:testRect.origin toView:nil];
|
| + testPoint = [window convertBaseToScreen:testPoint];
|
| + CGFloat closeToBottomOfScreen = testPoint.y + testRect.size.height;
|
| + if (eventScreenLocation.y <= closeToBottomOfScreen &&
|
| + ![scrollUpArrowView_ isHidden]) {
|
| [self beginScrollWindowUp];
|
| - } else if (eventScreenLocation.y > closeToTopOfScreen) {
|
| + } else if (eventScreenLocation.y > closeToTopOfScreen &&
|
| + ![scrollDownArrowView_ isHidden]) {
|
| [self beginScrollWindowDown];
|
| } else {
|
| [self endScroll];
|
| @@ -766,17 +964,6 @@
|
| scrollTrackingArea_.reset();
|
| }
|
|
|
| -// Delegate callback.
|
| -- (void)windowWillClose:(NSNotification*)notification {
|
| - // If a "hover open" is pending when the bookmark bar folder is
|
| - // closed, be sure it gets cancelled.
|
| - [NSObject cancelPreviousPerformRequestsWithTarget:self];
|
| -
|
| - [barController_ childFolderWillClose:self];
|
| - [self closeBookmarkFolder:self];
|
| - [self autorelease];
|
| -}
|
| -
|
| // Close the old hover-open bookmark folder, and open a new one. We
|
| // do both in one step to allow for a delay in closing the old one.
|
| // See comments above kDragHoverCloseDelay (bookmark_bar_controller.h)
|
| @@ -800,7 +987,7 @@
|
| }
|
|
|
| - (void)scrollWheel:(NSEvent *)theEvent {
|
| - if (scrollable_) {
|
| + if (![scrollUpArrowView_ isHidden] || ![scrollDownArrowView_ isHidden]) {
|
| // We go negative since an NSScrollView has a flipped coordinate frame.
|
| CGFloat amt = kBookmarkBarFolderScrollWheelAmount * -[theEvent deltaY];
|
| [self performOneScroll:amt];
|
| @@ -926,7 +1113,7 @@
|
| // dropLocation is in bar local coordinates.
|
| // http://crbug.com/36276
|
| NSPoint dropLocation =
|
| - [mainView_ convertPoint:point
|
| + [folderView_ convertPoint:point
|
| fromView:[[self window] contentView]];
|
| BookmarkButton* buttonToTheTopOfDraggedButton = nil;
|
| // Buttons are laid out in this array from top to bottom (screen
|
| @@ -1000,6 +1187,19 @@
|
| return wasCopiedOrMoved;
|
| }
|
|
|
| +#pragma mark NSWindowDelegate Functions
|
| +
|
| +- (void)windowWillClose:(NSNotification*)notification {
|
| + // If a "hover open" is pending when the bookmark bar folder is
|
| + // closed, be sure it gets cancelled.
|
| + [NSObject cancelPreviousPerformRequestsWithTarget:self];
|
| +
|
| + [self endScroll]; // Just in case we were scrolling.
|
| + [barController_ childFolderWillClose:self];
|
| + [self closeBookmarkFolder:self];
|
| + [self autorelease];
|
| +}
|
| +
|
| #pragma mark BookmarkButtonDelegate Protocol
|
|
|
| - (void)fillPasteboard:(NSPasteboard*)pboard
|
| @@ -1280,14 +1480,12 @@
|
| BookmarkButton* newButton = [self makeButtonForNode:node
|
| frame:newButtonFrame];
|
| [buttons_ insertObject:newButton atIndex:buttonIndex];
|
| - [mainView_ addSubview:newButton];
|
| + [folderView_ addSubview:newButton];
|
|
|
| // Close any child folder(s) which may still be open.
|
| [self closeBookmarkFolder:self];
|
|
|
| - // Prelim height of the window. We'll trim later as needed.
|
| - int height = [self windowHeightForButtonCount:[buttons_ count]];
|
| - [self adjustWindowForHeight:height];
|
| + [self adjustWindowForButtonCount:[buttons_ count]];
|
| }
|
|
|
| // More code which essentially duplicates that of BookmarkBarController.
|
| @@ -1394,9 +1592,6 @@
|
|
|
| [oldButton setDelegate:nil];
|
| [oldButton removeFromSuperview];
|
| - if (animate && !ignoreAnimations_)
|
| - NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
|
| - NSZeroSize, nil, nil, nil);
|
| [buttons_ removeObjectAtIndex:buttonIndex];
|
| for (NSInteger i = 0; i < buttonIndex; ++i) {
|
| BookmarkButton* button = [buttons_ objectAtIndex:i];
|
| @@ -1419,22 +1614,25 @@
|
| // If all nodes have been removed from this folder then add in the
|
| // 'empty' placeholder button.
|
| NSRect buttonFrame =
|
| - NSMakeRect(bookmarks::kBookmarkSubMenuHorizontalPadding,
|
| + NSMakeRect(0,
|
| bookmarks::kBookmarkButtonHeight -
|
| - (bookmarks::kBookmarkBarHeight -
|
| - bookmarks::kBookmarkVerticalPadding),
|
| + (bookmarks::kBookmarkBarHeight -
|
| + bookmarks::kBookmarkVerticalPadding),
|
| bookmarks::kDefaultBookmarkWidth,
|
| (bookmarks::kBookmarkBarHeight -
|
| - 2 * bookmarks::kBookmarkVerticalPadding));
|
| + 2 * bookmarks::kBookmarkVerticalPadding));
|
| BookmarkButton* button = [self makeButtonForNode:nil
|
| frame:buttonFrame];
|
| [buttons_ addObject:button];
|
| - [mainView_ addSubview:button];
|
| + [folderView_ addSubview:button];
|
| buttonCount = 1;
|
| }
|
|
|
| - // Propose a height for the window. We'll trim later as needed.
|
| - [self adjustWindowForHeight:[self windowHeightForButtonCount:buttonCount]];
|
| + [self adjustWindowForButtonCount:buttonCount];
|
| +
|
| + if (animate && !ignoreAnimations_)
|
| + NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
|
| + NSZeroSize, nil, nil, nil);
|
| }
|
|
|
| - (id<BookmarkButtonControllerProtocol>)controllerForNode:
|
| @@ -1448,6 +1646,30 @@
|
|
|
| #pragma mark TestingAPI Only
|
|
|
| +- (BOOL)canScrollUp {
|
| + return ![scrollUpArrowView_ isHidden];
|
| +}
|
| +
|
| +- (BOOL)canScrollDown {
|
| + return ![scrollDownArrowView_ isHidden];
|
| +}
|
| +
|
| +- (CGFloat)verticalScrollArrowHeight {
|
| + return verticalScrollArrowHeight_;
|
| +}
|
| +
|
| +- (NSView*)visibleView {
|
| + return visibleView_;
|
| +}
|
| +
|
| +- (NSView*)scrollView {
|
| + return scrollView_;
|
| +}
|
| +
|
| +- (NSView*)folderView {
|
| + return folderView_;
|
| +}
|
| +
|
| - (void)setIgnoreAnimations:(BOOL)ignore {
|
| ignoreAnimations_ = ignore;
|
| }
|
|
|