summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/panels
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/chromeos/panels')
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller.cc253
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller.h70
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller_container.cc30
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller_container.h37
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller_header.cc51
-rw-r--r--chrome/browser/chromeos/panels/panel_scroller_header.h42
6 files changed, 483 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/panels/panel_scroller.cc b/chrome/browser/chromeos/panels/panel_scroller.cc
new file mode 100644
index 0000000..c2af341
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2009 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/chromeos/panels/panel_scroller.h"
+
+#include "app/gfx/canvas.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "chrome/browser/chromeos/panels/panel_scroller_container.h"
+#include "chrome/browser/chromeos/panels/panel_scroller_header.h"
+#include "views/widget/widget_gtk.h"
+
+struct PanelScroller::Panel {
+ PanelScrollerHeader* header;
+ PanelScrollerContainer* container;
+};
+
+PanelScroller::PanelScroller()
+ : views::View(),
+ divider_height_(18),
+ needs_layout_(true),
+ scroll_pos_(0),
+ ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)),
+ animated_scroll_begin_(0),
+ animated_scroll_end_(0) {
+ animation_.SetTweenType(SlideAnimation::EASE_IN_OUT);
+ animation_.SetSlideDuration(300);
+
+ Panel* panel = new Panel;
+ panel->header = new PanelScrollerHeader(this);
+ panel->header->set_title(ASCIIToUTF16("Email"));
+ panel->container = new PanelScrollerContainer(this, new views::View());
+ panels_.push_back(panel);
+
+ panel = new Panel;
+ panel->header = new PanelScrollerHeader(this);
+ panel->header->set_title(ASCIIToUTF16("Chat"));
+ panel->container = new PanelScrollerContainer(this, new views::View());
+ panels_.push_back(panel);
+
+ panel = new Panel;
+ panel->header = new PanelScrollerHeader(this);
+ panel->header->set_title(ASCIIToUTF16("Calendar"));
+ panel->container = new PanelScrollerContainer(this, new views::View());
+ panels_.push_back(panel);
+
+ panel = new Panel;
+ panel->header = new PanelScrollerHeader(this);
+ panel->header->set_title(ASCIIToUTF16("Recent searches"));
+ panel->container = new PanelScrollerContainer(this, new views::View());
+ panels_.push_back(panel);
+
+ panel = new Panel;
+ panel->header = new PanelScrollerHeader(this);
+ panel->header->set_title(ASCIIToUTF16("Pony news"));
+ panel->container = new PanelScrollerContainer(this, new views::View());
+ panels_.push_back(panel);
+
+ // Add the containers first since they're on the bottom.
+ AddChildView(panels_[0]->container);
+ AddChildView(panels_[1]->container);
+ AddChildView(panels_[2]->container);
+ AddChildView(panels_[3]->container);
+ AddChildView(panels_[4]->container);
+
+ AddChildView(panels_[0]->header);
+ AddChildView(panels_[1]->header);
+ AddChildView(panels_[2]->header);
+ AddChildView(panels_[3]->header);
+ AddChildView(panels_[4]->header);
+}
+
+PanelScroller::~PanelScroller() {
+ STLDeleteContainerPointers(panels_.begin(), panels_.end());
+}
+
+// static
+PanelScroller* PanelScroller::CreateWindow() {
+ views::WidgetGtk* widget =
+ new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
+ widget->set_delete_on_destroy(true);
+ widget->Init(NULL, gfx::Rect(0, 0, 100, 800));
+
+ PanelScroller* scroller = new PanelScroller();
+ widget->SetContentsView(scroller);
+
+ widget->Show();
+
+ return scroller;
+}
+
+void PanelScroller::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ // Our child views changed without us knowing it. Stop the animation and mark
+ // us as dirty (needs_layout_ = true).
+ animation_.Stop();
+ needs_layout_ = true;
+}
+
+gfx::Size PanelScroller::GetPreferredSize() {
+ return gfx::Size(75, 200);
+}
+
+void PanelScroller::Layout() {
+/* TODO(brettw) this doesn't work for some reason.
+ if (!needs_layout_ || !animation_.IsShowing())
+ return;
+ needs_layout_ = false;*/
+
+ // The current location in the content that we're laying out. This is before
+ // scrolling is accounted for.
+ int cur_content_pos = 0;
+
+ // Number of pixels used by headers stuck to the top of the scroll area.
+ int top_header_pixel_count = 0;
+
+ int panel_count = static_cast<int>(panels_.size());
+ for (int i = 0; i < panel_count; i++) {
+ if (cur_content_pos < scroll_pos_ + top_header_pixel_count) {
+ // This panel is at least partially off the top. Put the header below the
+ // others already there.
+ panels_[i]->header->SetBounds(gfx::Rect(0, top_header_pixel_count,
+ width(), divider_height_));
+ top_header_pixel_count += divider_height_;
+
+ } else if (cur_content_pos > height() + scroll_pos_ -
+ (panel_count - i) * divider_height_) {
+ // When we've hit the bottom of the visible content, all the remaining
+ // headers will stack up at the bottom. Counting this header, there are
+ // (size() - i) left, which is used in the expression above.
+ int top = height() - (panel_count - i) * divider_height_;
+ panels_[i]->header->SetBounds(gfx::Rect(0, top,
+ width(), divider_height_));
+ } else {
+ // Normal header positioning in-flow.
+ panels_[i]->header->SetBounds(gfx::Rect(0, cur_content_pos - scroll_pos_,
+ width(), divider_height_));
+ }
+
+ cur_content_pos += divider_height_;
+
+ // Now position the content. It always goes in-flow ignoring any stacked
+ // up headers at the top or bottom.
+ int container_height = panels_[i]->container->GetPreferredSize().height();
+ panels_[i]->container->SetBounds(
+ gfx::Rect(0, cur_content_pos - scroll_pos_,
+ width(), container_height));
+ cur_content_pos += container_height;
+ }
+}
+
+bool PanelScroller::OnMousePressed(const views::MouseEvent& event) {
+ return true;
+}
+
+bool PanelScroller::OnMouseDragged(const views::MouseEvent& event) {
+ return true;
+}
+
+void PanelScroller::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+}
+
+void PanelScroller::HeaderClicked(PanelScrollerHeader* source) {
+ for (size_t i = 0; i < panels_.size(); i++) {
+ if (panels_[i]->header == source) {
+ ScrollToPanel(static_cast<int>(i));
+ return;
+ }
+ }
+ NOTREACHED() << "Invalid panel passed to HeaderClicked.";
+}
+
+void PanelScroller::ScrollToPanel(int index) {
+ int affected_panel_height =
+ panels_[index]->container->GetPreferredSize().height();
+
+ // The pixel size we need to reserve for the stuck headers.
+ int top_stuck_header_pixel_size = index * divider_height_;
+ int bottom_stuck_header_pixel_size =
+ (static_cast<int>(panels_.size()) - index - 1) * divider_height_;
+
+ // Compute the offset of the top of the panel to scroll to.
+ int space_above = 0;
+ for (int i = 0; i < index; i++) {
+ space_above += divider_height_ +
+ panels_[i]->container->GetPreferredSize().height();
+ }
+
+ // Compute the space below the top of the panel.
+ int space_below = 0;
+ for (int i = index; i < static_cast<int>(panels_.size()); i++) {
+ space_below += divider_height_ +
+ panels_[i]->container->GetPreferredSize().height();
+ }
+
+ // The scroll position of the top of the stuck headers is the space above
+ // minus the size of the headers stuck there.
+ int top_stuck_headers_scroll_pos = space_above - top_stuck_header_pixel_size;
+
+ // If the panel is already fully visible, do nothing.
+ if (scroll_pos_ <= top_stuck_headers_scroll_pos &&
+ space_above + divider_height_ + affected_panel_height -
+ bottom_stuck_header_pixel_size <= scroll_pos_ + height())
+ return;
+
+ // Compute the scroll position.
+ if (height() > space_below) {
+ // There's enough room for this panel and everything below it to fit on the
+ // screen.
+ animated_scroll_end_ = (space_above + space_below) - height();
+ if (animated_scroll_end_ > top_stuck_headers_scroll_pos)
+ animated_scroll_end_ = top_stuck_headers_scroll_pos;
+ } else if (space_above > scroll_pos_) {
+ // If we're going to be scrolling the content up, scroll just until the
+ // panel in question is fully visible.
+ animated_scroll_end_ = space_above +
+ divider_height_ + affected_panel_height + // Size of this panel.
+ bottom_stuck_header_pixel_size - // Leave room for these.
+ height(); // Available size in the window.
+ if (animated_scroll_end_ > top_stuck_headers_scroll_pos)
+ animated_scroll_end_ = top_stuck_headers_scroll_pos;
+ } else {
+ animated_scroll_end_ = top_stuck_headers_scroll_pos;
+ }
+
+ animated_scroll_begin_ = scroll_pos_;
+ if (animated_scroll_begin_ == animated_scroll_end_)
+ return; // Nothing to animate.
+
+ // Start animating to the destination.
+ animation_.Reset();
+ animation_.Show();
+}
+
+void PanelScroller::AnimationEnded(const Animation* animation) {
+}
+
+void PanelScroller::AnimationProgressed(const Animation* animation) {
+ scroll_pos_ = static_cast<int>(
+ static_cast<double>(animated_scroll_end_ - animated_scroll_begin_) *
+ animation_.GetCurrentValue()) + animated_scroll_begin_;
+
+ Layout();
+ SchedulePaint();
+}
+
+void PanelScroller::AnimationCanceled(const Animation* animation) {
+}
diff --git a/chrome/browser/chromeos/panels/panel_scroller.h b/chrome/browser/chromeos/panels/panel_scroller.h
new file mode 100644
index 0000000..a3db3db
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_H_
+#define CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_H_
+
+#include <vector>
+
+#include "app/slide_animation.h"
+#include "base/basictypes.h"
+#include "views/view.h"
+
+class PanelScrollerHeader;
+
+class PanelScroller : public views::View, public AnimationDelegate {
+ public:
+ PanelScroller();
+ ~PanelScroller();
+
+ static PanelScroller* CreateWindow();
+
+ // View overrides.
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ // Called when a panel header is clicked with the affected container. This
+ // function will make sure the panel is fully visible.
+ void HeaderClicked(PanelScrollerHeader* source);
+
+ private:
+ struct Panel;
+
+ // AnimationDelegate overrides.
+ virtual void AnimationEnded(const Animation* animation);
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationCanceled(const Animation* animation);
+
+ // Scrolls to the panel at the given index. It will be moved to the top.
+ void ScrollToPanel(int index);
+
+ // All panels in this scroller.
+ std::vector<Panel*> panels_;
+
+ // Height in pixels of the headers above each panel.
+ int divider_height_;
+
+ bool needs_layout_;
+
+ // The current scroll position.
+ int scroll_pos_;
+
+ SlideAnimation animation_;
+
+ // When animating a scroll, these indicate the beginning and ending of the
+ // scroll. The scroll_pos_ always indicates the current one.
+ int animated_scroll_begin_;
+ int animated_scroll_end_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelScroller);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_H_
+
diff --git a/chrome/browser/chromeos/panels/panel_scroller_container.cc b/chrome/browser/chromeos/panels/panel_scroller_container.cc
new file mode 100644
index 0000000..ace44d5
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller_container.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2009 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/chromeos/panels/panel_scroller_container.h"
+
+#include "app/gfx/canvas.h"
+
+PanelScrollerContainer::PanelScrollerContainer(PanelScroller* scroller,
+ views::View* contents)
+ : views::View(),
+ scroller_(scroller),
+ contents_(contents) {
+ AddChildView(0, contents_);
+ // TODO(brettw) figure out memory management.
+}
+
+PanelScrollerContainer::~PanelScrollerContainer() {
+}
+
+gfx::Size PanelScrollerContainer::GetPreferredSize() {
+ return gfx::Size(100, 500);
+}
+
+void PanelScrollerContainer::Layout() {
+}
+
+void PanelScrollerContainer::Paint(gfx::Canvas* canvas) {
+ canvas->DrawLineInt(0xFF000080, 0, 0, size().width(), size().height());
+}
diff --git a/chrome/browser/chromeos/panels/panel_scroller_container.h b/chrome/browser/chromeos/panels/panel_scroller_container.h
new file mode 100644
index 0000000..5007e95
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller_container.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_CONTAINER_H_
+#define CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_CONTAINER_H_
+
+#include "base/basictypes.h"
+#include "views/view.h"
+
+class PanelScroller;
+
+// This class wraps the contents of a panel in the panel scroller. It currently
+// doesn't do anything useful, but it just a placeholder.
+class PanelScrollerContainer : public views::View {
+ public:
+ PanelScrollerContainer(PanelScroller* scroller, views::View* contents);
+ virtual ~PanelScrollerContainer();
+
+ int HeaderSize() const;
+
+ // view::View overrides.
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual void Paint(gfx::Canvas* canvas);
+
+ private:
+ // Non-owning pointer to our parent scroller object.
+ PanelScroller* scroller_;
+
+ views::View* contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelScrollerContainer);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_CONTAINER_H_
+
diff --git a/chrome/browser/chromeos/panels/panel_scroller_header.cc b/chrome/browser/chromeos/panels/panel_scroller_header.cc
new file mode 100644
index 0000000..47da1ad
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller_header.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2009 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/chromeos/panels/panel_scroller_header.h"
+
+#include "app/gfx/canvas.h"
+#include "app/gfx/font.h"
+#include "app/resource_bundle.h"
+#include "base/string_util.h"
+#include "chrome/browser/chromeos/panels/panel_scroller.h"
+
+PanelScrollerHeader::PanelScrollerHeader(PanelScroller* scroller)
+ : views::View(),
+ scroller_(scroller) {
+}
+
+PanelScrollerHeader::~PanelScrollerHeader() {
+}
+
+bool PanelScrollerHeader::OnMousePressed(const views::MouseEvent& event) {
+ return true;
+}
+
+bool PanelScrollerHeader::OnMouseDragged(const views::MouseEvent& event) {
+ return false;
+}
+
+void PanelScrollerHeader::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ scroller_->HeaderClicked(this);
+}
+
+gfx::Size PanelScrollerHeader::GetPreferredSize() {
+ return gfx::Size(size().width(), 18);
+}
+
+void PanelScrollerHeader::Paint(gfx::Canvas* canvas) {
+ // TODO(brettw) fill this out with real styling.
+ canvas->FillRectInt(0xFFFFFFFF, 0, 0, size().width(), size().height());
+ canvas->DrawLineInt(0xFFE6E6E6, 0, size().height() - 1,
+ size().width(), size().height() - 1);
+
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font font =
+ rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD);
+ int font_top = 1;
+ canvas->DrawStringInt(UTF16ToWideHack(title_), font, 0xFF000000, 3, font_top,
+ size().width(), size().height() - font_top);
+
+}
diff --git a/chrome/browser/chromeos/panels/panel_scroller_header.h b/chrome/browser/chromeos/panels/panel_scroller_header.h
new file mode 100644
index 0000000..e4aa8d9
--- /dev/null
+++ b/chrome/browser/chromeos/panels/panel_scroller_header.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_HEADER_H_
+#define CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_HEADER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+#include "views/view.h"
+
+class PanelScroller;
+
+class PanelScrollerHeader : public views::View {
+ public:
+ PanelScrollerHeader(PanelScroller* scroller);
+ virtual ~PanelScrollerHeader();
+
+ void set_title(const string16& title) {
+ title_ = title;
+ }
+
+ // views::View overrides.
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+ virtual gfx::Size GetPreferredSize();
+ virtual void Paint(gfx::Canvas* canvas);
+
+ private:
+ // Non-owning pointer to our parent scroller object.
+ PanelScroller* scroller_;
+
+ string16 title_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelScrollerHeader);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_PANELS_PANEL_SCROLLER_HEADER_H_
+