15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_bounds_animation.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These values are experimental and subjective. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultFramerateHz = 50; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSetBoundsAnimationMs = 180; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSetBoundsAnimationBigMinimizeMs = 1500; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)PanelBoundsAnimation::PanelBoundsAnimation(gfx::AnimationDelegate* target, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Panel* panel, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_bounds, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& final_bounds) 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : gfx::LinearAnimation(kDefaultFramerateHz, target), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) panel_(panel), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for_big_minimize_(false), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_stop_to_show_titlebar_(0) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Detect animation that happens when expansion state is set to MINIMIZED 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and there is relatively big portion of the panel to hide from view. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize animation differently in this case, using fast-pause-slow 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method, see below for more details. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int duration = kSetBoundsAnimationMs; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initial_bounds.height() > final_bounds.height() && 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) panel_->expansion_state() == Panel::MINIMIZED) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double hidden_title_height = 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) panel_->TitleOnlyHeight() - final_bounds.height(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double distance_y = initial_bounds.height() - final_bounds.height(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_stop_to_show_titlebar_ = 1.0 - hidden_title_height / distance_y; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (animation_stop_to_show_titlebar_ > 0.7) { // Relatively big movement. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for_big_minimize_ = true; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration = kSetBoundsAnimationBigMinimizeMs; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetDuration(PanelManager::AdjustTimeInterval(duration)); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelBoundsAnimation::~PanelBoundsAnimation() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double PanelBoundsAnimation::GetCurrentValue() const { 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ComputeAnimationValue(gfx::LinearAnimation::GetCurrentValue(), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for_big_minimize_, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animation_stop_to_show_titlebar_); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double PanelBoundsAnimation::ComputeAnimationValue(double progress, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool for_big_minimize, double animation_stop_to_show_titlebar) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!for_big_minimize) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cubic easing out. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value = 1.0 - progress; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1.0 - value * value * value; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Minimize animation is done in 3 steps: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1. Quickly (0 -> 0.15) make only titlebar visible. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2. Freeze for a little bit (0.15->0.6), just showing titlebar. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3. Slowly minimize to thin strip (0.6->1.0) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kProgressAtFreezeStart = 0.15; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kProgressAtFreezeEnd = 0.6; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (progress <= kProgressAtFreezeStart) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = animation_stop_to_show_titlebar * 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (progress / kProgressAtFreezeStart); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (progress <= kProgressAtFreezeEnd) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = animation_stop_to_show_titlebar; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = animation_stop_to_show_titlebar + 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (1.0 - animation_stop_to_show_titlebar) * 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((progress - kProgressAtFreezeEnd) / (1.0 - kProgressAtFreezeEnd)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 82