| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extensions/browser_actions_controller.h" | 5 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 withBounds:(NSRect)bounds; | 128 withBounds:(NSRect)bounds; |
| 129 | 129 |
| 130 // Moves the given button both visually and within the toolbar model to the | 130 // Moves the given button both visually and within the toolbar model to the |
| 131 // specified index. | 131 // specified index. |
| 132 - (void)moveButton:(BrowserActionButton*)button | 132 - (void)moveButton:(BrowserActionButton*)button |
| 133 toIndex:(NSUInteger)index; | 133 toIndex:(NSUInteger)index; |
| 134 | 134 |
| 135 // Handles clicks for BrowserActionButtons. | 135 // Handles clicks for BrowserActionButtons. |
| 136 - (BOOL)browserActionClicked:(BrowserActionButton*)button; | 136 - (BOOL)browserActionClicked:(BrowserActionButton*)button; |
| 137 | 137 |
| 138 // Updates the container's grippy cursor based on the number of hidden buttons. | |
| 139 - (void)updateGrippyCursors; | |
| 140 | |
| 141 // Returns the associated ToolbarController. | 138 // Returns the associated ToolbarController. |
| 142 - (ToolbarController*)toolbarController; | 139 - (ToolbarController*)toolbarController; |
| 143 | 140 |
| 144 // Creates a message bubble with the given |delegate|. | 141 // Creates a message bubble with the given |delegate|. |
| 145 - (void)createMessageBubble: | 142 - (void)createMessageBubble: |
| 146 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate; | 143 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate; |
| 147 | 144 |
| 148 // Called when the window for the active bubble is closing, and sets the active | 145 // Called when the window for the active bubble is closing, and sets the active |
| 149 // bubble to nil. | 146 // bubble to nil. |
| 150 - (void)bubbleWindowClosing:(NSNotification*)notification; | 147 - (void)bubbleWindowClosing:(NSNotification*)notification; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 239 |
| 243 void ToolbarActionsBarBridge::ShowToolbarActionBubble( | 240 void ToolbarActionsBarBridge::ShowToolbarActionBubble( |
| 244 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) { | 241 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) { |
| 245 [controller_ createMessageBubble:std::move(bubble)]; | 242 [controller_ createMessageBubble:std::move(bubble)]; |
| 246 } | 243 } |
| 247 | 244 |
| 248 } // namespace | 245 } // namespace |
| 249 | 246 |
| 250 @implementation BrowserActionsController | 247 @implementation BrowserActionsController |
| 251 | 248 |
| 249 @synthesize maxWidth = maxWidth_; |
| 252 @synthesize containerView = containerView_; | 250 @synthesize containerView = containerView_; |
| 253 @synthesize browser = browser_; | 251 @synthesize browser = browser_; |
| 254 @synthesize isOverflow = isOverflow_; | 252 @synthesize isOverflow = isOverflow_; |
| 255 @synthesize activeBubble = activeBubble_; | 253 @synthesize activeBubble = activeBubble_; |
| 256 | 254 |
| 257 #pragma mark - | 255 #pragma mark - |
| 258 #pragma mark Public Methods | 256 #pragma mark Public Methods |
| 259 | 257 |
| 260 - (id)initWithBrowser:(Browser*)browser | 258 - (id)initWithBrowser:(Browser*)browser |
| 261 containerView:(BrowserActionsContainerView*)container | 259 containerView:(BrowserActionsContainerView*)container |
| 262 mainController:(BrowserActionsController*)mainController { | 260 mainController:(BrowserActionsController*)mainController { |
| 263 DCHECK(browser && container); | 261 DCHECK(browser && container); |
| 264 | 262 |
| 265 if ((self = [super init])) { | 263 if ((self = [super init])) { |
| 266 browser_ = browser; | 264 browser_ = browser; |
| 267 isOverflow_ = mainController != nil; | 265 isOverflow_ = mainController != nil; |
| 268 | 266 |
| 269 toolbarActionsBarBridge_.reset(new ToolbarActionsBarBridge(self)); | 267 toolbarActionsBarBridge_.reset(new ToolbarActionsBarBridge(self)); |
| 270 ToolbarActionsBar* mainBar = | 268 ToolbarActionsBar* mainBar = |
| 271 mainController ? [mainController toolbarActionsBar] : nullptr; | 269 mainController ? [mainController toolbarActionsBar] : nullptr; |
| 272 toolbarActionsBar_.reset( | 270 toolbarActionsBar_.reset( |
| 273 new ToolbarActionsBar(toolbarActionsBarBridge_.get(), | 271 new ToolbarActionsBar(toolbarActionsBarBridge_.get(), |
| 274 browser_, | 272 browser_, |
| 275 mainBar)); | 273 mainBar)); |
| 276 | 274 |
| 277 containerView_ = container; | 275 containerView_ = container; |
| 276 [containerView_ setMinWidth:toolbarActionsBar_->GetMinimumWidth()]; |
| 278 [containerView_ setPostsFrameChangedNotifications:YES]; | 277 [containerView_ setPostsFrameChangedNotifications:YES]; |
| 279 [[NSNotificationCenter defaultCenter] | 278 [[NSNotificationCenter defaultCenter] |
| 280 addObserver:self | 279 addObserver:self |
| 281 selector:@selector(containerFrameChanged:) | 280 selector:@selector(containerFrameChanged:) |
| 282 name:NSViewFrameDidChangeNotification | 281 name:NSViewFrameDidChangeNotification |
| 283 object:containerView_]; | 282 object:containerView_]; |
| 284 [[NSNotificationCenter defaultCenter] | 283 [[NSNotificationCenter defaultCenter] |
| 285 addObserver:self | 284 addObserver:self |
| 286 selector:@selector(containerDragStart:) | 285 selector:@selector(containerDragStart:) |
| 287 name:kBrowserActionGrippyDragStartedNotification | 286 name:kBrowserActionGrippyDragStartedNotification |
| (...skipping 19 matching lines...) Expand all Loading... |
| 307 addObserver:self | 306 addObserver:self |
| 308 selector:@selector(actionButtonDragFinished:) | 307 selector:@selector(actionButtonDragFinished:) |
| 309 name:kBrowserActionButtonDragEndNotification | 308 name:kBrowserActionButtonDragEndNotification |
| 310 object:nil]; | 309 object:nil]; |
| 311 | 310 |
| 312 if (isOverflow_) | 311 if (isOverflow_) |
| 313 toolbarActionsBar_->SetOverflowRowWidth(NSWidth([containerView_ frame])); | 312 toolbarActionsBar_->SetOverflowRowWidth(NSWidth([containerView_ frame])); |
| 314 | 313 |
| 315 buttons_.reset([[NSMutableArray alloc] init]); | 314 buttons_.reset([[NSMutableArray alloc] init]); |
| 316 toolbarActionsBar_->CreateActions(); | 315 toolbarActionsBar_->CreateActions(); |
| 317 [self updateGrippyCursors]; | |
| 318 [container setIsOverflow:isOverflow_]; | 316 [container setIsOverflow:isOverflow_]; |
| 319 | 317 |
| 320 focusedViewIndex_ = -1; | 318 focusedViewIndex_ = -1; |
| 321 } | 319 } |
| 322 | 320 |
| 323 return self; | 321 return self; |
| 324 } | 322 } |
| 325 | 323 |
| 326 - (void)dealloc { | 324 - (void)dealloc { |
| 327 [self browserWillBeDestroyed]; | 325 [self browserWillBeDestroyed]; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 [buttons_ count] - toolbarActionsBar_->GetIconCount() : -1; | 396 [buttons_ count] - toolbarActionsBar_->GetIconCount() : -1; |
| 399 [self setFocusedViewIndex:index]; | 397 [self setFocusedViewIndex:index]; |
| 400 } | 398 } |
| 401 } | 399 } |
| 402 | 400 |
| 403 - (gfx::Size)sizeForOverflowWidth:(int)maxWidth { | 401 - (gfx::Size)sizeForOverflowWidth:(int)maxWidth { |
| 404 toolbarActionsBar_->SetOverflowRowWidth(maxWidth); | 402 toolbarActionsBar_->SetOverflowRowWidth(maxWidth); |
| 405 return [self preferredSize]; | 403 return [self preferredSize]; |
| 406 } | 404 } |
| 407 | 405 |
| 406 - (void)updateMaxWidth { |
| 407 const CGFloat ownMaxWidth = toolbarActionsBar_->GetMaximumWidth(); |
| 408 containerView_.maxWidth = |
| 409 (maxWidth_ ? std::min(maxWidth_, ownMaxWidth) : ownMaxWidth); |
| 410 } |
| 411 |
| 412 - (void)setMaxWidth:(CGFloat)maxWidth { |
| 413 maxWidth_ = maxWidth; |
| 414 [self updateMaxWidth]; |
| 415 } |
| 416 |
| 408 - (void)addViewForAction:(ToolbarActionViewController*)action | 417 - (void)addViewForAction:(ToolbarActionViewController*)action |
| 409 withIndex:(NSUInteger)index { | 418 withIndex:(NSUInteger)index { |
| 410 NSRect buttonFrame = NSMakeRect(NSMaxX([containerView_ bounds]), | 419 NSRect buttonFrame = NSMakeRect(NSMaxX([containerView_ bounds]), |
| 411 0, | 420 0, |
| 412 ToolbarActionsBar::IconWidth(false), | 421 ToolbarActionsBar::IconWidth(false), |
| 413 ToolbarActionsBar::IconHeight()); | 422 ToolbarActionsBar::IconHeight()); |
| 414 BrowserActionButton* newButton = | 423 BrowserActionButton* newButton = |
| 415 [[[BrowserActionButton alloc] | 424 [[[BrowserActionButton alloc] |
| 416 initWithFrame:buttonFrame | 425 initWithFrame:buttonFrame |
| 417 viewController:action | 426 viewController:action |
| 418 controller:self] autorelease]; | 427 controller:self] autorelease]; |
| 419 [newButton setTarget:self]; | 428 [newButton setTarget:self]; |
| 420 [newButton setAction:@selector(browserActionClicked:)]; | 429 [newButton setAction:@selector(browserActionClicked:)]; |
| 421 [buttons_ insertObject:newButton atIndex:index]; | 430 [buttons_ insertObject:newButton atIndex:index]; |
| 422 | 431 |
| 432 [self updateMaxWidth]; |
| 423 [[NSNotificationCenter defaultCenter] | 433 [[NSNotificationCenter defaultCenter] |
| 424 addObserver:self | 434 addObserver:self |
| 425 selector:@selector(actionButtonDragging:) | 435 selector:@selector(actionButtonDragging:) |
| 426 name:kBrowserActionButtonDraggingNotification | 436 name:kBrowserActionButtonDraggingNotification |
| 427 object:newButton]; | 437 object:newButton]; |
| 428 | |
| 429 [containerView_ setMaxDesiredWidth:toolbarActionsBar_->GetMaximumWidth()]; | |
| 430 } | 438 } |
| 431 | 439 |
| 432 - (void)redraw { | 440 - (void)redraw { |
| 433 if (![self updateContainerVisibility]) | 441 if (![self updateContainerVisibility]) |
| 434 return; // Container is hidden; no need to update. | 442 return; // Container is hidden; no need to update. |
| 435 | 443 |
| 436 std::unique_ptr<ui::NinePartImageIds> highlight; | 444 std::unique_ptr<ui::NinePartImageIds> highlight; |
| 437 if (toolbarActionsBar_->is_highlighting()) { | 445 if (toolbarActionsBar_->is_highlighting()) { |
| 438 highlight.reset( | 446 highlight.reset( |
| 439 new ui::NinePartImageIds(IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT))); | 447 new ui::NinePartImageIds(IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT))); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 // |buttons_|, so make sure we retain a reference. | 506 // |buttons_|, so make sure we retain a reference. |
| 499 base::scoped_nsobject<BrowserActionButton> button( | 507 base::scoped_nsobject<BrowserActionButton> button( |
| 500 [[self buttonForId:action->GetId()] retain]); | 508 [[self buttonForId:action->GetId()] retain]); |
| 501 | 509 |
| 502 // Note: We remove the button from the view and the buttons list first because | 510 // Note: We remove the button from the view and the buttons list first because |
| 503 // destroying it (or calling -onRemoved) can cause redraws, and we don't want | 511 // destroying it (or calling -onRemoved) can cause redraws, and we don't want |
| 504 // to include it when the view is gone. | 512 // to include it when the view is gone. |
| 505 [button removeFromSuperview]; | 513 [button removeFromSuperview]; |
| 506 [buttons_ removeObject:button]; | 514 [buttons_ removeObject:button]; |
| 507 | 515 |
| 516 [self updateMaxWidth]; |
| 508 [button onRemoved]; | 517 [button onRemoved]; |
| 509 | |
| 510 [containerView_ setMaxDesiredWidth:toolbarActionsBar_->GetMaximumWidth()]; | |
| 511 } | 518 } |
| 512 | 519 |
| 513 - (void)removeAllViews { | 520 - (void)removeAllViews { |
| 514 for (BrowserActionButton* button in buttons_.get()) { | 521 for (BrowserActionButton* button in buttons_.get()) { |
| 515 [button removeFromSuperview]; | 522 [button removeFromSuperview]; |
| 516 [button onRemoved]; | 523 [button onRemoved]; |
| 517 } | 524 } |
| 518 [buttons_ removeAllObjects]; | 525 [buttons_ removeAllObjects]; |
| 519 } | 526 } |
| 520 | 527 |
| 521 - (void)resizeContainerToWidth:(CGFloat)width { | 528 - (void)resizeContainerToWidth:(CGFloat)width { |
| 522 // Cocoa goes a little crazy if we try and change animations while adjusting | 529 // Cocoa goes a little crazy if we try and change animations while adjusting |
| 523 // child frames (i.e., the buttons). If the toolbar is already animating, | 530 // child frames (i.e., the buttons). If the toolbar is already animating, |
| 524 // just jump to the new frame. (This typically only happens if someone is | 531 // just jump to the new frame. (This typically only happens if someone is |
| 525 // "spamming" a button to add/remove an action.) If the window isn't visible | 532 // "spamming" a button to add/remove an action.) If the window isn't visible |
| 526 // (for example it's in the process of being created), don't bother animating. | 533 // (for example it's in the process of being created), don't bother animating. |
| 527 BOOL animate = !toolbarActionsBar_->suppress_animation() && | 534 BOOL animate = !toolbarActionsBar_->suppress_animation() && |
| 528 ![containerView_ isAnimating] && [[containerView_ window] isVisible]; | 535 ![containerView_ isAnimating] && [[containerView_ window] isVisible]; |
| 529 [self updateContainerVisibility]; | 536 [self updateContainerVisibility]; |
| 530 [containerView_ resizeToWidth:width | 537 [containerView_ resizeToWidth:width |
| 531 animate:animate]; | 538 animate:animate]; |
| 532 [containerView_ setNeedsDisplay:YES]; | 539 [containerView_ setNeedsDisplay:YES]; |
| 533 | 540 |
| 534 if (!animate) { | 541 if (!animate) { |
| 535 [[NSNotificationCenter defaultCenter] | 542 [[NSNotificationCenter defaultCenter] |
| 536 postNotificationName:kBrowserActionVisibilityChangedNotification | 543 postNotificationName:kBrowserActionVisibilityChangedNotification |
| 537 object:self]; | 544 object:self]; |
| 538 } | 545 } |
| 539 [self redraw]; | 546 [self redraw]; |
| 540 [self updateGrippyCursors]; | 547 [[containerView_ window] invalidateCursorRectsForView:containerView_]; |
| 541 } | 548 } |
| 542 | 549 |
| 543 - (BOOL)updateContainerVisibility { | 550 - (BOOL)updateContainerVisibility { |
| 544 BOOL hidden = [buttons_ count] == 0; | 551 BOOL hidden = [buttons_ count] == 0; |
| 545 if ([containerView_ isHidden] != hidden) | 552 if ([containerView_ isHidden] != hidden) |
| 546 [containerView_ setHidden:hidden]; | 553 [containerView_ setHidden:hidden]; |
| 547 return !hidden; | 554 return !hidden; |
| 548 } | 555 } |
| 549 | 556 |
| 550 - (void)updateButtonOpacity { | 557 - (void)updateButtonOpacity { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 - (void)containerDragStart:(NSNotification*)notification { | 622 - (void)containerDragStart:(NSNotification*)notification { |
| 616 for (BrowserActionButton* button in buttons_.get()) { | 623 for (BrowserActionButton* button in buttons_.get()) { |
| 617 if ([button superview] != containerView_) { | 624 if ([button superview] != containerView_) { |
| 618 [button setAlphaValue:1.0]; | 625 [button setAlphaValue:1.0]; |
| 619 [containerView_ addSubview:button]; | 626 [containerView_ addSubview:button]; |
| 620 } | 627 } |
| 621 } | 628 } |
| 622 } | 629 } |
| 623 | 630 |
| 624 - (void)containerDragFinished:(NSNotification*)notification { | 631 - (void)containerDragFinished:(NSNotification*)notification { |
| 625 for (BrowserActionButton* button in buttons_.get()) { | 632 toolbarActionsBar_->OnResizeComplete(NSWidth(containerView_.bounds)); |
| 626 NSRect buttonFrame = [button frame]; | 633 [[containerView_ window] invalidateCursorRectsForView:containerView_]; |
| 627 if (NSContainsRect([containerView_ bounds], buttonFrame)) | |
| 628 continue; | |
| 629 | |
| 630 CGFloat intersectionWidth = | |
| 631 NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); | |
| 632 // Hide the button if it's not "mostly" visible. "Mostly" here equates to | |
| 633 // having three or fewer pixels hidden. | |
| 634 if (([containerView_ grippyPinned] && intersectionWidth > 0) || | |
| 635 (intersectionWidth <= NSWidth(buttonFrame) - 3.0)) { | |
| 636 [button setAlphaValue:0.0]; | |
| 637 [button removeFromSuperview]; | |
| 638 } | |
| 639 } | |
| 640 | |
| 641 toolbarActionsBar_->OnResizeComplete( | |
| 642 toolbarActionsBar_->IconCountToWidth([self visibleButtonCount])); | |
| 643 | |
| 644 [self updateGrippyCursors]; | |
| 645 [self resizeContainerToWidth:toolbarActionsBar_->GetPreferredSize().width()]; | |
| 646 } | 634 } |
| 647 | 635 |
| 648 - (void)containerAnimationEnded:(NSNotification*)notification { | 636 - (void)containerAnimationEnded:(NSNotification*)notification { |
| 649 if (![containerView_ isAnimating]) | 637 if (![containerView_ isAnimating]) |
| 650 toolbarActionsBar_->OnAnimationEnded(); | 638 toolbarActionsBar_->OnAnimationEnded(); |
| 651 } | 639 } |
| 652 | 640 |
| 653 - (void)containerKeyEvent:(NSNotification*)notification { | 641 - (void)containerKeyEvent:(NSNotification*)notification { |
| 654 DCHECK(isOverflow_); // We only manually process key events in overflow. | 642 DCHECK(isOverflow_); // We only manually process key events in overflow. |
| 655 | 643 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 if (!NSEqualRects(buttonFrame, [button frameAfterAnimation])) { | 767 if (!NSEqualRects(buttonFrame, [button frameAfterAnimation])) { |
| 780 [button setFrame:buttonFrame | 768 [button setFrame:buttonFrame |
| 781 animate:!toolbarActionsBar_->suppress_animation() && !isOverflow_]; | 769 animate:!toolbarActionsBar_->suppress_animation() && !isOverflow_]; |
| 782 } | 770 } |
| 783 } | 771 } |
| 784 | 772 |
| 785 - (BOOL)browserActionClicked:(BrowserActionButton*)button { | 773 - (BOOL)browserActionClicked:(BrowserActionButton*)button { |
| 786 return [button viewController]->ExecuteAction(true); | 774 return [button viewController]->ExecuteAction(true); |
| 787 } | 775 } |
| 788 | 776 |
| 789 - (void)updateGrippyCursors { | |
| 790 BOOL canClose = [self visibleButtonCount] > 0; | |
| 791 BOOL canOpen = toolbarActionsBar_->GetIconCount() != [buttons_ count]; | |
| 792 [containerView_ | |
| 793 setCanDragLeft:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() | |
| 794 ? canClose | |
| 795 : canOpen]; | |
| 796 [containerView_ | |
| 797 setCanDragRight:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() | |
| 798 ? canOpen | |
| 799 : canClose]; | |
| 800 [[containerView_ window] invalidateCursorRectsForView:containerView_]; | |
| 801 } | |
| 802 | |
| 803 - (ToolbarController*)toolbarController { | 777 - (ToolbarController*)toolbarController { |
| 804 return [[BrowserWindowController browserWindowControllerForWindow: | 778 return [[BrowserWindowController browserWindowControllerForWindow: |
| 805 browser_->window()->GetNativeWindow()] toolbarController]; | 779 browser_->window()->GetNativeWindow()] toolbarController]; |
| 806 } | 780 } |
| 807 | 781 |
| 808 - (void)createMessageBubble: | 782 - (void)createMessageBubble: |
| 809 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate { | 783 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate { |
| 810 NSView* anchorView = nil; | 784 NSView* anchorView = nil; |
| 811 BOOL anchoredToAction = NO; | 785 BOOL anchoredToAction = NO; |
| 812 if (!delegate->GetAnchorActionId().empty()) { | 786 if (!delegate->GetAnchorActionId().empty()) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 } | 825 } |
| 852 | 826 |
| 853 #pragma mark - | 827 #pragma mark - |
| 854 #pragma mark Testing Methods | 828 #pragma mark Testing Methods |
| 855 | 829 |
| 856 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index { | 830 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index { |
| 857 return index < [buttons_ count] ? [buttons_ objectAtIndex:index] : nil; | 831 return index < [buttons_ count] ? [buttons_ objectAtIndex:index] : nil; |
| 858 } | 832 } |
| 859 | 833 |
| 860 @end | 834 @end |
| OLD | NEW |