| 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
|
| index 6841dc98145ab8fe009f87b47a4b1f45616bc4ff..f7e5cc285ecc0a0c934762ab2ded6966bbd0b395 100644
|
| --- a/chrome/browser/views/extensions/extension_shelf.cc
|
| +++ b/chrome/browser/views/extensions/extension_shelf.cc
|
| @@ -112,12 +112,16 @@ class ExtensionShelf::PlaceholderView : public views::View {
|
| // 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 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
|
| virtual void Paint(gfx::Canvas* canvas);
|
| virtual gfx::Size GetPreferredSize();
|
| @@ -181,6 +185,10 @@ class ExtensionShelf::Toolstrip : public views::View,
|
| 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_;
|
| @@ -210,12 +218,18 @@ class ExtensionShelf::Toolstrip : public views::View,
|
| bool dragging_;
|
| bool expanded_;
|
|
|
| + // 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_;
|
|
|
| // 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);
|
| };
|
|
|
| @@ -233,6 +247,8 @@ ExtensionShelf::Toolstrip::Toolstrip(ExtensionShelf* shelf,
|
| // We're owned by shelf_, not the bubble that we get inserted in and out of.
|
| SetParentOwned(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
|
| @@ -275,11 +291,16 @@ void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) {
|
| }
|
| }
|
|
|
| -gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() {
|
| +gfx::Size ExtensionShelf::Toolstrip::GetHandlePreferredSize() {
|
| gfx::Size sz = title_->GetPreferredSize();
|
| sz.set_width(std::max(view()->width(), sz.width()));
|
| if (!expanded_)
|
| sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2);
|
| + return sz;
|
| +}
|
| +
|
| +gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() {
|
| + gfx::Size sz = GetHandlePreferredSize();
|
| if (dragging_ || expanded_) {
|
| gfx::Size extension_size = view()->GetPreferredSize();
|
| sz.Enlarge(0, extension_size.height() + 2);
|
| @@ -384,26 +405,47 @@ void ExtensionShelf::Toolstrip::LayoutHandle() {
|
| if (!handle_.get())
|
| return;
|
|
|
| + int handle_height;
|
| + if (mole_animation_->IsAnimating()) {
|
| + // 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 handle_offset = shelf_->height();
|
| + if (!mole_animation_->IsShowing())
|
| + handle_offset += GetPreferredSize().height();
|
| + else
|
| + handle_offset += GetHandlePreferredSize().height();
|
| + int h = expanded_height_ - handle_offset;
|
| + handle_height = static_cast<int>(h * mole_animation_->GetCurrentValue());
|
| + handle_height += handle_offset;
|
| + } else {
|
| + handle_height = height();
|
| + }
|
| +
|
| + // Now figure out where to place the handle on the screen. Since it's a top-
|
| + // level widget, we need to do some coordinate conversion to get this right.
|
| int handle_width = std::max(view()->width(), width());
|
| - gfx::Point origin(-kToolstripPadding, -(height() + kToolstripPadding - 1));
|
| - if (expanded_) {
|
| - origin.set_y(GetShelfView()->height() - height());
|
| + gfx::Point origin(-kToolstripPadding,
|
| + -(handle_height + kToolstripPadding - 1));
|
| + if (expanded_ || mole_animation_->IsAnimating()) {
|
| + origin.set_y(GetShelfView()->height() - handle_height);
|
| views::View::ConvertPointToView(GetShelfView(), shelf_->GetRootView(),
|
| &origin);
|
| } else {
|
| views::View::ConvertPointToWidget(view(), &origin);
|
| }
|
| SetBounds(0, 0, handle_width, height());
|
| - handle_->SetBounds(origin.x(), origin.y(), handle_width, height());
|
| - handle_->ResizeToView();
|
| + handle_->SetBounds(origin.x(), origin.y(), handle_width, handle_height);
|
| }
|
|
|
| void ExtensionShelf::Toolstrip::ChildPreferredSizeChanged(View* child) {
|
| if (child == view()) {
|
| child->SizeToPreferredSize();
|
| Layout();
|
| + LayoutHandle();
|
| if (expanded_) {
|
| - LayoutHandle();
|
| placeholder_view_->SetWidth(child->width());
|
| shelf_->Layout();
|
| }
|
| @@ -420,6 +462,20 @@ void ExtensionShelf::Toolstrip::BubbleBrowserWindowClosing(
|
| DoHideShelfHandle();
|
| }
|
|
|
| +void ExtensionShelf::Toolstrip::AnimationProgressed(
|
| + const Animation* animation) {
|
| + LayoutHandle();
|
| +}
|
| +
|
| +void ExtensionShelf::Toolstrip::AnimationEnded(const Animation* animation) {
|
| + LayoutHandle();
|
| + if (!expanded_) {
|
| + // Must use the delay due to bug 18248.
|
| + HideShelfHandle(kHideDelayMs * 2);
|
| + AttachToShelf(false);
|
| + }
|
| +}
|
| +
|
| void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) {
|
| DCHECK(handle_.get());
|
| DCHECK(!placeholder_view_);
|
| @@ -498,10 +554,12 @@ void ExtensionShelf::Toolstrip::Expand(int height, const GURL& url) {
|
| StopHandleTimer();
|
| DetachFromShelf(false);
|
|
|
| + mole_animation_->Show();
|
| +
|
| gfx::Size extension_size = view()->GetPreferredSize();
|
| extension_size.set_height(height);
|
| view()->SetPreferredSize(extension_size);
|
| - LayoutHandle();
|
| + 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
|
| @@ -515,10 +573,11 @@ void ExtensionShelf::Toolstrip::Collapse(const GURL& url) {
|
| expanded_ = false;
|
| view()->set_is_toolstrip(!expanded_);
|
|
|
| + mole_animation_->Hide();
|
| +
|
| gfx::Size extension_size = view()->GetPreferredSize();
|
| extension_size.set_height(kToolstripHeight);
|
| view()->SetPreferredSize(extension_size);
|
| - AttachToShelf(false);
|
|
|
| if (!url.is_empty() && url != host_->GetURL()) {
|
| host_->NavigateToURL(url);
|
| @@ -528,9 +587,6 @@ void ExtensionShelf::Toolstrip::Collapse(const GURL& url) {
|
| // visibility to true.
|
| view()->SetVisible(false);
|
| }
|
| -
|
| - // Must use the delay due to bug 18248.
|
| - HideShelfHandle(kHideDelayMs);
|
| }
|
|
|
| void ExtensionShelf::Toolstrip::ShowShelfHandle() {
|
| @@ -545,8 +601,10 @@ void ExtensionShelf::Toolstrip::ShowShelfHandle() {
|
|
|
| void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) {
|
| StopHandleTimer();
|
| - if (!handle_visible() || dragging_ || expanded_)
|
| + if (!handle_visible() || dragging_ || expanded_ ||
|
| + mole_animation_->IsAnimating()) {
|
| return;
|
| + }
|
| if (delay_ms) {
|
| MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
| timer_factory_.NewRunnableMethod(
|
|
|