Chromium Code Reviews| 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" |
| 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/browser_theme_provider.h" |
| 16 #include "chrome/browser/extensions/extension_host.h" | 16 #include "chrome/browser/extensions/extension_host.h" |
| 17 #include "chrome/browser/extensions/extension_process_manager.h" | 17 #include "chrome/browser/extensions/extension_process_manager.h" |
| 18 #include "chrome/browser/extensions/extensions_service.h" | 18 #include "chrome/browser/extensions/extensions_service.h" |
| 19 #include "chrome/browser/profile.h" | 19 #include "chrome/browser/profile.h" |
| 20 #include "chrome/browser/tab_contents/tab_contents.h" | 20 #include "chrome/browser/tab_contents/tab_contents.h" |
| 21 #include "chrome/browser/views/extensions/extension_view.h" | 21 #include "chrome/browser/views/extensions/extension_view.h" |
| 22 #include "chrome/common/chrome_switches.h" | |
| 22 #include "chrome/common/extensions/extension.h" | 23 #include "chrome/common/extensions/extension.h" |
| 23 #include "chrome/common/notification_service.h" | 24 #include "chrome/common/notification_service.h" |
| 24 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
| 25 #include "skia/ext/skia_utils.h" | 26 #include "skia/ext/skia_utils.h" |
| 26 #include "views/controls/label.h" | 27 #include "views/controls/label.h" |
| 27 #include "views/screen.h" | 28 #include "views/screen.h" |
| 28 #include "views/widget/root_view.h" | 29 #include "views/widget/root_view.h" |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 // Margins around the content. | 33 // Margins around the content. |
| 33 static const int kTopMargin = 2; | 34 static const int kTopMargin = 2; |
| 34 static const int kBottomMargin = 2; | 35 static const int kBottomMargin = 2; |
| 35 static const int kLeftMargin = 0; | 36 static const int kLeftMargin = 0; |
| 36 static const int kRightMargin = 0; | 37 static const int kRightMargin = 0; |
| 37 | 38 |
| 38 // Padding on left and right side of an extension toolstrip. | 39 // Padding on left and right side of an extension toolstrip. |
| 39 static const int kToolstripPadding = 2; | 40 static const int kToolstripPadding = 2; |
| 40 | 41 |
| 41 // Width of the toolstrip divider. | 42 // Width of the toolstrip divider. |
| 42 static const int kToolstripDividerWidth = 2; | 43 static const int kToolstripDividerWidth = 2; |
| 43 | 44 |
| 44 // Preferred height of the ExtensionShelf. | 45 // Preferred height of the ExtensionShelf. |
| 45 static const int kShelfHeight = 29; | 46 static const int kShelfHeight = 29; |
| 46 | 47 |
| 47 // Preferred height of the Extension shelf when only shown on the new tab page. | 48 // Preferred height of the Extension shelf when only shown on the new tab page. |
| 48 const int kNewtabShelfHeight = 57; | 49 const int kNewtabShelfHeight = 58; |
| 49 | 50 |
| 50 // How inset the extension shelf is when displayed on the new tab page. This is | 51 // How inset the extension shelf is when displayed on the new tab page. This is |
| 51 // in addition to the margins above. | 52 // in addition to the margins above. |
| 52 static const int kNewtabHorizontalPadding = 8; | 53 static const int kNewtabHorizontalPadding = 8; |
| 53 static const int kNewtabVerticalPadding = 12; | 54 static const int kNewtabVerticalPadding = 12; |
| 54 | 55 |
| 55 // We need an extra margin to the left of all the toolstrips in detached mode, | 56 // 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 // so that the first toolstrip doesn't look so squished against the rounded |
| 57 // corners of the extension shelf. | 58 // corners of the extension shelf. |
| 58 static const int kNewtabExtraHorMargin = 2; | 59 static const int kNewtabExtraHorMargin = 2; |
| 59 static const int kNewtabExtraVerMargin = 2; | 60 static const int kNewtabExtraVerMargin = 2; |
| 60 | 61 |
| 61 // How round the 'new tab' style extension shelf is. | |
| 62 static const int kNewtabBarRoundness = 5; | |
| 63 | |
| 64 // Height of the toolstrip within the shelf. | 62 // Height of the toolstrip within the shelf. |
| 65 static const int kToolstripHeight = kShelfHeight - (kTopMargin + kBottomMargin); | 63 static const int kToolstripHeight = kShelfHeight - (kTopMargin + kBottomMargin); |
| 66 | 64 |
| 67 // Colors for the ExtensionShelf. | 65 // Colors for the ExtensionShelf. |
| 68 static const SkColor kBackgroundColor = SkColorSetRGB(230, 237, 244); | |
| 69 static const SkColor kBorderColor = SkColorSetRGB(201, 212, 225); | |
| 70 static const SkColor kDividerHighlightColor = SkColorSetRGB(247, 250, 253); | 66 static const SkColor kDividerHighlightColor = SkColorSetRGB(247, 250, 253); |
| 71 | 67 |
| 72 // Text colors for the handle. | |
| 73 static const SkColor kHandleTextColor = SkColorSetRGB(6, 45, 117); | |
| 74 static const SkColor kHandleTextHighlightColor = | |
| 75 SkColorSetARGB(200, 255, 255, 255); | |
| 76 | |
| 77 // Handle padding. | 68 // Handle padding. |
| 78 static const int kHandlePadding = 4; | 69 static const int kHandlePadding = 4; |
| 79 | 70 |
| 80 // TODO(erikkay) convert back to a gradient when Glen figures out the | |
| 81 // specs. | |
| 82 // static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); | |
| 83 // static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); | |
| 84 | |
| 85 // Delays for showing and hiding the shelf handle. | 71 // Delays for showing and hiding the shelf handle. |
| 86 static const int kHideDelayMs = 500; | 72 static const int kShowDelayMs = 500; |
| 73 static const int kHideDelayMs = 300; | |
| 87 | 74 |
| 88 } // namespace | 75 } // namespace |
| 89 | 76 |
| 90 | 77 |
| 91 // A view that holds the place for a toolstrip in the shelf while the toolstrip | 78 // A view that holds the place for a toolstrip in the shelf while the toolstrip |
| 92 // is being dragged or moved. | 79 // is being dragged or moved. |
| 93 // TODO(erikkay) this should draw a dimmed out version of the toolstrip. | 80 // TODO(erikkay) this should draw a dimmed out version of the toolstrip. |
| 94 class ExtensionShelf::PlaceholderView : public views::View { | 81 class ExtensionShelf::PlaceholderView : public views::View { |
| 95 public: | 82 public: |
| 96 PlaceholderView() {} | 83 PlaceholderView() {} |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 115 public BrowserBubble::Delegate, | 102 public BrowserBubble::Delegate, |
| 116 public AnimationDelegate { | 103 public AnimationDelegate { |
| 117 public: | 104 public: |
| 118 Toolstrip(ExtensionShelf* shelf, ExtensionHost* host, | 105 Toolstrip(ExtensionShelf* shelf, ExtensionHost* host, |
| 119 const Extension::ToolstripInfo& info); | 106 const Extension::ToolstripInfo& info); |
| 120 virtual ~Toolstrip(); | 107 virtual ~Toolstrip(); |
| 121 | 108 |
| 122 // Convenience to calculate just the size of the handle. | 109 // Convenience to calculate just the size of the handle. |
| 123 gfx::Size GetHandlePreferredSize(); | 110 gfx::Size GetHandlePreferredSize(); |
| 124 | 111 |
| 125 // View | 112 // View methods: |
| 126 virtual void Paint(gfx::Canvas* canvas); | 113 virtual void Paint(gfx::Canvas* canvas); |
| 127 virtual gfx::Size GetPreferredSize(); | 114 virtual gfx::Size GetPreferredSize(); |
| 128 virtual void Layout(); | 115 virtual void Layout(); |
| 129 virtual void OnMouseEntered(const views::MouseEvent& event); | 116 virtual void OnMouseEntered(const views::MouseEvent& event); |
| 130 virtual void OnMouseExited(const views::MouseEvent& event); | 117 virtual void OnMouseExited(const views::MouseEvent& event); |
| 131 virtual bool OnMousePressed(const views::MouseEvent& event); | 118 virtual bool OnMousePressed(const views::MouseEvent& event); |
| 132 virtual bool OnMouseDragged(const views::MouseEvent& event); | 119 virtual bool OnMouseDragged(const views::MouseEvent& event); |
| 133 virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); | 120 virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); |
| 134 virtual bool IsFocusable() const { return true; } | 121 virtual bool IsFocusable() const { return true; } |
| 135 virtual void ChildPreferredSizeChanged(View* child); | 122 virtual void ChildPreferredSizeChanged(View* child); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 SetParentOwned(false); | 235 SetParentOwned(false); |
| 249 | 236 |
| 250 mole_animation_.reset(new SlideAnimation(this)); | 237 mole_animation_.reset(new SlideAnimation(this)); |
| 251 | 238 |
| 252 std::wstring name = UTF8ToWide(host_->extension()->name()); | 239 std::wstring name = UTF8ToWide(host_->extension()->name()); |
| 253 // |title_| isn't actually put in the view hierarchy. We just use it | 240 // |title_| isn't actually put in the view hierarchy. We just use it |
| 254 // to draw in place. The reason for this is so that we can properly handle | 241 // to draw in place. The reason for this is so that we can properly handle |
| 255 // the various mouse events necessary for hovering and dragging. | 242 // the various mouse events necessary for hovering and dragging. |
| 256 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 243 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 257 title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont))); | 244 title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont))); |
| 258 title_->SetColor(kHandleTextColor); | |
| 259 title_->SetDrawHighlighted(true); | |
| 260 title_->SetHighlightColor(kHandleTextHighlightColor); | |
| 261 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); | 245 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); |
| 262 title_->SizeToPreferredSize(); | 246 title_->SizeToPreferredSize(); |
| 263 | 247 |
| 264 SizeToPreferredSize(); | 248 SizeToPreferredSize(); |
| 265 } | 249 } |
| 266 | 250 |
| 267 ExtensionShelf::Toolstrip::~Toolstrip() { | 251 ExtensionShelf::Toolstrip::~Toolstrip() { |
| 268 if (handle_.get() && handle_->attached()) | 252 if (handle_.get() && handle_->attached()) |
| 269 handle_->DetachFromBrowser(); | 253 handle_->DetachFromBrowser(); |
| 270 } | 254 } |
| 271 | 255 |
| 272 void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) { | 256 void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) { |
| 273 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); | 257 // Paints the handle for the toolstrip (only called on mouse-hover). |
| 274 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); | 258 SkColor theme_toolbar_color = |
| 275 canvas->FillRectInt(kBorderColor, 0, 0, 1, height() - 1); | 259 shelf_->GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); |
| 276 canvas->FillRectInt(kBorderColor, width() - 1, 0, 1, height() - 1); | 260 canvas->FillRectInt(theme_toolbar_color, 0, 0, width(), height()); |
| 261 | |
| 262 SkColor border_color = ResourceBundle::toolbar_separator_color; | |
| 263 canvas->FillRectInt(border_color, 0, 0, width(), 1); | |
| 264 canvas->FillRectInt(border_color, 0, 0, 1, height() - 1); | |
| 265 canvas->FillRectInt(border_color, width() - 1, 0, 1, height() - 1); | |
| 277 int ext_width = view()->width() + kToolstripPadding + | 266 int ext_width = view()->width() + kToolstripPadding + |
| 278 kToolstripDividerWidth; | 267 kToolstripDividerWidth; |
| 279 if (ext_width < width()) { | 268 if (ext_width < width()) { |
| 280 canvas->FillRectInt(kBorderColor, ext_width, height() - 1, | 269 canvas->FillRectInt(border_color, ext_width, height() - 1, |
| 281 width() - ext_width, 1); | 270 width() - ext_width, 1); |
| 282 } | 271 } |
| 283 | 272 |
| 284 // Draw the title using a Label as a stamp. | 273 // Draw the title using a Label as a stamp. |
| 285 // See constructor for comment about this. | 274 // See constructor for comment about this. |
| 286 title_->ProcessPaint(canvas); | 275 title_->ProcessPaint(canvas); |
| 287 | 276 |
| 288 if (dragging_) { | 277 if (dragging_) { |
| 289 // when we're dragging, draw the bottom border. | 278 // When we're dragging, draw the bottom border. |
| 290 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); | 279 canvas->FillRectInt(border_color, 0, height() - 1, width(), 1); |
| 291 } | 280 } |
| 292 } | 281 } |
| 293 | 282 |
| 294 gfx::Size ExtensionShelf::Toolstrip::GetHandlePreferredSize() { | 283 gfx::Size ExtensionShelf::Toolstrip::GetHandlePreferredSize() { |
| 295 gfx::Size sz = title_->GetPreferredSize(); | 284 gfx::Size sz = title_->GetPreferredSize(); |
| 296 sz.set_width(std::max(view()->width(), sz.width())); | 285 sz.set_width(std::max(view()->width(), sz.width())); |
| 297 if (!expanded_) | 286 if (!expanded_) |
| 298 sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2); | 287 sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2); |
| 299 return sz; | 288 return sz; |
| 300 } | 289 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 placeholder_view_ = NULL; | 501 placeholder_view_ = NULL; |
| 513 | 502 |
| 514 SizeToPreferredSize(); | 503 SizeToPreferredSize(); |
| 515 Layout(); | 504 Layout(); |
| 516 shelf_->Layout(); | 505 shelf_->Layout(); |
| 517 } | 506 } |
| 518 | 507 |
| 519 void ExtensionShelf::Toolstrip::DoShowShelfHandle() { | 508 void ExtensionShelf::Toolstrip::DoShowShelfHandle() { |
| 520 GetHandle(); | 509 GetHandle(); |
| 521 if (!handle_->visible()) { | 510 if (!handle_->visible()) { |
| 511 // Make sure the text color for the title matches the theme colors. | |
| 512 title_->SetColor( | |
| 513 shelf_->GetThemeProvider()->GetColor( | |
| 514 BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); | |
| 515 | |
| 522 LayoutHandle(); | 516 LayoutHandle(); |
| 523 handle_->Show(); | 517 handle_->Show(); |
| 524 } | 518 } |
| 525 } | 519 } |
| 526 | 520 |
| 527 void ExtensionShelf::Toolstrip::DoHideShelfHandle() { | 521 void ExtensionShelf::Toolstrip::DoHideShelfHandle() { |
| 528 if (!handle_visible()) | 522 if (!handle_visible()) |
| 529 return; | 523 return; |
| 530 handle_->Hide(); | 524 handle_->Hide(); |
| 531 if (handle_->attached()) | 525 if (handle_->attached()) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 } | 583 } |
| 590 } | 584 } |
| 591 | 585 |
| 592 void ExtensionShelf::Toolstrip::ShowShelfHandle() { | 586 void ExtensionShelf::Toolstrip::ShowShelfHandle() { |
| 593 StopHandleTimer(); | 587 StopHandleTimer(); |
| 594 if (handle_visible()) | 588 if (handle_visible()) |
| 595 return; | 589 return; |
| 596 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 590 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 597 timer_factory_.NewRunnableMethod( | 591 timer_factory_.NewRunnableMethod( |
| 598 &ExtensionShelf::Toolstrip::DoShowShelfHandle), | 592 &ExtensionShelf::Toolstrip::DoShowShelfHandle), |
| 599 1000); | 593 kShowDelayMs); |
| 600 } | 594 } |
| 601 | 595 |
| 602 void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { | 596 void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { |
| 603 StopHandleTimer(); | 597 StopHandleTimer(); |
| 604 if (!handle_visible() || dragging_ || expanded_ || | 598 if (!handle_visible() || dragging_ || expanded_ || |
| 605 mole_animation_->IsAnimating()) { | 599 mole_animation_->IsAnimating()) { |
| 606 return; | 600 return; |
| 607 } | 601 } |
| 608 if (delay_ms) { | 602 if (delay_ms) { |
| 609 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 603 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 610 timer_factory_.NewRunnableMethod( | 604 timer_factory_.NewRunnableMethod( |
| 611 &ExtensionShelf::Toolstrip::DoHideShelfHandle), | 605 &ExtensionShelf::Toolstrip::DoHideShelfHandle), |
| 612 delay_ms); | 606 delay_ms); |
| 613 } else { | 607 } else { |
| 614 DoHideShelfHandle(); | 608 DoHideShelfHandle(); |
| 615 } | 609 } |
| 616 } | 610 } |
| 617 | 611 |
| 618 //////////////////////////////////////////////////////////////////////////////// | 612 //////////////////////////////////////////////////////////////////////////////// |
| 619 | 613 |
| 620 ExtensionShelf::ExtensionShelf(Browser* browser) | 614 ExtensionShelf::ExtensionShelf(Browser* browser) |
| 621 : browser_(browser), | 615 : background_for_detached_(false), |
| 616 browser_(browser), | |
| 617 background_needs_repaint_(true), | |
| 622 model_(browser->extension_shelf_model()) { | 618 model_(browser->extension_shelf_model()) { |
| 623 model_->AddObserver(this); | 619 model_->AddObserver(this); |
| 624 LoadFromModel(); | 620 LoadFromModel(); |
| 625 EnableCanvasFlippingForRTLUI(true); | 621 EnableCanvasFlippingForRTLUI(true); |
| 626 registrar_.Add(this, | 622 registrar_.Add(this, |
| 627 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED, | 623 NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED, |
| 628 NotificationService::AllSources()); | 624 NotificationService::AllSources()); |
| 629 | 625 |
| 630 size_animation_.reset(new SlideAnimation(this)); | 626 size_animation_.reset(new SlideAnimation(this)); |
| 631 if (IsAlwaysShown()) | 627 if (IsAlwaysShown()) |
| 632 size_animation_->Reset(1); | 628 size_animation_->Reset(1); |
| 633 else | 629 else |
| 634 size_animation_->Reset(0); | 630 size_animation_->Reset(0); |
| 635 } | 631 } |
| 636 | 632 |
| 637 ExtensionShelf::~ExtensionShelf() { | 633 ExtensionShelf::~ExtensionShelf() { |
| 638 if (model_) { | 634 if (model_) { |
| 639 int count = model_->count(); | 635 int count = model_->count(); |
| 640 for (int i = 0; i < count; ++i) { | 636 for (int i = 0; i < count; ++i) { |
| 641 delete ToolstripAtIndex(i); | 637 delete ToolstripAtIndex(i); |
| 642 model_->SetToolstripDataAt(i, NULL); | 638 model_->SetToolstripDataAt(i, NULL); |
| 643 } | 639 } |
| 644 model_->RemoveObserver(this); | 640 model_->RemoveObserver(this); |
| 645 } | 641 } |
| 646 } | 642 } |
| 647 | 643 |
| 648 void ExtensionShelf::Paint(gfx::Canvas* canvas) { | 644 void ExtensionShelf::PaintChildren(gfx::Canvas* canvas) { |
| 649 if (IsDetachedStyle()) { | 645 // Capture a background bitmap to give to the toolstrips. |
| 650 // Draw the background to match the new tab page. | 646 SkRect background_rect = { |
| 651 ThemeProvider* tp = GetThemeProvider(); | 647 SkIntToScalar(0), |
| 652 canvas->FillRectInt( | 648 SkIntToScalar(0), |
| 653 tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND), | 649 SkIntToScalar(width()), |
| 654 0, 0, width(), height()); | 650 SkIntToScalar(height()) |
| 655 | 651 }; |
| 656 // As 'hidden' according to the animation is the full in-tab state, | 652 InitBackground(canvas, background_rect); |
| 657 // we invert the value - when current_state is at '0', we expect the | |
| 658 // shelf to be docked. | |
| 659 double current_state = 1 - size_animation_->GetCurrentValue(); | |
| 660 | |
| 661 // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness. | |
| 662 double h_padding = static_cast<double> | |
| 663 (kNewtabHorizontalPadding) * current_state; | |
| 664 double v_padding = static_cast<double> | |
| 665 (kNewtabVerticalPadding) * current_state; | |
| 666 SkRect rect; | |
| 667 rect.set(SkDoubleToScalar(h_padding - 0.5), | |
| 668 SkDoubleToScalar(v_padding - 0.5), | |
| 669 SkDoubleToScalar(width() - h_padding - 0.5), | |
| 670 SkDoubleToScalar(height() - v_padding - 0.5)); | |
| 671 | |
| 672 double roundness = static_cast<double> | |
| 673 (kNewtabBarRoundness) * current_state; | |
| 674 | |
| 675 // Draw the background behind the toolstrips. | |
| 676 SkPaint paint; | |
| 677 paint.setAntiAlias(true); | |
| 678 paint.setColor(kBackgroundColor); | |
| 679 | |
| 680 canvas->drawRoundRect(rect, | |
| 681 SkDoubleToScalar(roundness), | |
| 682 SkDoubleToScalar(roundness), paint); | |
| 683 | |
| 684 SkRect background_rect = { | |
| 685 SkIntToScalar(h_padding), | |
| 686 SkIntToScalar(v_padding + 2), | |
| 687 SkIntToScalar(h_padding + 1), | |
| 688 SkIntToScalar(v_padding + kToolstripHeight - 3)}; | |
| 689 InitBackground(canvas, background_rect); | |
| 690 | |
| 691 // Draw the border around the toolstrips in the extension shelf. | |
| 692 SkPaint border_paint; | |
| 693 border_paint.setColor( | |
| 694 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER)); | |
| 695 border_paint.setStyle(SkPaint::kStroke_Style); | |
| 696 border_paint.setAlpha(96); | |
| 697 border_paint.setAntiAlias(true); | |
| 698 canvas->drawRoundRect(rect, | |
| 699 SkDoubleToScalar(roundness), | |
| 700 SkDoubleToScalar(roundness), border_paint); | |
| 701 } else { | |
| 702 #if 0 | |
| 703 // TODO(erikkay) Re-enable when Glen has the gradient values worked out. | |
| 704 SkPaint paint; | |
| 705 paint.setShader(skia::CreateGradientShader(0, | |
| 706 height(), | |
| 707 kTopGradientColor, | |
| 708 kBackgroundColor))->safeUnref(); | |
| 709 canvas->FillRectInt(0, 0, width(), height(), paint); | |
| 710 #else | |
| 711 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); | |
| 712 #endif | |
| 713 | |
| 714 SkRect background_rect = { | |
| 715 SkIntToScalar(0), | |
| 716 SkIntToScalar(0), | |
| 717 SkIntToScalar(1), | |
| 718 SkIntToScalar(height()) | |
| 719 }; | |
| 720 InitBackground(canvas, background_rect); | |
| 721 | |
| 722 // Draw border around shelf in attached mode. If we are in detached mode | |
| 723 // we've already drawn the borders. | |
| 724 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); | |
| 725 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); | |
| 726 } | |
| 727 | 653 |
| 728 // Draw vertical dividers between Toolstrip items in the Extension shelf. | 654 // Draw vertical dividers between Toolstrip items in the Extension shelf. |
| 729 int count = GetChildViewCount(); | 655 int count = GetChildViewCount(); |
| 730 for (int i = 0; i < count; ++i) { | 656 for (int i = 0; i < count; ++i) { |
| 731 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; | 657 int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; |
| 732 int y = IsDetachedStyle() ? kNewtabVerticalPadding : 1; | 658 int vertical_padding = IsDetached() ? (height() - kShelfHeight) / 2 : 1; |
| 733 int h = IsDetachedStyle() ? height() - (2 * kNewtabVerticalPadding) - 1: | 659 |
| 734 height() - 2; | 660 DetachableToolbarView::PaintVerticalDivider( |
| 735 canvas->FillRectInt(kBorderColor, right, y, 1, h); | 661 canvas, right, height(), vertical_padding, |
| 736 canvas->FillRectInt(kDividerHighlightColor, right + 1, y, 1, h); | 662 SK_ColorWHITE, |
| 663 kDividerHighlightColor, | |
| 664 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); | |
| 737 } | 665 } |
| 738 } | 666 } |
| 739 | 667 |
| 740 // static | 668 // static |
| 741 void ExtensionShelf::ToggleWhenExtensionShelfVisible(Profile* profile) { | 669 void ExtensionShelf::ToggleWhenExtensionShelfVisible(Profile* profile) { |
| 742 PrefService* prefs = profile->GetPrefs(); | 670 PrefService* prefs = profile->GetPrefs(); |
| 743 const bool always_show = !prefs->GetBoolean(prefs::kShowExtensionShelf); | 671 const bool always_show = !prefs->GetBoolean(prefs::kShowExtensionShelf); |
| 744 | 672 |
| 745 // The user changed when the Extension Shelf is shown, update the | 673 // The user changed when the Extension Shelf is shown, update the |
| 746 // preferences. | 674 // preferences. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 764 if (!toolstrip) | 692 if (!toolstrip) |
| 765 return; | 693 return; |
| 766 | 694 |
| 767 PreferredSizeChanged(); | 695 PreferredSizeChanged(); |
| 768 } | 696 } |
| 769 | 697 |
| 770 void ExtensionShelf::Layout() { | 698 void ExtensionShelf::Layout() { |
| 771 LayoutItems(false); | 699 LayoutItems(false); |
| 772 } | 700 } |
| 773 | 701 |
| 774 | |
| 775 void ExtensionShelf::OnMouseEntered(const views::MouseEvent& event) { | 702 void ExtensionShelf::OnMouseEntered(const views::MouseEvent& event) { |
| 776 } | 703 } |
| 777 | 704 |
| 778 void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) { | 705 void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) { |
| 779 } | 706 } |
| 780 | 707 |
| 781 bool ExtensionShelf::GetAccessibleRole(AccessibilityTypes::Role* role) { | 708 bool ExtensionShelf::GetAccessibleRole(AccessibilityTypes::Role* role) { |
| 782 DCHECK(role); | 709 DCHECK(role); |
| 783 | 710 |
| 784 *role = AccessibilityTypes::ROLE_TOOLBAR; | 711 *role = AccessibilityTypes::ROLE_TOOLBAR; |
| 785 return true; | 712 return true; |
| 786 } | 713 } |
| 787 | 714 |
| 788 bool ExtensionShelf::GetAccessibleName(std::wstring* name) { | 715 bool ExtensionShelf::GetAccessibleName(std::wstring* name) { |
| 789 DCHECK(name); | 716 DCHECK(name); |
| 790 | 717 |
| 791 if (!accessible_name_.empty()) { | 718 if (!accessible_name_.empty()) { |
| 792 name->assign(accessible_name_); | 719 name->assign(accessible_name_); |
| 793 return true; | 720 return true; |
| 794 } | 721 } |
| 795 return false; | 722 return false; |
| 796 } | 723 } |
| 797 | 724 |
| 798 void ExtensionShelf::SetAccessibleName(const std::wstring& name) { | 725 void ExtensionShelf::SetAccessibleName(const std::wstring& name) { |
| 799 accessible_name_.assign(name); | 726 accessible_name_.assign(name); |
| 800 } | 727 } |
| 801 | 728 |
| 729 void ExtensionShelf::ThemeChanged() { | |
| 730 background_needs_repaint_ = true; | |
| 731 | |
| 732 // Refresh the CSS to update toolstrip text colors from theme. | |
| 733 int count = model_->count(); | |
| 734 for (int i = 0; i < count; ++i) | |
| 735 ToolstripAtIndex(i)->view()->host()->InsertCssIfToolstrip(); | |
| 736 | |
| 737 Layout(); | |
| 738 } | |
| 739 | |
| 802 void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, | 740 void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, |
| 803 int index) { | 741 int index) { |
| 804 model_->SetToolstripDataAt(index, | 742 model_->SetToolstripDataAt(index, |
| 805 new Toolstrip(this, host, model_->ToolstripAt(index).info)); | 743 new Toolstrip(this, host, model_->ToolstripAt(index).info)); |
| 806 | 744 |
| 807 bool had_views = GetChildViewCount() > 0; | 745 bool had_views = GetChildViewCount() > 0; |
| 808 ExtensionView* view = host->view(); | 746 ExtensionView* view = host->view(); |
| 809 if (!background_.empty()) | 747 background_needs_repaint_ = true; |
| 810 view->SetBackground(background_); | |
| 811 AddChildView(view); | 748 AddChildView(view); |
| 812 view->SetContainer(this); | 749 view->SetContainer(this); |
| 813 if (!had_views) | 750 if (!had_views) |
| 814 PreferredSizeChanged(); | 751 PreferredSizeChanged(); |
| 815 Layout(); | 752 Layout(); |
| 816 } | 753 } |
| 817 | 754 |
| 818 void ExtensionShelf::ToolstripRemovingAt(ExtensionHost* host, int index) { | 755 void ExtensionShelf::ToolstripRemovingAt(ExtensionHost* host, int index) { |
| 819 // Delete the Toolstrip view and remove it from the model. | 756 // Delete the Toolstrip view and remove it from the model. |
| 820 Toolstrip* toolstrip = ToolstripAtIndex(index); | 757 Toolstrip* toolstrip = ToolstripAtIndex(index); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 | 806 |
| 870 void ExtensionShelf::AnimationProgressed(const Animation* animation) { | 807 void ExtensionShelf::AnimationProgressed(const Animation* animation) { |
| 871 if (browser_) | 808 if (browser_) |
| 872 browser_->ExtensionShelfSizeChanged(); | 809 browser_->ExtensionShelfSizeChanged(); |
| 873 } | 810 } |
| 874 | 811 |
| 875 void ExtensionShelf::AnimationEnded(const Animation* animation) { | 812 void ExtensionShelf::AnimationEnded(const Animation* animation) { |
| 876 if (browser_) | 813 if (browser_) |
| 877 browser_->ExtensionShelfSizeChanged(); | 814 browser_->ExtensionShelfSizeChanged(); |
| 878 | 815 |
| 879 SchedulePaint(); | 816 background_needs_repaint_ = true; |
| 817 Layout(); | |
| 880 } | 818 } |
| 881 | 819 |
| 882 void ExtensionShelf::Observe(NotificationType type, | 820 void ExtensionShelf::Observe(NotificationType type, |
| 883 const NotificationSource& source, | 821 const NotificationSource& source, |
| 884 const NotificationDetails& details) { | 822 const NotificationDetails& details) { |
| 885 switch (type.value) { | 823 switch (type.value) { |
| 886 case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: { | 824 case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: { |
| 887 if (IsAlwaysShown()) | 825 if (IsAlwaysShown()) |
| 888 size_animation_->Show(); | 826 size_animation_->Show(); |
| 889 else | 827 else |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 929 int height) { | 867 int height) { |
| 930 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); | 868 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
| 931 model_->ExpandToolstrip(toolstrip, url, height); | 869 model_->ExpandToolstrip(toolstrip, url, height); |
| 932 } | 870 } |
| 933 | 871 |
| 934 void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { | 872 void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { |
| 935 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); | 873 ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
| 936 model_->CollapseToolstrip(toolstrip, url); | 874 model_->CollapseToolstrip(toolstrip, url); |
| 937 } | 875 } |
| 938 | 876 |
| 939 void ExtensionShelf::InitBackground(gfx::Canvas* canvas, const SkRect& subset) { | 877 void ExtensionShelf::InitBackground( |
| 940 if (!background_.empty()) | 878 gfx::Canvas* canvas, const SkRect& subset) { |
| 879 bool detached = IsDetached(); | |
| 880 if (!background_needs_repaint_ && background_for_detached_ == detached) | |
|
Aaron Boodman
2009/09/17 19:42:38
Seems like you could consolidate these two cases b
Finnur
2009/09/17 22:23:07
Yeah, in my upcoming changelist this flag (backgro
| |
| 941 return; | 881 return; |
| 942 | 882 |
| 943 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); | 883 background_for_detached_ = detached; |
| 944 | |
| 945 // Extract the correct subset of the toolstrip background into a bitmap. We | |
| 946 // must use a temporary here because extractSubset() returns a bitmap that | |
| 947 // references pixels in the original one and we want to actually make a copy | |
| 948 // that will have a long lifetime. | |
| 949 SkBitmap temp; | |
| 950 temp.setConfig(background.config(), | |
| 951 static_cast<int>(subset.width()), | |
| 952 static_cast<int>(subset.height())); | |
| 953 | |
| 954 SkRect mapped_subset = subset; | |
| 955 bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); | |
| 956 DCHECK(result); | |
| 957 | |
| 958 SkIRect isubset; | |
| 959 mapped_subset.round(&isubset); | |
| 960 result = background.extractSubset(&temp, isubset); | |
| 961 if (!result) | |
| 962 return; | |
| 963 | |
| 964 temp.copyTo(&background_, temp.config()); | |
| 965 DCHECK(background_.readyToDraw()); | |
| 966 | 884 |
| 967 // Tell all extension views about the new background | 885 // Tell all extension views about the new background |
| 968 int count = model_->count(); | 886 int count = model_->count(); |
| 969 for (int i = 0; i < count; ++i) | 887 for (int i = 0; i < count; ++i) { |
| 970 ToolstripAtIndex(i)->view()->SetBackground(background_); | 888 ExtensionView* view = ToolstripAtIndex(i)->view(); |
| 889 | |
| 890 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); | |
| 891 | |
| 892 // Extract the correct subset of the toolstrip background into a bitmap. We | |
| 893 // must use a temporary here because extractSubset() returns a bitmap that | |
| 894 // references pixels in the original one and we want to actually make a copy | |
| 895 // that will have a long lifetime. | |
| 896 SkBitmap temp; | |
| 897 temp.setConfig(background.config(), | |
| 898 static_cast<int>(subset.width()), | |
| 899 static_cast<int>(subset.height())); | |
| 900 | |
| 901 SkRect mapped_subset = subset; | |
| 902 gfx::Rect view_bounds = view->bounds(); | |
| 903 mapped_subset.offset(SkIntToScalar(view_bounds.x()), | |
| 904 SkIntToScalar(view_bounds.y())); | |
| 905 bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); | |
| 906 DCHECK(result); | |
| 907 | |
| 908 SkIRect isubset; | |
| 909 mapped_subset.round(&isubset); | |
| 910 result = background.extractSubset(&temp, isubset); | |
| 911 if (!result) | |
| 912 return; | |
| 913 | |
| 914 DCHECK(temp.readyToDraw()); | |
| 915 | |
| 916 view->SetBackground(temp); | |
| 917 } | |
| 918 | |
| 919 background_needs_repaint_ = false; | |
| 971 } | 920 } |
| 972 | 921 |
| 973 ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { | 922 ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { |
| 974 int count = model_->count(); | 923 int count = model_->count(); |
| 975 if (count == 0) | 924 if (count == 0) |
| 976 return NULL; | 925 return NULL; |
| 977 | 926 |
| 978 if (x < 0) | 927 if (x < 0) |
| 979 return NULL; | 928 return NULL; |
| 980 | 929 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 x += static_cast<int>(static_cast<double> | 974 x += static_cast<int>(static_cast<double> |
| 1026 (kNewtabHorizontalPadding + kNewtabExtraHorMargin) * current_state); | 975 (kNewtabHorizontalPadding + kNewtabExtraHorMargin) * current_state); |
| 1027 y += static_cast<int>(static_cast<double> | 976 y += static_cast<int>(static_cast<double> |
| 1028 (kNewtabVerticalPadding + kNewtabExtraVerMargin) * current_state); | 977 (kNewtabVerticalPadding + kNewtabExtraVerMargin) * current_state); |
| 1029 max_x -= static_cast<int>(static_cast<double> | 978 max_x -= static_cast<int>(static_cast<double> |
| 1030 (kNewtabHorizontalPadding) * current_state); | 979 (kNewtabHorizontalPadding) * current_state); |
| 1031 } | 980 } |
| 1032 | 981 |
| 1033 int count = model_->count(); | 982 int count = model_->count(); |
| 1034 for (int i = 0; i < count; ++i) { | 983 for (int i = 0; i < count; ++i) { |
| 1035 x += kToolstripPadding; // left padding | 984 x += kToolstripPadding; // Left padding. |
| 1036 Toolstrip* toolstrip = ToolstripAtIndex(i); | 985 Toolstrip* toolstrip = ToolstripAtIndex(i); |
| 1037 if (!toolstrip) // can be NULL while in the process of removing | 986 if (!toolstrip) // Can be NULL while in the process of removing. |
| 1038 continue; | 987 continue; |
| 1039 View* view = toolstrip->GetShelfView(); | 988 View* view = toolstrip->GetShelfView(); |
| 1040 gfx::Size pref = view->GetPreferredSize(); | 989 gfx::Size pref = view->GetPreferredSize(); |
| 1041 int next_x = x + pref.width() + kToolstripPadding; // right padding | 990 int next_x = x + pref.width() + kToolstripPadding; // Right padding. |
| 1042 if (!compute_bounds_only) { | 991 if (!compute_bounds_only) { |
| 1043 if (view == toolstrip->view()) | 992 if (view == toolstrip->view()) |
| 1044 toolstrip->view()->set_is_clipped(next_x >= max_x); | 993 toolstrip->view()->set_is_clipped(next_x >= max_x); |
| 1045 view->SetBounds(x, y, pref.width(), content_height); | 994 view->SetBounds(x, y, pref.width(), content_height); |
| 1046 view->Layout(); | 995 view->Layout(); |
| 1047 if (toolstrip->handle_visible()) | 996 if (toolstrip->handle_visible()) |
| 1048 toolstrip->LayoutHandle(); | 997 toolstrip->LayoutHandle(); |
| 1049 } | 998 } |
| 1050 x = next_x + kToolstripDividerWidth; | 999 x = next_x + kToolstripDividerWidth; |
| 1051 } | 1000 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1063 size_animation_->GetCurrentValue())); | 1012 size_animation_->GetCurrentValue())); |
| 1064 } | 1013 } |
| 1065 | 1014 |
| 1066 x += kRightMargin; | 1015 x += kRightMargin; |
| 1067 prefsize.set_width(x); | 1016 prefsize.set_width(x); |
| 1068 } | 1017 } |
| 1069 | 1018 |
| 1070 return prefsize; | 1019 return prefsize; |
| 1071 } | 1020 } |
| 1072 | 1021 |
| 1073 bool ExtensionShelf::IsDetachedStyle() { | 1022 bool ExtensionShelf::IsOnTop() const { |
| 1023 static bool is_on_top = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1024 switches::kShowExtensionsOnTop); | |
| 1025 return is_on_top; | |
| 1026 } | |
| 1027 | |
| 1028 bool ExtensionShelf::IsDetached() const { | |
| 1074 return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); | 1029 return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); |
| 1075 } | 1030 } |
| 1076 | 1031 |
| 1077 bool ExtensionShelf::IsAlwaysShown() { | 1032 bool ExtensionShelf::IsAlwaysShown() const { |
| 1078 Profile* profile = browser_->profile(); | 1033 Profile* profile = browser_->profile(); |
| 1079 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); | 1034 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); |
| 1080 } | 1035 } |
| 1081 | 1036 |
| 1082 bool ExtensionShelf::OnNewTabPage() { | 1037 bool ExtensionShelf::OnNewTabPage() const { |
| 1083 return (browser_ && browser_->GetSelectedTabContents() && | 1038 return (browser_ && browser_->GetSelectedTabContents() && |
| 1084 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); | 1039 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); |
| 1085 } | 1040 } |
| OLD | NEW |