diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 23:41:24 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 23:41:24 +0000 |
commit | ae25f9f425e0e652e0d72edf6fb5d080d5760f3b (patch) | |
tree | 702d964850ddbf39389014d65d2d39dda8dcbb43 /chrome/browser/chromeos/panels | |
parent | 61eeb15a8909da1141c10316d8cf8c6841ed29d1 (diff) | |
download | chromium_src-ae25f9f425e0e652e0d72edf6fb5d080d5760f3b.zip chromium_src-ae25f9f425e0e652e0d72edf6fb5d080d5760f3b.tar.gz chromium_src-ae25f9f425e0e652e0d72edf6fb5d080d5760f3b.tar.bz2 |
* Moved panel controller to chromeos directory
* Include BrowserExtender to regular build to remove CHROMEOS ifdefs in BrowserView
* moved browser_extender.h to chrome/browser/views/frame, and BrowserExtender methods
to chrome/browser/views/frame/browser_extender.cc.
* Added StandardExtender (standard_extender.cc), which is empty now. I'm going to add MainMenu support to win,
which will be added vua StandardExtender with a command line flag.
* factory method "Create" is now defined in standard_extender.cc and chromeos/chromeos_browser_extenders.cc.
toolkit_views=1 uses chromeos_browser_extenders.cc and other build uses standard_extender
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/317001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29836 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/panels')
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_ + |