| 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 <cmath> | |
| 8 #include <string> | 7 #include <string> |
| 9 | 8 |
| 10 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 11 #include "chrome/browser/profiles/profile.h" | |
| 12 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| 13 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h" | 11 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h" |
| 14 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" | 12 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" |
| 15 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h" | 13 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h" |
| 16 #import "chrome/browser/ui/cocoa/image_button_cell.h" | 14 #import "chrome/browser/ui/cocoa/image_button_cell.h" |
| 17 #import "chrome/browser/ui/cocoa/menu_button.h" | 15 #import "chrome/browser/ui/cocoa/menu_button.h" |
| 18 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 19 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" | 17 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" |
| 20 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" | 18 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" |
| 21 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" | 19 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 51 // Removes the view for the given |action| from the ccontainer. | 49 // Removes the view for the given |action| from the ccontainer. |
| 52 - (void)removeViewForAction:(ToolbarActionViewController*)action; | 50 - (void)removeViewForAction:(ToolbarActionViewController*)action; |
| 53 | 51 |
| 54 // Removes views for all actions. | 52 // Removes views for all actions. |
| 55 - (void)removeAllViews; | 53 - (void)removeAllViews; |
| 56 | 54 |
| 57 // Redraws the BrowserActionsContainerView and updates the button order to match | 55 // Redraws the BrowserActionsContainerView and updates the button order to match |
| 58 // the order in the ToolbarActionsBar. | 56 // the order in the ToolbarActionsBar. |
| 59 - (void)redraw; | 57 - (void)redraw; |
| 60 | 58 |
| 61 // Resizes the container to the specified |width|, optionally animating. | 59 // Resizes the container to the specified |width|, and animates according to |
| 62 - (void)resizeContainerToWidth:(CGFloat)width | 60 // the ToolbarActionsBar. |
| 63 shouldAnimate:(BOOL)animate; | 61 - (void)resizeContainerToWidth:(CGFloat)width; |
| 64 | 62 |
| 65 // Sets the container to be either hidden or visible based on whether there are | 63 // Sets the container to be either hidden or visible based on whether there are |
| 66 // any actions to show. | 64 // any actions to show. |
| 67 // Returns whether the container is visible. | 65 // Returns whether the container is visible. |
| 68 - (BOOL)updateContainerVisibility; | 66 - (BOOL)updateContainerVisibility; |
| 69 | 67 |
| 70 // During container resizing, buttons become more transparent as they are pushed | 68 // During container resizing, buttons become more transparent as they are pushed |
| 71 // off the screen. This method updates each button's opacity determined by the | 69 // off the screen. This method updates each button's opacity determined by the |
| 72 // position of the button. | 70 // position of the button. |
| 73 - (void)updateButtonOpacity; | 71 - (void)updateButtonOpacity; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 95 - (void)actionButtonDragging:(NSNotification*)notification; | 93 - (void)actionButtonDragging:(NSNotification*)notification; |
| 96 | 94 |
| 97 // Updates the position of the Browser Actions within the container. This fires | 95 // Updates the position of the Browser Actions within the container. This fires |
| 98 // when _any_ Browser Action button is done dragging to keep all open windows in | 96 // when _any_ Browser Action button is done dragging to keep all open windows in |
| 99 // sync visually. | 97 // sync visually. |
| 100 - (void)actionButtonDragFinished:(NSNotification*)notification; | 98 - (void)actionButtonDragFinished:(NSNotification*)notification; |
| 101 | 99 |
| 102 // Moves the given button both visually and within the toolbar model to the | 100 // Moves the given button both visually and within the toolbar model to the |
| 103 // specified index. | 101 // specified index. |
| 104 - (void)moveButton:(BrowserActionButton*)button | 102 - (void)moveButton:(BrowserActionButton*)button |
| 105 toIndex:(NSUInteger)index | 103 toIndex:(NSUInteger)index; |
| 106 animate:(BOOL)animate; | |
| 107 | 104 |
| 108 // Handles clicks for BrowserActionButtons. | 105 // Handles clicks for BrowserActionButtons. |
| 109 - (BOOL)browserActionClicked:(BrowserActionButton*)button; | 106 - (BOOL)browserActionClicked:(BrowserActionButton*)button; |
| 110 | 107 |
| 111 // The reason |frame| is specified in these chevron functions is because the | 108 // The reason |frame| is specified in these chevron functions is because the |
| 112 // container may be animating and the end frame of the animation should be | 109 // container may be animating and the end frame of the animation should be |
| 113 // passed instead of the current frame (which may be off and cause the chevron | 110 // passed instead of the current frame (which may be off and cause the chevron |
| 114 // to jump at the end of its animation). | 111 // to jump at the end of its animation). |
| 115 | 112 |
| 116 // Shows the overflow chevron button depending on whether there are any hidden | 113 // Shows the overflow chevron button depending on whether there are any hidden |
| 117 // extensions within the frame given. | 114 // extensions within the frame given. |
| 118 - (void)showChevronIfNecessaryInFrame:(NSRect)frame animate:(BOOL)animate; | 115 - (void)showChevronIfNecessaryInFrame:(NSRect)frame; |
| 119 | 116 |
| 120 // Moves the chevron to its correct position within |frame|. | 117 // Moves the chevron to its correct position within |frame|. |
| 121 - (void)updateChevronPositionInFrame:(NSRect)frame; | 118 - (void)updateChevronPositionInFrame:(NSRect)frame; |
| 122 | 119 |
| 123 // Shows or hides the chevron, animating as specified by |animate|. | 120 // Shows or hides the chevron in the given |frame|. |
| 124 - (void)setChevronHidden:(BOOL)hidden | 121 - (void)setChevronHidden:(BOOL)hidden |
| 125 inFrame:(NSRect)frame | 122 inFrame:(NSRect)frame; |
| 126 animate:(BOOL)animate; | |
| 127 | 123 |
| 128 // Handles when a menu item within the chevron overflow menu is selected. | 124 // Handles when a menu item within the chevron overflow menu is selected. |
| 129 - (void)chevronItemSelected:(id)menuItem; | 125 - (void)chevronItemSelected:(id)menuItem; |
| 130 | 126 |
| 131 // Updates the container's grippy cursor based on the number of hidden buttons. | 127 // Updates the container's grippy cursor based on the number of hidden buttons. |
| 132 - (void)updateGrippyCursors; | 128 - (void)updateGrippyCursors; |
| 133 | 129 |
| 134 - (ToolbarActionsBar*)toolbarActionsBar; | |
| 135 | |
| 136 @end | 130 @end |
| 137 | 131 |
| 138 namespace { | 132 namespace { |
| 139 | 133 |
| 140 // A bridge between the ToolbarActionsBar and the BrowserActionsController. | 134 // A bridge between the ToolbarActionsBar and the BrowserActionsController. |
| 141 class ToolbarActionsBarBridge : public ToolbarActionsBarDelegate { | 135 class ToolbarActionsBarBridge : public ToolbarActionsBarDelegate { |
| 142 public: | 136 public: |
| 143 explicit ToolbarActionsBarBridge(BrowserActionsController* controller); | 137 explicit ToolbarActionsBarBridge(BrowserActionsController* controller); |
| 144 ~ToolbarActionsBarBridge() override; | 138 ~ToolbarActionsBarBridge() override; |
| 145 | 139 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 [controller_ removeAllViews]; | 184 [controller_ removeAllViews]; |
| 191 } | 185 } |
| 192 | 186 |
| 193 void ToolbarActionsBarBridge::Redraw(bool order_changed) { | 187 void ToolbarActionsBarBridge::Redraw(bool order_changed) { |
| 194 [controller_ redraw]; | 188 [controller_ redraw]; |
| 195 } | 189 } |
| 196 | 190 |
| 197 void ToolbarActionsBarBridge::ResizeAndAnimate(gfx::Tween::Type tween_type, | 191 void ToolbarActionsBarBridge::ResizeAndAnimate(gfx::Tween::Type tween_type, |
| 198 int target_width, | 192 int target_width, |
| 199 bool suppress_chevron) { | 193 bool suppress_chevron) { |
| 200 [controller_ resizeContainerToWidth:target_width | 194 [controller_ resizeContainerToWidth:target_width]; |
| 201 shouldAnimate:![controller_ toolbarActionsBar]-> | |
| 202 suppress_animation()]; | |
| 203 } | 195 } |
| 204 | 196 |
| 205 void ToolbarActionsBarBridge::SetChevronVisibility(bool chevron_visible) { | 197 void ToolbarActionsBarBridge::SetChevronVisibility(bool chevron_visible) { |
| 206 [controller_ setChevronHidden:!chevron_visible | 198 [controller_ setChevronHidden:!chevron_visible |
| 207 inFrame:[[controller_ containerView] frame] | 199 inFrame:[[controller_ containerView] frame]]; |
| 208 animate:YES]; | |
| 209 } | 200 } |
| 210 | 201 |
| 211 int ToolbarActionsBarBridge::GetWidth() const { | 202 int ToolbarActionsBarBridge::GetWidth() const { |
| 212 return NSWidth([[controller_ containerView] frame]); | 203 return NSWidth([[controller_ containerView] frame]); |
| 213 } | 204 } |
| 214 | 205 |
| 215 bool ToolbarActionsBarBridge::IsAnimating() const { | 206 bool ToolbarActionsBarBridge::IsAnimating() const { |
| 216 return false; | 207 return false; |
| 217 } | 208 } |
| 218 | 209 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 235 | 226 |
| 236 #pragma mark - | 227 #pragma mark - |
| 237 #pragma mark Public Methods | 228 #pragma mark Public Methods |
| 238 | 229 |
| 239 - (id)initWithBrowser:(Browser*)browser | 230 - (id)initWithBrowser:(Browser*)browser |
| 240 containerView:(BrowserActionsContainerView*)container { | 231 containerView:(BrowserActionsContainerView*)container { |
| 241 DCHECK(browser && container); | 232 DCHECK(browser && container); |
| 242 | 233 |
| 243 if ((self = [super init])) { | 234 if ((self = [super init])) { |
| 244 browser_ = browser; | 235 browser_ = browser; |
| 245 profile_ = browser->profile(); | |
| 246 | 236 |
| 247 toolbarActionsBarBridge_.reset(new ToolbarActionsBarBridge(self)); | 237 toolbarActionsBarBridge_.reset(new ToolbarActionsBarBridge(self)); |
| 248 toolbarActionsBar_.reset( | 238 toolbarActionsBar_.reset( |
| 249 new ToolbarActionsBar(toolbarActionsBarBridge_.get(), browser_, false)); | 239 new ToolbarActionsBar(toolbarActionsBarBridge_.get(), browser_, false)); |
| 250 | 240 |
| 251 containerView_ = container; | 241 containerView_ = container; |
| 252 [containerView_ setPostsFrameChangedNotifications:YES]; | 242 [containerView_ setPostsFrameChangedNotifications:YES]; |
| 253 [[NSNotificationCenter defaultCenter] | 243 [[NSNotificationCenter defaultCenter] |
| 254 addObserver:self | 244 addObserver:self |
| 255 selector:@selector(containerFrameChanged:) | 245 selector:@selector(containerFrameChanged:) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 274 object:nil]; | 264 object:nil]; |
| 275 | 265 |
| 276 suppressChevron_ = NO; | 266 suppressChevron_ = NO; |
| 277 chevronAnimation_.reset([[NSViewAnimation alloc] init]); | 267 chevronAnimation_.reset([[NSViewAnimation alloc] init]); |
| 278 [chevronAnimation_ gtm_setDuration:kAnimationDuration | 268 [chevronAnimation_ gtm_setDuration:kAnimationDuration |
| 279 eventMask:NSLeftMouseUpMask]; | 269 eventMask:NSLeftMouseUpMask]; |
| 280 [chevronAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; | 270 [chevronAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; |
| 281 | 271 |
| 282 buttons_.reset([[NSMutableArray alloc] init]); | 272 buttons_.reset([[NSMutableArray alloc] init]); |
| 283 toolbarActionsBar_->CreateActions(); | 273 toolbarActionsBar_->CreateActions(); |
| 284 if ([buttons_ count] != 0) | 274 [self showChevronIfNecessaryInFrame:[containerView_ frame]]; |
| 285 [self resizeContainerAndAnimate:NO]; | |
| 286 [self showChevronIfNecessaryInFrame:[containerView_ frame] animate:NO]; | |
| 287 [self updateGrippyCursors]; | 275 [self updateGrippyCursors]; |
| 288 [container setResizable:YES]; | 276 [container setResizable:YES]; |
| 289 } | 277 } |
| 290 | 278 |
| 291 return self; | 279 return self; |
| 292 } | 280 } |
| 293 | 281 |
| 294 - (void)dealloc { | 282 - (void)dealloc { |
| 295 // Explicitly destroy the ToolbarActionsBar so all buttons get removed with a | 283 // Explicitly destroy the ToolbarActionsBar so all buttons get removed with a |
| 296 // valid BrowserActionsController, and so we can verify state before | 284 // valid BrowserActionsController, and so we can verify state before |
| (...skipping 14 matching lines...) Expand all Loading... |
| 311 return [buttons_ count]; | 299 return [buttons_ count]; |
| 312 } | 300 } |
| 313 | 301 |
| 314 - (NSUInteger)visibleButtonCount { | 302 - (NSUInteger)visibleButtonCount { |
| 315 NSUInteger visibleCount = 0; | 303 NSUInteger visibleCount = 0; |
| 316 for (BrowserActionButton* button in buttons_.get()) | 304 for (BrowserActionButton* button in buttons_.get()) |
| 317 visibleCount += [button superview] == containerView_; | 305 visibleCount += [button superview] == containerView_; |
| 318 return visibleCount; | 306 return visibleCount; |
| 319 } | 307 } |
| 320 | 308 |
| 321 - (void)resizeContainerAndAnimate:(BOOL)animate { | |
| 322 [self resizeContainerToWidth:toolbarActionsBar_->GetPreferredSize().width() | |
| 323 shouldAnimate:animate]; | |
| 324 } | |
| 325 | |
| 326 - (CGFloat)savedWidth { | 309 - (CGFloat)savedWidth { |
| 327 return toolbarActionsBar_->GetPreferredSize().width(); | 310 return toolbarActionsBar_->GetPreferredSize().width(); |
| 328 } | 311 } |
| 329 | 312 |
| 330 - (NSPoint)popupPointForId:(const std::string&)id { | 313 - (NSPoint)popupPointForId:(const std::string&)id { |
| 331 BrowserActionButton* button = [self buttonForId:id]; | 314 BrowserActionButton* button = [self buttonForId:id]; |
| 332 if (!button) | 315 if (!button) |
| 333 return NSZeroPoint; | 316 return NSZeroPoint; |
| 334 | 317 |
| 335 NSRect bounds; | 318 NSRect bounds; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 toolbarActionsBar_->toolbar_actions(); | 419 toolbarActionsBar_->toolbar_actions(); |
| 437 for (NSUInteger i = 0; i < [buttons_ count]; ++i) { | 420 for (NSUInteger i = 0; i < [buttons_ count]; ++i) { |
| 438 if ([[buttons_ objectAtIndex:i] viewController] != toolbar_actions[i]) { | 421 if ([[buttons_ objectAtIndex:i] viewController] != toolbar_actions[i]) { |
| 439 size_t j = i + 1; | 422 size_t j = i + 1; |
| 440 while (toolbar_actions[i] != [[buttons_ objectAtIndex:j] viewController]) | 423 while (toolbar_actions[i] != [[buttons_ objectAtIndex:j] viewController]) |
| 441 ++j; | 424 ++j; |
| 442 [buttons_ exchangeObjectAtIndex:i withObjectAtIndex: j]; | 425 [buttons_ exchangeObjectAtIndex:i withObjectAtIndex: j]; |
| 443 } | 426 } |
| 444 } | 427 } |
| 445 | 428 |
| 446 BOOL animate = !toolbarActionsBar_->suppress_animation(); | 429 [self showChevronIfNecessaryInFrame:[containerView_ frame]]; |
| 447 [self showChevronIfNecessaryInFrame:[containerView_ frame] animate:animate]; | |
| 448 for (NSUInteger i = 0; i < [buttons_ count]; ++i) { | 430 for (NSUInteger i = 0; i < [buttons_ count]; ++i) { |
| 449 if (![[buttons_ objectAtIndex:i] isBeingDragged]) | 431 if (![[buttons_ objectAtIndex:i] isBeingDragged]) |
| 450 [self moveButton:[buttons_ objectAtIndex:i] | 432 [self moveButton:[buttons_ objectAtIndex:i] toIndex:i]; |
| 451 toIndex:i | |
| 452 animate:animate]; | |
| 453 } | 433 } |
| 454 } | 434 } |
| 455 | 435 |
| 456 - (void)removeViewForAction:(ToolbarActionViewController*)action { | 436 - (void)removeViewForAction:(ToolbarActionViewController*)action { |
| 457 BrowserActionButton* button = [self buttonForId:action->GetId()]; | 437 BrowserActionButton* button = [self buttonForId:action->GetId()]; |
| 458 | 438 |
| 459 [button removeFromSuperview]; | 439 [button removeFromSuperview]; |
| 460 [button onRemoved]; | 440 [button onRemoved]; |
| 461 [buttons_ removeObject:button]; | 441 [buttons_ removeObject:button]; |
| 462 } | 442 } |
| 463 | 443 |
| 464 - (void)removeAllViews { | 444 - (void)removeAllViews { |
| 465 for (BrowserActionButton* button in buttons_.get()) { | 445 for (BrowserActionButton* button in buttons_.get()) { |
| 466 [button removeFromSuperview]; | 446 [button removeFromSuperview]; |
| 467 [button onRemoved]; | 447 [button onRemoved]; |
| 468 } | 448 } |
| 469 [buttons_ removeAllObjects]; | 449 [buttons_ removeAllObjects]; |
| 470 } | 450 } |
| 471 | 451 |
| 472 - (void)resizeContainerToWidth:(CGFloat)width | 452 - (void)resizeContainerToWidth:(CGFloat)width { |
| 473 shouldAnimate:(BOOL)animate { | 453 BOOL animate = !toolbarActionsBar_->suppress_animation(); |
| 474 [self updateContainerVisibility]; | 454 [self updateContainerVisibility]; |
| 475 [containerView_ setMaxWidth: | 455 [containerView_ setMaxWidth: |
| 476 toolbarActionsBar_->IconCountToWidth([self buttonCount])]; | 456 toolbarActionsBar_->IconCountToWidth([self buttonCount])]; |
| 477 [containerView_ resizeToWidth:width | 457 [containerView_ resizeToWidth:width |
| 478 animate:animate]; | 458 animate:animate]; |
| 479 NSRect frame = animate ? [containerView_ animationEndFrame] : | 459 NSRect frame = animate ? [containerView_ animationEndFrame] : |
| 480 [containerView_ frame]; | 460 [containerView_ frame]; |
| 481 | 461 |
| 482 [self showChevronIfNecessaryInFrame:frame animate:animate]; | 462 [self showChevronIfNecessaryInFrame:frame]; |
| 483 | 463 |
| 484 [containerView_ setNeedsDisplay:YES]; | 464 [containerView_ setNeedsDisplay:YES]; |
| 485 | 465 |
| 486 if (!animate) { | 466 if (!animate) { |
| 487 [[NSNotificationCenter defaultCenter] | 467 [[NSNotificationCenter defaultCenter] |
| 488 postNotificationName:kBrowserActionVisibilityChangedNotification | 468 postNotificationName:kBrowserActionVisibilityChangedNotification |
| 489 object:self]; | 469 object:self]; |
| 490 } | 470 } |
| 491 [self redraw]; | 471 [self redraw]; |
| 492 } | 472 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 return nil; | 504 return nil; |
| 525 } | 505 } |
| 526 | 506 |
| 527 - (void)containerFrameChanged:(NSNotification*)notification { | 507 - (void)containerFrameChanged:(NSNotification*)notification { |
| 528 [self updateButtonOpacity]; | 508 [self updateButtonOpacity]; |
| 529 [[containerView_ window] invalidateCursorRectsForView:containerView_]; | 509 [[containerView_ window] invalidateCursorRectsForView:containerView_]; |
| 530 [self updateChevronPositionInFrame:[containerView_ frame]]; | 510 [self updateChevronPositionInFrame:[containerView_ frame]]; |
| 531 } | 511 } |
| 532 | 512 |
| 533 - (void)containerDragStart:(NSNotification*)notification { | 513 - (void)containerDragStart:(NSNotification*)notification { |
| 534 [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES]; | 514 [self setChevronHidden:YES inFrame:[containerView_ frame]]; |
| 535 for (BrowserActionButton* button in buttons_.get()) { | 515 for (BrowserActionButton* button in buttons_.get()) { |
| 536 if ([button superview] != containerView_) { | 516 if ([button superview] != containerView_) { |
| 537 [button setAlphaValue:1.0]; | 517 [button setAlphaValue:1.0]; |
| 538 [containerView_ addSubview:button]; | 518 [containerView_ addSubview:button]; |
| 539 } | 519 } |
| 540 } | 520 } |
| 541 } | 521 } |
| 542 | 522 |
| 543 - (void)containerDragFinished:(NSNotification*)notification { | 523 - (void)containerDragFinished:(NSNotification*)notification { |
| 544 for (BrowserActionButton* button in buttons_.get()) { | 524 for (BrowserActionButton* button in buttons_.get()) { |
| 545 NSRect buttonFrame = [button frame]; | 525 NSRect buttonFrame = [button frame]; |
| 546 if (NSContainsRect([containerView_ bounds], buttonFrame)) | 526 if (NSContainsRect([containerView_ bounds], buttonFrame)) |
| 547 continue; | 527 continue; |
| 548 | 528 |
| 549 CGFloat intersectionWidth = | 529 CGFloat intersectionWidth = |
| 550 NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); | 530 NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); |
| 551 // Pad the threshold by 5 pixels in order to have the buttons hide more | 531 // Pad the threshold by 5 pixels in order to have the buttons hide more |
| 552 // easily. | 532 // easily. |
| 553 if (([containerView_ grippyPinned] && intersectionWidth > 0) || | 533 if (([containerView_ grippyPinned] && intersectionWidth > 0) || |
| 554 (intersectionWidth <= (NSWidth(buttonFrame) / 2) + 5.0)) { | 534 (intersectionWidth <= (NSWidth(buttonFrame) / 2) + 5.0)) { |
| 555 [button setAlphaValue:0.0]; | 535 [button setAlphaValue:0.0]; |
| 556 [button removeFromSuperview]; | 536 [button removeFromSuperview]; |
| 557 } | 537 } |
| 558 } | 538 } |
| 559 | 539 |
| 560 toolbarActionsBar_->OnResizeComplete( | 540 toolbarActionsBar_->OnResizeComplete( |
| 561 toolbarActionsBar_->IconCountToWidth([self visibleButtonCount])); | 541 toolbarActionsBar_->IconCountToWidth([self visibleButtonCount])); |
| 562 | 542 |
| 563 [self updateGrippyCursors]; | 543 [self updateGrippyCursors]; |
| 564 | 544 [self resizeContainerToWidth:toolbarActionsBar_->GetPreferredSize().width()]; |
| 565 [[NSNotificationCenter defaultCenter] | |
| 566 postNotificationName:kBrowserActionGrippyDragFinishedNotification | |
| 567 object:self]; | |
| 568 } | 545 } |
| 569 | 546 |
| 570 - (void)actionButtonDragging:(NSNotification*)notification { | 547 - (void)actionButtonDragging:(NSNotification*)notification { |
| 571 suppressChevron_ = YES; | 548 suppressChevron_ = YES; |
| 572 if (![self chevronIsHidden]) | 549 if (![self chevronIsHidden]) |
| 573 [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES]; | 550 [self setChevronHidden:YES inFrame:[containerView_ frame]]; |
| 574 | 551 |
| 575 // Determine what index the dragged button should lie in, alter the model and | 552 // Determine what index the dragged button should lie in, alter the model and |
| 576 // reposition the buttons. | 553 // reposition the buttons. |
| 577 CGFloat dragThreshold = ToolbarActionsBar::IconWidth(false) / 2; | 554 CGFloat dragThreshold = ToolbarActionsBar::IconWidth(false) / 2; |
| 578 BrowserActionButton* draggedButton = [notification object]; | 555 BrowserActionButton* draggedButton = [notification object]; |
| 579 NSRect draggedButtonFrame = [draggedButton frame]; | 556 NSRect draggedButtonFrame = [draggedButton frame]; |
| 580 | 557 |
| 581 NSUInteger index = 0; | 558 NSUInteger index = 0; |
| 582 std::vector<ToolbarActionViewController*> toolbar_actions = | 559 for (BrowserActionButton* button in buttons_.get()) { |
| 583 toolbarActionsBar_->toolbar_actions(); | |
| 584 for (ToolbarActionViewController* action : toolbar_actions) { | |
| 585 BrowserActionButton* button = [self buttonForId:(action->GetId())]; | |
| 586 CGFloat intersectionWidth = | 560 CGFloat intersectionWidth = |
| 587 NSWidth(NSIntersectionRect(draggedButtonFrame, [button frame])); | 561 NSWidth(NSIntersectionRect(draggedButtonFrame, [button frame])); |
| 588 | 562 |
| 589 if (intersectionWidth > dragThreshold && button != draggedButton && | 563 if (intersectionWidth > dragThreshold && button != draggedButton && |
| 590 ![button isAnimating] && index < [self visibleButtonCount]) { | 564 ![button isAnimating] && index < [self visibleButtonCount]) { |
| 591 toolbarActionsBar_->OnDragDrop( | 565 toolbarActionsBar_->OnDragDrop( |
| 592 [buttons_ indexOfObject:draggedButton], | 566 [buttons_ indexOfObject:draggedButton], |
| 593 index, | 567 index, |
| 594 ToolbarActionsBar::DRAG_TO_SAME); | 568 ToolbarActionsBar::DRAG_TO_SAME); |
| 595 return; | 569 return; |
| 596 } | 570 } |
| 597 ++index; | 571 ++index; |
| 598 } | 572 } |
| 599 } | 573 } |
| 600 | 574 |
| 601 - (void)actionButtonDragFinished:(NSNotification*)notification { | 575 - (void)actionButtonDragFinished:(NSNotification*)notification { |
| 602 suppressChevron_ = NO; | 576 suppressChevron_ = NO; |
| 603 [self redraw]; | 577 [self redraw]; |
| 604 } | 578 } |
| 605 | 579 |
| 606 - (void)moveButton:(BrowserActionButton*)button | 580 - (void)moveButton:(BrowserActionButton*)button |
| 607 toIndex:(NSUInteger)index | 581 toIndex:(NSUInteger)index { |
| 608 animate:(BOOL)animate { | |
| 609 const ToolbarActionsBar::PlatformSettings& platformSettings = | 582 const ToolbarActionsBar::PlatformSettings& platformSettings = |
| 610 toolbarActionsBar_->platform_settings(); | 583 toolbarActionsBar_->platform_settings(); |
| 611 CGFloat xOffset = platformSettings.left_padding + | 584 CGFloat xOffset = platformSettings.left_padding + |
| 612 (index * ToolbarActionsBar::IconWidth(true)); | 585 (index * ToolbarActionsBar::IconWidth(true)); |
| 613 NSRect buttonFrame = [button frame]; | 586 NSRect buttonFrame = [button frame]; |
| 614 buttonFrame.origin.x = xOffset; | 587 buttonFrame.origin.x = xOffset; |
| 615 [button setFrame:buttonFrame animate:animate]; | 588 [button setFrame:buttonFrame |
| 589 animate:!toolbarActionsBar_->suppress_animation()]; |
| 616 | 590 |
| 617 if (index < toolbarActionsBar_->GetIconCount()) { | 591 if (index < toolbarActionsBar_->GetIconCount()) { |
| 618 // Make sure the button is within the visible container. | 592 // Make sure the button is within the visible container. |
| 619 if ([button superview] != containerView_) { | 593 if ([button superview] != containerView_) { |
| 620 // We add the subview under the sibling views so that when it "slides in", | 594 // We add the subview under the sibling views so that when it "slides in", |
| 621 // it does so under its neighbors. | 595 // it does so under its neighbors. |
| 622 [containerView_ addSubview:button | 596 [containerView_ addSubview:button |
| 623 positioned:NSWindowBelow | 597 positioned:NSWindowBelow |
| 624 relativeTo:nil]; | 598 relativeTo:nil]; |
| 625 } | 599 } |
| 626 // We need to set the alpha value in case the container has resized. | 600 // We need to set the alpha value in case the container has resized. |
| 627 [button setAlphaValue:1.0]; | 601 [button setAlphaValue:1.0]; |
| 628 } else if ([button superview] == containerView_) { | 602 } else if ([button superview] == containerView_) { |
| 629 [button removeFromSuperview]; | 603 [button removeFromSuperview]; |
| 630 [button setAlphaValue:0.0]; | 604 [button setAlphaValue:0.0]; |
| 631 } | 605 } |
| 632 } | 606 } |
| 633 | 607 |
| 634 - (BOOL)browserActionClicked:(BrowserActionButton*)button | 608 - (BOOL)browserActionClicked:(BrowserActionButton*)button { |
| 635 shouldGrant:(BOOL)shouldGrant { | 609 return [button viewController]->ExecuteAction(true); |
| 636 return [button viewController]->ExecuteAction(shouldGrant); | |
| 637 } | 610 } |
| 638 | 611 |
| 639 - (BOOL)browserActionClicked:(BrowserActionButton*)button { | 612 - (void)showChevronIfNecessaryInFrame:(NSRect)frame { |
| 640 return [self browserActionClicked:button | |
| 641 shouldGrant:YES]; | |
| 642 } | |
| 643 | |
| 644 - (void)showChevronIfNecessaryInFrame:(NSRect)frame animate:(BOOL)animate { | |
| 645 bool hidden = suppressChevron_ || | 613 bool hidden = suppressChevron_ || |
| 646 toolbarActionsBar_->GetIconCount() == [self buttonCount]; | 614 toolbarActionsBar_->GetIconCount() == [self buttonCount]; |
| 647 [self setChevronHidden:hidden | 615 [self setChevronHidden:hidden inFrame:frame]; |
| 648 inFrame:frame | |
| 649 animate:animate]; | |
| 650 } | 616 } |
| 651 | 617 |
| 652 - (void)updateChevronPositionInFrame:(NSRect)frame { | 618 - (void)updateChevronPositionInFrame:(NSRect)frame { |
| 653 CGFloat xPos = NSWidth(frame) - kChevronWidth; | 619 CGFloat xPos = NSWidth(frame) - kChevronWidth; |
| 654 NSRect buttonFrame = NSMakeRect(xPos, | 620 NSRect buttonFrame = NSMakeRect(xPos, |
| 655 kBrowserActionOriginYOffset, | 621 kBrowserActionOriginYOffset, |
| 656 kChevronWidth, | 622 kChevronWidth, |
| 657 ToolbarActionsBar::IconHeight()); | 623 ToolbarActionsBar::IconHeight()); |
| 658 [chevronAnimation_ stopAnimation]; | 624 [chevronAnimation_ stopAnimation]; |
| 659 [chevronMenuButton_ setFrame:buttonFrame]; | 625 [chevronMenuButton_ setFrame:buttonFrame]; |
| 660 } | 626 } |
| 661 | 627 |
| 662 - (void)setChevronHidden:(BOOL)hidden | 628 - (void)setChevronHidden:(BOOL)hidden |
| 663 inFrame:(NSRect)frame | 629 inFrame:(NSRect)frame { |
| 664 animate:(BOOL)animate { | |
| 665 if (hidden == [self chevronIsHidden]) | 630 if (hidden == [self chevronIsHidden]) |
| 666 return; | 631 return; |
| 667 | 632 |
| 668 if (!chevronMenuButton_.get()) { | 633 if (!chevronMenuButton_.get()) { |
| 669 chevronMenuButton_.reset([[MenuButton alloc] init]); | 634 chevronMenuButton_.reset([[MenuButton alloc] init]); |
| 670 [chevronMenuButton_ setOpenMenuOnClick:YES]; | 635 [chevronMenuButton_ setOpenMenuOnClick:YES]; |
| 671 [chevronMenuButton_ setBordered:NO]; | 636 [chevronMenuButton_ setBordered:NO]; |
| 672 [chevronMenuButton_ setShowsBorderOnlyWhileMouseInside:YES]; | 637 [chevronMenuButton_ setShowsBorderOnlyWhileMouseInside:YES]; |
| 673 | 638 |
| 674 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW | 639 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW |
| 675 forButtonState:image_button_cell::kDefaultState]; | 640 forButtonState:image_button_cell::kDefaultState]; |
| 676 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_H | 641 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_H |
| 677 forButtonState:image_button_cell::kHoverState]; | 642 forButtonState:image_button_cell::kHoverState]; |
| 678 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_P | 643 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_P |
| 679 forButtonState:image_button_cell::kPressedState]; | 644 forButtonState:image_button_cell::kPressedState]; |
| 680 | 645 |
| 681 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]); | 646 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]); |
| 682 [overflowMenu_ setAutoenablesItems:NO]; | 647 [overflowMenu_ setAutoenablesItems:NO]; |
| 683 [overflowMenu_ setDelegate:self]; | 648 [overflowMenu_ setDelegate:self]; |
| 684 [chevronMenuButton_ setAttachedMenu:overflowMenu_]; | 649 [chevronMenuButton_ setAttachedMenu:overflowMenu_]; |
| 685 | 650 |
| 686 [containerView_ addSubview:chevronMenuButton_]; | 651 [containerView_ addSubview:chevronMenuButton_]; |
| 687 } | 652 } |
| 688 | 653 |
| 689 [self updateChevronPositionInFrame:frame]; | 654 [self updateChevronPositionInFrame:frame]; |
| 690 | 655 |
| 691 // Stop any running animation. | 656 // Stop any running animation. |
| 692 [chevronAnimation_ stopAnimation]; | 657 [chevronAnimation_ stopAnimation]; |
| 693 | 658 |
| 694 if (!animate) { | 659 if (toolbarActionsBar_->suppress_animation()) { |
| 695 [chevronMenuButton_ setHidden:hidden]; | 660 [chevronMenuButton_ setHidden:hidden]; |
| 696 return; | 661 return; |
| 697 } | 662 } |
| 698 | 663 |
| 699 NSString* animationEffect; | 664 NSString* animationEffect; |
| 700 if (hidden) { | 665 if (hidden) { |
| 701 animationEffect = NSViewAnimationFadeOutEffect; | 666 animationEffect = NSViewAnimationFadeOutEffect; |
| 702 } else { | 667 } else { |
| 703 [chevronMenuButton_ setHidden:NO]; | 668 [chevronMenuButton_ setHidden:NO]; |
| 704 animationEffect = NSViewAnimationFadeInEffect; | 669 animationEffect = NSViewAnimationFadeInEffect; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 716 [self browserActionClicked:[menuItem representedObject]]; | 681 [self browserActionClicked:[menuItem representedObject]]; |
| 717 } | 682 } |
| 718 | 683 |
| 719 - (void)updateGrippyCursors { | 684 - (void)updateGrippyCursors { |
| 720 [containerView_ | 685 [containerView_ |
| 721 setCanDragLeft:toolbarActionsBar_->GetIconCount() != [buttons_ count]]; | 686 setCanDragLeft:toolbarActionsBar_->GetIconCount() != [buttons_ count]]; |
| 722 [containerView_ setCanDragRight:[self visibleButtonCount] > 0]; | 687 [containerView_ setCanDragRight:[self visibleButtonCount] > 0]; |
| 723 [[containerView_ window] invalidateCursorRectsForView:containerView_]; | 688 [[containerView_ window] invalidateCursorRectsForView:containerView_]; |
| 724 } | 689 } |
| 725 | 690 |
| 726 - (ToolbarActionsBar*)toolbarActionsBar { | |
| 727 return toolbarActionsBar_.get(); | |
| 728 } | |
| 729 | |
| 730 #pragma mark - | 691 #pragma mark - |
| 731 #pragma mark Testing Methods | 692 #pragma mark Testing Methods |
| 732 | 693 |
| 733 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index { | 694 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index { |
| 734 const std::vector<ToolbarActionViewController*>& toolbar_actions = | 695 return index < [buttons_ count] ? [buttons_ objectAtIndex:index] : nil; |
| 735 toolbarActionsBar_->toolbar_actions(); | |
| 736 if (index < toolbar_actions.size()) | |
| 737 return [self buttonForId:toolbar_actions[index]->GetId()]; | |
| 738 return nil; | |
| 739 } | 696 } |
| 740 | 697 |
| 741 @end | 698 @end |
| OLD | NEW |