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

Unified Diff: chrome/browser/views/extensions/extension_shelf.cc

Issue 3129003: remove toolstrips (Closed)
Patch Set: merge Created 10 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/views/extensions/extension_shelf.cc
diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc
deleted file mode 100644
index 000c9889fbaca52aa3062e4f481423bb386cbe56..0000000000000000000000000000000000000000
--- a/chrome/browser/views/extensions/extension_shelf.cc
+++ /dev/null
@@ -1,1108 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/views/extensions/extension_shelf.h"
-
-#include <algorithm>
-
-#include "app/resource_bundle.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_theme_provider.h"
-#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/extensions/extension_view.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/pref_names.h"
-#include "gfx/canvas_skia.h"
-#include "views/controls/label.h"
-#include "views/screen.h"
-#include "views/widget/root_view.h"
-
-namespace {
-
-// This is the slight padding that is there around the edge of the browser. This
-// has been determined empirically.
-// TODO(sidchat): Compute this value from the root view of the extension shelf.
-static const int kExtensionShelfPaddingOnLeft = 4;
-
-// Margins around the content.
-static const int kTopMarginWhenExtensionsOnTop = 1;
-static const int kTopMarginWhenExtensionsOnBottom = 2;
-static const int kBottomMargin = 2;
-static const int kLeftMargin = 0;
-static const int kRightMargin = 0;
-
-// Padding on left and right side of an extension toolstrip.
-static const int kToolstripPadding = 2;
-
-// Width of the toolstrip divider.
-static const int kToolstripDividerWidth = 2;
-
-// Preferred height of the ExtensionShelf.
-static const int kShelfHeight = 29;
-
-// Preferred height of the Extension shelf when only shown on the new tab page.
-const int kNewtabShelfHeight = 58;
-
-// How inset the extension shelf is when displayed on the new tab page. This is
-// in addition to the margins above.
-static const int kNewtabHorizontalPadding = 8;
-static const int kNewtabVerticalPadding = 12;
-
-// We need an extra margin to the left of all the toolstrips in detached mode,
-// so that the first toolstrip doesn't look so squished against the rounded
-// corners of the extension shelf.
-static const int kNewtabExtraHorMargin = 2;
-static const int kNewtabExtraVerMargin = 2;
-
-// Padding for the title inside the handle.
-static const int kHandlePadding = 4;
-
-// Inset for the extension view when displayed either dragging or expanded.
-static const int kWindowInset = 1;
-
-// Delays for showing and hiding the shelf handle.
-static const int kShowDelayMs = 500;
-static const int kHideDelayMs = 300;
-
-} // namespace
-
-
-// A view that holds the place for a toolstrip in the shelf while the toolstrip
-// is being dragged or moved.
-// TODO(erikkay) this should draw a dimmed out version of the toolstrip.
-class ExtensionShelf::PlaceholderView : public views::View {
- public:
- PlaceholderView() {}
-
- void SetWidth(int width) {
- SetBounds(x(), y(), width, height());
- PreferredSizeChanged();
- }
-
- // ExtensionShelf resizes its views to their preferred size at layout,
- // so just always prefer the current size.
- gfx::Size GetPreferredSize() { return size(); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PlaceholderView);
-};
-
-// A wrapper class for the ExtensionHost displayed as a toolstrip.
-// The class itself also acts as the View for the handle of the toolstrip
-// it represents.
-class ExtensionShelf::Toolstrip : public views::View,
- public BrowserBubble::Delegate,
- public AnimationDelegate {
- public:
- Toolstrip(ExtensionShelf* shelf, ExtensionHost* host,
- const Extension::ToolstripInfo& info);
- virtual ~Toolstrip();
-
- // Convenience to calculate just the size of the handle.
- gfx::Size GetHandlePreferredSize();
-
- // View methods:
- virtual void Paint(gfx::Canvas* canvas);
- virtual gfx::Size GetPreferredSize();
- virtual void Layout();
- virtual void OnMouseEntered(const views::MouseEvent& event);
- virtual void OnMouseExited(const views::MouseEvent& event);
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual bool OnMouseDragged(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
- virtual bool IsFocusable() const { return true; }
- virtual void ChildPreferredSizeChanged(View* child);
-
- // Adjust the size and position of the window/handle.
- void LayoutWindow();
-
- // Is the toolstrip window visible (not necessarily the handle).
- bool window_visible() { return (window_.get() && window_->visible()); }
-
- // Is the handle for this toolstrip currently visible.
- bool handle_visible() { return (window_visible() && handle_visible_); }
-
- // Is the toolstrip opened in expanded mode.
- bool expanded() { return expanded_; }
-
- // Is the toolstrip being dragged.
- bool dragging() { return dragging_; }
-
- // Accessors for the host and its view.
- ExtensionHost* host() const { return host_; }
- ExtensionView* view() const { return host_->view(); }
-
- // The view that's currently displayed in the shelf. This could be
- // either the ExtensionView or |placeholder_view_| depending on the
- // current state.
- View* GetShelfView() const {
- if (placeholder_view_)
- return placeholder_view_;
- return view();
- }
-
- // Detaching the toolstrip from the shelf means that the ExtensionView is
- // displayed inside of the BrowserBubble rather than the shelf. This may
- // still visually appear to be part of the shelf (expanded) or completely
- // separate (dragging).
- // If |browser| is true, it also will detach/attach to the browser window.
- void DetachFromShelf(bool browser);
- void AttachToShelf(bool browser);
-
- // Show / Hide the shelf handle.
- void ShowShelfHandle();
- void DoShowShelfHandle();
- void HideShelfHandle(int delay_ms);
- void DoHideShelfHandle();
- void StopHandleTimer();
- void HideWindow();
- void ShowWindow();
-
- // Expand / Collapse
- void Expand(int height, const GURL& url);
- void Collapse(const GURL& url);
-
- // BrowserBubble::Delegate
- virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble);
- virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble);
-
- // AnimationDelegate
- virtual void AnimationProgressed(const Animation* animation);
- virtual void AnimationEnded(const Animation* animation);
-
- private:
- // The actual renderer that this toolstrip contains.
- ExtensionHost* host_;
-
- // Manifest definition of this toolstrip.
- Extension::ToolstripInfo info_;
-
- // A window that can be logically attached to the browser window. This is
- // used for two purposes: a handle that sits above the toolstrip when it's
- // collapsed and not dragging, and as a container for the toolstrip when it's
- // dragging or expanded.
- scoped_ptr<BrowserBubble> window_;
-
- // Used for drawing the name of the extension in the handle.
- scoped_ptr<views::Label> title_;
-
- // Pointer back to the containing shelf.
- ExtensionShelf* shelf_;
-
- // When dragging, a placeholder view is put into the shelf to hold space
- // for the ExtensionView. This view is parent owned when it's in the view
- // hierarchy, so there's no ownership issues here.
- PlaceholderView* placeholder_view_;
-
- // Current state of the toolstrip, currently can't both be expanded and
- // dragging.
- // TODO(erikkay) Support dragging while expanded.
- bool dragging_;
- bool expanded_;
- bool handle_visible_;
-
- // The target expanded height of the toolstrip (used for animation).
- int expanded_height_;
-
- // If dragging, where did the drag start from.
- gfx::Point initial_drag_location_;
-
- // We have to remember the initial drag point in screen coordinates, because
- // later, when the toolstrip is being dragged around, there is no good way of
- // computing the screen coordinates given the initial drag view coordinates.
- gfx::Point initial_drag_screen_point_;
-
- // Timers for tracking mouse hovering.
- ScopedRunnableMethodFactory<ExtensionShelf::Toolstrip> timer_factory_;
-
- // Animate opening and closing the mole.
- scoped_ptr<SlideAnimation> mole_animation_;
-
- DISALLOW_COPY_AND_ASSIGN(Toolstrip);
-};
-
-ExtensionShelf::Toolstrip::Toolstrip(ExtensionShelf* shelf,
- ExtensionHost* host,
- const Extension::ToolstripInfo& info)
- : host_(host),
- info_(info),
- shelf_(shelf),
- placeholder_view_(NULL),
- dragging_(false),
- expanded_(false),
- handle_visible_(false),
- expanded_height_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) {
- DCHECK(host->view());
- // We're owned by shelf_, not the bubble that we get inserted in and out of.
- set_parent_owned(false);
-
- mole_animation_.reset(new SlideAnimation(this));
-
- std::wstring name = UTF8ToWide(host_->extension()->name());
- // |title_| isn't actually put in the view hierarchy. We just use it
- // to draw in place. The reason for this is so that we can properly handle
- // the various mouse events necessary for hovering and dragging.
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont)));
- title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100);
- title_->SizeToPreferredSize();
-
- SizeToPreferredSize();
-}
-
-ExtensionShelf::Toolstrip::~Toolstrip() {
- if (window_.get() && window_->attached())
- window_->DetachFromBrowser();
-}
-
-void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) {
- // Paint the background.
- SkColor theme_toolbar_color =
- shelf_->GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR);
- canvas->FillRectInt(theme_toolbar_color, 0, 0, width(), height());
-
- // Paints the handle for the toolstrip (only called on mouse-hover).
- SkColor border_color = ResourceBundle::toolbar_separator_color;
- canvas->FillRectInt(border_color, 0, 0, width(), 1);
- canvas->FillRectInt(border_color, 0, 0, 1, height() - 1);
- canvas->FillRectInt(border_color, width() - 1, 0, 1, height() - 1);
- int ext_width = view()->width() + kToolstripPadding +
- kToolstripDividerWidth;
- if (ext_width < width()) {
- canvas->FillRectInt(border_color, ext_width, height() - 1,
- width() - ext_width, 1);
- }
-
- if (handle_visible_) {
- // Draw the title using a Label as a stamp.
- // See constructor for comment about this.
- title_->ProcessPaint(canvas);
-
- if (dragging_) {
- // When we're dragging, draw the bottom border.
- canvas->FillRectInt(border_color, 0, height() - 1, width(), 1);
- }
- }
-}
-
-gfx::Size ExtensionShelf::Toolstrip::GetHandlePreferredSize() {
- gfx::Size sz;
- if (handle_visible_) {
- sz = title_->GetPreferredSize();
- sz.set_width(std::max(view()->width(), sz.width()));
- sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2);
- }
- return sz;
-}
-
-gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() {
- gfx::Size sz;
- if (handle_visible_)
- sz = GetHandlePreferredSize();
- if (view()->GetParent() == this) {
- gfx::Size extension_size = view()->GetPreferredSize();
- sz.Enlarge(0, extension_size.height());
- sz.set_width(extension_size.width());
- }
-
- // The view is inset slightly when displayed in the window.
- sz.Enlarge(kWindowInset * 2, kWindowInset * 2);
- return sz;
-}
-
-void ExtensionShelf::Toolstrip::Layout() {
- if (view()->GetParent() == this) {
- int view_y = kWindowInset;
- if (handle_visible_)
- view_y += GetHandlePreferredSize().height();
- view()->SetBounds(kWindowInset, view_y, view()->width(), view()->height());
- }
-}
-
-void ExtensionShelf::Toolstrip::OnMouseEntered(const views::MouseEvent& event) {
- if (dragging_)
- return;
- ShowShelfHandle();
-}
-
-void ExtensionShelf::Toolstrip::OnMouseExited(const views::MouseEvent& event) {
- if (dragging_)
- return;
- HideShelfHandle(kHideDelayMs);
-}
-
-bool ExtensionShelf::Toolstrip::OnMousePressed(const views::MouseEvent& event) {
- initial_drag_location_ = event.location();
- initial_drag_screen_point_ = views::Screen::GetCursorScreenPoint();
- return true;
-}
-
-bool ExtensionShelf::Toolstrip::OnMouseDragged(const views::MouseEvent& event) {
- if (expanded_) {
- // Do nothing for now.
- } else if (!dragging_) {
- int y_delta = abs(initial_drag_location_.y() - event.location().y());
- int x_delta = abs(initial_drag_location_.x() - event.location().x());
- if (y_delta > GetVerticalDragThreshold() ||
- x_delta > GetHorizontalDragThreshold()) {
- dragging_ = true;
- StopHandleTimer();
- DetachFromShelf(true);
- }
- } else {
- // When freely dragging a window, you can really only trust the
- // actual screen point. Local coordinate conversions don't work.
- gfx::Point screen = views::Screen::GetCursorScreenPoint();
-
- // However, the handle is actually a child of the browser window
- // so we need to convert it back to local coordinates.
- gfx::Point origin(0, 0);
- views::View::ConvertPointToScreen(shelf_->GetRootView(), &origin);
- int screen_x = screen.x() - initial_drag_location_.x() - origin.x();
-
- // Restrict the horizontal and vertical motions of the toolstrip so that it
- // cannot be dragged out of the extension shelf. If the extension shelf is
- // on the top along with the bookmark bar, the toolstrip cannot be dragged
- // into the space allocated for bookmarks. The toolstrip cannot be dragged
- // out of the browser window.
- if (screen_x < kExtensionShelfPaddingOnLeft) {
- screen_x = kExtensionShelfPaddingOnLeft;
- } else if (screen_x > shelf_->width() - width() +
- kExtensionShelfPaddingOnLeft) {
- screen_x = shelf_->width() - width() + kExtensionShelfPaddingOnLeft;
- }
- screen.set_x(screen_x);
- screen.set_y(initial_drag_screen_point_.y() - origin.y() -
- initial_drag_location_.y());
-
- // TODO(erikkay) as this gets dragged around, update the placeholder view
- // on the shelf to show where it will get dropped to.
- window_->MoveTo(screen.x(), screen.y());
- }
- return true;
-}
-
-void ExtensionShelf::Toolstrip::OnMouseReleased(const views::MouseEvent& event,
- bool canceled) {
- StopHandleTimer();
- if (dragging_) {
- // Drop the toolstrip roughly where it is now.
- views::View::OnMouseReleased(event, canceled);
- dragging_ = false;
- // |this| and |shelf_| are in different view hierarchies, so we need to
- // convert to screen coordinates and back again to map locations.
- gfx::Point loc = event.location();
- View::ConvertPointToScreen(this, &loc);
- View::ConvertPointToView(NULL, shelf_, &loc);
- shelf_->DropExtension(this, loc, canceled);
- AttachToShelf(true);
- } else if (!canceled) {
- // Toggle mole to either expanded or collapsed.
- // TODO(erikkay) If there's no valid URL in the manifest, should we
- // post an event to the toolstrip in this case?
- if (expanded_) {
- if (info_.toolstrip.is_valid())
- shelf_->CollapseToolstrip(host_, info_.toolstrip);
- } else {
- if (info_.mole.is_valid())
- shelf_->ExpandToolstrip(host_, info_.mole, info_.mole_height);
- }
- }
-}
-
-void ExtensionShelf::Toolstrip::LayoutWindow() {
- if (!window_visible() && !handle_visible_ && !expanded_)
- return;
-
- if (!window_.get()) {
- window_.reset(new BrowserBubble(this, shelf_->GetWidget(),
- gfx::Point(0, 0),
- false)); // Do not add a drop-shadow.
- window_->set_delegate(this);
- }
-
- gfx::Size window_size = GetPreferredSize();
- if (mole_animation_->is_animating()) {
- // We only want to animate the body of the mole window. When we're
- // expanding, this is everything except for the handle. When we're
- // collapsing, this is everything except for the handle and the toolstrip.
- // We subtract this amount from the target height, figure out the step in
- // the animation from the rest, and then add it back in.
- int window_offset = shelf_->height();
- if (!mole_animation_->IsShowing())
- window_offset += GetPreferredSize().height();
- else
- window_offset += GetHandlePreferredSize().height();
- int h = expanded_height_ - window_offset;
- window_size.set_height(window_offset +
- static_cast<int>(h * mole_animation_->GetCurrentValue()));
- } else if (!expanded_ && !dragging_) {
- window_size.set_height(GetHandlePreferredSize().height());
- }
-
- // Now figure out where to place the window on the screen. Since it's a top-
- // level widget, we need to do some coordinate conversion to get this right.
- gfx::Point origin(-kToolstripPadding, 0);
- if (expanded_ || mole_animation_->is_animating()) {
- origin.set_y(GetShelfView()->height() - window_size.height());
- views::View::ConvertPointToView(GetShelfView(), shelf_->GetRootView(),
- &origin);
- } else {
- origin.set_y(-(window_size.height() + kToolstripPadding - 1));
- views::View::ConvertPointToWidget(view(), &origin);
- }
- SetBounds(0, 0, window_size.width(), window_size.height());
- window_->SetBounds(origin.x(), origin.y(),
- window_size.width(), window_size.height());
-}
-
-void ExtensionShelf::Toolstrip::ChildPreferredSizeChanged(View* child) {
- if (child == view()) {
- child->SizeToPreferredSize();
- Layout();
- if (window_visible())
- LayoutWindow();
- if (expanded_) {
- placeholder_view_->SetWidth(child->width());
- shelf_->Layout();
- }
- }
-}
-
-void ExtensionShelf::Toolstrip::BubbleBrowserWindowMoved(
- BrowserBubble* bubble) {
- if (!expanded_)
- HideWindow();
-}
-
-void ExtensionShelf::Toolstrip::BubbleBrowserWindowClosing(
- BrowserBubble* bubble) {
- HideWindow();
-}
-
-void ExtensionShelf::Toolstrip::AnimationProgressed(
- const Animation* animation) {
- LayoutWindow();
-}
-
-void ExtensionShelf::Toolstrip::AnimationEnded(const Animation* animation) {
- if (window_visible())
- LayoutWindow();
- if (!expanded_) {
- AttachToShelf(false);
- HideShelfHandle(kHideDelayMs);
- }
-}
-
-void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) {
- DCHECK(window_.get());
- DCHECK(!placeholder_view_);
- if (browserDetach && window_->attached())
- window_->DetachFromBrowser();
-
- // Construct a placeholder view to replace the view.
- placeholder_view_ = new PlaceholderView();
- placeholder_view_->SetBounds(view()->bounds());
- shelf_->AddChildView(placeholder_view_);
-
- AddChildView(view());
- SizeToPreferredSize();
- window_->ResizeToView();
- Layout();
-}
-
-void ExtensionShelf::Toolstrip::AttachToShelf(bool browserAttach) {
- DCHECK(window_.get());
- DCHECK(placeholder_view_);
- if (browserAttach && !window_->attached())
- window_->AttachToBrowser();
-
- // Move the view back into the shelf and remove the old placeholder.
- shelf_->AddChildView(view());
-
- // The size of the view may have changed, so just set the position.
- view()->SetX(placeholder_view_->x());
- view()->SetY(placeholder_view_->y());
-
- // Remove the old placeholder.
- shelf_->RemoveChildView(placeholder_view_);
- delete placeholder_view_;
- placeholder_view_ = NULL;
-
- SizeToPreferredSize();
- Layout();
- shelf_->Layout();
-}
-
-void ExtensionShelf::Toolstrip::DoShowShelfHandle() {
- if (!handle_visible()) {
- handle_visible_ = true;
-
- // Make sure the text color for the title matches the theme colors.
- title_->SetColor(
- shelf_->GetThemeProvider()->GetColor(
- BrowserThemeProvider::COLOR_BOOKMARK_TEXT));
-
- ShowWindow();
- }
-}
-
-void ExtensionShelf::Toolstrip::HideWindow() {
- if (!window_visible())
- return;
- handle_visible_ = false;
- window_->Hide();
- if (expanded_) {
- if (info_.toolstrip.is_valid())
- shelf_->CollapseToolstrip(host_, info_.toolstrip);
- else
- shelf_->CollapseToolstrip(host_, GURL());
- }
- if (window_->attached())
- window_->DetachFromBrowser();
- window_.reset(NULL);
- shelf_->Layout();
-}
-
-void ExtensionShelf::Toolstrip::ShowWindow() {
- DCHECK(handle_visible_ || expanded_);
-
- LayoutWindow();
- if (!window_visible())
- window_->Show(false); // |false| means show, but don't activate.
-}
-
-void ExtensionShelf::Toolstrip::DoHideShelfHandle() {
- if (!handle_visible())
- return;
- handle_visible_ = false;
- if (expanded_) {
- LayoutWindow();
- Layout();
- } else {
- HideWindow();
- }
-}
-
-void ExtensionShelf::Toolstrip::StopHandleTimer() {
- if (!timer_factory_.empty())
- timer_factory_.RevokeAll();
-}
-
-void ExtensionShelf::Toolstrip::Expand(int height, const GURL& url) {
- DCHECK(!expanded_);
-
- expanded_ = true;
- ShowWindow();
-
- bool navigate = (!url.is_empty() && url != host_->GetURL());
- if (navigate)
- host_->NavigateToURL(url);
-
- StopHandleTimer();
- DetachFromShelf(false);
-
- mole_animation_->Show();
-
- gfx::Size extension_size = view()->GetPreferredSize();
- extension_size.set_height(height);
- view()->SetPreferredSize(extension_size);
- expanded_height_ = GetPreferredSize().height();
-
- // This is to prevent flickering as the page loads and lays out.
- // Once the navigation is finished, ExtensionView will wind up setting
- // visibility to true.
- if (navigate)
- view()->SetVisible(false);
-}
-
-void ExtensionShelf::Toolstrip::Collapse(const GURL& url) {
- DCHECK(expanded_);
- expanded_ = false;
-
- if (window_visible())
- mole_animation_->Hide();
-
- gfx::Size extension_size = view()->GetPreferredSize();
- extension_size.set_height(
- kShelfHeight - (shelf_->top_margin() + kBottomMargin));
- view()->SetPreferredSize(extension_size);
-
- if (!url.is_empty() && url != host_->GetURL()) {
- host_->NavigateToURL(url);
-
- // This is to prevent flickering as the page loads and lays out.
- // Once the navigation is finished, ExtensionView will wind up setting
- // visibility to true.
- view()->SetVisible(false);
- }
-
- if (!window_visible())
- AnimationEnded(NULL);
-}
-
-void ExtensionShelf::Toolstrip::ShowShelfHandle() {
- StopHandleTimer();
- if (handle_visible())
- return;
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- timer_factory_.NewRunnableMethod(
- &ExtensionShelf::Toolstrip::DoShowShelfHandle),
- kShowDelayMs);
-}
-
-void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) {
- StopHandleTimer();
- if (!handle_visible() || dragging_ || mole_animation_->is_animating())
- return;
- if (delay_ms) {
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- timer_factory_.NewRunnableMethod(
- &ExtensionShelf::Toolstrip::DoHideShelfHandle),
- delay_ms);
- } else {
- DoHideShelfHandle();
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-ExtensionShelf::ExtensionShelf(Browser* browser)
- : background_needs_repaint_(true),
- browser_(browser),
- model_(browser->extension_shelf_model()),
- fullscreen_(false) {
- SetID(VIEW_ID_DEV_EXTENSION_SHELF);
-
- top_margin_ = kTopMarginWhenExtensionsOnBottom;
-
- model_->AddObserver(this);
- LoadFromModel();
- EnableCanvasFlippingForRTLUI(true);
- registrar_.Add(this,
- NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED,
- NotificationService::AllSources());
-
- size_animation_.reset(new SlideAnimation(this));
- if (IsAlwaysShown())
- size_animation_->Reset(1);
- else
- size_animation_->Reset(0);
-}
-
-ExtensionShelf::~ExtensionShelf() {
- if (model_) {
- int count = model_->count();
- for (int i = 0; i < count; ++i) {
- delete ToolstripAtIndex(i);
- model_->SetToolstripDataAt(i, NULL);
- }
- model_->RemoveObserver(this);
- }
-}
-
-void ExtensionShelf::PaintChildren(gfx::Canvas* canvas) {
- InitBackground(canvas);
-
- int max_x = width();
- if (IsDetached())
- max_x -= 2 * kNewtabHorizontalPadding;
-
- // Draw vertical dividers between Toolstrip items in the Extension shelf.
- int count = GetChildViewCount();
- for (int i = 0; i < count; ++i) {
- int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding;
- if (right >= max_x)
- break;
- int vertical_padding = IsDetached() ? (height() - kShelfHeight) / 2 : 1;
-
- DetachableToolbarView::PaintVerticalDivider(
- canvas, right, height(), vertical_padding,
- DetachableToolbarView::kEdgeDividerColor,
- DetachableToolbarView::kMiddleDividerColor,
- GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
- }
-}
-
-// static
-void ExtensionShelf::ToggleWhenExtensionShelfVisible(Profile* profile) {
- PrefService* prefs = profile->GetPrefs();
- const bool always_show = !prefs->GetBoolean(prefs::kShowExtensionShelf);
-
- // The user changed when the Extension Shelf is shown, update the
- // preferences.
- prefs->SetBoolean(prefs::kShowExtensionShelf, always_show);
- prefs->ScheduleSavePersistentPrefs();
-
- // And notify the notification service.
- Source<Profile> source(profile);
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED,
- source,
- NotificationService::NoDetails());
-}
-
-gfx::Size ExtensionShelf::GetPreferredSize() {
- return LayoutItems(true);
-}
-
-void ExtensionShelf::ChildPreferredSizeChanged(View* child) {
- PreferredSizeChanged();
-}
-
-void ExtensionShelf::Layout() {
- LayoutItems(false);
-}
-
-void ExtensionShelf::OnMouseEntered(const views::MouseEvent& event) {
-}
-
-void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) {
-}
-
-bool ExtensionShelf::GetAccessibleRole(AccessibilityTypes::Role* role) {
- DCHECK(role);
-
- *role = AccessibilityTypes::ROLE_TOOLBAR;
- return true;
-}
-
-void ExtensionShelf::OnThemeChanged() {
- // Refresh the CSS to update toolstrip text colors from theme.
- int count = model_->count();
- for (int i = 0; i < count; ++i)
- ToolstripAtIndex(i)->view()->host()->InsertThemedToolstripCSS();
-
- Layout();
-}
-
-void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host,
- int index) {
- model_->SetToolstripDataAt(index,
- new Toolstrip(this, host, model_->ToolstripAt(index).info));
-
- bool had_views = GetChildViewCount() > 0;
- ExtensionView* view = host->view();
- AddChildView(view);
- view->SetContainer(this);
- if (!had_views)
- PreferredSizeChanged();
- Layout();
-}
-
-void ExtensionShelf::ToolstripRemovingAt(ExtensionHost* host, int index) {
- // Delete the Toolstrip view and remove it from the model.
- Toolstrip* toolstrip = ToolstripAtIndex(index);
- View* view = toolstrip->GetShelfView();
- RemoveChildView(view);
- delete toolstrip;
- model_->SetToolstripDataAt(index, NULL);
-
- // Technically, the toolstrip is still in the model at this point, but
- // the Layout code handles this case.
- Layout();
-}
-
-void ExtensionShelf::ToolstripDraggingFrom(ExtensionHost* host, int index) {
-}
-
-void ExtensionShelf::ToolstripMoved(ExtensionHost* host, int from_index,
- int to_index) {
- Layout();
-}
-
-void ExtensionShelf::ToolstripChanged(ExtensionShelfModel::iterator toolstrip) {
- Toolstrip* t = static_cast<Toolstrip*>(toolstrip->data);
- if (toolstrip->height > 0) {
- if (!t->expanded()) {
- t->Expand(toolstrip->height, toolstrip->url);
- }
- } else if (t->expanded()) {
- t->Collapse(toolstrip->url);
- }
-}
-
-void ExtensionShelf::ExtensionShelfEmpty() {
- PreferredSizeChanged();
-}
-
-void ExtensionShelf::ShelfModelReloaded() {
- // None of the child views are parent owned, so nothing is being leaked here.
- RemoveAllChildViews(false);
- LoadFromModel();
-}
-
-void ExtensionShelf::ShelfModelDeleting() {
- int count = model_->count();
- for (int i = 0; i < count; ++i) {
- delete ToolstripAtIndex(i);
- model_->SetToolstripDataAt(i, NULL);
- }
- model_->RemoveObserver(this);
- model_ = NULL;
-}
-
-void ExtensionShelf::AnimationProgressed(const Animation* animation) {
- if (browser_)
- browser_->ExtensionShelfSizeChanged();
-}
-
-void ExtensionShelf::AnimationEnded(const Animation* animation) {
- if (browser_)
- browser_->ExtensionShelfSizeChanged();
-
- Layout();
-}
-
-void ExtensionShelf::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- switch (type.value) {
- case NotificationType::EXTENSION_SHELF_VISIBILITY_PREF_CHANGED: {
- if (fullscreen_)
- break;
- if (IsAlwaysShown())
- size_animation_->Show();
- else
- size_animation_->Hide();
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-}
-
-void ExtensionShelf::OnExtensionMouseMove(ExtensionView* view) {
- Toolstrip *toolstrip = ToolstripForView(view);
- if (toolstrip)
- toolstrip->ShowShelfHandle();
-}
-
-void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) {
- Toolstrip *toolstrip = ToolstripForView(view);
- if (toolstrip)
- toolstrip->HideShelfHandle(kHideDelayMs);
-}
-
-void ExtensionShelf::DropExtension(Toolstrip* toolstrip, const gfx::Point& pt,
- bool cancel) {
- Toolstrip* dest_toolstrip = ToolstripAtX(pt.x());
- if (!dest_toolstrip) {
- if (pt.x() > 0)
- dest_toolstrip = ToolstripAtIndex(model_->count() - 1);
- else
- dest_toolstrip = ToolstripAtIndex(0);
- }
- if (toolstrip == dest_toolstrip)
- return;
- int from = model_->IndexOfHost(toolstrip->host());
- int to = model_->IndexOfHost(dest_toolstrip->host());
- DCHECK(from != to);
- model_->MoveToolstripAt(from, to);
-}
-
-void ExtensionShelf::ExpandToolstrip(ExtensionHost* host, const GURL& url,
- int height) {
- ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host);
- model_->ExpandToolstrip(toolstrip, url, height);
-}
-
-void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) {
- ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host);
- model_->CollapseToolstrip(toolstrip, url);
-}
-
-void ExtensionShelf::InitBackground(gfx::Canvas* canvas) {
- if (!background_needs_repaint_)
- return;
-
- // Capture a background bitmap to give to the toolstrips.
- SkRect background_rect = {
- SkIntToScalar(0),
- SkIntToScalar(0),
- SkIntToScalar(width()),
- SkIntToScalar(height())
- };
-
- // Tell all extension views about the new background.
- int count = model_->count();
- for (int i = 0; i < count; ++i) {
- ExtensionView* view = ToolstripAtIndex(i)->view();
-
- const SkBitmap& background =
- canvas->AsCanvasSkia()->getDevice()->accessBitmap(false);
-
- SkRect mapped_subset = background_rect;
- gfx::Rect view_bounds = view->bounds();
- mapped_subset.offset(SkIntToScalar(view_bounds.x()),
- SkIntToScalar(view_bounds.y()));
- bool result =
- canvas->AsCanvasSkia()->getTotalMatrix().mapRect(&mapped_subset);
- DCHECK(result);
-
- SkIRect isubset;
- mapped_subset.round(&isubset);
- SkBitmap subset_bitmap;
- // This will create another bitmap that just references pixels in the
- // actual bitmap.
- result = background.extractSubset(&subset_bitmap, isubset);
- if (!result)
- return;
-
- // We do a deep copy because extractSubset() returns a bitmap that
- // references pixels in the original one and we want to actually make a
- // smaller copy that will have a long lifetime.
- SkBitmap smaller_copy;
- if (!subset_bitmap.copyTo(&smaller_copy, SkBitmap::kARGB_8888_Config))
- return;
- DCHECK(smaller_copy.readyToDraw());
-
- view->SetBackground(smaller_copy);
- }
-
- background_needs_repaint_ = false;
-}
-
-ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) {
- int count = model_->count();
- if (count == 0)
- return NULL;
-
- if (x < 0)
- return NULL;
-
- for (int i = 0; i < count; ++i) {
- Toolstrip* toolstrip = ToolstripAtIndex(i);
- View* view = toolstrip->GetShelfView();
- int x_mirrored = view->GetRootView()->MirroredXCoordinateInsideView(x);
- if (x_mirrored > view->x() + view->width() + kToolstripPadding)
- continue;
- return toolstrip;
- }
-
- return NULL;
-}
-
-ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtIndex(int index) {
- return static_cast<Toolstrip*>(model_->ToolstripAt(index).data);
-}
-
-ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripForView(
- ExtensionView* view) {
- int count = model_->count();
- for (int i = 0; i < count; ++i) {
- Toolstrip* toolstrip = ToolstripAtIndex(i);
- if (view == toolstrip->view())
- return toolstrip;
- }
- return NULL;
-}
-
-void ExtensionShelf::LoadFromModel() {
- int count = model_->count();
- for (int i = 0; i < count; ++i)
- ToolstripInsertedAt(model_->ToolstripAt(i).host, i);
-}
-
-gfx::Size ExtensionShelf::LayoutItems(bool compute_bounds_only) {
- if (!GetParent() || !model_ || !model_->count())
- return gfx::Size(0, 0);
-
- gfx::Size prefsize;
- int x = kLeftMargin;
- int y = top_margin_;
- int content_height = kShelfHeight - top_margin_ - kBottomMargin;
- int max_x = width() - kRightMargin;
-
- if (OnNewTabPage()) {
- double current_state = 1 - size_animation_->GetCurrentValue();
- x += static_cast<int>(static_cast<double>
- (kNewtabHorizontalPadding + kNewtabExtraHorMargin) * current_state);
- y += static_cast<int>(static_cast<double>
- (kNewtabVerticalPadding + kNewtabExtraVerMargin) * current_state);
- max_x -= static_cast<int>(static_cast<double>
- (2 * kNewtabHorizontalPadding) * current_state);
- }
-
- int count = model_->count();
- for (int i = 0; i < count; ++i) {
- x += kToolstripPadding; // Left padding.
- Toolstrip* toolstrip = ToolstripAtIndex(i);
- if (!toolstrip) // Can be NULL while in the process of removing.
- continue;
- View* view = toolstrip->GetShelfView();
- gfx::Size pref = view->GetPreferredSize();
-
- // |next_x| is the x value for where the next toolstrip in the list will be.
- int next_x = x + pref.width() + kToolstripPadding; // Right padding.
- if (!compute_bounds_only) {
- bool clipped = next_x >= max_x;
- if (clipped)
- pref.set_width(std::max(0, max_x - x));
- if (view == toolstrip->view())
- toolstrip->view()->SetIsClipped(clipped);
- view->SetBounds(x, y, pref.width(), content_height);
- view->Layout();
- if (toolstrip->window_visible())
- toolstrip->LayoutWindow();
- }
- x = next_x + kToolstripDividerWidth;
- }
-
- if (!compute_bounds_only) {
- background_needs_repaint_ = true;
- SchedulePaint();
- } else {
- if (OnNewTabPage()) {
- prefsize.set_height(kShelfHeight + static_cast<int>(static_cast<double>
- (kNewtabShelfHeight - kShelfHeight) *
- (1 - size_animation_->GetCurrentValue())));
- } else {
- prefsize.set_height(static_cast<int>(static_cast<double>(kShelfHeight) *
- size_animation_->GetCurrentValue()));
- }
-
- x += kRightMargin;
- prefsize.set_width(x);
- }
-
- return prefsize;
-}
-
-bool ExtensionShelf::IsDetached() const {
- return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1);
-}
-
-bool ExtensionShelf::IsAlwaysShown() const {
- Profile* profile = browser_->profile();
- return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf);
-}
-
-bool ExtensionShelf::OnNewTabPage() const {
- return (browser_ && browser_->GetSelectedTabContents() &&
- browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible());
-}
-
-void ExtensionShelf::OnFullscreenToggled(bool fullscreen) {
- if (fullscreen == fullscreen_)
- return;
- fullscreen_ = fullscreen;
- if (!IsAlwaysShown())
- return;
- size_animation_->Reset(fullscreen ? 0 : 1);
-}
« no previous file with comments | « chrome/browser/views/extensions/extension_shelf.h ('k') | chrome/browser/views/extensions/extension_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698