13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 23f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 33f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/panels/panel_scroller.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/compiler_specific.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/panels/panel_scroller_container.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/panels/panel_scroller_header.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/widget.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct PanelScroller::Panel { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PanelScrollerHeader* header; 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PanelScrollerContainer* container; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPanelScroller::PanelScroller() 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : views::View(), 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch divider_height_(18), 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch needs_layout_(true), 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scroll_pos_(0), 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)), 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_begin_(0), 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_(0) { 303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen animation_.SetTweenType(ui::Tween::EASE_IN_OUT); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.SetSlideDuration(300); 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Panel* panel = new Panel; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header = new PanelScrollerHeader(this); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header->set_title(ASCIIToUTF16("Email")); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->container = new PanelScrollerContainer(this, new views::View()); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_.push_back(panel); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel = new Panel; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header = new PanelScrollerHeader(this); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header->set_title(ASCIIToUTF16("Chat")); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->container = new PanelScrollerContainer(this, new views::View()); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_.push_back(panel); 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel = new Panel; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header = new PanelScrollerHeader(this); 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header->set_title(ASCIIToUTF16("Calendar")); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->container = new PanelScrollerContainer(this, new views::View()); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_.push_back(panel); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel = new Panel; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header = new PanelScrollerHeader(this); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header->set_title(ASCIIToUTF16("Recent searches")); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->container = new PanelScrollerContainer(this, new views::View()); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_.push_back(panel); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel = new Panel; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header = new PanelScrollerHeader(this); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->header->set_title(ASCIIToUTF16("Pony news")); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panel->container = new PanelScrollerContainer(this, new views::View()); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_.push_back(panel); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the containers first since they're on the bottom. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[0]->container); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[1]->container); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[2]->container); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[3]->container); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[4]->container); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[0]->header); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[1]->header); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[2]->header); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[3]->header); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(panels_[4]->header); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPanelScroller::~PanelScroller() { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteContainerPointers(panels_.begin(), panels_.end()); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPanelScroller* PanelScroller::CreateWindow() { 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Widget* widget = views::Widget::CreateWidget( 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Widget::CreateParams(views::Widget::CreateParams::TYPE_WINDOW)); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->Init(NULL, gfx::Rect(0, 0, 100, 800)); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PanelScroller* scroller = new PanelScroller(); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->SetContentsView(scroller); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->Show(); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return scroller; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::ViewHierarchyChanged(bool is_add, 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View* parent, 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View* child) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Our child views changed without us knowing it. Stop the animation and mark 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // us as dirty (needs_layout_ = true). 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Stop(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch needs_layout_ = true; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size PanelScroller::GetPreferredSize() { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Size(75, 200); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::Layout() { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* TODO(brettw) this doesn't work for some reason. 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!needs_layout_ || !animation_.IsShowing()) 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch needs_layout_ = false;*/ 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The current location in the content that we're laying out. This is before 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // scrolling is accounted for. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int cur_content_pos = 0; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Number of pixels used by headers stuck to the top of the scroll area. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_header_pixel_count = 0; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int panel_count = static_cast<int>(panels_.size()); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < panel_count; i++) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cur_content_pos < scroll_pos_ + top_header_pixel_count) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This panel is at least partially off the top. Put the header below the 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // others already there. 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect(gfx::Rect(0, top_header_pixel_count, 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen width(), divider_height_)); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_header_pixel_count += divider_height_; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (cur_content_pos > height() + scroll_pos_ - 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (panel_count - i) * divider_height_) { 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When we've hit the bottom of the visible content, all the remaining 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // headers will stack up at the bottom. Counting this header, there are 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (size() - i) left, which is used in the expression above. 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top = height() - (panel_count - i) * divider_height_; 13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect(gfx::Rect(0, top, 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen width(), divider_height_)); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Normal header positioning in-flow. 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect( 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::Rect(0, cur_content_pos - scroll_pos_, width(), 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen divider_height_)); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cur_content_pos += divider_height_; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now position the content. It always goes in-flow ignoring any stacked 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // up headers at the top or bottom. 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int container_height = panels_[i]->container->GetPreferredSize().height(); 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->container->SetBoundsRect( 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect(0, cur_content_pos - scroll_pos_, 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width(), container_height)); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cur_content_pos += container_height; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool PanelScroller::OnMousePressed(const views::MouseEvent& event) { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool PanelScroller::OnMouseDragged(const views::MouseEvent& event) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::HeaderClicked(PanelScrollerHeader* source) { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < panels_.size(); i++) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (panels_[i]->header == source) { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScrollToPanel(static_cast<int>(i)); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Invalid panel passed to HeaderClicked."; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::ScrollToPanel(int index) { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int affected_panel_height = 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[index]->container->GetPreferredSize().height(); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The pixel size we need to reserve for the stuck headers. 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_stuck_header_pixel_size = index * divider_height_; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bottom_stuck_header_pixel_size = 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (static_cast<int>(panels_.size()) - index - 1) * divider_height_; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the offset of the top of the panel to scroll to. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int space_above = 0; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < index; i++) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_above += divider_height_ + 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[i]->container->GetPreferredSize().height(); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the space below the top of the panel. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int space_below = 0; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = index; i < static_cast<int>(panels_.size()); i++) { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_below += divider_height_ + 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[i]->container->GetPreferredSize().height(); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The scroll position of the top of the stuck headers is the space above 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // minus the size of the headers stuck there. 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_stuck_headers_scroll_pos = space_above - top_stuck_header_pixel_size; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the panel is already fully visible, do nothing. 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (scroll_pos_ <= top_stuck_headers_scroll_pos && 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_above + divider_height_ + affected_panel_height - 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_stuck_header_pixel_size <= scroll_pos_ + height()) 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the scroll position. 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (height() > space_below) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There's enough room for this panel and everything below it to fit on the 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // screen. 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = (space_above + space_below) - height(); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_end_ > top_stuck_headers_scroll_pos) 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (space_above > scroll_pos_) { 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we're going to be scrolling the content up, scroll just until the 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // panel in question is fully visible. 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = space_above + 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch divider_height_ + affected_panel_height + // Size of this panel. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_stuck_header_pixel_size - // Leave room for these. 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch height(); // Available size in the window. 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_end_ > top_stuck_headers_scroll_pos) 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_begin_ = scroll_pos_; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_begin_ == animated_scroll_end_) 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // Nothing to animate. 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start animating to the destination. 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Reset(); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Show(); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid PanelScroller::AnimationProgressed(const ui::Animation* animation) { 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scroll_pos_ = static_cast<int>( 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<double>(animated_scroll_end_ - animated_scroll_begin_) * 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.GetCurrentValue()) + animated_scroll_begin_; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Layout(); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SchedulePaint(); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 245