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 |