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

Side by Side Diff: chrome/browser/views/extensions/extension_shelf.cc

Issue 175017: Experiment with dislodging the Extension Shelf and having it only appear on t... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/extensions/extension_shelf.h" 5 #include "chrome/browser/views/extensions/extension_shelf.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/stl_util-inl.h" 12 #include "base/stl_util-inl.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "chrome/browser/browser.h" 14 #include "chrome/browser/browser.h"
15 #include "chrome/browser/browser_theme_provider.h"
15 #include "chrome/browser/extensions/extension_host.h" 16 #include "chrome/browser/extensions/extension_host.h"
16 #include "chrome/browser/extensions/extension_process_manager.h" 17 #include "chrome/browser/extensions/extension_process_manager.h"
17 #include "chrome/browser/extensions/extensions_service.h" 18 #include "chrome/browser/extensions/extensions_service.h"
18 #include "chrome/browser/profile.h" 19 #include "chrome/browser/profile.h"
20 #include "chrome/browser/tab_contents/tab_contents.h"
19 #include "chrome/browser/views/extensions/extension_view.h" 21 #include "chrome/browser/views/extensions/extension_view.h"
20 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/notification_service.h" 23 #include "chrome/common/notification_service.h"
24 #include "chrome/common/pref_names.h"
22 #include "skia/ext/skia_utils.h" 25 #include "skia/ext/skia_utils.h"
23 #include "views/controls/label.h" 26 #include "views/controls/label.h"
24 #include "views/screen.h" 27 #include "views/screen.h"
25 #include "views/widget/root_view.h" 28 #include "views/widget/root_view.h"
26 29
27 namespace { 30 namespace {
28 31
29 // Margins around the content. 32 // Margins around the content.
30 static const int kTopMargin = 2; 33 static const int kTopMargin = 2;
31 static const int kBottomMargin = 2; 34 static const int kBottomMargin = 2;
32 static const int kLeftMargin = 0; 35 static const int kLeftMargin = 0;
33 static const int kRightMargin = 0; 36 static const int kRightMargin = 0;
34 37
35 // Padding on left and right side of an extension toolstrip. 38 // Padding on left and right side of an extension toolstrip.
36 static const int kToolstripPadding = 2; 39 static const int kToolstripPadding = 2;
37 40
38 // Width of the toolstrip divider. 41 // Width of the toolstrip divider.
39 static const int kToolstripDividerWidth = 2; 42 static const int kToolstripDividerWidth = 2;
40 43
41 // Preferred height of the ExtensionShelf. 44 // Preferred height of the ExtensionShelf.
42 static const int kShelfHeight = 29; 45 static const int kShelfHeight = 29;
43 46
47 // Preferred height of the Extension shelf when only shown on the new tab page.
48 const int kNewtabShelfHeight = 57;
49
50 // How inset the extension shelf is when displayed on the new tab page. This is
51 // in addition to the margins above.
52 static const int kNewtabHorizontalPadding = 8;
53 static const int kNewtabVerticalPadding = 12;
54
55 // We need an extra margin to the left of all the toolstrips in detached mode,
56 // so that the first toolstrip doesn't look so squished against the rounded
57 // corners of the extension shelf.
58 static const int kNewtabExtraHorMargin = 2;
59 static const int kNewtabExtraVerMargin = 2;
60
61 // How round the 'new tab' style extension shelf is.
62 static const int kNewtabBarRoundness = 5;
63
44 // Height of the toolstrip within the shelf. 64 // Height of the toolstrip within the shelf.
45 static const int kToolstripHeight = kShelfHeight - (kTopMargin + kBottomMargin); 65 static const int kToolstripHeight = kShelfHeight - (kTopMargin + kBottomMargin);
46 66
47 // Colors for the ExtensionShelf. 67 // Colors for the ExtensionShelf.
48 static const SkColor kBackgroundColor = SkColorSetRGB(230, 237, 244); 68 static const SkColor kBackgroundColor = SkColorSetRGB(230, 237, 244);
49 static const SkColor kBorderColor = SkColorSetRGB(201, 212, 225); 69 static const SkColor kBorderColor = SkColorSetRGB(201, 212, 225);
50 static const SkColor kDividerHighlightColor = SkColorSetRGB(247, 250, 253); 70 static const SkColor kDividerHighlightColor = SkColorSetRGB(247, 250, 253);
51 71
52 // Text colors for the handle 72 // Text colors for the handle.
53 static const SkColor kHandleTextColor = SkColorSetRGB(6, 45, 117); 73 static const SkColor kHandleTextColor = SkColorSetRGB(6, 45, 117);
54 static const SkColor kHandleTextHighlightColor = 74 static const SkColor kHandleTextHighlightColor =
55 SkColorSetARGB(200, 255, 255, 255); 75 SkColorSetARGB(200, 255, 255, 255);
56 76
57 // Handle padding 77 // Handle padding.
58 static const int kHandlePadding = 4; 78 static const int kHandlePadding = 4;
59 79
60 // TODO(erikkay) convert back to a gradient when Glen figures out the 80 // TODO(erikkay) convert back to a gradient when Glen figures out the
61 // specs. 81 // specs.
62 // static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); 82 // static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252);
63 // static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); 83 // static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248);
64 84
65 // Delays for showing and hiding the shelf handle. 85 // Delays for showing and hiding the shelf handle.
66 static const int kHideDelayMs = 500; 86 static const int kHideDelayMs = 500;
67 87
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 &ExtensionShelf::Toolstrip::DoHideShelfHandle), 553 &ExtensionShelf::Toolstrip::DoHideShelfHandle),
534 delay_ms); 554 delay_ms);
535 } else { 555 } else {
536 DoHideShelfHandle(); 556 DoHideShelfHandle();
537 } 557 }
538 } 558 }
539 559
540 //////////////////////////////////////////////////////////////////////////////// 560 ////////////////////////////////////////////////////////////////////////////////
541 561
542 ExtensionShelf::ExtensionShelf(Browser* browser) 562 ExtensionShelf::ExtensionShelf(Browser* browser)
543 : model_(browser->extension_shelf_model()) { 563 : model_(browser->extension_shelf_model()),
564 browser_(browser) {
544 model_->AddObserver(this); 565 model_->AddObserver(this);
545 LoadFromModel(); 566 LoadFromModel();
546 EnableCanvasFlippingForRTLUI(true); 567 EnableCanvasFlippingForRTLUI(true);
568 registrar_.Add(this,
569 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED,
570 NotificationService::AllSources());
571
572 size_animation_.reset(new SlideAnimation(this));
573 if (IsAlwaysShown())
574 size_animation_->Reset(1);
575 else
576 size_animation_->Reset(0);
547 } 577 }
548 578
549 ExtensionShelf::~ExtensionShelf() { 579 ExtensionShelf::~ExtensionShelf() {
550 if (model_) { 580 if (model_) {
551 int count = model_->count(); 581 int count = model_->count();
552 for (int i = 0; i < count; ++i) { 582 for (int i = 0; i < count; ++i) {
553 delete ToolstripAtIndex(i); 583 delete ToolstripAtIndex(i);
554 model_->SetToolstripDataAt(i, NULL); 584 model_->SetToolstripDataAt(i, NULL);
555 } 585 }
556 model_->RemoveObserver(this); 586 model_->RemoveObserver(this);
557 } 587 }
558 } 588 }
559 589
560 void ExtensionShelf::Paint(gfx::Canvas* canvas) { 590 void ExtensionShelf::Paint(gfx::Canvas* canvas) {
591 if (IsDetachedStyle()) {
592 // Draw the background to match the new tab page.
593 ThemeProvider* tp = GetThemeProvider();
594 canvas->FillRectInt(
595 tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND),
596 0, 0, width(), height());
597
598 // As 'hidden' according to the animation is the full in-tab state,
599 // we invert the value - when current_state is at '0', we expect the
600 // shelf to be docked.
601 double current_state = 1 - size_animation_->GetCurrentValue();
602
603 // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness.
604 double h_padding = static_cast<double>
605 (kNewtabHorizontalPadding) * current_state;
606 double v_padding = static_cast<double>
607 (kNewtabVerticalPadding) * current_state;
608 SkRect rect;
609 rect.set(SkDoubleToScalar(h_padding - 0.5),
610 SkDoubleToScalar(v_padding - 0.5),
611 SkDoubleToScalar(width() - h_padding - 0.5),
612 SkDoubleToScalar(height() - v_padding - 0.5));
613
614 double roundness = static_cast<double>
615 (kNewtabBarRoundness) * current_state;
616
617 // Draw the background behind the toolstrips.
618 SkPaint paint;
619 paint.setAntiAlias(true);
620 paint.setColor(kBackgroundColor);
621
622 canvas->drawRoundRect(rect,
623 SkDoubleToScalar(roundness),
624 SkDoubleToScalar(roundness), paint);
625
626 SkRect background_rect = {
627 SkIntToScalar(h_padding),
628 SkIntToScalar(v_padding + 2),
629 SkIntToScalar(h_padding + 1),
630 SkIntToScalar(v_padding + kToolstripHeight - 3)};
631 InitBackground(canvas, background_rect);
632
633 // Draw the border around the toolstrips in the extension shelf.
634 SkPaint border_paint;
635 border_paint.setColor(
636 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER));
637 border_paint.setStyle(SkPaint::kStroke_Style);
638 border_paint.setAlpha(96);
639 border_paint.setAntiAlias(true);
640 canvas->drawRoundRect(rect,
641 SkDoubleToScalar(roundness),
642 SkDoubleToScalar(roundness), border_paint);
643 } else {
561 #if 0 644 #if 0
562 // TODO(erikkay) re-enable this when Glen has the gradient values worked out. 645 // TODO(erikkay) Re-enable when Glen has the gradient values worked out.
563 SkPaint paint; 646 SkPaint paint;
564 paint.setShader(skia::CreateGradientShader(0, 647 paint.setShader(skia::CreateGradientShader(0,
565 height(), 648 height(),
566 kTopGradientColor, 649 kTopGradientColor,
567 kBackgroundColor))->safeUnref(); 650 kBackgroundColor))->safeUnref();
568 canvas->FillRectInt(0, 0, width(), height(), paint); 651 canvas->FillRectInt(0, 0, width(), height(), paint);
569 #else 652 #else
570 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); 653 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height());
571 #endif 654 #endif
572 655
573 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); 656 SkRect background_rect = {
574 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); 657 SkIntToScalar(0),
658 SkIntToScalar(0),
659 SkIntToScalar(1),
660 SkIntToScalar(height())
661 };
662 InitBackground(canvas, background_rect);
575 663
664 // Draw border around shelf in attached mode. If we are in detached mode
665 // we've already drawn the borders.
666 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1);
667 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1);
668 }
669
670 // Draw vertical dividers between Toolstrip items in the Extension shelf.
576 int count = GetChildViewCount(); 671 int count = GetChildViewCount();
577 for (int i = 0; i < count; ++i) { 672 for (int i = 0; i < count; ++i) {
578 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; 673 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding;
579 int h = height() - 2; 674 int y = IsDetachedStyle() ? kNewtabVerticalPadding : 1;
580 canvas->FillRectInt(kBorderColor, right, 1, 1, h); 675 int h = IsDetachedStyle() ? height() - (2 * kNewtabVerticalPadding) - 1:
581 canvas->FillRectInt(kDividerHighlightColor, right + 1, 1, 1, h); 676 height() - 2;
677 canvas->FillRectInt(kBorderColor, right, y, 1, h);
678 canvas->FillRectInt(kDividerHighlightColor, right + 1, y, 1, h);
582 } 679 }
680 }
583 681
584 SkRect background_rect = { 682 // static
585 SkIntToScalar(0), 683 void ExtensionShelf::ToggleWhenExtensionShelfVisible(Profile* profile) {
586 SkIntToScalar(1), 684 PrefService* prefs = profile->GetPrefs();
587 SkIntToScalar(1), 685 const bool always_show = !prefs->GetBoolean(prefs::kShowExtensionShelf);
588 SkIntToScalar(height() - 2)}; 686
589 InitBackground(canvas, background_rect); 687 // The user changed when the Extension Shelf is shown, update the
688 // preferences.
689 prefs->SetBoolean(prefs::kShowExtensionShelf, always_show);
690 prefs->ScheduleSavePersistentPrefs();
691
692 // And notify the notification service.
693 Source<Profile> source(profile);
694 NotificationService::current()->Notify(
695 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED,
696 source,
697 NotificationService::NoDetails());
590 } 698 }
591 699
592 gfx::Size ExtensionShelf::GetPreferredSize() { 700 gfx::Size ExtensionShelf::GetPreferredSize() {
593 if (model_->count()) 701 if (!model_->count())
594 return gfx::Size(0, kShelfHeight); 702 return gfx::Size(0, 0);
595 return gfx::Size(0, 0); 703
704 gfx::Size prefsize;
705 if (OnNewTabPage()) {
706 prefsize.set_height(kShelfHeight + static_cast<int>(static_cast<double>
707 (kNewtabShelfHeight - kShelfHeight) *
708 (1 - size_animation_->GetCurrentValue())));
709 } else {
710 prefsize.set_height(static_cast<int>(static_cast<double>(kShelfHeight) *
711 size_animation_->GetCurrentValue()));
712 }
713
714 // Width doesn't matter, we're always given a width based on the browser
715 // size.
716 prefsize.set_width(1);
717
718 return prefsize;
596 } 719 }
597 720
598 void ExtensionShelf::ChildPreferredSizeChanged(View* child) { 721 void ExtensionShelf::ChildPreferredSizeChanged(View* child) {
599 Toolstrip *toolstrip = ToolstripForView(static_cast<ExtensionView*>(child)); 722 Toolstrip *toolstrip = ToolstripForView(static_cast<ExtensionView*>(child));
600 if (!toolstrip) 723 if (!toolstrip)
601 return; 724 return;
602 Layout(); 725 Layout();
603 } 726 }
604 727
605 void ExtensionShelf::Layout() { 728 void ExtensionShelf::Layout() {
606 if (!GetParent()) 729 if (!GetParent())
607 return; 730 return;
608 if (!model_) 731 if (!model_)
609 return; 732 return;
610 733
611 int x = kLeftMargin; 734 int x = kLeftMargin;
612 int y = kTopMargin; 735 int y = kTopMargin;
613 int content_height = height() - kTopMargin - kBottomMargin; 736 int content_height = kShelfHeight - kTopMargin - kBottomMargin;
614 int max_x = width() - kRightMargin; 737 int max_x = width() - kRightMargin;
615 738
739 int max_x_before = max_x;
740
741 if (OnNewTabPage()) {
742 double current_state = 1 - size_animation_->GetCurrentValue();
743 x += static_cast<int>(static_cast<double>
744 (kNewtabHorizontalPadding + kNewtabExtraHorMargin) * current_state);
745 y += static_cast<int>(static_cast<double>
746 (kNewtabVerticalPadding + kNewtabExtraVerMargin) * current_state);
747 max_x -= static_cast<int>(static_cast<double>
748 (kNewtabHorizontalPadding) * current_state);
749 }
750
616 int count = model_->count(); 751 int count = model_->count();
617 for (int i = 0; i < count; ++i) { 752 for (int i = 0; i < count; ++i) {
618 x += kToolstripPadding; // left padding 753 x += kToolstripPadding; // left padding
619 Toolstrip* toolstrip = ToolstripAtIndex(i); 754 Toolstrip* toolstrip = ToolstripAtIndex(i);
620 if (!toolstrip) // can be NULL while in the process of removing 755 if (!toolstrip) // can be NULL while in the process of removing
621 continue; 756 continue;
622 View* view = toolstrip->GetShelfView(); 757 View* view = toolstrip->GetShelfView();
623 gfx::Size pref = view->GetPreferredSize(); 758 gfx::Size pref = view->GetPreferredSize();
624 int next_x = x + pref.width() + kToolstripPadding; // right padding 759 int next_x = x + pref.width() + kToolstripPadding; // right padding
625 if (view == toolstrip->view()) 760 if (view == toolstrip->view())
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 void ExtensionShelf::ShelfModelDeleting() { 856 void ExtensionShelf::ShelfModelDeleting() {
722 int count = model_->count(); 857 int count = model_->count();
723 for (int i = 0; i < count; ++i) { 858 for (int i = 0; i < count; ++i) {
724 delete ToolstripAtIndex(i); 859 delete ToolstripAtIndex(i);
725 model_->SetToolstripDataAt(i, NULL); 860 model_->SetToolstripDataAt(i, NULL);
726 } 861 }
727 model_->RemoveObserver(this); 862 model_->RemoveObserver(this);
728 model_ = NULL; 863 model_ = NULL;
729 } 864 }
730 865
866 void ExtensionShelf::AnimationProgressed(const Animation* animation) {
867 if (browser_)
868 browser_->ExtensionShelfSizeChanged();
869 }
870
871 void ExtensionShelf::AnimationEnded(const Animation* animation) {
872 if (browser_)
873 browser_->ExtensionShelfSizeChanged();
874
875 SchedulePaint();
876 }
877
878 void ExtensionShelf::Observe(NotificationType type,
879 const NotificationSource& source,
880 const NotificationDetails& details) {
881 switch (type.value) {
882 case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: {
883 if (IsAlwaysShown())
884 size_animation_->Show();
885 else
886 size_animation_->Hide();
887 break;
888 }
889 default:
890 NOTREACHED();
891 break;
892 }
893 }
894
731 void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) { 895 void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) {
732 Toolstrip *toolstrip = ToolstripForView(view); 896 Toolstrip *toolstrip = ToolstripForView(view);
733 if (toolstrip) 897 if (toolstrip)
734 toolstrip->ShowShelfHandle(); 898 toolstrip->ShowShelfHandle();
735 } 899 }
736 900
737 void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) { 901 void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) {
738 Toolstrip *toolstrip = ToolstripForView(view); 902 Toolstrip *toolstrip = ToolstripForView(view);
739 if (toolstrip) 903 if (toolstrip)
740 toolstrip->HideShelfHandle(kHideDelayMs); 904 toolstrip->HideShelfHandle(kHideDelayMs);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 return toolstrip; 998 return toolstrip;
835 } 999 }
836 return NULL; 1000 return NULL;
837 } 1001 }
838 1002
839 void ExtensionShelf::LoadFromModel() { 1003 void ExtensionShelf::LoadFromModel() {
840 int count = model_->count(); 1004 int count = model_->count();
841 for (int i = 0; i < count; ++i) 1005 for (int i = 0; i < count; ++i)
842 ToolstripInsertedAt(model_->ToolstripAt(i).host, i); 1006 ToolstripInsertedAt(model_->ToolstripAt(i).host, i);
843 } 1007 }
1008
1009 bool ExtensionShelf::IsDetachedStyle() {
1010 return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1);
1011 }
1012
1013 bool ExtensionShelf::IsAlwaysShown() {
1014 Profile* profile = browser_->profile();
1015 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf);
1016 }
1017
1018 bool ExtensionShelf::OnNewTabPage() {
1019 return (browser_ && browser_->GetSelectedTabContents() &&
1020 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible());
1021 }
OLDNEW
« no previous file with comments | « chrome/browser/views/extensions/extension_shelf.h ('k') | chrome/browser/views/frame/browser_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698