Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(749)

Side by Side Diff: chrome/browser/cocoa/bookmark_bar_folder_controller.mm

Issue 1813003: Vertical scrolling arrows in bookmark bar folder windows when needed.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/cocoa/bookmark_bar_folder_controller.h" 5 #import "chrome/browser/cocoa/bookmark_bar_folder_controller.h"
6 #include "base/mac_util.h" 6 #include "base/mac_util.h"
7 #include "base/nsimage_cache_mac.h"
7 #include "base/sys_string_conversions.h" 8 #include "base/sys_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_model.h" 9 #include "chrome/browser/bookmarks/bookmark_model.h"
9 #include "chrome/browser/bookmarks/bookmark_utils.h" 10 #include "chrome/browser/bookmarks/bookmark_utils.h"
10 #import "chrome/browser/browser_theme_provider.h" 11 #import "chrome/browser/browser_theme_provider.h"
11 #import "chrome/browser/cocoa/bookmark_bar_constants.h" // namespace bookmarks 12 #import "chrome/browser/cocoa/bookmark_bar_constants.h" // namespace bookmarks
12 #import "chrome/browser/cocoa/bookmark_bar_controller.h" // namespace bookmarks 13 #import "chrome/browser/cocoa/bookmark_bar_controller.h" // namespace bookmarks
13 #import "chrome/browser/cocoa/bookmark_bar_folder_view.h" 14 #import "chrome/browser/cocoa/bookmark_bar_folder_view.h"
14 #import "chrome/browser/cocoa/bookmark_bar_folder_button_cell.h" 15 #import "chrome/browser/cocoa/bookmark_bar_folder_button_cell.h"
15 #import "chrome/browser/cocoa/bookmark_bar_folder_hover_state.h" 16 #import "chrome/browser/cocoa/bookmark_bar_folder_hover_state.h"
16 #import "chrome/browser/cocoa/bookmark_folder_target.h" 17 #import "chrome/browser/cocoa/bookmark_folder_target.h"
(...skipping 16 matching lines...) Expand all
33 1 * (bookmarks::kBookmarkButtonHeight + 34 1 * (bookmarks::kBookmarkButtonHeight +
34 bookmarks::kBookmarkVerticalPadding); 35 bookmarks::kBookmarkVerticalPadding);
35 36
36 // Our NSScrollView is supposed to be just barely big enough to fit its 37 // Our NSScrollView is supposed to be just barely big enough to fit its
37 // contentView. It is actually a hair too small. 38 // contentView. It is actually a hair too small.
38 // This turns on horizontal scrolling which, although slight, is awkward. 39 // This turns on horizontal scrolling which, although slight, is awkward.
39 // Make sure our window (and NSScrollView) are wider than its documentView 40 // Make sure our window (and NSScrollView) are wider than its documentView
40 // by at least this much. 41 // by at least this much.
41 const CGFloat kScrollViewContentWidthMargin = 2; 42 const CGFloat kScrollViewContentWidthMargin = 2;
42 43
43
44 // When constraining a scrolling bookmark bar folder window to the 44 // When constraining a scrolling bookmark bar folder window to the
45 // screen, shrink the "constrain" by this much vertically. Currently 45 // screen, shrink the "constrain" by this much vertically. Currently
46 // this is 0.0 to avoid a problem with tracking areas leaving the 46 // this is 0.0 to avoid a problem with tracking areas leaving the
47 // window, but should probably be 8.0 or something. 47 // window, but should probably be 8.0 or something.
48 // TODO(jrg): http://crbug.com/36225 48 // TODO(jrg): http://crbug.com/36225
49 const CGFloat kScrollWindowVerticalMargin = 0.0; 49 const CGFloat kScrollWindowVerticalMargin = 0.0;
50 50
51 } // namespace 51 } // namespace
52 52
53 @interface BookmarkBarFolderController(Private) 53 @interface BookmarkBarFolderController(Private)
54 - (void)configureWindow; 54 - (void)configureWindow;
55 - (void)addOrUpdateScrollTracking; 55 - (void)addOrUpdateScrollTracking;
56 - (void)removeScrollTracking; 56 - (void)removeScrollTracking;
57 - (void)endScroll; 57 - (void)endScroll;
58 - (void)addScrollTimerWithDelta:(CGFloat)delta; 58 - (void)addScrollTimerWithDelta:(CGFloat)delta;
59 59
60 // Determine the best button width (which will be the widest button or the 60 // Determine the best button width (which will be the widest button or the
61 // maximum allowable button width, whichever is less) and resize all buttons. 61 // maximum allowable button width, whichever is less) and resize all buttons.
62 // Return the new width (so that the window can be adjusted, if necessary). 62 // Return the new width (so that the window can be adjusted, if necessary).
63 - (CGFloat)adjustButtonWidths; 63 - (CGFloat)adjustButtonWidths;
64 64
65 // Show or hide the scroll arrows at the top/bottom of the window.
66 - (void)showOrHideScrollArrows;
67
65 @end 68 @end
66 69
67 @implementation BookmarkBarFolderController 70 @implementation BookmarkBarFolderController
68 71
69 - (id)initWithParentButton:(BookmarkButton*)button 72 - (id)initWithParentButton:(BookmarkButton*)button
70 parentController:(BookmarkBarFolderController*)parentController 73 parentController:(BookmarkBarFolderController*)parentController
71 barController:(BookmarkBarController*)barController { 74 barController:(BookmarkBarController*)barController {
72 NSString* nibPath = 75 NSString* nibPath =
73 [mac_util::MainAppBundle() pathForResource:@"BookmarkBarFolderWindow" 76 [mac_util::MainAppBundle() pathForResource:@"BookmarkBarFolderWindow"
74 ofType:@"nib"]; 77 ofType:@"nib"];
75 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { 78 if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
76 parentButton_.reset([button retain]); 79 parentButton_.reset([button retain]);
77 parentController_.reset([parentController retain]); 80 parentController_.reset([parentController retain]);
78 barController_ = barController; // WEAK 81 barController_ = barController; // WEAK
79 buttons_.reset([[NSMutableArray alloc] init]); 82 buttons_.reset([[NSMutableArray alloc] init]);
80 folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]); 83 folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);
84 NSImage* image = nsimage_cache::ImageNamed(@"menu_overflow_up.pdf");
85 DCHECK(image);
86 verticalScrollArrowHeight_ = [image size].height;
81 [self configureWindow]; 87 [self configureWindow];
82 hoverState_.reset([[BookmarkBarFolderHoverState alloc] init]); 88 hoverState_.reset([[BookmarkBarFolderHoverState alloc] init]);
83 if (scrollable_) 89 if (scrollable_)
84 [self addOrUpdateScrollTracking]; 90 [self addOrUpdateScrollTracking];
85 } 91 }
86 return self; 92 return self;
87 } 93 }
88 94
89 - (void)dealloc { 95 - (void)dealloc {
90 [self removeScrollTracking]; 96 [self removeScrollTracking];
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 if (!NSContainsRect(screenFrame, windowFrame)) { 333 if (!NSContainsRect(screenFrame, windowFrame)) {
328 scrollable_ = YES; 334 scrollable_ = YES;
329 windowFrame = NSIntersectionRect(screenFrame, windowFrame); 335 windowFrame = NSIntersectionRect(screenFrame, windowFrame);
330 } 336 }
331 [[self window] setFrame:windowFrame display:YES]; 337 [[self window] setFrame:windowFrame display:YES];
332 if (scrollable_) { 338 if (scrollable_) {
333 [mainView_ scrollPoint:NSMakePoint(0, (NSHeight(mainViewFrame) - 339 [mainView_ scrollPoint:NSMakePoint(0, (NSHeight(mainViewFrame) -
334 NSHeight(windowFrame)))]; 340 NSHeight(windowFrame)))];
335 } 341 }
336 342
343 // If scrollable, show the arrows.
344 if (scrollable_) {
345 [self showOrHideScrollArrows];
346 }
347
337 // Finally pop me up. 348 // Finally pop me up.
338 [self configureWindowLevel]; 349 [self configureWindowLevel];
339 } 350 }
340 351
341 - (void)offsetFolderMenuWindow:(NSSize)offset { 352 - (void)offsetFolderMenuWindow:(NSSize)offset {
342 NSWindow* window = [self window]; 353 NSWindow* window = [self window];
343 NSRect windowFrame = [window frame]; 354 NSRect windowFrame = [window frame];
344 windowFrame.origin.x -= offset.width; 355 windowFrame.origin.x -= offset.width;
345 windowFrame.origin.y += offset.height; // Yes, in the opposite direction! 356 windowFrame.origin.y += offset.height; // Yes, in the opposite direction!
346 [window setFrame:windowFrame display:YES]; 357 [window setFrame:windowFrame display:YES];
(...skipping 10 matching lines...) Expand all
357 // Things look and feel more menu-like if all the buttons are the 368 // Things look and feel more menu-like if all the buttons are the
358 // full width of the window, especially if there are submenus. 369 // full width of the window, especially if there are submenus.
359 for (BookmarkButton* button in buttons_.get()) { 370 for (BookmarkButton* button in buttons_.get()) {
360 NSRect buttonFrame = [button frame]; 371 NSRect buttonFrame = [button frame];
361 buttonFrame.size.width = width; 372 buttonFrame.size.width = width;
362 [button setFrame:buttonFrame]; 373 [button setFrame:buttonFrame];
363 } 374 }
364 return width; 375 return width;
365 } 376 }
366 377
378 - (BOOL)canScrollUp {
379 // If removal of an arrow would make things "finished", state as
380 // such.
381 CGFloat scrollY = [scrollView_ documentVisibleRect].origin.y;
382 if (scrollUpArrowShown_)
383 scrollY -= verticalScrollArrowHeight_;
384
385 if (scrollY <= 0)
386 return NO;
387 return YES;
388 }
389
390 - (BOOL)canScrollDown {
391 CGFloat arrowAdjustment = 0.0;
392
393 // We do NOT adjust based on the scrollDOWN arrow. This keeps
394 // things from "jumping"; if removal of the down arrow (at the top
395 // of the window) would cause a scroll to end, we'll end.
396 if (scrollUpArrowShown_)
397 arrowAdjustment += verticalScrollArrowHeight_;
398
399 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
400 NSRect documentRect = [[scrollView_ documentView] frame];
401
402 // If we are exactly the right height, return no. We need this
403 // extra conditional in the case where we've just scrolled/grown
404 // into position.
405 if (NSHeight([[self window] frame]) == NSHeight(documentRect))
406 return NO;
407
408 if ((scrollPosition.y + NSHeight([[self window] frame])) >=
409 (NSHeight(documentRect) + arrowAdjustment)) {
410 return NO;
411 }
412 return YES;
413 }
414
415 - (void)showOrHideScrollArrows {
416 NSRect frame = [scrollView_ frame];
417 CGFloat scrollDelta = 0.0;
418 BOOL canScrollDown = [self canScrollDown];
419 BOOL canScrollUp = [self canScrollUp];
420
421 if (canScrollUp != scrollUpArrowShown_) {
422 if (scrollUpArrowShown_) {
423 frame.origin.y -= verticalScrollArrowHeight_;
424 frame.size.height += verticalScrollArrowHeight_;
425 scrollDelta = verticalScrollArrowHeight_;
426 } else {
427 frame.origin.y += verticalScrollArrowHeight_;
428 frame.size.height -= verticalScrollArrowHeight_;
429 scrollDelta = -verticalScrollArrowHeight_;
430 }
431 }
432 if (canScrollDown != scrollDownArrowShown_) {
433 if (scrollDownArrowShown_) {
434 frame.size.height += verticalScrollArrowHeight_;
435 } else {
436 frame.size.height -= verticalScrollArrowHeight_;
437 }
438 }
439 scrollUpArrowShown_ = canScrollUp;
440 scrollDownArrowShown_ = canScrollDown;
441 [scrollView_ setFrame:frame];
442
443 // Adjust scroll based on new frame. For example, if we make room
444 // for an arrow at the bottom, adjust the scroll so the topmost item
445 // is still fully visible.
446 if (scrollDelta) {
447 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
448 scrollPosition.y -= scrollDelta;
449 [[scrollView_ documentView] scrollPoint:scrollPosition];
450 }
451 }
452
367 #pragma mark BookmarkButtonControllerProtocol 453 #pragma mark BookmarkButtonControllerProtocol
368 454
369 - (void)addButtonForNode:(const BookmarkNode*)node 455 - (void)addButtonForNode:(const BookmarkNode*)node
370 atIndex:(NSInteger)buttonIndex { 456 atIndex:(NSInteger)buttonIndex {
371 if (buttonIndex == -1) 457 if (buttonIndex == -1)
372 buttonIndex = [buttons_ count]; 458 buttonIndex = [buttons_ count];
373 459
374 // Remember the last moved button's frame or the default. 460 // Remember the last moved button's frame or the default.
375 NSRect buttonFrame = NSMakeRect(bookmarks::kBookmarkHorizontalPadding, 461 NSRect buttonFrame = NSMakeRect(bookmarks::kBookmarkHorizontalPadding,
376 NSHeight([mainView_ frame]) + bookmarks::kBookmarkBarHeight + 462 NSHeight([mainView_ frame]) + bookmarks::kBookmarkBarHeight +
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 if (delta) { 638 if (delta) {
553 // If we can, grow the window (up). 639 // If we can, grow the window (up).
554 if (NSHeight(windowFrame) < screenHeightMinusMargin) { 640 if (NSHeight(windowFrame) < screenHeightMinusMargin) {
555 CGFloat growAmount = delta; 641 CGFloat growAmount = delta;
556 // Don't scroll more than enough to "finish". 642 // Don't scroll more than enough to "finish".
557 if (scrollPosition.y < 0) 643 if (scrollPosition.y < 0)
558 growAmount += scrollPosition.y; 644 growAmount += scrollPosition.y;
559 windowFrame.size.height += growAmount; 645 windowFrame.size.height += growAmount;
560 windowFrame.size.height = std::min(NSHeight(windowFrame), 646 windowFrame.size.height = std::min(NSHeight(windowFrame),
561 screenHeightMinusMargin); 647 screenHeightMinusMargin);
648 // Watch out for a finish that isn't the full height of the screen.
649 // We get here if using the scroll wheel to scroll by small amounts.
650 windowFrame.size.height = std::min(NSHeight(windowFrame),
651 NSHeight([mainView_ frame]));
562 // Don't allow scrolling to make the window smaller, ever. This 652 // Don't allow scrolling to make the window smaller, ever. This
563 // conditional is important when processing scrollWheel events. 653 // conditional is important when processing scrollWheel events.
564 if (windowFrame.size.height > [[self window] frame].size.height) { 654 if (windowFrame.size.height > [[self window] frame].size.height) {
565 [[self window] setFrame:windowFrame display:YES]; 655 [[self window] setFrame:windowFrame display:YES];
566 [self addOrUpdateScrollTracking]; 656 [self addOrUpdateScrollTracking];
567 } 657 }
568 } 658 }
569 } 659 }
570 660
571 // If we're at either end, happiness. 661 // If we're at either end, happiness.
572 if ((scrollPosition.y <= 0) || 662 if ((scrollPosition.y <= 0) ||
573 ((scrollPosition.y + NSHeight(windowFrame) >= 663 ((scrollPosition.y + NSHeight(windowFrame) >=
574 NSHeight([mainView_ frame])) && 664 NSHeight([mainView_ frame])) &&
575 (windowFrame.size.height == screenHeightMinusMargin))) { 665 (windowFrame.size.height == screenHeightMinusMargin))) {
576 [self endScroll]; 666 [self endScroll];
577 667
578 // If the entire view is now visible the window is no longer scrollable. 668 // If we can't scroll either up or down we are completely done.
579 if (NSHeight([mainView_ visibleRect]) == NSHeight([mainView_ bounds])) { 669 // For example, perhaps we've scrolled a little and grown the
670 // window on-screen until there is now room for everything.
671 if (![self canScrollUp] && ![self canScrollDown]) {
580 scrollable_ = NO; 672 scrollable_ = NO;
581 [self removeScrollTracking]; 673 [self removeScrollTracking];
582 } 674 }
583 } 675 }
676
677 [self showOrHideScrollArrows];
584 } 678 }
585 679
586 // Perform a scroll of the window on the screen. 680 // Perform a scroll of the window on the screen.
587 // Called by a timer when scrolling. 681 // Called by a timer when scrolling.
588 - (void)performScroll:(NSTimer*)timer { 682 - (void)performScroll:(NSTimer*)timer {
589 DCHECK(verticalScrollDelta_); 683 DCHECK(verticalScrollDelta_);
590 [self performOneScroll:verticalScrollDelta_]; 684 [self performOneScroll:verticalScrollDelta_];
591 } 685 }
592 686
593 687
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 - (IBAction)openBookmarkInNewForegroundTab:(id)sender { 1179 - (IBAction)openBookmarkInNewForegroundTab:(id)sender {
1086 [barController_ openBookmarkInNewForegroundTab:sender]; 1180 [barController_ openBookmarkInNewForegroundTab:sender];
1087 } 1181 }
1088 1182
1089 - (IBAction)openBookmarkInNewWindow:(id)sender { 1183 - (IBAction)openBookmarkInNewWindow:(id)sender {
1090 [barController_ openBookmarkInNewWindow:sender]; 1184 [barController_ openBookmarkInNewWindow:sender];
1091 } 1185 }
1092 1186
1093 1187
1094 @end // BookmarkBarFolderController 1188 @end // BookmarkBarFolderController
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/bookmark_bar_folder_controller.h ('k') | chrome/browser/cocoa/bookmark_bar_folder_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698