| OLD | NEW |
| 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" |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 void ExtensionShelf::Toolstrip::AnimationEnded(const Animation* animation) { | 473 void ExtensionShelf::Toolstrip::AnimationEnded(const Animation* animation) { |
| 474 LayoutHandle(); | 474 LayoutHandle(); |
| 475 if (!expanded_) { | 475 if (!expanded_) { |
| 476 // Must use the delay due to bug 18248. | 476 // Must use the delay due to bug 18248. |
| 477 HideShelfHandle(kHideDelayMs * 2); | 477 HideShelfHandle(kHideDelayMs * 2); |
| 478 AttachToShelf(false); | 478 AttachToShelf(false); |
| 479 } | 479 } |
| 480 } | 480 } |
| 481 | 481 |
| 482 int ExtensionShelf::Toolstrip::GetVerticalTearFromShelfThreshold() { | 482 int ExtensionShelf::Toolstrip::GetVerticalTearFromShelfThreshold() { |
| 483 // TODO (sidchat): Compute this value from the toolstrip height. | 483 // TODO(sidchat): Compute this value from the toolstrip height. |
| 484 return 29; | 484 return 29; |
| 485 } | 485 } |
| 486 | 486 |
| 487 void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) { | 487 void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) { |
| 488 DCHECK(handle_.get()); | 488 DCHECK(handle_.get()); |
| 489 DCHECK(!placeholder_view_); | 489 DCHECK(!placeholder_view_); |
| 490 if (browserDetach && handle_->attached()) | 490 if (browserDetach && handle_->attached()) |
| 491 handle_->DetachFromBrowser(); | 491 handle_->DetachFromBrowser(); |
| 492 | 492 |
| 493 // Construct a placeholder view to replace the view. | 493 // Construct a placeholder view to replace the view. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 delay_ms); | 625 delay_ms); |
| 626 } else { | 626 } else { |
| 627 DoHideShelfHandle(); | 627 DoHideShelfHandle(); |
| 628 } | 628 } |
| 629 } | 629 } |
| 630 | 630 |
| 631 //////////////////////////////////////////////////////////////////////////////// | 631 //////////////////////////////////////////////////////////////////////////////// |
| 632 | 632 |
| 633 ExtensionShelf::ExtensionShelf(Browser* browser) | 633 ExtensionShelf::ExtensionShelf(Browser* browser) |
| 634 : background_needs_repaint_(true), | 634 : background_needs_repaint_(true), |
| 635 background_for_detached_(false), | |
| 636 browser_(browser), | 635 browser_(browser), |
| 637 model_(browser->extension_shelf_model()) { | 636 model_(browser->extension_shelf_model()) { |
| 638 model_->AddObserver(this); | 637 model_->AddObserver(this); |
| 639 LoadFromModel(); | 638 LoadFromModel(); |
| 640 EnableCanvasFlippingForRTLUI(true); | 639 EnableCanvasFlippingForRTLUI(true); |
| 641 registrar_.Add(this, | 640 registrar_.Add(this, |
| 642 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED, | 641 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED, |
| 643 NotificationService::AllSources()); | 642 NotificationService::AllSources()); |
| 644 | 643 |
| 645 size_animation_.reset(new SlideAnimation(this)); | 644 size_animation_.reset(new SlideAnimation(this)); |
| 646 if (IsAlwaysShown()) | 645 if (IsAlwaysShown()) |
| 647 size_animation_->Reset(1); | 646 size_animation_->Reset(1); |
| 648 else | 647 else |
| 649 size_animation_->Reset(0); | 648 size_animation_->Reset(0); |
| 650 } | 649 } |
| 651 | 650 |
| 652 ExtensionShelf::~ExtensionShelf() { | 651 ExtensionShelf::~ExtensionShelf() { |
| 653 if (model_) { | 652 if (model_) { |
| 654 int count = model_->count(); | 653 int count = model_->count(); |
| 655 for (int i = 0; i < count; ++i) { | 654 for (int i = 0; i < count; ++i) { |
| 656 delete ToolstripAtIndex(i); | 655 delete ToolstripAtIndex(i); |
| 657 model_->SetToolstripDataAt(i, NULL); | 656 model_->SetToolstripDataAt(i, NULL); |
| 658 } | 657 } |
| 659 model_->RemoveObserver(this); | 658 model_->RemoveObserver(this); |
| 660 } | 659 } |
| 661 } | 660 } |
| 662 | 661 |
| 663 void ExtensionShelf::PaintChildren(gfx::Canvas* canvas) { | 662 void ExtensionShelf::PaintChildren(gfx::Canvas* canvas) { |
| 664 // Capture a background bitmap to give to the toolstrips. | 663 InitBackground(canvas); |
| 665 SkRect background_rect = { | |
| 666 SkIntToScalar(0), | |
| 667 SkIntToScalar(0), | |
| 668 SkIntToScalar(width()), | |
| 669 SkIntToScalar(height()) | |
| 670 }; | |
| 671 InitBackground(canvas, background_rect); | |
| 672 | 664 |
| 673 // Draw vertical dividers between Toolstrip items in the Extension shelf. | 665 // Draw vertical dividers between Toolstrip items in the Extension shelf. |
| 674 int count = GetChildViewCount(); | 666 int count = GetChildViewCount(); |
| 675 for (int i = 0; i < count; ++i) { | 667 for (int i = 0; i < count; ++i) { |
| 676 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; | 668 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; |
| 677 int vertical_padding = IsDetached() ? (height() - kShelfHeight) / 2 : 1; | 669 int vertical_padding = IsDetached() ? (height() - kShelfHeight) / 2 : 1; |
| 678 | 670 |
| 679 DetachableToolbarView::PaintVerticalDivider( | 671 DetachableToolbarView::PaintVerticalDivider( |
| 680 canvas, right, height(), vertical_padding, | 672 canvas, right, height(), vertical_padding, |
| 681 DetachableToolbarView::kEdgeDividerColor, | 673 DetachableToolbarView::kEdgeDividerColor, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 return true; | 731 return true; |
| 740 } | 732 } |
| 741 return false; | 733 return false; |
| 742 } | 734 } |
| 743 | 735 |
| 744 void ExtensionShelf::SetAccessibleName(const std::wstring& name) { | 736 void ExtensionShelf::SetAccessibleName(const std::wstring& name) { |
| 745 accessible_name_.assign(name); | 737 accessible_name_.assign(name); |
| 746 } | 738 } |
| 747 | 739 |
| 748 void ExtensionShelf::ThemeChanged() { | 740 void ExtensionShelf::ThemeChanged() { |
| 749 background_needs_repaint_ = true; | |
| 750 | |
| 751 // Refresh the CSS to update toolstrip text colors from theme. | 741 // Refresh the CSS to update toolstrip text colors from theme. |
| 752 int count = model_->count(); | 742 int count = model_->count(); |
| 753 for (int i = 0; i < count; ++i) | 743 for (int i = 0; i < count; ++i) |
| 754 ToolstripAtIndex(i)->view()->host()->InsertCssIfToolstrip(); | 744 ToolstripAtIndex(i)->view()->host()->InsertCssIfToolstrip(); |
| 755 | 745 |
| 756 Layout(); | 746 Layout(); |
| 757 } | 747 } |
| 758 | 748 |
| 759 void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, | 749 void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, |
| 760 int index) { | 750 int index) { |
| 761 model_->SetToolstripDataAt(index, | 751 model_->SetToolstripDataAt(index, |
| 762 new Toolstrip(this, host, model_->ToolstripAt(index).info)); | 752 new Toolstrip(this, host, model_->ToolstripAt(index).info)); |
| 763 | 753 |
| 764 bool had_views = GetChildViewCount() > 0; | 754 bool had_views = GetChildViewCount() > 0; |
| 765 ExtensionView* view = host->view(); | 755 ExtensionView* view = host->view(); |
| 766 background_needs_repaint_ = true; | |
| 767 AddChildView(view); | 756 AddChildView(view); |
| 768 view->SetContainer(this); | 757 view->SetContainer(this); |
| 769 if (!had_views) | 758 if (!had_views) |
| 770 PreferredSizeChanged(); | 759 PreferredSizeChanged(); |
| 771 Layout(); | 760 Layout(); |
| 772 } | 761 } |
| 773 | 762 |
| 774 void ExtensionShelf::ToolstripRemovingAt(ExtensionHost* host, int index) { | 763 void ExtensionShelf::ToolstripRemovingAt(ExtensionHost* host, int index) { |
| 775 // Delete the Toolstrip view and remove it from the model. | 764 // Delete the Toolstrip view and remove it from the model. |
| 776 Toolstrip* toolstrip = ToolstripAtIndex(index); | 765 Toolstrip* toolstrip = ToolstripAtIndex(index); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 814 |
| 826 void ExtensionShelf::AnimationProgressed(const Animation* animation) { | 815 void ExtensionShelf::AnimationProgressed(const Animation* animation) { |
| 827 if (browser_) | 816 if (browser_) |
| 828 browser_->ExtensionShelfSizeChanged(); | 817 browser_->ExtensionShelfSizeChanged(); |
| 829 } | 818 } |
| 830 | 819 |
| 831 void ExtensionShelf::AnimationEnded(const Animation* animation) { | 820 void ExtensionShelf::AnimationEnded(const Animation* animation) { |
| 832 if (browser_) | 821 if (browser_) |
| 833 browser_->ExtensionShelfSizeChanged(); | 822 browser_->ExtensionShelfSizeChanged(); |
| 834 | 823 |
| 835 background_needs_repaint_ = true; | |
| 836 Layout(); | 824 Layout(); |
| 837 } | 825 } |
| 838 | 826 |
| 839 void ExtensionShelf::Observe(NotificationType type, | 827 void ExtensionShelf::Observe(NotificationType type, |
| 840 const NotificationSource& source, | 828 const NotificationSource& source, |
| 841 const NotificationDetails& details) { | 829 const NotificationDetails& details) { |
| 842 switch (type.value) { | 830 switch (type.value) { |
| 843 case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: { | 831 case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: { |
| 844 if (IsAlwaysShown()) | 832 if (IsAlwaysShown()) |
| 845 size_animation_->Show(); | 833 size_animation_->Show(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 int height) { | 874 int height) { |
| 887 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); | 875 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
| 888 model_->ExpandToolstrip(toolstrip, url, height); | 876 model_->ExpandToolstrip(toolstrip, url, height); |
| 889 } | 877 } |
| 890 | 878 |
| 891 void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { | 879 void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { |
| 892 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); | 880 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
| 893 model_->CollapseToolstrip(toolstrip, url); | 881 model_->CollapseToolstrip(toolstrip, url); |
| 894 } | 882 } |
| 895 | 883 |
| 896 void ExtensionShelf::InitBackground( | 884 void ExtensionShelf::InitBackground(gfx::Canvas* canvas) { |
| 897 gfx::Canvas* canvas, const SkRect& subset) { | 885 if (!background_needs_repaint_) |
| 898 bool detached = IsDetached(); | |
| 899 if (!background_needs_repaint_ && background_for_detached_ == detached) | |
| 900 return; | 886 return; |
| 901 | 887 |
| 902 background_for_detached_ = detached; | 888 // Capture a background bitmap to give to the toolstrips. |
| 889 SkRect background_rect = { |
| 890 SkIntToScalar(0), |
| 891 SkIntToScalar(0), |
| 892 SkIntToScalar(width()), |
| 893 SkIntToScalar(height()) |
| 894 }; |
| 903 | 895 |
| 904 // Tell all extension views about the new background | 896 // Tell all extension views about the new background. |
| 905 int count = model_->count(); | 897 int count = model_->count(); |
| 906 for (int i = 0; i < count; ++i) { | 898 for (int i = 0; i < count; ++i) { |
| 907 ExtensionView* view = ToolstripAtIndex(i)->view(); | 899 ExtensionView* view = ToolstripAtIndex(i)->view(); |
| 908 | 900 |
| 909 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); | 901 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); |
| 910 | 902 |
| 911 // Extract the correct subset of the toolstrip background into a bitmap. We | 903 SkRect mapped_subset = background_rect; |
| 912 // must use a temporary here because extractSubset() returns a bitmap that | |
| 913 // references pixels in the original one and we want to actually make a copy | |
| 914 // that will have a long lifetime. | |
| 915 SkBitmap temp; | |
| 916 temp.setConfig(background.config(), | |
| 917 static_cast<int>(subset.width()), | |
| 918 static_cast<int>(subset.height())); | |
| 919 | |
| 920 SkRect mapped_subset = subset; | |
| 921 gfx::Rect view_bounds = view->bounds(); | 904 gfx::Rect view_bounds = view->bounds(); |
| 922 mapped_subset.offset(SkIntToScalar(view_bounds.x()), | 905 mapped_subset.offset(SkIntToScalar(view_bounds.x()), |
| 923 SkIntToScalar(view_bounds.y())); | 906 SkIntToScalar(view_bounds.y())); |
| 924 bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); | 907 bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); |
| 925 DCHECK(result); | 908 DCHECK(result); |
| 926 | 909 |
| 927 SkIRect isubset; | 910 SkIRect isubset; |
| 928 mapped_subset.round(&isubset); | 911 mapped_subset.round(&isubset); |
| 929 result = background.extractSubset(&temp, isubset); | 912 SkBitmap subset_bitmap; |
| 913 // This will create another bitmap that just references pixels in the |
| 914 // actual bitmap. |
| 915 result = background.extractSubset(&subset_bitmap, isubset); |
| 930 if (!result) | 916 if (!result) |
| 931 return; | 917 return; |
| 932 | 918 |
| 933 DCHECK(temp.readyToDraw()); | 919 // We do a deep copy because extractSubset() returns a bitmap that |
| 920 // references pixels in the original one and we want to actually make a |
| 921 // smaller copy that will have a long lifetime. |
| 922 SkBitmap smaller_copy; |
| 923 if (!subset_bitmap.copyTo(&smaller_copy, SkBitmap::kARGB_8888_Config)) |
| 924 return; |
| 925 DCHECK(smaller_copy.readyToDraw()); |
| 934 | 926 |
| 935 view->SetBackground(temp); | 927 view->SetBackground(smaller_copy); |
| 936 } | 928 } |
| 937 | 929 |
| 938 background_needs_repaint_ = false; | 930 background_needs_repaint_ = false; |
| 939 } | 931 } |
| 940 | 932 |
| 941 ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { | 933 ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { |
| 942 int count = model_->count(); | 934 int count = model_->count(); |
| 943 if (count == 0) | 935 if (count == 0) |
| 944 return NULL; | 936 return NULL; |
| 945 | 937 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 if (view == toolstrip->view()) | 1004 if (view == toolstrip->view()) |
| 1013 toolstrip->view()->set_is_clipped(next_x >= max_x); | 1005 toolstrip->view()->set_is_clipped(next_x >= max_x); |
| 1014 view->SetBounds(x, y, pref.width(), content_height); | 1006 view->SetBounds(x, y, pref.width(), content_height); |
| 1015 view->Layout(); | 1007 view->Layout(); |
| 1016 if (toolstrip->handle_visible()) | 1008 if (toolstrip->handle_visible()) |
| 1017 toolstrip->LayoutHandle(); | 1009 toolstrip->LayoutHandle(); |
| 1018 } | 1010 } |
| 1019 x = next_x + kToolstripDividerWidth; | 1011 x = next_x + kToolstripDividerWidth; |
| 1020 } | 1012 } |
| 1021 | 1013 |
| 1022 if (!compute_bounds_only) | 1014 if (!compute_bounds_only) { |
| 1015 background_needs_repaint_ = true; |
| 1023 SchedulePaint(); | 1016 SchedulePaint(); |
| 1024 | 1017 } else { |
| 1025 if (compute_bounds_only) { | |
| 1026 if (OnNewTabPage()) { | 1018 if (OnNewTabPage()) { |
| 1027 prefsize.set_height(kShelfHeight + static_cast<int>(static_cast<double> | 1019 prefsize.set_height(kShelfHeight + static_cast<int>(static_cast<double> |
| 1028 (kNewtabShelfHeight - kShelfHeight) * | 1020 (kNewtabShelfHeight - kShelfHeight) * |
| 1029 (1 - size_animation_->GetCurrentValue()))); | 1021 (1 - size_animation_->GetCurrentValue()))); |
| 1030 } else { | 1022 } else { |
| 1031 prefsize.set_height(static_cast<int>(static_cast<double>(kShelfHeight) * | 1023 prefsize.set_height(static_cast<int>(static_cast<double>(kShelfHeight) * |
| 1032 size_animation_->GetCurrentValue())); | 1024 size_animation_->GetCurrentValue())); |
| 1033 } | 1025 } |
| 1034 | 1026 |
| 1035 x += kRightMargin; | 1027 x += kRightMargin; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1051 | 1043 |
| 1052 bool ExtensionShelf::IsAlwaysShown() const { | 1044 bool ExtensionShelf::IsAlwaysShown() const { |
| 1053 Profile* profile = browser_->profile(); | 1045 Profile* profile = browser_->profile(); |
| 1054 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); | 1046 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); |
| 1055 } | 1047 } |
| 1056 | 1048 |
| 1057 bool ExtensionShelf::OnNewTabPage() const { | 1049 bool ExtensionShelf::OnNewTabPage() const { |
| 1058 return (browser_ && browser_->GetSelectedTabContents() && | 1050 return (browser_ && browser_->GetSelectedTabContents() && |
| 1059 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); | 1051 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); |
| 1060 } | 1052 } |
| OLD | NEW |