OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" | 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" |
6 | 6 |
7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
8 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
9 #include "chrome/browser/bookmarks/bookmark_model.h" | 9 #include "chrome/browser/bookmarks/bookmark_model.h" |
10 #include "chrome/browser/bookmarks/bookmark_utils.h" | 10 #include "chrome/browser/bookmarks/bookmark_utils.h" |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 451 } |
452 // Unhappy; do the best we can. | 452 // Unhappy; do the best we can. |
453 return NSMaxX([[[self window] screen] frame]) - windowWidth; | 453 return NSMaxX([[[self window] screen] frame]) - windowWidth; |
454 } | 454 } |
455 | 455 |
456 | 456 |
457 // Compute and return the top left point of our window (screen | 457 // Compute and return the top left point of our window (screen |
458 // coordinates). The top left is positioned in a manner similar to | 458 // coordinates). The top left is positioned in a manner similar to |
459 // cascading menus. Windows may grow to either the right or left of | 459 // cascading menus. Windows may grow to either the right or left of |
460 // their parent (if a sub-folder) so we need to know |windowWidth|. | 460 // their parent (if a sub-folder) so we need to know |windowWidth|. |
461 - (NSPoint)windowTopLeftForWidth:(int)windowWidth { | 461 - (NSPoint)windowTopLeftForWidth:(int)windowWidth height:(int)windowHeight { |
| 462 CGFloat kMinSqueezedMenuHeight = bookmarks::kBookmarkFolderButtonHeight * 2.0; |
462 NSPoint newWindowTopLeft; | 463 NSPoint newWindowTopLeft; |
463 if (![parentController_ isKindOfClass:[self class]]) { | 464 if (![parentController_ isKindOfClass:[self class]]) { |
464 // If we're not popping up from one of ourselves, we must be | 465 // If we're not popping up from one of ourselves, we must be |
465 // popping up from the bookmark bar itself. In this case, start | 466 // popping up from the bookmark bar itself. In this case, start |
466 // BELOW the parent button. Our left is the button left; our top | 467 // BELOW the parent button. Our left is the button left; our top |
467 // is bottom of button's parent view. | 468 // is bottom of button's parent view. |
468 NSPoint buttonBottomLeftInScreen = | 469 NSPoint buttonBottomLeftInScreen = |
469 [[parentButton_ window] | 470 [[parentButton_ window] |
470 convertBaseToScreen:[parentButton_ | 471 convertBaseToScreen:[parentButton_ |
471 convertPoint:NSZeroPoint toView:nil]]; | 472 convertPoint:NSZeroPoint toView:nil]]; |
472 NSPoint bookmarkBarBottomLeftInScreen = | 473 NSPoint bookmarkBarBottomLeftInScreen = |
473 [[parentButton_ window] | 474 [[parentButton_ window] |
474 convertBaseToScreen:[[parentButton_ superview] | 475 convertBaseToScreen:[[parentButton_ superview] |
475 convertPoint:NSZeroPoint toView:nil]]; | 476 convertPoint:NSZeroPoint toView:nil]]; |
476 newWindowTopLeft = NSMakePoint( | 477 newWindowTopLeft = NSMakePoint( |
477 buttonBottomLeftInScreen.x + bookmarks::kBookmarkBarButtonOffset, | 478 buttonBottomLeftInScreen.x + bookmarks::kBookmarkBarButtonOffset, |
478 bookmarkBarBottomLeftInScreen.y + bookmarks::kBookmarkBarMenuOffset); | 479 bookmarkBarBottomLeftInScreen.y + bookmarks::kBookmarkBarMenuOffset); |
479 // Make sure the window is on-screen; if not, push left. It is | 480 // Make sure the window is on-screen; if not, push left. It is |
480 // intentional that top level folders "push left" slightly | 481 // intentional that top level folders "push left" slightly |
481 // different than subfolders. | 482 // different than subfolders. |
482 NSRect screenFrame = [[[parentButton_ window] screen] frame]; | 483 NSRect screenFrame = [[[parentButton_ window] screen] frame]; |
483 CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame); | 484 CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame); |
484 if (spillOff > 0.0) { | 485 if (spillOff > 0.0) { |
485 newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff, | 486 newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff, |
486 NSMinX(screenFrame)); | 487 NSMinX(screenFrame)); |
487 } | 488 } |
| 489 // The menu looks bad when it is squeezed up against the bottom of the |
| 490 // screen and ends up being only a few pixels tall. If it meets the |
| 491 // threshold for this case, instead show the menu above the button. |
| 492 NSRect visFrame = [[[parentButton_ window] screen] visibleFrame]; |
| 493 CGFloat availableVerticalSpace = newWindowTopLeft.y - |
| 494 (NSMinY(visFrame) + bookmarks::kScrollWindowVerticalMargin); |
| 495 if ((availableVerticalSpace < kMinSqueezedMenuHeight) && |
| 496 (windowHeight > availableVerticalSpace)) { |
| 497 newWindowTopLeft.y = std::min( |
| 498 newWindowTopLeft.y + windowHeight + NSHeight([parentButton_ frame]), |
| 499 NSMaxY(visFrame)); |
| 500 } |
488 } else { | 501 } else { |
489 // Parent is a folder: expose as much as we can vertically; grow right/left. | 502 // Parent is a folder: expose as much as we can vertically; grow right/left. |
490 newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth]; | 503 newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth]; |
491 NSPoint topOfWindow = NSMakePoint(0, | 504 NSPoint topOfWindow = NSMakePoint(0, |
492 NSMaxY([parentButton_ frame]) - | 505 NSMaxY([parentButton_ frame]) - |
493 bookmarks::kBookmarkVerticalPadding); | 506 bookmarks::kBookmarkVerticalPadding); |
494 topOfWindow = [[parentButton_ window] | 507 topOfWindow = [[parentButton_ window] |
495 convertBaseToScreen:[[parentButton_ superview] | 508 convertBaseToScreen:[[parentButton_ superview] |
496 convertPoint:topOfWindow toView:nil]]; | 509 convertPoint:topOfWindow toView:nil]]; |
497 newWindowTopLeft.y = topOfWindow.y; | 510 newWindowTopLeft.y = topOfWindow.y; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 // If the height has changed then also change the origin, and adjust the | 708 // If the height has changed then also change the origin, and adjust the |
696 // scroll (if scrolling). | 709 // scroll (if scrolling). |
697 if ([self canScrollUp]) { | 710 if ([self canScrollUp]) { |
698 NSPoint scrollPoint = [scrollView_ documentVisibleRect].origin; | 711 NSPoint scrollPoint = [scrollView_ documentVisibleRect].origin; |
699 scrollPoint.y += deltaMenuHeight; | 712 scrollPoint.y += deltaMenuHeight; |
700 [[scrollView_ documentView] scrollPoint:scrollPoint]; | 713 [[scrollView_ documentView] scrollPoint:scrollPoint]; |
701 } | 714 } |
702 folderFrame.size.height += deltaMenuHeight; | 715 folderFrame.size.height += deltaMenuHeight; |
703 [folderView_ setFrameSize:folderFrame.size]; | 716 [folderView_ setFrameSize:folderFrame.size]; |
704 CGFloat windowWidth = [self adjustButtonWidths] + padding_; | 717 CGFloat windowWidth = [self adjustButtonWidths] + padding_; |
705 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth]; | 718 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth |
| 719 height:deltaMenuHeight]; |
706 CGFloat left = newWindowTopLeft.x; | 720 CGFloat left = newWindowTopLeft.x; |
707 NSSize newSize = NSMakeSize(windowWidth, deltaMenuHeight); | 721 NSSize newSize = NSMakeSize(windowWidth, deltaMenuHeight); |
708 [self adjustWindowLeft:left size:newSize scrollingBy:0.0]; | 722 [self adjustWindowLeft:left size:newSize scrollingBy:0.0]; |
709 } | 723 } |
710 | 724 |
711 // Determine window size and position. | 725 // Determine window size and position. |
712 // Create buttons for all our nodes. | 726 // Create buttons for all our nodes. |
713 // TODO(jrg): break up into more and smaller routines for easier unit testing. | 727 // TODO(jrg): break up into more and smaller routines for easier unit testing. |
714 - (void)configureWindow { | 728 - (void)configureWindow { |
715 const BookmarkNode* node = [parentButton_ bookmarkNode]; | 729 const BookmarkNode* node = [parentButton_ bookmarkNode]; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 } | 769 } |
756 } | 770 } |
757 [self layOutWindowWithHeight:height]; | 771 [self layOutWindowWithHeight:height]; |
758 } | 772 } |
759 | 773 |
760 - (void)layOutWindowWithHeight:(CGFloat)height { | 774 - (void)layOutWindowWithHeight:(CGFloat)height { |
761 // Lay out the window by adjusting all button widths to be consistent, then | 775 // Lay out the window by adjusting all button widths to be consistent, then |
762 // base the window width on this ideal button width. | 776 // base the window width on this ideal button width. |
763 CGFloat buttonWidth = [self adjustButtonWidths]; | 777 CGFloat buttonWidth = [self adjustButtonWidths]; |
764 CGFloat windowWidth = buttonWidth + padding_; | 778 CGFloat windowWidth = buttonWidth + padding_; |
765 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth]; | 779 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth |
| 780 height:height]; |
766 // Make sure as much of a submenu is exposed (which otherwise would be a | 781 // Make sure as much of a submenu is exposed (which otherwise would be a |
767 // problem if the parent button is close to the bottom of the screen). | 782 // problem if the parent button is close to the bottom of the screen). |
768 if ([parentController_ isKindOfClass:[self class]]) { | 783 if ([parentController_ isKindOfClass:[self class]]) { |
769 CGFloat minimumY = NSMinY([[[self window] screen] visibleFrame]) + | 784 CGFloat minimumY = NSMinY([[[self window] screen] visibleFrame]) + |
770 bookmarks::kScrollWindowVerticalMargin + | 785 bookmarks::kScrollWindowVerticalMargin + |
771 height; | 786 height; |
772 newWindowTopLeft.y = MAX(newWindowTopLeft.y, minimumY); | 787 newWindowTopLeft.y = MAX(newWindowTopLeft.y, minimumY); |
773 } | 788 } |
774 NSWindow* window = [self window]; | 789 NSWindow* window = [self window]; |
775 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x, | 790 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x, |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 | 1680 |
1666 - (void)setIgnoreAnimations:(BOOL)ignore { | 1681 - (void)setIgnoreAnimations:(BOOL)ignore { |
1667 ignoreAnimations_ = ignore; | 1682 ignoreAnimations_ = ignore; |
1668 } | 1683 } |
1669 | 1684 |
1670 - (BookmarkButton*)buttonThatMouseIsIn { | 1685 - (BookmarkButton*)buttonThatMouseIsIn { |
1671 return buttonThatMouseIsIn_; | 1686 return buttonThatMouseIsIn_; |
1672 } | 1687 } |
1673 | 1688 |
1674 @end // BookmarkBarFolderController | 1689 @end // BookmarkBarFolderController |
OLD | NEW |