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

Side by Side Diff: chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm

Issue 2008763002: [Extensions UI] Remove all traces of the chevron (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
OLDNEW
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 20 matching lines...) Expand all
31 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h " 31 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h "
32 #include "ui/base/cocoa/appkit_utils.h" 32 #include "ui/base/cocoa/appkit_utils.h"
33 #include "ui/base/cocoa/cocoa_base_utils.h" 33 #include "ui/base/cocoa/cocoa_base_utils.h"
34 #include "ui/base/material_design/material_design_controller.h" 34 #include "ui/base/material_design/material_design_controller.h"
35 35
36 NSString* const kBrowserActionVisibilityChangedNotification = 36 NSString* const kBrowserActionVisibilityChangedNotification =
37 @"BrowserActionVisibilityChangedNotification"; 37 @"BrowserActionVisibilityChangedNotification";
38 38
39 namespace { 39 namespace {
40 40
41 const CGFloat kAnimationDuration = 0.2;
42
43 const CGFloat kChevronWidth = 18;
44
45 // How far to inset from the bottom of the view to get the top border 41 // How far to inset from the bottom of the view to get the top border
46 // of the popup 2px below the bottom of the Omnibox. 42 // of the popup 2px below the bottom of the Omnibox.
47 const CGFloat kBrowserActionBubbleYOffset = 3.0; 43 const CGFloat kBrowserActionBubbleYOffset = 3.0;
48 44
49 } // namespace 45 } // namespace
50 46
51 @interface BrowserActionsController(Private) 47 @interface BrowserActionsController(Private)
52 48
53 // Creates and adds a view for the given |action| at |index|. 49 // Creates and adds a view for the given |action| at |index|.
54 - (void)addViewForAction:(ToolbarActionViewController*)action 50 - (void)addViewForAction:(ToolbarActionViewController*)action
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // found. 84 // found.
89 - (BrowserActionButton*)buttonForId:(const std::string&)id; 85 - (BrowserActionButton*)buttonForId:(const std::string&)id;
90 86
91 // Returns the button at the given index. This is just a wrapper around 87 // Returns the button at the given index. This is just a wrapper around
92 // [NSArray objectAtIndex:], since that technically defaults to returning ids 88 // [NSArray objectAtIndex:], since that technically defaults to returning ids
93 // (and can cause compile errors). 89 // (and can cause compile errors).
94 - (BrowserActionButton*)buttonAtIndex:(NSUInteger)index; 90 - (BrowserActionButton*)buttonAtIndex:(NSUInteger)index;
95 91
96 // Notification handlers for events registered by the class. 92 // Notification handlers for events registered by the class.
97 93
98 // Updates each button's opacity, the cursor rects and chevron position. 94 // Updates each button's opacity and the cursor rects.
99 - (void)containerFrameChanged:(NSNotification*)notification; 95 - (void)containerFrameChanged:(NSNotification*)notification;
100 96
101 // Hides the chevron and unhides every hidden button so that dragging the 97 // Unhides every hidden button so that dragging the container out smoothly shows
102 // container out smoothly shows the Browser Action buttons. 98 // the Browser Action buttons.
103 - (void)containerDragStart:(NSNotification*)notification; 99 - (void)containerDragStart:(NSNotification*)notification;
104 100
105 // Determines which buttons need to be hidden based on the new size, hides them 101 // Determines which buttons need to be hidden based on the new size and hides
106 // and updates the chevron overflow menu. Also fires a notification to let the 102 // them. Also fires a notification to let the toolbar know that the drag has
107 // toolbar know that the drag has finished. 103 // finished.
108 - (void)containerDragFinished:(NSNotification*)notification; 104 - (void)containerDragFinished:(NSNotification*)notification;
109 105
110 // Notifies the controlling ToolbarActionsBar that any running animation has 106 // Notifies the controlling ToolbarActionsBar that any running animation has
111 // ended. 107 // ended.
112 - (void)containerAnimationEnded:(NSNotification*)notification; 108 - (void)containerAnimationEnded:(NSNotification*)notification;
113 109
114 // Processes a key event from the container. 110 // Processes a key event from the container.
115 - (void)containerKeyEvent:(NSNotification*)notification; 111 - (void)containerKeyEvent:(NSNotification*)notification;
116 112
117 // Adjusts the position of the surrounding action buttons depending on where the 113 // Adjusts the position of the surrounding action buttons depending on where the
(...skipping 13 matching lines...) Expand all
131 withBounds:(NSRect)bounds; 127 withBounds:(NSRect)bounds;
132 128
133 // Moves the given button both visually and within the toolbar model to the 129 // Moves the given button both visually and within the toolbar model to the
134 // specified index. 130 // specified index.
135 - (void)moveButton:(BrowserActionButton*)button 131 - (void)moveButton:(BrowserActionButton*)button
136 toIndex:(NSUInteger)index; 132 toIndex:(NSUInteger)index;
137 133
138 // Handles clicks for BrowserActionButtons. 134 // Handles clicks for BrowserActionButtons.
139 - (BOOL)browserActionClicked:(BrowserActionButton*)button; 135 - (BOOL)browserActionClicked:(BrowserActionButton*)button;
140 136
141 // The reason |frame| is specified in these chevron functions is because the
142 // container may be animating and the end frame of the animation should be
143 // passed instead of the current frame (which may be off and cause the chevron
144 // to jump at the end of its animation).
145
146 // Shows the overflow chevron button depending on whether there are any hidden
147 // extensions within the frame given.
148 - (void)showChevronIfNecessaryInFrame:(NSRect)frame;
149
150 // Moves the chevron to its correct position within |frame|.
151 - (void)updateChevronPositionInFrame:(NSRect)frame;
152
153 // Shows or hides the chevron in the given |frame|.
154 - (void)setChevronHidden:(BOOL)hidden
155 inFrame:(NSRect)frame;
156
157 // Handles when a menu item within the chevron overflow menu is selected.
158 - (void)chevronItemSelected:(id)menuItem;
159
160 // Updates the container's grippy cursor based on the number of hidden buttons. 137 // Updates the container's grippy cursor based on the number of hidden buttons.
161 - (void)updateGrippyCursors; 138 - (void)updateGrippyCursors;
162 139
163 // Returns the associated ToolbarController. 140 // Returns the associated ToolbarController.
164 - (ToolbarController*)toolbarController; 141 - (ToolbarController*)toolbarController;
165 142
166 // Creates a message bubble with the given |delegate|. 143 // Creates a message bubble with the given |delegate|.
167 - (void)createMessageBubble: 144 - (void)createMessageBubble:
168 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate; 145 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>)delegate;
169 146
170 // Called when the window for the active bubble is closing, and sets the active 147 // Called when the window for the active bubble is closing, and sets the active
171 // bubble to nil. 148 // bubble to nil.
172 - (void)bubbleWindowClosing:(NSNotification*)notification; 149 - (void)bubbleWindowClosing:(NSNotification*)notification;
173 150
174 // Sets the current focused view. Should only be used for the overflow 151 // Sets the current focused view. Should only be used for the overflow
175 // container. 152 // container.
176 - (void)setFocusedViewIndex:(NSInteger)index; 153 - (void)setFocusedViewIndex:(NSInteger)index;
177 154
178 @end 155 @end
179 156
180 // A subclass of MenuButton that draws the chevron button in MD style.
181 @interface ChevronMenuButton : MenuButton
182 @end
183
184 @implementation ChevronMenuButton
185
186 - (gfx::VectorIconId)vectorIconId {
187 return gfx::VectorIconId::OVERFLOW_CHEVRON;
188 }
189
190 @end
191
192 namespace { 157 namespace {
193 158
194 // A bridge between the ToolbarActionsBar and the BrowserActionsController. 159 // A bridge between the ToolbarActionsBar and the BrowserActionsController.
195 class ToolbarActionsBarBridge : public ToolbarActionsBarDelegate { 160 class ToolbarActionsBarBridge : public ToolbarActionsBarDelegate {
196 public: 161 public:
197 explicit ToolbarActionsBarBridge(BrowserActionsController* controller); 162 explicit ToolbarActionsBarBridge(BrowserActionsController* controller);
198 ~ToolbarActionsBarBridge() override; 163 ~ToolbarActionsBarBridge() override;
199 164
200 BrowserActionsController* controller_for_test() { return controller_; } 165 BrowserActionsController* controller_for_test() { return controller_; }
201 166
202 private: 167 private:
203 // ToolbarActionsBarDelegate: 168 // ToolbarActionsBarDelegate:
204 void AddViewForAction(ToolbarActionViewController* action, 169 void AddViewForAction(ToolbarActionViewController* action,
205 size_t index) override; 170 size_t index) override;
206 void RemoveViewForAction(ToolbarActionViewController* action) override; 171 void RemoveViewForAction(ToolbarActionViewController* action) override;
207 void RemoveAllViews() override; 172 void RemoveAllViews() override;
208 void Redraw(bool order_changed) override; 173 void Redraw(bool order_changed) override;
209 void ResizeAndAnimate(gfx::Tween::Type tween_type, 174 void ResizeAndAnimate(gfx::Tween::Type tween_type,
210 int target_width, 175 int target_width) override;
211 bool suppress_chevron) override;
212 void SetChevronVisibility(bool chevron_visible) override;
213 int GetWidth(GetWidthTime get_width_time) const override; 176 int GetWidth(GetWidthTime get_width_time) const override;
214 bool IsAnimating() const override; 177 bool IsAnimating() const override;
215 void StopAnimating() override; 178 void StopAnimating() override;
216 int GetChevronWidth() const override;
217 void ShowToolbarActionBubble( 179 void ShowToolbarActionBubble(
218 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) override; 180 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) override;
219 181
220 // The owning BrowserActionsController; weak. 182 // The owning BrowserActionsController; weak.
221 BrowserActionsController* controller_; 183 BrowserActionsController* controller_;
222 184
223 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBarBridge); 185 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBarBridge);
224 }; 186 };
225 187
226 ToolbarActionsBarBridge::ToolbarActionsBarBridge( 188 ToolbarActionsBarBridge::ToolbarActionsBarBridge(
(...skipping 18 matching lines...) Expand all
245 207
246 void ToolbarActionsBarBridge::RemoveAllViews() { 208 void ToolbarActionsBarBridge::RemoveAllViews() {
247 [controller_ removeAllViews]; 209 [controller_ removeAllViews];
248 } 210 }
249 211
250 void ToolbarActionsBarBridge::Redraw(bool order_changed) { 212 void ToolbarActionsBarBridge::Redraw(bool order_changed) {
251 [controller_ redraw]; 213 [controller_ redraw];
252 } 214 }
253 215
254 void ToolbarActionsBarBridge::ResizeAndAnimate(gfx::Tween::Type tween_type, 216 void ToolbarActionsBarBridge::ResizeAndAnimate(gfx::Tween::Type tween_type,
255 int target_width, 217 int target_width) {
256 bool suppress_chevron) {
257 [controller_ resizeContainerToWidth:target_width]; 218 [controller_ resizeContainerToWidth:target_width];
258 } 219 }
259 220
260 void ToolbarActionsBarBridge::SetChevronVisibility(bool chevron_visible) {
261 [controller_ setChevronHidden:!chevron_visible
262 inFrame:[[controller_ containerView] frame]];
263 }
264
265 int ToolbarActionsBarBridge::GetWidth(GetWidthTime get_width_time) const { 221 int ToolbarActionsBarBridge::GetWidth(GetWidthTime get_width_time) const {
266 NSRect frame = 222 NSRect frame =
267 get_width_time == ToolbarActionsBarDelegate::GET_WIDTH_AFTER_ANIMATION 223 get_width_time == ToolbarActionsBarDelegate::GET_WIDTH_AFTER_ANIMATION
268 ? [[controller_ containerView] animationEndFrame] 224 ? [[controller_ containerView] animationEndFrame]
269 : [[controller_ containerView] frame]; 225 : [[controller_ containerView] frame];
270 return NSWidth(frame); 226 return NSWidth(frame);
271 } 227 }
272 228
273 bool ToolbarActionsBarBridge::IsAnimating() const { 229 bool ToolbarActionsBarBridge::IsAnimating() const {
274 return [[controller_ containerView] isAnimating]; 230 return [[controller_ containerView] isAnimating];
275 } 231 }
276 232
277 void ToolbarActionsBarBridge::StopAnimating() { 233 void ToolbarActionsBarBridge::StopAnimating() {
278 // Unfortunately, animating the browser actions container affects neighboring 234 // Unfortunately, animating the browser actions container affects neighboring
279 // views (like the omnibox), which could also be animating. Because of this, 235 // views (like the omnibox), which could also be animating. Because of this,
280 // instead of just ending the animation, the cleanest way to terminate is to 236 // instead of just ending the animation, the cleanest way to terminate is to
281 // "animate" to the current frame. 237 // "animate" to the current frame.
282 [controller_ resizeContainerToWidth: 238 [controller_ resizeContainerToWidth:
283 NSWidth([[controller_ containerView] frame])]; 239 NSWidth([[controller_ containerView] frame])];
284 } 240 }
285 241
286 int ToolbarActionsBarBridge::GetChevronWidth() const {
287 return kChevronWidth;
288 }
289
290 void ToolbarActionsBarBridge::ShowToolbarActionBubble( 242 void ToolbarActionsBarBridge::ShowToolbarActionBubble(
291 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) { 243 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) {
292 [controller_ createMessageBubble:std::move(bubble)]; 244 [controller_ createMessageBubble:std::move(bubble)];
293 } 245 }
294 246
295 } // namespace 247 } // namespace
296 248
297 @implementation BrowserActionsController 249 @implementation BrowserActionsController
298 250
299 @synthesize containerView = containerView_; 251 @synthesize containerView = containerView_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 name:kBrowserActionsContainerReceivedKeyEvent 301 name:kBrowserActionsContainerReceivedKeyEvent
350 object:containerView_]; 302 object:containerView_];
351 // Listen for a finished drag from any button to make sure each open window 303 // Listen for a finished drag from any button to make sure each open window
352 // stays in sync. 304 // stays in sync.
353 [[NSNotificationCenter defaultCenter] 305 [[NSNotificationCenter defaultCenter]
354 addObserver:self 306 addObserver:self
355 selector:@selector(actionButtonDragFinished:) 307 selector:@selector(actionButtonDragFinished:)
356 name:kBrowserActionButtonDragEndNotification 308 name:kBrowserActionButtonDragEndNotification
357 object:nil]; 309 object:nil];
358 310
359 suppressChevron_ = NO;
360 if (toolbarActionsBar_->platform_settings().chevron_enabled) {
361 chevronAnimation_.reset([[NSViewAnimation alloc] init]);
362 [chevronAnimation_ gtm_setDuration:kAnimationDuration
363 eventMask:NSLeftMouseUpMask];
364 [chevronAnimation_ setAnimationBlockingMode:NSAnimationNonblocking];
365 }
366
367 if (isOverflow_) 311 if (isOverflow_)
368 toolbarActionsBar_->SetOverflowRowWidth(NSWidth([containerView_ frame])); 312 toolbarActionsBar_->SetOverflowRowWidth(NSWidth([containerView_ frame]));
369 313
370 buttons_.reset([[NSMutableArray alloc] init]); 314 buttons_.reset([[NSMutableArray alloc] init]);
371 toolbarActionsBar_->CreateActions(); 315 toolbarActionsBar_->CreateActions();
372 [self showChevronIfNecessaryInFrame:[containerView_ frame]];
373 [self updateGrippyCursors]; 316 [self updateGrippyCursors];
374 [container setIsOverflow:isOverflow_]; 317 [container setIsOverflow:isOverflow_];
375 318
376 focusedViewIndex_ = -1; 319 focusedViewIndex_ = -1;
377 } 320 }
378 321
379 return self; 322 return self;
380 } 323 }
381 324
382 - (void)dealloc { 325 - (void)dealloc {
383 [self browserWillBeDestroyed]; 326 [self browserWillBeDestroyed];
384 [super dealloc]; 327 [super dealloc];
385 } 328 }
386 329
387 - (void)browserWillBeDestroyed { 330 - (void)browserWillBeDestroyed {
388 [overflowMenu_ setDelegate:nil];
389 // Explicitly destroy the ToolbarActionsBar so all buttons get removed with a 331 // Explicitly destroy the ToolbarActionsBar so all buttons get removed with a
390 // valid BrowserActionsController, and so we can verify state before 332 // valid BrowserActionsController, and so we can verify state before
391 // destruction. 333 // destruction.
392 if (toolbarActionsBar_.get()) { 334 if (toolbarActionsBar_.get()) {
393 toolbarActionsBar_->DeleteActions(); 335 toolbarActionsBar_->DeleteActions();
394 toolbarActionsBar_.reset(); 336 toolbarActionsBar_.reset();
395 } 337 }
396 DCHECK_EQ(0u, [buttons_ count]); 338 DCHECK_EQ(0u, [buttons_ count]);
397 [[NSNotificationCenter defaultCenter] removeObserver:self]; 339 [[NSNotificationCenter defaultCenter] removeObserver:self];
398 browser_ = nullptr; 340 browser_ = nullptr;
(...skipping 19 matching lines...) Expand all
418 } 360 }
419 361
420 - (NSPoint)popupPointForId:(const std::string&)id { 362 - (NSPoint)popupPointForId:(const std::string&)id {
421 BrowserActionButton* button = [self buttonForId:id]; 363 BrowserActionButton* button = [self buttonForId:id];
422 if (!button) 364 if (!button)
423 return NSZeroPoint; 365 return NSZeroPoint;
424 366
425 NSRect bounds; 367 NSRect bounds;
426 NSView* referenceButton = button; 368 NSView* referenceButton = button;
427 if ([button superview] != containerView_ || isOverflow_) { 369 if ([button superview] != containerView_ || isOverflow_) {
428 referenceButton = toolbarActionsBar_->platform_settings().chevron_enabled ? 370 bounds = [[[self toolbarController] appMenuButton] bounds];
429 chevronMenuButton_.get() : [[self toolbarController] appMenuButton];
430 bounds = [referenceButton bounds];
431 } else { 371 } else {
432 bounds = [button convertRect:[button frameAfterAnimation] 372 bounds = [button convertRect:[button frameAfterAnimation]
433 fromView:[button superview]]; 373 fromView:[button superview]];
434 } 374 }
435 375
436 return [self popupPointForView:referenceButton withBounds:bounds]; 376 return [self popupPointForView:referenceButton withBounds:bounds];
437 } 377 }
438 378
439 - (BOOL)chevronIsHidden {
440 if (!chevronMenuButton_.get())
441 return YES;
442
443 if (![chevronAnimation_ isAnimating])
444 return [chevronMenuButton_ isHidden];
445
446 DCHECK([[chevronAnimation_ viewAnimations] count] > 0);
447
448 // The chevron is animating in or out. Determine which one and have the return
449 // value reflect where the animation is headed.
450 NSString* effect = [[[chevronAnimation_ viewAnimations] objectAtIndex:0]
451 valueForKey:NSViewAnimationEffectKey];
452 if (effect == NSViewAnimationFadeInEffect) {
453 return NO;
454 } else if (effect == NSViewAnimationFadeOutEffect) {
455 return YES;
456 }
457
458 NOTREACHED();
459 return YES;
460 }
461
462 - (content::WebContents*)currentWebContents { 379 - (content::WebContents*)currentWebContents {
463 return browser_->tab_strip_model()->GetActiveWebContents(); 380 return browser_->tab_strip_model()->GetActiveWebContents();
464 } 381 }
465 382
466 - (BrowserActionButton*)mainButtonForId:(const std::string&)id { 383 - (BrowserActionButton*)mainButtonForId:(const std::string&)id {
467 BrowserActionsController* mainController = isOverflow_ ? 384 BrowserActionsController* mainController = isOverflow_ ?
468 [[self toolbarController] browserActionsController] : self; 385 [[self toolbarController] browserActionsController] : self;
469 return [mainController buttonForId:id]; 386 return [mainController buttonForId:id];
470 } 387 }
471 388
472 - (ToolbarActionsBar*)toolbarActionsBar { 389 - (ToolbarActionsBar*)toolbarActionsBar {
473 return toolbarActionsBar_.get(); 390 return toolbarActionsBar_.get();
474 } 391 }
475 392
476 - (void)setFocusedInOverflow:(BOOL)focused { 393 - (void)setFocusedInOverflow:(BOOL)focused {
477 BOOL isFocused = focusedViewIndex_ != -1; 394 BOOL isFocused = focusedViewIndex_ != -1;
478 if (isFocused != focused) { 395 if (isFocused != focused) {
479 int index = focused ? 396 int index = focused ?
480 [buttons_ count] - toolbarActionsBar_->GetIconCount() : -1; 397 [buttons_ count] - toolbarActionsBar_->GetIconCount() : -1;
481 [self setFocusedViewIndex:index]; 398 [self setFocusedViewIndex:index];
482 } 399 }
483 } 400 }
484 401
485 - (gfx::Size)sizeForOverflowWidth:(int)maxWidth { 402 - (gfx::Size)sizeForOverflowWidth:(int)maxWidth {
486 toolbarActionsBar_->SetOverflowRowWidth(maxWidth); 403 toolbarActionsBar_->SetOverflowRowWidth(maxWidth);
487 return [self preferredSize]; 404 return [self preferredSize];
488 } 405 }
489 406
490 #pragma mark -
491 #pragma mark NSMenuDelegate
492
493 - (void)menuNeedsUpdate:(NSMenu*)menu {
494 [menu removeAllItems];
495
496 // See menu_button.h for documentation on why this is needed.
497 [menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
498
499 NSUInteger iconCount = toolbarActionsBar_->GetIconCount();
500 NSRange hiddenButtonRange =
501 NSMakeRange(iconCount, [buttons_ count] - iconCount);
502 for (BrowserActionButton* button in
503 [buttons_ subarrayWithRange:hiddenButtonRange]) {
504 NSString* name =
505 base::SysUTF16ToNSString([button viewController]->GetActionName());
506 NSMenuItem* item =
507 [menu addItemWithTitle:name
508 action:@selector(chevronItemSelected:)
509 keyEquivalent:@""];
510 [item setRepresentedObject:button];
511 [item setImage:[button compositedImage]];
512 [item setTarget:self];
513 [item setEnabled:[button isEnabled]];
514 }
515 }
516
517 #pragma mark -
518 #pragma mark Private Methods
519
520 - (void)addViewForAction:(ToolbarActionViewController*)action 407 - (void)addViewForAction:(ToolbarActionViewController*)action
521 withIndex:(NSUInteger)index { 408 withIndex:(NSUInteger)index {
522 NSRect buttonFrame = NSMakeRect(NSMaxX([containerView_ bounds]), 409 NSRect buttonFrame = NSMakeRect(NSMaxX([containerView_ bounds]),
523 0, 410 0,
524 ToolbarActionsBar::IconWidth(false), 411 ToolbarActionsBar::IconWidth(false),
525 ToolbarActionsBar::IconHeight()); 412 ToolbarActionsBar::IconHeight());
526 BrowserActionButton* newButton = 413 BrowserActionButton* newButton =
527 [[[BrowserActionButton alloc] 414 [[[BrowserActionButton alloc]
528 initWithFrame:buttonFrame 415 initWithFrame:buttonFrame
529 viewController:action 416 viewController:action
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 ToolbarActionViewController* other_controller = 455 ToolbarActionViewController* other_controller =
569 [[self buttonAtIndex:j] viewController]; 456 [[self buttonAtIndex:j] viewController];
570 if (other_controller == toolbar_actions[i]) 457 if (other_controller == toolbar_actions[i])
571 break; 458 break;
572 ++j; 459 ++j;
573 } 460 }
574 [buttons_ exchangeObjectAtIndex:i withObjectAtIndex:j]; 461 [buttons_ exchangeObjectAtIndex:i withObjectAtIndex:j];
575 } 462 }
576 } 463 }
577 464
578 [self showChevronIfNecessaryInFrame:[containerView_ frame]];
579 NSUInteger startIndex = toolbarActionsBar_->GetStartIndexInBounds(); 465 NSUInteger startIndex = toolbarActionsBar_->GetStartIndexInBounds();
580 NSUInteger endIndex = toolbarActionsBar_->GetEndIndexInBounds(); 466 NSUInteger endIndex = toolbarActionsBar_->GetEndIndexInBounds();
581 for (NSUInteger i = 0; i < [buttons_ count]; ++i) { 467 for (NSUInteger i = 0; i < [buttons_ count]; ++i) {
582 BrowserActionButton* button = [buttons_ objectAtIndex:i]; 468 BrowserActionButton* button = [buttons_ objectAtIndex:i];
583 if ([button isBeingDragged]) 469 if ([button isBeingDragged])
584 continue; 470 continue;
585 471
586 [self moveButton:[buttons_ objectAtIndex:i] toIndex:i]; 472 [self moveButton:[buttons_ objectAtIndex:i] toIndex:i];
587 473
588 if (i >= startIndex && i < endIndex) { 474 if (i >= startIndex && i < endIndex) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 // Cocoa goes a little crazy if we try and change animations while adjusting 521 // Cocoa goes a little crazy if we try and change animations while adjusting
636 // child frames (i.e., the buttons). If the toolbar is already animating, 522 // child frames (i.e., the buttons). If the toolbar is already animating,
637 // just jump to the new frame. (This typically only happens if someone is 523 // just jump to the new frame. (This typically only happens if someone is
638 // "spamming" a button to add/remove an action.) If the window isn't visible 524 // "spamming" a button to add/remove an action.) If the window isn't visible
639 // (for example it's in the process of being created), don't bother animating. 525 // (for example it's in the process of being created), don't bother animating.
640 BOOL animate = !toolbarActionsBar_->suppress_animation() && 526 BOOL animate = !toolbarActionsBar_->suppress_animation() &&
641 ![containerView_ isAnimating] && [[containerView_ window] isVisible]; 527 ![containerView_ isAnimating] && [[containerView_ window] isVisible];
642 [self updateContainerVisibility]; 528 [self updateContainerVisibility];
643 [containerView_ resizeToWidth:width 529 [containerView_ resizeToWidth:width
644 animate:animate]; 530 animate:animate];
645 NSRect frame = animate ? [containerView_ animationEndFrame] :
646 [containerView_ frame];
647
648 [self showChevronIfNecessaryInFrame:frame];
649
650 [containerView_ setNeedsDisplay:YES]; 531 [containerView_ setNeedsDisplay:YES];
651 532
652 if (!animate) { 533 if (!animate) {
653 [[NSNotificationCenter defaultCenter] 534 [[NSNotificationCenter defaultCenter]
654 postNotificationName:kBrowserActionVisibilityChangedNotification 535 postNotificationName:kBrowserActionVisibilityChangedNotification
655 object:self]; 536 object:self];
656 } 537 }
657 [self redraw]; 538 [self redraw];
658 [self updateGrippyCursors]; 539 [self updateGrippyCursors];
659 } 540 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 } 599 }
719 600
720 - (BrowserActionButton*)buttonAtIndex:(NSUInteger)index { 601 - (BrowserActionButton*)buttonAtIndex:(NSUInteger)index {
721 return static_cast<BrowserActionButton*>([buttons_ objectAtIndex:index]); 602 return static_cast<BrowserActionButton*>([buttons_ objectAtIndex:index]);
722 } 603 }
723 604
724 - (void)containerFrameChanged:(NSNotification*)notification { 605 - (void)containerFrameChanged:(NSNotification*)notification {
725 [self updateButtonPositions]; 606 [self updateButtonPositions];
726 [self updateButtonOpacity]; 607 [self updateButtonOpacity];
727 [[containerView_ window] invalidateCursorRectsForView:containerView_]; 608 [[containerView_ window] invalidateCursorRectsForView:containerView_];
728 [self updateChevronPositionInFrame:[containerView_ frame]];
729 } 609 }
730 610
731 - (void)containerDragStart:(NSNotification*)notification { 611 - (void)containerDragStart:(NSNotification*)notification {
732 [self setChevronHidden:YES inFrame:[containerView_ frame]];
733 for (BrowserActionButton* button in buttons_.get()) { 612 for (BrowserActionButton* button in buttons_.get()) {
734 if ([button superview] != containerView_) { 613 if ([button superview] != containerView_) {
735 [button setAlphaValue:1.0]; 614 [button setAlphaValue:1.0];
736 [containerView_ addSubview:button]; 615 [containerView_ addSubview:button];
737 } 616 }
738 } 617 }
739 } 618 }
740 619
741 - (void)containerDragFinished:(NSNotification*)notification { 620 - (void)containerDragFinished:(NSNotification*)notification {
742 for (BrowserActionButton* button in buttons_.get()) { 621 for (BrowserActionButton* button in buttons_.get()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 [focusedButton performClick:focusedButton]; 671 [focusedButton performClick:focusedButton];
793 } 672 }
794 break; 673 break;
795 } 674 }
796 case BROWSER_ACTIONS_INVALID_KEY_ACTION: 675 case BROWSER_ACTIONS_INVALID_KEY_ACTION:
797 NOTREACHED(); 676 NOTREACHED();
798 } 677 }
799 } 678 }
800 679
801 - (void)actionButtonDragging:(NSNotification*)notification { 680 - (void)actionButtonDragging:(NSNotification*)notification {
802 suppressChevron_ = YES;
803 if (![self chevronIsHidden])
804 [self setChevronHidden:YES inFrame:[containerView_ frame]];
805
806 // Determine what index the dragged button should lie in, alter the model and 681 // Determine what index the dragged button should lie in, alter the model and
807 // reposition the buttons. 682 // reposition the buttons.
808 BrowserActionButton* draggedButton = [notification object]; 683 BrowserActionButton* draggedButton = [notification object];
809 NSRect draggedButtonFrame = [draggedButton frame]; 684 NSRect draggedButtonFrame = [draggedButton frame];
810 // Find the mid-point. We flip the y-coordinates so that y = 0 is at the 685 // Find the mid-point. We flip the y-coordinates so that y = 0 is at the
811 // top of the container to make row calculation more logical. 686 // top of the container to make row calculation more logical.
812 NSPoint midPoint = 687 NSPoint midPoint =
813 NSMakePoint(NSMidX(draggedButtonFrame), 688 NSMakePoint(NSMidX(draggedButtonFrame),
814 NSMaxY([containerView_ bounds]) - NSMidY(draggedButtonFrame)); 689 NSMaxY([containerView_ bounds]) - NSMidY(draggedButtonFrame));
815 690
(...skipping 13 matching lines...) Expand all
829 [buttons_ count] - toolbarActionsBar_->GetIconCount() : 0; 704 [buttons_ count] - toolbarActionsBar_->GetIconCount() : 0;
830 NSInteger index = 705 NSInteger index =
831 std::min(maxIndex, offset + rowIndex * icons_per_row + indexInRow); 706 std::min(maxIndex, offset + rowIndex * icons_per_row + indexInRow);
832 707
833 toolbarActionsBar_->OnDragDrop([buttons_ indexOfObject:draggedButton], 708 toolbarActionsBar_->OnDragDrop([buttons_ indexOfObject:draggedButton],
834 index, 709 index,
835 ToolbarActionsBar::DRAG_TO_SAME); 710 ToolbarActionsBar::DRAG_TO_SAME);
836 } 711 }
837 712
838 - (void)actionButtonDragFinished:(NSNotification*)notification { 713 - (void)actionButtonDragFinished:(NSNotification*)notification {
839 suppressChevron_ = NO;
840 [self redraw]; 714 [self redraw];
841 } 715 }
842 716
843 - (NSRect)frameForIndex:(NSUInteger)index { 717 - (NSRect)frameForIndex:(NSUInteger)index {
844 gfx::Rect frameRect = toolbarActionsBar_->GetFrameForIndex(index); 718 gfx::Rect frameRect = toolbarActionsBar_->GetFrameForIndex(index);
845 int iconWidth = ToolbarActionsBar::IconWidth(false); 719 int iconWidth = ToolbarActionsBar::IconWidth(false);
846 // The toolbar actions bar will return an empty rect if the index is for an 720 // The toolbar actions bar will return an empty rect if the index is for an
847 // action that is before range we show (i.e., is for a button that's on the 721 // action that is before range we show (i.e., is for a button that's on the
848 // main bar, and this is the overflow). Set the frame to be outside the bounds 722 // main bar, and this is the overflow). Set the frame to be outside the bounds
849 // of the view. 723 // of the view.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 if (!NSEqualRects(buttonFrame, [button frameAfterAnimation])) { 775 if (!NSEqualRects(buttonFrame, [button frameAfterAnimation])) {
902 [button setFrame:buttonFrame 776 [button setFrame:buttonFrame
903 animate:!toolbarActionsBar_->suppress_animation() && !isOverflow_]; 777 animate:!toolbarActionsBar_->suppress_animation() && !isOverflow_];
904 } 778 }
905 } 779 }
906 780
907 - (BOOL)browserActionClicked:(BrowserActionButton*)button { 781 - (BOOL)browserActionClicked:(BrowserActionButton*)button {
908 return [button viewController]->ExecuteAction(true); 782 return [button viewController]->ExecuteAction(true);
909 } 783 }
910 784
911 - (void)showChevronIfNecessaryInFrame:(NSRect)frame {
912 if (!toolbarActionsBar_->platform_settings().chevron_enabled)
913 return;
914 bool hidden = suppressChevron_ ||
915 toolbarActionsBar_->GetIconCount() == [self buttonCount];
916 [self setChevronHidden:hidden inFrame:frame];
917 }
918
919 - (void)updateChevronPositionInFrame:(NSRect)frame {
920 CGFloat xPos = NSWidth(frame) - kChevronWidth -
921 toolbarActionsBar_->platform_settings().item_spacing;
922 NSRect buttonFrame = NSMakeRect(xPos,
923 0,
924 kChevronWidth,
925 ToolbarActionsBar::IconHeight());
926 [chevronAnimation_ stopAnimation];
927 [chevronMenuButton_ setFrame:buttonFrame];
928 }
929
930 - (void)setChevronHidden:(BOOL)hidden
931 inFrame:(NSRect)frame {
932 if (!toolbarActionsBar_->platform_settings().chevron_enabled ||
933 hidden == [self chevronIsHidden])
934 return;
935
936 if (!chevronMenuButton_.get()) {
937 bool isModeMaterial = ui::MaterialDesignController::IsModeMaterial();
938 if (isModeMaterial) {
939 chevronMenuButton_.reset([[ChevronMenuButton alloc] init]);
940 } else {
941 chevronMenuButton_.reset([[MenuButton alloc] init]);
942 }
943 [chevronMenuButton_ setOpenMenuOnClick:YES];
944 [chevronMenuButton_ setBordered:NO];
945 [chevronMenuButton_ setShowsBorderOnlyWhileMouseInside:YES];
946
947 if (!isModeMaterial) {
948 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW
949 forButtonState:image_button_cell::kDefaultState];
950 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_H
951 forButtonState:image_button_cell::kHoverState];
952 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_P
953 forButtonState:image_button_cell::kPressedState];
954 }
955 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]);
956 [overflowMenu_ setAutoenablesItems:NO];
957 [overflowMenu_ setDelegate:self];
958 [chevronMenuButton_ setAttachedMenu:overflowMenu_];
959
960 [containerView_ addSubview:chevronMenuButton_];
961 }
962
963 [self updateChevronPositionInFrame:frame];
964
965 // Stop any running animation.
966 [chevronAnimation_ stopAnimation];
967
968 if (toolbarActionsBar_->suppress_animation()) {
969 [chevronMenuButton_ setHidden:hidden];
970 return;
971 }
972
973 NSString* animationEffect;
974 if (hidden) {
975 animationEffect = NSViewAnimationFadeOutEffect;
976 } else {
977 [chevronMenuButton_ setHidden:NO];
978 animationEffect = NSViewAnimationFadeInEffect;
979 }
980 NSDictionary* animationDictionary = @{
981 NSViewAnimationTargetKey : chevronMenuButton_.get(),
982 NSViewAnimationEffectKey : animationEffect
983 };
984 [chevronAnimation_ setViewAnimations:
985 [NSArray arrayWithObject:animationDictionary]];
986 [chevronAnimation_ startAnimation];
987 }
988
989 - (void)chevronItemSelected:(id)menuItem {
990 [self browserActionClicked:[menuItem representedObject]];
991 }
992
993 - (void)updateGrippyCursors { 785 - (void)updateGrippyCursors {
994 [containerView_ 786 [containerView_
995 setCanDragLeft:toolbarActionsBar_->GetIconCount() != [buttons_ count]]; 787 setCanDragLeft:toolbarActionsBar_->GetIconCount() != [buttons_ count]];
996 [containerView_ setCanDragRight:[self visibleButtonCount] > 0]; 788 [containerView_ setCanDragRight:[self visibleButtonCount] > 0];
997 [[containerView_ window] invalidateCursorRectsForView:containerView_]; 789 [[containerView_ window] invalidateCursorRectsForView:containerView_];
998 } 790 }
999 791
1000 - (ToolbarController*)toolbarController { 792 - (ToolbarController*)toolbarController {
1001 return [[BrowserWindowController browserWindowControllerForWindow: 793 return [[BrowserWindowController browserWindowControllerForWindow:
1002 browser_->window()->GetNativeWindow()] toolbarController]; 794 browser_->window()->GetNativeWindow()] toolbarController];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 } 840 }
1049 841
1050 #pragma mark - 842 #pragma mark -
1051 #pragma mark Testing Methods 843 #pragma mark Testing Methods
1052 844
1053 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index { 845 - (BrowserActionButton*)buttonWithIndex:(NSUInteger)index {
1054 return index < [buttons_ count] ? [buttons_ objectAtIndex:index] : nil; 846 return index < [buttons_ count] ? [buttons_ objectAtIndex:index] : nil;
1055 } 847 }
1056 848
1057 @end 849 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698