| OLD | NEW |
| 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/nsimage_cache_mac.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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 [[self window] setLevel:NSPopUpMenuWindowLevel]; | 370 [[self window] setLevel:NSPopUpMenuWindowLevel]; |
| 371 } | 371 } |
| 372 | 372 |
| 373 - (void)adjustWindowForHeight:(int)windowHeight { | 373 - (void)adjustWindowForHeight:(int)windowHeight { |
| 374 // Adjust all button widths to be consistent, determine the best size for | 374 // Adjust all button widths to be consistent, determine the best size for |
| 375 // the window, and set the window frame. | 375 // the window, and set the window frame. |
| 376 CGFloat windowWidth = | 376 CGFloat windowWidth = |
| 377 [self adjustButtonWidths] + (2 * bookmarks::kBookmarkVerticalPadding) + | 377 [self adjustButtonWidths] + (2 * bookmarks::kBookmarkVerticalPadding) + |
| 378 bookmarks::kScrollViewContentWidthMargin; | 378 bookmarks::kScrollViewContentWidthMargin; |
| 379 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth]; | 379 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth]; |
| 380 NSSize windowSize = [scrollView_ convertSize:NSMakeSize(windowWidth, | 380 NSSize windowSize = NSMakeSize(windowWidth, windowHeight); |
| 381 windowHeight) | 381 windowSize = [scrollView_ convertSize:windowSize toView:nil]; |
| 382 toView:nil]; | 382 NSWindow* window = [self window]; |
| 383 newWindowTopLeft.y -= windowSize.height; | 383 // If the window is already visible then make sure its top remains stable. |
| 384 BOOL windowAlreadyShowing = [window isVisible]; |
| 385 CGFloat deltaY = windowHeight - NSHeight([mainView_ frame]); |
| 386 if (windowAlreadyShowing) { |
| 387 NSRect oldFrame = [window frame]; |
| 388 newWindowTopLeft.y = oldFrame.origin.y + NSHeight(oldFrame); |
| 389 } |
| 384 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x, | 390 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x, |
| 385 newWindowTopLeft.y, | 391 newWindowTopLeft.y - windowHeight, windowSize.width, windowHeight); |
| 386 windowSize.width, | |
| 387 windowSize.height); | |
| 388 | |
| 389 // Make the scrolled content be the right size (full size). | 392 // Make the scrolled content be the right size (full size). |
| 390 NSRect mainViewFrame = NSMakeRect(0, 0, | 393 NSRect mainViewFrame = NSMakeRect(0, 0, NSWidth(windowFrame) - |
| 391 windowWidth - | 394 bookmarks::kScrollViewContentWidthMargin, NSHeight(windowFrame)); |
| 392 bookmarks::kScrollViewContentWidthMargin, | |
| 393 windowHeight); | |
| 394 [mainView_ setFrame:mainViewFrame]; | 395 [mainView_ setFrame:mainViewFrame]; |
| 395 | |
| 396 // Make sure the window fits on the screen. If not, constrain. | 396 // Make sure the window fits on the screen. If not, constrain. |
| 397 // We'll scroll to allow the user to see all the content. | 397 // We'll scroll to allow the user to see all the content. |
| 398 NSRect screenFrame = [[[self window] screen] frame]; | 398 NSRect screenFrame = [[[self window] screen] frame]; |
| 399 screenFrame = NSInsetRect(screenFrame, 0, kScrollWindowVerticalMargin); | 399 screenFrame = NSInsetRect(screenFrame, 0, kScrollWindowVerticalMargin); |
| 400 BOOL wasScrollable = scrollable_; | 400 BOOL wasScrollable = scrollable_; |
| 401 if (!NSContainsRect(screenFrame, windowFrame)) { | 401 if (!NSContainsRect(screenFrame, windowFrame)) { |
| 402 scrollable_ = YES; | 402 scrollable_ = YES; |
| 403 windowFrame = NSIntersectionRect(screenFrame, windowFrame); | 403 windowFrame = NSIntersectionRect(screenFrame, windowFrame); |
| 404 } else { | 404 } else { |
| 405 scrollable_ = NO; | 405 scrollable_ = NO; |
| 406 } | 406 } |
| 407 NSWindow* window = [self window]; | 407 [window setFrame:windowFrame display:NO]; |
| 408 [window setFrame:windowFrame display:YES]; | |
| 409 // If scrollable then offset the view and show the arrows. | |
| 410 if (wasScrollable != scrollable_) { | 408 if (wasScrollable != scrollable_) { |
| 411 NSSize windowLocalSize = [scrollView_ convertSize:windowFrame.size | 409 // If scrollability changed then rework visibility of the scroll arrows |
| 412 fromView:nil]; | 410 // and the scroll offset of the menu view. |
| 413 [mainView_ scrollPoint:NSMakePoint(0, (NSHeight(mainViewFrame) - | 411 NSSize windowLocalSize = |
| 414 windowLocalSize.height))]; | 412 [scrollView_ convertSize:windowFrame.size fromView:nil]; |
| 413 CGFloat scrollPointY = NSHeight(mainViewFrame) - windowLocalSize.height + |
| 414 bookmarks::kBookmarkVerticalPadding; |
| 415 [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)]; |
| 415 [self showOrHideScrollArrows]; | 416 [self showOrHideScrollArrows]; |
| 416 [self addOrUpdateScrollTracking]; | 417 [self addOrUpdateScrollTracking]; |
| 418 } else if (scrollable_ && windowAlreadyShowing) { |
| 419 // If the window was already showing and is still scrollable then make |
| 420 // sure the main view moves upward, not downward so that the content |
| 421 // at the bottom of the menu, not the top, appears to move. |
| 422 // The edge case is when the menu is scrolled all the way to top (hence |
| 423 // the test of scrollDownArrowShown_) - don't scroll then. |
| 424 NSView* superView = [mainView_ superview]; |
| 425 DCHECK([superView isKindOfClass:[NSClipView class]]); |
| 426 NSClipView* clipView = static_cast<NSClipView*>(superView); |
| 427 CGFloat scrollPointY = [clipView bounds].origin.y + |
| 428 bookmarks::kBookmarkVerticalPadding; |
| 429 if (scrollDownArrowShown_ || deltaY > 0.0) |
| 430 scrollPointY += deltaY; |
| 431 [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)]; |
| 417 } | 432 } |
| 433 [window display]; |
| 418 } | 434 } |
| 419 | 435 |
| 420 // Determine window size and position. | 436 // Determine window size and position. |
| 421 // Create buttons for all our nodes. | 437 // Create buttons for all our nodes. |
| 422 // TODO(jrg): break up into more and smaller routines for easier unit testing. | 438 // TODO(jrg): break up into more and smaller routines for easier unit testing. |
| 423 - (void)configureWindow { | 439 - (void)configureWindow { |
| 424 const BookmarkNode* node = [parentButton_ bookmarkNode]; | 440 const BookmarkNode* node = [parentButton_ bookmarkNode]; |
| 425 DCHECK(node); | 441 DCHECK(node); |
| 426 int startingIndex = [[parentButton_ cell] startingChildIndex]; | 442 int startingIndex = [[parentButton_ cell] startingChildIndex]; |
| 427 DCHECK_LE(startingIndex, node->GetChildCount()); | 443 DCHECK_LE(startingIndex, node->GetChildCount()); |
| 428 // Must have at least 1 button (for "empty") | 444 // Must have at least 1 button (for "empty") |
| 429 int buttons = std::max(node->GetChildCount() - startingIndex, 1); | 445 int buttons = std::max(node->GetChildCount() - startingIndex, 1); |
| 430 | 446 |
| 431 // Prelim height of the window. We'll trim later as needed. | 447 // Prelim height of the window. We'll trim later as needed. |
| 432 int height = buttons * bookmarks::kBookmarkButtonHeight; | 448 int height = buttons * bookmarks::kBookmarkButtonHeight + |
| 449 bookmarks::kBookmarkVerticalPadding; |
| 433 // We'll need this soon... | 450 // We'll need this soon... |
| 434 [self window]; | 451 [self window]; |
| 435 | 452 |
| 436 // TODO(jrg): combine with frame code in bookmark_bar_controller.mm | 453 // TODO(jrg): combine with frame code in bookmark_bar_controller.mm |
| 437 // http://crbug.com/35966 | 454 // http://crbug.com/35966 |
| 438 NSRect buttonsOuterFrame = NSMakeRect( | 455 NSRect buttonsOuterFrame = NSMakeRect( |
| 439 bookmarks::kBookmarkHorizontalPadding, | 456 bookmarks::kBookmarkHorizontalPadding, |
| 440 height - bookmarks::kBookmarkButtonHeight, | 457 height - bookmarks::kBookmarkButtonHeight, |
| 441 bookmarks::kDefaultBookmarkWidth, | 458 bookmarks::kDefaultBookmarkWidth, |
| 442 bookmarks::kBookmarkButtonHeight); | 459 bookmarks::kBookmarkButtonHeight); |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 buttonFrame.origin.y -= bookmarks::kBookmarkBarHeight; | 1247 buttonFrame.origin.y -= bookmarks::kBookmarkBarHeight; |
| 1231 BookmarkButton* newButton = [self makeButtonForNode:node | 1248 BookmarkButton* newButton = [self makeButtonForNode:node |
| 1232 frame:buttonFrame]; | 1249 frame:buttonFrame]; |
| 1233 [buttons_ insertObject:newButton atIndex:buttonIndex]; | 1250 [buttons_ insertObject:newButton atIndex:buttonIndex]; |
| 1234 [mainView_ addSubview:newButton]; | 1251 [mainView_ addSubview:newButton]; |
| 1235 | 1252 |
| 1236 // Close any child folder(s) which may still be open. | 1253 // Close any child folder(s) which may still be open. |
| 1237 [self closeBookmarkFolder:self]; | 1254 [self closeBookmarkFolder:self]; |
| 1238 | 1255 |
| 1239 // Prelim height of the window. We'll trim later as needed. | 1256 // Prelim height of the window. We'll trim later as needed. |
| 1240 int height = [buttons_ count] * bookmarks::kBookmarkButtonHeight; | 1257 int height = [buttons_ count] * bookmarks::kBookmarkButtonHeight + |
| 1258 bookmarks::kBookmarkVerticalPadding; |
| 1241 [self adjustWindowForHeight:height]; | 1259 [self adjustWindowForHeight:height]; |
| 1242 } | 1260 } |
| 1243 | 1261 |
| 1244 // More code which essentially duplicates that of BookmarkBarController. | 1262 // More code which essentially duplicates that of BookmarkBarController. |
| 1245 // TODO(mrossetti,jrg): http://crbug.com/35966 | 1263 // TODO(mrossetti,jrg): http://crbug.com/35966 |
| 1246 - (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point { | 1264 - (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point { |
| 1247 DCHECK([urls count] == [titles count]); | 1265 DCHECK([urls count] == [titles count]); |
| 1248 BOOL nodesWereAdded = NO; | 1266 BOOL nodesWereAdded = NO; |
| 1249 // Figure out where these new bookmarks nodes are to be added. | 1267 // Figure out where these new bookmarks nodes are to be added. |
| 1250 BookmarkButton* button = [self buttonForDroppingOnAtPoint:point]; | 1268 BookmarkButton* button = [self buttonForDroppingOnAtPoint:point]; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 (bookmarks::kBookmarkBarHeight - | 1381 (bookmarks::kBookmarkBarHeight - |
| 1364 2 * bookmarks::kBookmarkVerticalPadding)); | 1382 2 * bookmarks::kBookmarkVerticalPadding)); |
| 1365 BookmarkButton* button = [self makeButtonForNode:nil | 1383 BookmarkButton* button = [self makeButtonForNode:nil |
| 1366 frame:buttonFrame]; | 1384 frame:buttonFrame]; |
| 1367 [buttons_ addObject:button]; | 1385 [buttons_ addObject:button]; |
| 1368 [mainView_ addSubview:button]; | 1386 [mainView_ addSubview:button]; |
| 1369 buttonCount = 1; | 1387 buttonCount = 1; |
| 1370 } | 1388 } |
| 1371 | 1389 |
| 1372 // Propose a height for the window. We'll trim later as needed. | 1390 // Propose a height for the window. We'll trim later as needed. |
| 1373 int height = buttonCount * bookmarks::kBookmarkButtonHeight; | 1391 int height = buttonCount * bookmarks::kBookmarkButtonHeight + |
| 1392 bookmarks::kBookmarkVerticalPadding; |
| 1374 [self adjustWindowForHeight:height]; | 1393 [self adjustWindowForHeight:height]; |
| 1375 } | 1394 } |
| 1376 | 1395 |
| 1377 - (id<BookmarkButtonControllerProtocol>)controllerForNode: | 1396 - (id<BookmarkButtonControllerProtocol>)controllerForNode: |
| 1378 (const BookmarkNode*)node { | 1397 (const BookmarkNode*)node { |
| 1379 // See if we are holding this node, otherwise see if it is in our | 1398 // See if we are holding this node, otherwise see if it is in our |
| 1380 // hierarchy of visible folder menus. | 1399 // hierarchy of visible folder menus. |
| 1381 if ([parentButton_ bookmarkNode] == node) | 1400 if ([parentButton_ bookmarkNode] == node) |
| 1382 return self; | 1401 return self; |
| 1383 return [folderController_ controllerForNode:node]; | 1402 return [folderController_ controllerForNode:node]; |
| 1384 } | 1403 } |
| 1385 | 1404 |
| 1386 #pragma mark TestingAPI Only | 1405 #pragma mark TestingAPI Only |
| 1387 | 1406 |
| 1388 - (void)setIgnoreAnimations:(BOOL)ignore { | 1407 - (void)setIgnoreAnimations:(BOOL)ignore { |
| 1389 ignoreAnimations_ = ignore; | 1408 ignoreAnimations_ = ignore; |
| 1390 } | 1409 } |
| 1391 | 1410 |
| 1392 @end // BookmarkBarFolderController | 1411 @end // BookmarkBarFolderController |
| OLD | NEW |