diff options
Diffstat (limited to 'chrome/browser')
8 files changed, 154 insertions, 5 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.h b/chrome/browser/cocoa/bookmark_bar_folder_controller.h index d2e1238..fef2a56 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller.h +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.h @@ -116,6 +116,9 @@ - (IBAction)pasteBookmark:(id)sender; - (IBAction)deleteBookmark:(id)sender; +// Passed up by a child view to tell us of a desire to scroll. +- (void)scrollWheel:(NSEvent *)theEvent; + // Forwarded to the associated BookmarkBarController. - (IBAction)addFolder:(id)sender; - (IBAction)addPage:(id)sender; @@ -126,6 +129,7 @@ - (IBAction)openBookmarkInIncognitoWindow:(id)sender; - (IBAction)openBookmarkInNewForegroundTab:(id)sender; - (IBAction)openBookmarkInNewWindow:(id)sender; + @end @interface BookmarkBarFolderController(TestingAPI) diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm index 5aa8f12..54e5c07 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm @@ -29,6 +29,11 @@ const CGFloat kBookmarkBarFolderScrollAmount = 2 * (bookmarks::kBookmarkButtonHeight + bookmarks::kBookmarkVerticalPadding); +// Amount to scroll for each scroll wheel delta. +const CGFloat kBookmarkBarFolderScrollWheelAmount = + 1 * (bookmarks::kBookmarkButtonHeight + + bookmarks::kBookmarkVerticalPadding); + // 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 @@ -85,7 +90,7 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; [super showWindow:sender]; } -- (NSCell*)cellForBookmarkNode:(const BookmarkNode*)child { +- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)child { NSImage* image = child ? [barController_ favIconForNode:child] : nil; NSMenu* menu = child ? child->is_folder() ? folderMenu_ : buttonMenu_ : nil; BookmarkBarFolderButtonCell* cell = @@ -114,9 +119,18 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; // http://crbug.com/35966 - (BookmarkButton*)makeButtonForNode:(const BookmarkNode*)node frame:(NSRect)frame { - NSCell* cell = [self cellForBookmarkNode:node]; + BookmarkButtonCell* cell = [self cellForBookmarkNode:node]; DCHECK(cell); + // We must decide if we draw the folder arrow before we ask the cell + // how big it needs to be. + if (node && node->is_folder()) { + // Warning when combining code with bookmark_bar_controller.mm: + // this call should NOT be made for the bar buttons; only for the + // subfolder buttons. + [cell setDrawFolderArrow:YES]; + } + // The "+2" is needed because, sometimes, Cocoa is off by a tad when // returning the value it thinks it needs. CGFloat desired = [cell cellSize].width + 2; @@ -147,6 +161,7 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; } } else { [button setEnabled:NO]; + [button setBordered:NO]; } return button; } @@ -374,8 +389,12 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; windowFrame.size.height += growAmount; windowFrame.size.height = std::min(NSHeight(windowFrame), screenHeightMinusMargin); - [[self window] setFrame:windowFrame display:YES]; - [self addOrUpdateScrollTracking]; + // 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]; + } } } @@ -807,6 +826,14 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [super close]; } +- (void)scrollWheel:(NSEvent *)theEvent { + if (scrollable_) { + // We go negative since an NSScrollView has a flipped coordinate frame. + CGFloat amt = kBookmarkBarFolderScrollWheelAmount * -[theEvent deltaY]; + [self performOneScroll:amt]; + } +} + #pragma mark Methods Forwarded to BookmarkBarController - (IBAction)cutBookmark:(id)sender { @@ -865,4 +892,5 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [barController_ openBookmarkInNewWindow:sender]; } + @end // BookmarkBarFolderController diff --git a/chrome/browser/cocoa/bookmark_bar_folder_window.h b/chrome/browser/cocoa/bookmark_bar_folder_window.h index 8f96d27..c35bd2e3 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_window.h +++ b/chrome/browser/cocoa/bookmark_bar_folder_window.h @@ -13,10 +13,14 @@ @interface BookmarkBarFolderWindow : NSWindow @end - // Content view for the above window. "Stock" other than the drawing // of rounded corners. Only used in the nib. @interface BookmarkBarFolderWindowContentView : NSView @end +// Scroll view that contains the main view (where the buttons go). +@interface BookmarkBarFolderWindowScrollView : NSScrollView +@end + + #endif // CHROME_BROWSER_COCOA_BOOKMARK_BAR_FOLDER_WINDOW_H_ diff --git a/chrome/browser/cocoa/bookmark_bar_folder_window.mm b/chrome/browser/cocoa/bookmark_bar_folder_window.mm index 6cae7c5..732bed1 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_window.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_window.mm @@ -4,7 +4,9 @@ #import "chrome/browser/cocoa/bookmark_bar_folder_window.h" +#import "base/logging.h" #import "base/scoped_nsobject.h" +#import "chrome/browser/cocoa/bookmark_bar_folder_controller.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" @@ -72,3 +74,20 @@ const CGFloat kViewCornerRadius = 4.0; } @end + + +@implementation BookmarkBarFolderWindowScrollView + +// We want "draw background" of the NSScrollView in the xib to be NOT +// checked. That allows us to round the bottom corners of the folder +// window. However that also allows some scrollWheel: events to leak +// into the NSWindow behind it (even in a different application). +// Better to plug the scroll leak than to round corners for M5. +- (void)scrollWheel:(NSEvent *)theEvent { + DCHECK([[[self window] windowController] + respondsToSelector:@selector(scrollWheel:)]); + [[[self window] windowController] scrollWheel:theEvent]; +} + + +@end diff --git a/chrome/browser/cocoa/bookmark_bar_folder_window_unittest.mm b/chrome/browser/cocoa/bookmark_bar_folder_window_unittest.mm index 586417e..269aa3d 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_window_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_window_unittest.mm @@ -21,6 +21,7 @@ TEST_F(BookmarkBarFolderWindowTest, Borderless) { EXPECT_EQ(NSBorderlessWindowMask, [window_ styleMask]); } + class BookmarkBarFolderWindowContentViewTest : public CocoaTest { public: BookmarkBarFolderWindowContentViewTest() { @@ -29,6 +30,20 @@ class BookmarkBarFolderWindowContentViewTest : public CocoaTest { [[test_window() contentView] addSubview:view_.get()]; } scoped_nsobject<BookmarkBarFolderWindowContentView> view_; + scoped_nsobject<BookmarkBarFolderWindowScrollView> scroll_view_; }; TEST_VIEW(BookmarkBarFolderWindowContentViewTest, view_); + + +class BookmarkBarFolderWindowScrollViewTest : public CocoaTest { + public: + BookmarkBarFolderWindowScrollViewTest() { + scroll_view_.reset([[BookmarkBarFolderWindowScrollView alloc] + initWithFrame:NSMakeRect(0, 0, 100, 100)]); + [[test_window() contentView] addSubview:scroll_view_.get()]; + } + scoped_nsobject<BookmarkBarFolderWindowScrollView> scroll_view_; +}; + +TEST_VIEW(BookmarkBarFolderWindowScrollViewTest, scroll_view_); diff --git a/chrome/browser/cocoa/bookmark_button_cell.h b/chrome/browser/cocoa/bookmark_button_cell.h index 6684b8e..6213343 100644 --- a/chrome/browser/cocoa/bookmark_button_cell.h +++ b/chrome/browser/cocoa/bookmark_button_cell.h @@ -20,10 +20,18 @@ class BookmarkNode; // Starting index of bookmarkFolder children that we care to use. int startingChildIndex_; + + // Should we draw the folder arrow as needed? Not used for the bar + // itself but used on the folder windows. + BOOL drawFolderArrow_; + + // Arrow for folders + scoped_nsobject<NSImage> arrowImage_; } @property (readwrite, assign) const BookmarkNode* bookmarkNode; @property (readwrite, assign) int startingChildIndex; +@property (readwrite, assign) BOOL drawFolderArrow; // Create a button cell which draws with a theme. + (id)buttonCellForNode:(const BookmarkNode*)node diff --git a/chrome/browser/cocoa/bookmark_button_cell.mm b/chrome/browser/cocoa/bookmark_button_cell.mm index edae5f9..85cfaf4 100644 --- a/chrome/browser/cocoa/bookmark_button_cell.mm +++ b/chrome/browser/cocoa/bookmark_button_cell.mm @@ -6,9 +6,11 @@ #include "app/l10n_util_mac.h" #include "base/logging.h" +#include "base/nsimage_cache_mac.h" #include "base/sys_string_conversions.h" #import "chrome/browser/bookmarks/bookmark_model.h" #import "chrome/browser/cocoa/bookmark_menu.h" +#import "chrome/browser/cocoa/bookmark_button.h" #include "grit/generated_resources.h" @@ -20,6 +22,7 @@ @implementation BookmarkButtonCell @synthesize startingChildIndex = startingChildIndex_; +@synthesize drawFolderArrow = drawFolderArrow_; + (id)buttonCellForNode:(const BookmarkNode*)node contextMenu:(NSMenu*)contextMenu @@ -53,6 +56,7 @@ image:nil]; } } + return self; } @@ -176,4 +180,47 @@ [[self controlView] mouseExited:event]; } +- (void)setDrawFolderArrow:(BOOL)draw { + drawFolderArrow_ = draw; + if (draw && !arrowImage_) { + arrowImage_.reset([nsimage_cache::ImageNamed(@"menu_hierarchy_arrow.pdf") + retain]); + } +} + +// Add extra size for the arrow so it doesn't overlap the text. +// Does not sanity check to be sure this is actually a folder node. +- (NSSize)cellSize { + NSSize cellSize = [super cellSize]; + if (drawFolderArrow_) { + cellSize.width += [arrowImage_ size].width; // plus margin? + } + return cellSize; +} + +// Override cell drawing to add a submenu arrow like a real menu. +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { + // First draw "everything else". + [super drawInteriorWithFrame:cellFrame inView:controlView]; + + // If asked to do so, and if a folder, draw the arrow. + if (!drawFolderArrow_) + return; + BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]); + DCHECK([button respondsToSelector:@selector(isFolder)]); + if ([button isFolder]) { + NSRect imageRect = NSZeroRect; + imageRect.size = [arrowImage_ size]; + NSRect drawRect = NSOffsetRect(imageRect, + NSWidth(cellFrame) - NSWidth(imageRect), + (NSHeight(cellFrame) / 2.0) - + (NSHeight(imageRect) / 2.0)); + [arrowImage_ setFlipped:[controlView isFlipped]]; + [arrowImage_ drawInRect:drawRect + fromRect:imageRect + operation:NSCompositeSourceOver + fraction:[self isEnabled] ? 1.0 : 0.5]; + } +} + @end diff --git a/chrome/browser/cocoa/bookmark_button_cell_unittest.mm b/chrome/browser/cocoa/bookmark_button_cell_unittest.mm index da378f1..0762863 100644 --- a/chrome/browser/cocoa/bookmark_button_cell_unittest.mm +++ b/chrome/browser/cocoa/bookmark_button_cell_unittest.mm @@ -121,4 +121,28 @@ TEST_F(BookmarkButtonCellTest, Awake) { EXPECT_EQ(NSLeftTextAlignment, [cell alignment]); } +// Subfolder arrow details. +TEST_F(BookmarkButtonCellTest, FolderArrow) { + BookmarkModel* model = helper_.profile()->GetBookmarkModel(); + const BookmarkNode* bar = model->GetBookmarkBarNode(); + const BookmarkNode* node = model->AddURL(bar, bar->GetChildCount(), L"title", + GURL("http://www.google.com")); + scoped_nsobject<BookmarkButtonCell> cell( + [[BookmarkButtonCell alloc] initForNode:node + contextMenu:nil + cellText:@"small" + cellImage:nil]); + EXPECT_TRUE(cell.get()); + + NSSize size = [cell cellSize]; + // sanity check + EXPECT_GE(size.width, 2); + EXPECT_GE(size.height, 2); + + // Once we turn on arrow drawing make sure there is now room for it. + [cell setDrawFolderArrow:YES]; + NSSize arrowSize = [cell cellSize]; + EXPECT_GT(arrowSize.width, size.width); +} + } // namespace |