panel_scroller.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
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" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget_gtk.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() { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::WidgetGtk* widget = 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->set_delete_on_destroy(true); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->Init(NULL, gfx::Rect(0, 0, 100, 800)); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PanelScroller* scroller = new PanelScroller(); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->SetContentsView(scroller); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->Show(); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return scroller; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::ViewHierarchyChanged(bool is_add, 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View* parent, 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View* child) { 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Our child views changed without us knowing it. Stop the animation and mark 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // us as dirty (needs_layout_ = true). 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Stop(); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch needs_layout_ = true; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size PanelScroller::GetPreferredSize() { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Size(75, 200); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::Layout() { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* TODO(brettw) this doesn't work for some reason. 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!needs_layout_ || !animation_.IsShowing()) 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch needs_layout_ = false;*/ 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The current location in the content that we're laying out. This is before 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // scrolling is accounted for. 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int cur_content_pos = 0; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Number of pixels used by headers stuck to the top of the scroll area. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_header_pixel_count = 0; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int panel_count = static_cast<int>(panels_.size()); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < panel_count; i++) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cur_content_pos < scroll_pos_ + top_header_pixel_count) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This panel is at least partially off the top. Put the header below the 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // others already there. 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect(gfx::Rect(0, top_header_pixel_count, 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen width(), divider_height_)); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_header_pixel_count += divider_height_; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (cur_content_pos > height() + scroll_pos_ - 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (panel_count - i) * divider_height_) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When we've hit the bottom of the visible content, all the remaining 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // headers will stack up at the bottom. Counting this header, there are 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (size() - i) left, which is used in the expression above. 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top = height() - (panel_count - i) * divider_height_; 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect(gfx::Rect(0, top, 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen width(), divider_height_)); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Normal header positioning in-flow. 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->header->SetBoundsRect( 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::Rect(0, cur_content_pos - scroll_pos_, width(), 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen divider_height_)); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cur_content_pos += divider_height_; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now position the content. It always goes in-flow ignoring any stacked 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // up headers at the top or bottom. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int container_height = panels_[i]->container->GetPreferredSize().height(); 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen panels_[i]->container->SetBoundsRect( 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect(0, cur_content_pos - scroll_pos_, 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width(), container_height)); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cur_content_pos += container_height; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool PanelScroller::OnMousePressed(const views::MouseEvent& event) { 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool PanelScroller::OnMouseDragged(const views::MouseEvent& event) { 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::OnMouseReleased(const views::MouseEvent& event, 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool canceled) { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::HeaderClicked(PanelScrollerHeader* source) { 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < panels_.size(); i++) { 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (panels_[i]->header == source) { 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScrollToPanel(static_cast<int>(i)); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Invalid panel passed to HeaderClicked."; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PanelScroller::ScrollToPanel(int index) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int affected_panel_height = 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[index]->container->GetPreferredSize().height(); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The pixel size we need to reserve for the stuck headers. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_stuck_header_pixel_size = index * divider_height_; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bottom_stuck_header_pixel_size = 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (static_cast<int>(panels_.size()) - index - 1) * divider_height_; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the offset of the top of the panel to scroll to. 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int space_above = 0; 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < index; i++) { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_above += divider_height_ + 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[i]->container->GetPreferredSize().height(); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the space below the top of the panel. 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int space_below = 0; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = index; i < static_cast<int>(panels_.size()); i++) { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_below += divider_height_ + 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch panels_[i]->container->GetPreferredSize().height(); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The scroll position of the top of the stuck headers is the space above 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // minus the size of the headers stuck there. 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top_stuck_headers_scroll_pos = space_above - top_stuck_header_pixel_size; 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the panel is already fully visible, do nothing. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (scroll_pos_ <= top_stuck_headers_scroll_pos && 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch space_above + divider_height_ + affected_panel_height - 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_stuck_header_pixel_size <= scroll_pos_ + height()) 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compute the scroll position. 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (height() > space_below) { 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There's enough room for this panel and everything below it to fit on the 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // screen. 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = (space_above + space_below) - height(); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_end_ > top_stuck_headers_scroll_pos) 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (space_above > scroll_pos_) { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we're going to be scrolling the content up, scroll just until the 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // panel in question is fully visible. 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = space_above + 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch divider_height_ + affected_panel_height + // Size of this panel. 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_stuck_header_pixel_size - // Leave room for these. 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch height(); // Available size in the window. 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_end_ > top_stuck_headers_scroll_pos) 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_end_ = top_stuck_headers_scroll_pos; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animated_scroll_begin_ = scroll_pos_; 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animated_scroll_begin_ == animated_scroll_end_) 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // Nothing to animate. 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start animating to the destination. 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Reset(); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.Show(); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid PanelScroller::AnimationProgressed(const ui::Animation* animation) { 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scroll_pos_ = static_cast<int>( 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<double>(animated_scroll_end_ - animated_scroll_begin_) * 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch animation_.GetCurrentValue()) + animated_scroll_begin_; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Layout(); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SchedulePaint(); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 250