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

Side by Side Diff: chrome/browser/views/browser_actions_container.cc

Issue 554057: Windows: use ExtensionToolbarModel for ordering of browser action buttons.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "chrome/browser/views/browser_actions_container.h" 5 #include "chrome/browser/views/browser_actions_container.h"
6 6
7 #include "app/gfx/canvas.h" 7 #include "app/gfx/canvas.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "app/slide_animation.h" 9 #include "app/slide_animation.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 261
262 //////////////////////////////////////////////////////////////////////////////// 262 ////////////////////////////////////////////////////////////////////////////////
263 // BrowserActionsContainer 263 // BrowserActionsContainer
264 264
265 BrowserActionsContainer::BrowserActionsContainer( 265 BrowserActionsContainer::BrowserActionsContainer(
266 Profile* profile, ToolbarView* toolbar) 266 Profile* profile, ToolbarView* toolbar)
267 : profile_(profile), 267 : profile_(profile),
268 toolbar_(toolbar), 268 toolbar_(toolbar),
269 popup_(NULL), 269 popup_(NULL),
270 popup_button_(NULL), 270 popup_button_(NULL),
271 model_(NULL),
271 resize_gripper_(NULL), 272 resize_gripper_(NULL),
272 chevron_(NULL), 273 chevron_(NULL),
273 suppress_chevron_(false), 274 suppress_chevron_(false),
274 resize_amount_(0), 275 resize_amount_(0),
275 animation_target_size_(0), 276 animation_target_size_(0),
276 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { 277 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
278 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
279
277 ExtensionsService* extension_service = profile->GetExtensionsService(); 280 ExtensionsService* extension_service = profile->GetExtensionsService();
278 if (!extension_service) // The |extension_service| can be NULL in Incognito. 281 if (!extension_service) // The |extension_service| can be NULL in Incognito.
279 return; 282 return;
280 283
281 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
282 Source<Profile>(profile_));
283 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
284 Source<Profile>(profile_));
285 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
286 Source<Profile>(profile_));
287 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 284 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
288 Source<Profile>(profile_)); 285 Source<Profile>(profile_));
289 286
287 model_ = extension_service->toolbar_model();
288 model_->AddObserver(this);
289
290 resize_animation_.reset(new SlideAnimation(this)); 290 resize_animation_.reset(new SlideAnimation(this));
291
292 resize_gripper_ = new views::ResizeGripper(this); 291 resize_gripper_ = new views::ResizeGripper(this);
293 resize_gripper_->SetVisible(false); 292 resize_gripper_->SetVisible(false);
294 AddChildView(resize_gripper_); 293 AddChildView(resize_gripper_);
295 294
296 // TODO(glen): Come up with a new bitmap for the chevron. 295 // TODO(glen): Come up with a new bitmap for the chevron.
297 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 296 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
298 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS); 297 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
299 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); 298 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
300 chevron_->SetVisible(false); 299 chevron_->SetVisible(false);
301 chevron_->SetIcon(*chevron_image); 300 chevron_->SetIcon(*chevron_image);
302 // Chevron contains >> that should point left in LTR locales. 301 // Chevron contains >> that should point left in LTR locales.
303 chevron_->EnableCanvasFlippingForRTLUI(true); 302 chevron_->EnableCanvasFlippingForRTLUI(true);
304 AddChildView(chevron_); 303 AddChildView(chevron_);
305 304
306 int predefined_width = 305 int predefined_width =
307 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); 306 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth);
308 container_size_ = gfx::Size(predefined_width, kButtonSize); 307 container_size_ = gfx::Size(predefined_width, kButtonSize);
309
310 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
311 } 308 }
312 309
313 BrowserActionsContainer::~BrowserActionsContainer() { 310 BrowserActionsContainer::~BrowserActionsContainer() {
314 HidePopup(); 311 HidePopup();
315 DeleteBrowserActionViews(); 312 DeleteBrowserActionViews();
316 } 313 }
317 314
318 // Static. 315 // Static.
319 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) { 316 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) {
320 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0); 317 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
(...skipping 17 matching lines...) Expand all
338 } 335 }
339 336
340 return NULL; 337 return NULL;
341 } 338 }
342 339
343 void BrowserActionsContainer::RefreshBrowserActionViews() { 340 void BrowserActionsContainer::RefreshBrowserActionViews() {
344 for (size_t i = 0; i < browser_action_views_.size(); ++i) 341 for (size_t i = 0; i < browser_action_views_.size(); ++i)
345 browser_action_views_[i]->button()->UpdateState(); 342 browser_action_views_[i]->button()->UpdateState();
346 } 343 }
347 344
348 void BrowserActionsContainer::AddBrowserAction(Extension* extension) {
349 #if defined(DEBUG)
350 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
351 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
352 "Asked to add a browser action view for an extension that already "
353 "exists.";
354 }
355 #endif
356 if (!extension->browser_action())
357 return;
358
359 // Before we change anything, determine the number of visible browser actions.
360 size_t visible_actions = 0;
361 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
362 if (browser_action_views_[i]->IsVisible())
363 ++visible_actions;
364 }
365
366 // Add the new browser action to the vector and the view hierarchy.
367 BrowserActionView* view = new BrowserActionView(extension, this);
368 browser_action_views_.push_back(view);
369 AddChildView(view);
370
371 // For details on why we do the following see the class comments in the
372 // header.
373
374 // Determine if we need to increase (we only do that if the container was
375 // showing all icons before the addition of this icon). We use -1 because
376 // we don't want to count the view that we just added.
377 if (visible_actions < browser_action_views_.size() - 1) {
378 // Some icons were hidden, don't increase the size of the container.
379 OnBrowserActionVisibilityChanged();
380 } else {
381 // Container was at max, increase the size of it by one icon.
382 animation_target_size_ = IconCountToWidth(visible_actions + 1);
383
384 // We don't want the chevron to appear while we animate. See documentation
385 // in the header for why we do this.
386 suppress_chevron_ = !chevron_->IsVisible();
387
388 // Animate!
389 resize_animation_->Reset();
390 resize_animation_->SetTweenType(SlideAnimation::NONE);
391 resize_animation_->Show();
392 }
393 }
394
395 void BrowserActionsContainer::RemoveBrowserAction(Extension* extension) {
396 if (!extension->browser_action())
397 return;
398
399 if (popup_ && popup_->host()->extension() == extension) {
400 HidePopup();
401 }
402
403 // Before we change anything, determine the number of visible browser actions.
404 int visible_actions = 0;
405 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
406 if (browser_action_views_[i]->IsVisible())
407 ++visible_actions;
408 }
409
410 for (std::vector<BrowserActionView*>::iterator iter =
411 browser_action_views_.begin(); iter != browser_action_views_.end();
412 ++iter) {
413 if ((*iter)->button()->extension() == extension) {
414 RemoveChildView(*iter);
415 delete *iter;
416 browser_action_views_.erase(iter);
417
418 // For details on why we do the following see the class comments in the
419 // header.
420
421 // Calculate the target size we'll animate to (end state). This might be
422 // the same size (if the icon we are removing is in the overflow bucket
423 // and there are other icons there). We don't decrement visible_actions
424 // because we want the container to stay the same size (clamping will take
425 // care of shrinking the container if there aren't enough icons to show).
426 animation_target_size_ =
427 ClampToNearestIconCount(IconCountToWidth(visible_actions));
428
429 // Animate!
430 resize_animation_->Reset();
431 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
432 resize_animation_->Show();
433 return;
434 }
435 }
436 }
437
438 void BrowserActionsContainer::DeleteBrowserActionViews() { 345 void BrowserActionsContainer::DeleteBrowserActionViews() {
439 if (!browser_action_views_.empty()) { 346 if (!browser_action_views_.empty()) {
440 for (size_t i = 0; i < browser_action_views_.size(); ++i) 347 for (size_t i = 0; i < browser_action_views_.size(); ++i)
441 RemoveChildView(browser_action_views_[i]); 348 RemoveChildView(browser_action_views_[i]);
442 STLDeleteContainerPointers(browser_action_views_.begin(), 349 STLDeleteContainerPointers(browser_action_views_.begin(),
443 browser_action_views_.end()); 350 browser_action_views_.end());
444 browser_action_views_.clear(); 351 browser_action_views_.clear();
445 } 352 }
446 } 353 }
447 354
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 width() - kDividerHorizontalMargin, height(), kDividerVerticalPadding, 516 width() - kDividerHorizontalMargin, height(), kDividerVerticalPadding,
610 DetachableToolbarView::kEdgeDividerColor, 517 DetachableToolbarView::kEdgeDividerColor,
611 DetachableToolbarView::kMiddleDividerColor, 518 DetachableToolbarView::kMiddleDividerColor,
612 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); 519 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
613 } 520 }
614 521
615 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, 522 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
616 views::View* parent, 523 views::View* parent,
617 views::View* child) { 524 views::View* child) {
618 if (is_add && child == this) { 525 if (is_add && child == this) {
526 // Initial toolbar button creation + packing.
619 // We do this here instead of in the constructor because AddBrowserAction 527 // We do this here instead of in the constructor because AddBrowserAction
620 // calls Layout on the Toolbar, which needs this object to be constructed 528 // calls Layout on the Toolbar, which needs this object to be constructed
621 // before its Layout function is called. 529 // before its Layout function is called.
622 ExtensionsService* extension_service = profile_->GetExtensionsService(); 530 for (ExtensionList::iterator iter = model_->begin();
623 if (!extension_service) 531 iter != model_->end(); ++iter) {
624 return; // The |extension_service| can be NULL in Incognito. 532 BrowserActionView* view = new BrowserActionView(*iter, this);
625 for (size_t i = 0; i < extension_service->extensions()->size(); ++i) 533 browser_action_views_.push_back(view);
626 AddBrowserAction(extension_service->extensions()->at(i)); 534 AddChildView(view);
535 }
627 } 536 }
628 } 537 }
629 538
630 void BrowserActionsContainer::Observe(NotificationType type, 539 void BrowserActionsContainer::Observe(NotificationType type,
631 const NotificationSource& source, 540 const NotificationSource& source,
632 const NotificationDetails& details) { 541 const NotificationDetails& details) {
633 switch (type.value) { 542 switch (type.value) {
634 case NotificationType::EXTENSION_LOADED:
635 AddBrowserAction(Details<Extension>(details).ptr());
636 OnBrowserActionVisibilityChanged();
637 break;
638
639 case NotificationType::EXTENSION_UNLOADED:
640 case NotificationType::EXTENSION_UNLOADED_DISABLED:
641 RemoveBrowserAction(Details<Extension>(details).ptr());
642 OnBrowserActionVisibilityChanged();
643 break;
644
645 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: 543 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
646 // If we aren't the host of the popup, then disregard the notification. 544 // If we aren't the host of the popup, then disregard the notification.
647 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details) 545 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details)
648 return; 546 return;
649 547
650 HidePopup(); 548 HidePopup();
651 break; 549 break;
652 550
653 default: 551 default:
654 NOTREACHED() << "Unexpected notification"; 552 NOTREACHED() << "Unexpected notification";
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 } else { 628 } else {
731 // A negative |pixels| count indicates caller wants to know the max width 629 // A negative |pixels| count indicates caller wants to know the max width
732 // that fits all icons; 630 // that fits all icons;
733 icon_count = browser_action_views_.size(); 631 icon_count = browser_action_views_.size();
734 } 632 }
735 633
736 int returning = extras + (icon_count * icon_width); 634 int returning = extras + (icon_count * icon_width);
737 return returning; 635 return returning;
738 } 636 }
739 637
638 void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
639 int index) {
640 #if defined(DEBUG)
641 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
642 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
643 "Asked to add a browser action view for an extension that already "
644 "exists.";
645 }
646 #endif
647
648 // Before we change anything, determine the number of visible browser actions.
649 size_t visible_actions = 0;
650 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
651 if (browser_action_views_[i]->IsVisible())
652 ++visible_actions;
653 }
654
655 // Add the new browser action to the vector and the view hierarchy.
656 BrowserActionView* view = new BrowserActionView(extension, this);
657 browser_action_views_.push_back(view);
658 AddChildView(index, view);
659
660 // For details on why we do the following see the class comments in the
661 // header.
662
663 // Determine if we need to increase (we only do that if the container was
664 // showing all icons before the addition of this icon). We use -1 because
665 // we don't want to count the view that we just added.
666 if (visible_actions < browser_action_views_.size() - 1) {
667 // Some icons were hidden, don't increase the size of the container.
668 OnBrowserActionVisibilityChanged();
669 } else {
670 // Container was at max, increase the size of it by one icon.
671 animation_target_size_ = IconCountToWidth(visible_actions + 1);
672
673 // We don't want the chevron to appear while we animate. See documentation
674 // in the header for why we do this.
675 suppress_chevron_ = !chevron_->IsVisible();
676
677 // Animate!
678 resize_animation_->Reset();
679 resize_animation_->SetTweenType(SlideAnimation::NONE);
680 resize_animation_->Show();
681 }
682 }
683
684 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
685 if (popup_ && popup_->host()->extension() == extension)
686 HidePopup();
687
688 // Before we change anything, determine the number of visible browser actions.
689 int visible_actions = 0;
690 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
691 if (browser_action_views_[i]->IsVisible())
692 ++visible_actions;
693 }
694
695 for (std::vector<BrowserActionView*>::iterator iter =
696 browser_action_views_.begin(); iter != browser_action_views_.end();
697 ++iter) {
698 if ((*iter)->button()->extension() == extension) {
699 RemoveChildView(*iter);
700 delete *iter;
701 browser_action_views_.erase(iter);
702
703 // For details on why we do the following see the class comments in the
704 // header.
705
706 // Calculate the target size we'll animate to (end state). This might be
707 // the same size (if the icon we are removing is in the overflow bucket
708 // and there are other icons there). We don't decrement visible_actions
709 // because we want the container to stay the same size (clamping will take
710 // care of shrinking the container if there aren't enough icons to show).
711 animation_target_size_ =
712 ClampToNearestIconCount(IconCountToWidth(visible_actions));
713
714 // Animate!
715 resize_animation_->Reset();
716 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
717 resize_animation_->Show();
718 return;
719 }
720 }
721 }
722
740 int BrowserActionsContainer::WidthOfNonIconArea() const { 723 int BrowserActionsContainer::WidthOfNonIconArea() const {
741 int chevron_size = (chevron_->IsVisible()) ? 724 int chevron_size = (chevron_->IsVisible()) ?
742 chevron_->GetPreferredSize().width() : 0; 725 chevron_->GetPreferredSize().width() : 0;
743 return resize_gripper_->GetPreferredSize().width() + kHorizontalPadding + 726 return resize_gripper_->GetPreferredSize().width() + kHorizontalPadding +
744 chevron_size + kChevronRightMargin + kDividerHorizontalMargin; 727 chevron_size + kChevronRightMargin + kDividerHorizontalMargin;
745 } 728 }
746 729
747 int BrowserActionsContainer::IconCountToWidth(int icons) const { 730 int BrowserActionsContainer::IconCountToWidth(int icons) const {
748 DCHECK(icons >= 0); 731 DCHECK(icons >= 0);
749 if (icons == 0) 732 if (icons == 0)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 void BrowserActionsContainer::AnimationEnded(const Animation* animation) { 780 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
798 container_size_.set_width(animation_target_size_); 781 container_size_.set_width(animation_target_size_);
799 animation_target_size_ = 0; 782 animation_target_size_ = 0;
800 resize_amount_ = 0; 783 resize_amount_ = 0;
801 OnBrowserActionVisibilityChanged(); 784 OnBrowserActionVisibilityChanged();
802 suppress_chevron_ = false; 785 suppress_chevron_ = false;
803 786
804 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth, 787 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth,
805 container_size_.width()); 788 container_size_.width());
806 } 789 }
OLDNEW
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698