Commit 30e02313 authored by mukai's avatar mukai Committed by Commit bot

Refactor the home card structure and introduce animation.

This CL includes the following refactorings:
- minimized home is simply a layer instead of views
- moves the mouse click handler of minimized home to home card impl
- home card now has the same size of the screen. Changing state is
  now simply changing its position.

Then schedule the animation between BOTTOM state and CENTERED state.

BUG=398062
R=sadrul@chromium.org, oshima@chromium.org
TEST=manually on remote desktop

Review URL: https://codereview.chromium.org/478293004

Cr-Commit-Position: refs/heads/master@{#292092}
parent bf20fc68
...@@ -127,17 +127,13 @@ class SearchBoxContainer : public views::View { ...@@ -127,17 +127,13 @@ class SearchBoxContainer : public views::View {
new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius), new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius),
gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth, gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth,
kSearchBoxBorderWidth, kSearchBoxBorderWidth))); kSearchBoxBorderWidth, kSearchBoxBorderWidth)));
SetLayoutManager(new views::FillLayout());
AddChildView(search_box_); AddChildView(search_box_);
} }
virtual ~SearchBoxContainer() {} virtual ~SearchBoxContainer() {}
private: private:
// views::View: // views::View:
virtual void Layout() OVERRIDE {
gfx::Rect search_box_bounds = GetContentsBounds();
search_box_bounds.ClampToCenteredSize(GetPreferredSize());
search_box_->SetBoundsRect(search_box_bounds);
}
virtual gfx::Size GetPreferredSize() const OVERRIDE { virtual gfx::Size GetPreferredSize() const OVERRIDE {
return gfx::Size(kSearchBoxWidth, kSearchBoxHeight); return gfx::Size(kSearchBoxWidth, kSearchBoxHeight);
} }
...@@ -152,13 +148,30 @@ class SearchBoxContainer : public views::View { ...@@ -152,13 +148,30 @@ class SearchBoxContainer : public views::View {
namespace athena { namespace athena {
// static
const char AthenaStartPageView::kViewClassName[] = "AthenaStartPageView";
AthenaStartPageView::LayoutData::LayoutData()
: logo_opacity(1.0f),
background_opacity(1.0f) {
}
AthenaStartPageView::AthenaStartPageView( AthenaStartPageView::AthenaStartPageView(
app_list::AppListViewDelegate* view_delegate) app_list::AppListViewDelegate* view_delegate)
: delegate_(view_delegate), : delegate_(view_delegate),
layout_state_(0.0f),
weak_factory_(this) { weak_factory_(this) {
background_ = new views::View();
background_->set_background(
views::Background::CreateSolidBackground(SK_ColorWHITE));
background_->SetPaintToLayer(true);
background_->SetFillsBoundsOpaquely(false);
AddChildView(background_);
logo_ = view_delegate->CreateStartPageWebView( logo_ = view_delegate->CreateStartPageWebView(
gfx::Size(kWebViewWidth, kWebViewHeight)); gfx::Size(kWebViewWidth, kWebViewHeight));
logo_->SetPaintToLayer(true); logo_->SetPaintToLayer(true);
logo_->SetSize(logo_->GetPreferredSize());
AddChildView(logo_); AddChildView(logo_);
search_results_view_ = new app_list::SearchResultListView( search_results_view_ = new app_list::SearchResultListView(
...@@ -183,13 +196,7 @@ AthenaStartPageView::AthenaStartPageView( ...@@ -183,13 +196,7 @@ AthenaStartPageView::AthenaStartPageView(
view_delegate->GetModel()->top_level_item_list(); view_delegate->GetModel()->top_level_item_list();
for (size_t i = 0; i < std::min(top_level->item_count(), kMaxIconNum); ++i) for (size_t i = 0; i < std::min(top_level->item_count(), kMaxIconNum); ++i)
app_icon_container_->AddChildView(new AppIconButton(top_level->item_at(i))); app_icon_container_->AddChildView(new AppIconButton(top_level->item_at(i)));
app_icon_container_->SetSize(app_icon_container_->GetPreferredSize());
search_box_view_ = new app_list::SearchBoxView(this, view_delegate);
search_box_view_->set_contents_view(this);
search_box_container_ = new SearchBoxContainer(search_box_view_);
search_box_container_->SetPaintToLayer(true);
search_box_container_->SetFillsBoundsOpaquely(false);
AddChildView(search_box_container_);
control_icon_container_ = new views::View(); control_icon_container_ = new views::View();
control_icon_container_->SetPaintToLayer(true); control_icon_container_->SetPaintToLayer(true);
...@@ -199,6 +206,15 @@ AthenaStartPageView::AthenaStartPageView( ...@@ -199,6 +206,15 @@ AthenaStartPageView::AthenaStartPageView(
views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); views::BoxLayout::kHorizontal, 0, 0, kIconMargin));
for (size_t i = 0; i < kMaxIconNum; ++i) for (size_t i = 0; i < kMaxIconNum; ++i)
control_icon_container_->AddChildView(new PlaceHolderButton()); control_icon_container_->AddChildView(new PlaceHolderButton());
control_icon_container_->SetSize(control_icon_container_->GetPreferredSize());
search_box_view_ = new app_list::SearchBoxView(this, view_delegate);
search_box_view_->set_contents_view(this);
search_box_container_ = new SearchBoxContainer(search_box_view_);
search_box_container_->SetPaintToLayer(true);
search_box_container_->SetFillsBoundsOpaquely(false);
search_box_container_->SetSize(search_box_container_->GetPreferredSize());
AddChildView(search_box_container_);
} }
AthenaStartPageView::~AthenaStartPageView() {} AthenaStartPageView::~AthenaStartPageView() {}
...@@ -207,6 +223,69 @@ void AthenaStartPageView::RequestFocusOnSearchBox() { ...@@ -207,6 +223,69 @@ void AthenaStartPageView::RequestFocusOnSearchBox() {
search_box_view_->search_box()->RequestFocus(); search_box_view_->search_box()->RequestFocus();
} }
void AthenaStartPageView::SetLayoutState(float layout_state) {
layout_state_ = layout_state;
Layout();
}
void AthenaStartPageView::SetLayoutStateWithAnimation(float layout_state) {
ui::ScopedLayerAnimationSettings logo(logo_->layer()->GetAnimator());
ui::ScopedLayerAnimationSettings search_box(
search_box_container_->layer()->GetAnimator());
ui::ScopedLayerAnimationSettings icons(
app_icon_container_->layer()->GetAnimator());
ui::ScopedLayerAnimationSettings controls(
control_icon_container_->layer()->GetAnimator());
logo.SetTweenType(gfx::Tween::EASE_IN_OUT);
search_box.SetTweenType(gfx::Tween::EASE_IN_OUT);
icons.SetTweenType(gfx::Tween::EASE_IN_OUT);
controls.SetTweenType(gfx::Tween::EASE_IN_OUT);
SetLayoutState(layout_state);
}
AthenaStartPageView::LayoutData AthenaStartPageView::CreateBottomBounds(
int width) {
LayoutData state;
state.icons.set_size(app_icon_container_->size());
state.icons.set_x(kIconMargin);
state.icons.set_y(kIconMargin);
state.controls.set_size(control_icon_container_->size());
state.controls.set_x(width - kIconMargin - state.controls.width());
state.controls.set_y(kIconMargin);
state.search_box.set_size(search_box_container_->size());
state.search_box.set_x((width - state.search_box.width()) / 2);
state.search_box.set_y((kHomeCardHeight - state.search_box.height()) / 2);
state.logo_opacity = 0.0f;
state.background_opacity = 0.9f;
return state;
}
AthenaStartPageView::LayoutData AthenaStartPageView::CreateCenteredBounds(
int width) {
LayoutData state;
state.search_box.set_size(search_box_container_->size());
state.search_box.set_x((width - state.search_box.width()) / 2);
state.search_box.set_y(logo_->bounds().bottom() + kInstantContainerSpacing);
state.icons.set_size(app_icon_container_->size());
state.icons.set_x(width / 2 - state.icons.width() - kIconMargin / 2);
state.icons.set_y(state.search_box.bottom() + kInstantContainerSpacing);
state.controls.set_size(control_icon_container_->size());
state.controls.set_x(width / 2 + kIconMargin / 2 + kIconMargin % 2);
state.controls.set_y(state.icons.y());
state.logo_opacity = 1.0f;
state.background_opacity = 1.0f;
return state;
}
void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) { void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) {
if (should_show_search_results == if (should_show_search_results ==
search_results_view_->layer()->GetTargetVisibility()) { search_results_view_->layer()->GetTargetVisibility()) {
...@@ -276,57 +355,31 @@ void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted( ...@@ -276,57 +355,31 @@ void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted(
} }
void AthenaStartPageView::Layout() { void AthenaStartPageView::Layout() {
gfx::Rect bounds = GetContentsBounds();
search_results_view_->SetVisible(false); search_results_view_->SetVisible(false);
gfx::Rect logo_bounds(x() + width() / 2 - kWebViewWidth / 2, y() + kTopMargin,
if (bounds.height() <= kHomeCardHeight) { kWebViewWidth, kWebViewHeight);
logo_->SetVisible(false);
gfx::Rect icon_bounds(app_icon_container_->GetPreferredSize());
icon_bounds.set_x(bounds.x() + kIconMargin);
icon_bounds.set_y(bounds.x() + kIconMargin);
app_icon_container_->SetBoundsRect(icon_bounds);
gfx::Rect control_bounds(control_icon_container_->GetPreferredSize());
control_bounds.set_x(
bounds.right() - kIconMargin - control_bounds.width());
control_bounds.set_y(bounds.y() + kIconMargin);
control_icon_container_->SetBoundsRect(control_bounds);
search_box_container_->SetBounds(
icon_bounds.right(), bounds.y(),
control_bounds.x() - icon_bounds.right(), kHomeCardHeight);
set_background(views::Background::CreateSolidBackground(
255, 255, 255, 255 * 0.9));
} else {
// TODO(mukai): set the intermediate state.
logo_->SetVisible(true);
logo_->layer()->SetOpacity(1.0f);
set_background(views::Background::CreateSolidBackground(SK_ColorWHITE));
gfx::Rect logo_bounds(bounds.x() + bounds.width() / 2 - kWebViewWidth / 2,
bounds.y() + kTopMargin,
kWebViewWidth,
kWebViewHeight);
logo_->SetBoundsRect(logo_bounds); logo_->SetBoundsRect(logo_bounds);
gfx::Rect search_box_bounds(search_box_container_->GetPreferredSize()); LayoutData bottom_bounds = CreateBottomBounds(width());
search_box_bounds.set_x( LayoutData centered_bounds = CreateCenteredBounds(width());
bounds.x() + bounds.width() / 2 - search_box_bounds.width() / 2);
search_box_bounds.set_y(logo_bounds.bottom() + kInstantContainerSpacing); logo_->layer()->SetOpacity(gfx::Tween::FloatValueBetween(
search_box_container_->SetBoundsRect(search_box_bounds); gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_),
bottom_bounds.logo_opacity, centered_bounds.logo_opacity));
gfx::Rect icon_bounds(app_icon_container_->GetPreferredSize()); logo_->SetVisible(logo_->layer()->GetTargetOpacity() != 0.0f);
icon_bounds.set_x(bounds.x() + bounds.width() / 2 -
icon_bounds.width() - kIconMargin / 2); app_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
icon_bounds.set_y(search_box_bounds.bottom() + kInstantContainerSpacing); layout_state_, bottom_bounds.icons, centered_bounds.icons));
app_icon_container_->SetBoundsRect(icon_bounds); control_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
layout_state_, bottom_bounds.controls, centered_bounds.controls));
gfx::Rect control_bounds(control_icon_container_->GetPreferredSize()); search_box_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
control_bounds.set_x(bounds.x() + bounds.width() / 2 + layout_state_, bottom_bounds.search_box, centered_bounds.search_box));
kIconMargin / 2 + kIconMargin % 2);
control_bounds.set_y(icon_bounds.y()); background_->SetBoundsRect(bounds());
control_icon_container_->SetBoundsRect(control_bounds); background_->layer()->SetOpacity(gfx::Tween::FloatValueBetween(
} layout_state_,
bottom_bounds.background_opacity,
centered_bounds.background_opacity));
} }
bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) { bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) {
......
...@@ -17,8 +17,6 @@ class SearchResultListView; ...@@ -17,8 +17,6 @@ class SearchResultListView;
namespace athena { namespace athena {
// It will replace app_list::StartPageView in Athena UI in the future.
// Right now it's simply used for VISIBLE_BOTTOM state.
class AthenaStartPageView : public views::View, class AthenaStartPageView : public views::View,
public app_list::SearchBoxViewDelegate { public app_list::SearchBoxViewDelegate {
public: public:
...@@ -28,7 +26,33 @@ class AthenaStartPageView : public views::View, ...@@ -28,7 +26,33 @@ class AthenaStartPageView : public views::View,
// Requests the focus on the search box in the start page view. // Requests the focus on the search box in the start page view.
void RequestFocusOnSearchBox(); void RequestFocusOnSearchBox();
// Updates the layout state. See the comment of |layout_state_| field.
void SetLayoutState(float layout_state);
// Updates the layout state and move the subviews to the target location with
// animation.
void SetLayoutStateWithAnimation(float layout_state);
private: private:
static const char kViewClassName[];
// A struct which bundles the layout data of subviews.
struct LayoutData {
gfx::Rect search_box;
gfx::Rect icons;
gfx::Rect controls;
float logo_opacity;
float background_opacity;
LayoutData();
};
// Returns the bounds for |VISIBLE_BOTTOM|.
LayoutData CreateBottomBounds(int width);
// Returns the bounds for |VISIBLE_CENTERED|.
LayoutData CreateCenteredBounds(int width);
// Schedules the animation for the layout the search box and the search // Schedules the animation for the layout the search box and the search
// results. // results.
void LayoutSearchResults(bool should_show_search_results); void LayoutSearchResults(bool should_show_search_results);
...@@ -55,9 +79,17 @@ class AthenaStartPageView : public views::View, ...@@ -55,9 +79,17 @@ class AthenaStartPageView : public views::View,
app_list::SearchBoxView* search_box_view_; app_list::SearchBoxView* search_box_view_;
app_list::SearchResultListView* search_results_view_; app_list::SearchResultListView* search_results_view_;
// Do not use views::Background but a views::View with ui::Layer for gradient
// background opacity update and animation.
views::View* background_;
// The expected height of |search_results_view_| // The expected height of |search_results_view_|
int search_results_height_; int search_results_height_;
// The state to specify how each of the subviews should be laid out, in the
// range of [0, 1]. 0 means fully BOTTOM state, and 1 is fully CENTERED state.
float layout_state_;
base::WeakPtrFactory<AthenaStartPageView> weak_factory_; base::WeakPtrFactory<AthenaStartPageView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AthenaStartPageView); DISALLOW_COPY_AND_ASSIGN(AthenaStartPageView);
......
...@@ -99,6 +99,7 @@ void HomeCardGestureManager::UpdateScrollState(const ui::GestureEvent& event) { ...@@ -99,6 +99,7 @@ void HomeCardGestureManager::UpdateScrollState(const ui::GestureEvent& event) {
// The finger is between two states. // The finger is between two states.
float progress = (last_estimated_height_ - smaller_height) / float progress = (last_estimated_height_ - smaller_height) /
(bigger_height - smaller_height); (bigger_height - smaller_height);
progress = std::min(1.0f, std::max(0.0f, progress));
if (last_state_ == state) { if (last_state_ == state) {
if (event.details().scroll_y() > 0) { if (event.details().scroll_y() > 0) {
......
...@@ -19,22 +19,19 @@ ...@@ -19,22 +19,19 @@
#include "athena/screen/public/screen_manager.h" #include "athena/screen/public/screen_manager.h"
#include "athena/wm/public/window_manager.h" #include "athena/wm/public/window_manager.h"
#include "athena/wm/public/window_manager_observer.h" #include "athena/wm/public/window_manager_observer.h"
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "ui/app_list/search_provider.h" #include "ui/app_list/search_provider.h"
#include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/contents_view.h"
#include "ui/aura/layout_manager.h" #include "ui/aura/layout_manager.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/compositor/closure_animation_observer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/views/background.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/shadow_types.h" #include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/visibility_controller.h" #include "ui/wm/core/visibility_controller.h"
#include "ui/wm/core/window_animations.h"
#include "ui/wm/public/activation_change_observer.h" #include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h" #include "ui/wm/public/activation_client.h"
...@@ -52,16 +49,18 @@ gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds, ...@@ -52,16 +49,18 @@ gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
case HomeCard::VISIBLE_CENTERED: case HomeCard::VISIBLE_CENTERED:
return screen_bounds; return screen_bounds;
// Do not change the home_card's size, only changes the top position
// instead, because size change causes unnecessary re-layouts.
case HomeCard::VISIBLE_BOTTOM: case HomeCard::VISIBLE_BOTTOM:
return gfx::Rect(0, return gfx::Rect(0,
screen_bounds.bottom() - kHomeCardHeight, screen_bounds.bottom() - kHomeCardHeight,
screen_bounds.width(), screen_bounds.width(),
kHomeCardHeight); screen_bounds.height());
case HomeCard::VISIBLE_MINIMIZED: case HomeCard::VISIBLE_MINIMIZED:
return gfx::Rect(0, return gfx::Rect(0,
screen_bounds.bottom() - kHomeCardMinimizedHeight, screen_bounds.bottom() - kHomeCardMinimizedHeight,
screen_bounds.width(), screen_bounds.width(),
kHomeCardMinimizedHeight); screen_bounds.height());
} }
NOTREACHED(); NOTREACHED();
...@@ -72,33 +71,51 @@ gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds, ...@@ -72,33 +71,51 @@ gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
// vertically. // vertically.
class HomeCardLayoutManager : public aura::LayoutManager { class HomeCardLayoutManager : public aura::LayoutManager {
public: public:
explicit HomeCardLayoutManager() HomeCardLayoutManager()
: home_card_(NULL) {} : home_card_(NULL),
minimized_layer_(NULL) {}
virtual ~HomeCardLayoutManager() {} virtual ~HomeCardLayoutManager() {}
void Layout() { void Layout(bool animate) {
// |home_card| could be detached from the root window (e.g. when it is being // |home_card| could be detached from the root window (e.g. when it is being
// destroyed). // destroyed).
if (!home_card_ || !home_card_->IsVisible() || !home_card_->GetRootWindow()) if (!home_card_ || !home_card_->IsVisible() || !home_card_->GetRootWindow())
return; return;
{ scoped_ptr<ui::ScopedLayerAnimationSettings> settings;
ui::ScopedLayerAnimationSettings settings( if (animate) {
home_card_->layer()->GetAnimator()); settings.reset(new ui::ScopedLayerAnimationSettings(
settings.SetTweenType(gfx::Tween::EASE_IN_OUT); home_card_->layer()->GetAnimator()));
settings->SetTweenType(gfx::Tween::EASE_IN_OUT);
}
SetChildBoundsDirect(home_card_, GetBoundsForState( SetChildBoundsDirect(home_card_, GetBoundsForState(
home_card_->GetRootWindow()->bounds(), HomeCard::Get()->GetState())); home_card_->GetRootWindow()->bounds(), HomeCard::Get()->GetState()));
} }
void SetMinimizedLayer(ui::Layer* minimized_layer) {
minimized_layer_ = minimized_layer;
UpdateMinimizedHomeBounds();
} }
private: private:
void UpdateMinimizedHomeBounds() {
gfx::Rect minimized_bounds = minimized_layer_->parent()->bounds();
minimized_bounds.set_y(
minimized_bounds.bottom() - kHomeCardMinimizedHeight);
minimized_bounds.set_height(kHomeCardMinimizedHeight);
minimized_layer_->SetBounds(minimized_bounds);
}
// aura::LayoutManager: // aura::LayoutManager:
virtual void OnWindowResized() OVERRIDE { Layout(); } virtual void OnWindowResized() OVERRIDE {
Layout(false);
UpdateMinimizedHomeBounds();
}
virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {
if (!home_card_) { if (!home_card_) {
home_card_ = child; home_card_ = child;
Layout(); Layout(false);
} }
} }
virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE { virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {
...@@ -106,11 +123,11 @@ class HomeCardLayoutManager : public aura::LayoutManager { ...@@ -106,11 +123,11 @@ class HomeCardLayoutManager : public aura::LayoutManager {
home_card_ = NULL; home_card_ = NULL;
} }
virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE { virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
Layout(); Layout(false);
} }
virtual void OnChildWindowVisibilityChanged(aura::Window* child, virtual void OnChildWindowVisibilityChanged(aura::Window* child,
bool visible) OVERRIDE { bool visible) OVERRIDE {
Layout(); Layout(false);
} }
virtual void SetChildBounds(aura::Window* child, virtual void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) OVERRIDE { const gfx::Rect& requested_bounds) OVERRIDE {
...@@ -118,6 +135,7 @@ class HomeCardLayoutManager : public aura::LayoutManager { ...@@ -118,6 +135,7 @@ class HomeCardLayoutManager : public aura::LayoutManager {
} }
aura::Window* home_card_; aura::Window* home_card_;
ui::Layer* minimized_layer_;
DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager); DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager);
}; };
...@@ -128,47 +146,28 @@ class HomeCardView : public views::WidgetDelegateView { ...@@ -128,47 +146,28 @@ class HomeCardView : public views::WidgetDelegateView {
HomeCardView(app_list::AppListViewDelegate* view_delegate, HomeCardView(app_list::AppListViewDelegate* view_delegate,
aura::Window* container, aura::Window* container,
HomeCardGestureManager::Delegate* gesture_delegate) HomeCardGestureManager::Delegate* gesture_delegate)
: gesture_delegate_(gesture_delegate), : gesture_delegate_(gesture_delegate) {
weak_factory_(this) { SetLayoutManager(new views::FillLayout());
// Ideally AppListMainView should be used here and have AthenaStartPageView // Ideally AppListMainView should be used here and have AthenaStartPageView
// as its child view, so that custom pages and apps grid are available in // as its child view, so that custom pages and apps grid are available in
// the home card. // the home card.
// TODO(mukai): make it so after the detailed UI has been fixed. // TODO(mukai): make it so after the detailed UI has been fixed.
main_view_ = new AthenaStartPageView(view_delegate); main_view_ = new AthenaStartPageView(view_delegate);
AddChildView(main_view_); AddChildView(main_view_);
minimized_view_ = CreateMinimizedHome();
minimized_view_->SetPaintToLayer(true);
AddChildView(minimized_view_);
} }
void SetStateProgress(HomeCard::State from_state, void SetStateProgress(HomeCard::State from_state,
HomeCard::State to_state, HomeCard::State to_state,
float progress) { float progress) {
if (from_state == HomeCard::VISIBLE_BOTTOM && if (from_state == HomeCard::VISIBLE_CENTERED)
to_state == HomeCard::VISIBLE_MINIMIZED) { main_view_->SetLayoutState(1.0f - progress);
SetStateProgress(to_state, from_state, 1.0 - progress); else if (to_state == HomeCard::VISIBLE_CENTERED)
return; main_view_->SetLayoutState(progress);
} else
// View from minimized to bottom.
if (from_state == HomeCard::VISIBLE_MINIMIZED &&
to_state == HomeCard::VISIBLE_BOTTOM) {
main_view_->SetVisible(true);
minimized_view_->SetVisible(true);
minimized_view_->layer()->SetOpacity(1.0f - progress);
return;
}
SetState(to_state); SetState(to_state);
} }
void SetState(HomeCard::State state) { void SetState(HomeCard::State state) {
main_view_->SetVisible(state == HomeCard::VISIBLE_BOTTOM ||
state == HomeCard::VISIBLE_CENTERED);
minimized_view_->SetVisible(state == HomeCard::VISIBLE_MINIMIZED);
if (minimized_view_->visible())
minimized_view_->layer()->SetOpacity(1.0f);
if (state == HomeCard::VISIBLE_CENTERED) if (state == HomeCard::VISIBLE_CENTERED)
main_view_->RequestFocusOnSearchBox(); main_view_->RequestFocusOnSearchBox();
else else
...@@ -177,31 +176,16 @@ class HomeCardView : public views::WidgetDelegateView { ...@@ -177,31 +176,16 @@ class HomeCardView : public views::WidgetDelegateView {
state == HomeCard::VISIBLE_MINIMIZED ? state == HomeCard::VISIBLE_MINIMIZED ?
wm::SHADOW_TYPE_NONE : wm::SHADOW_TYPE_NONE :
wm::SHADOW_TYPE_RECTANGULAR); wm::SHADOW_TYPE_RECTANGULAR);
main_view_->SetLayoutState(
(state == HomeCard::VISIBLE_CENTERED) ? 1.0f : 0.0f);
} }
void SetStateWithAnimation(HomeCard::State from_state, void SetStateWithAnimation(HomeCard::State state) {
HomeCard::State to_state) { if (state == HomeCard::VISIBLE_MINIMIZED)
if ((from_state == HomeCard::VISIBLE_MINIMIZED && return;
to_state == HomeCard::VISIBLE_BOTTOM) ||
(from_state == HomeCard::VISIBLE_BOTTOM && main_view_->SetLayoutStateWithAnimation(
to_state == HomeCard::VISIBLE_MINIMIZED)) { (state == HomeCard::VISIBLE_CENTERED) ? 1.0f : 0.0f);
minimized_view_->SetVisible(true);
main_view_->SetVisible(true);
{
ui::ScopedLayerAnimationSettings settings(
minimized_view_->layer()->GetAnimator());
settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
settings.AddObserver(new ui::ClosureAnimationObserver(
base::Bind(&HomeCardView::SetState,
weak_factory_.GetWeakPtr(),
to_state)));
minimized_view_->layer()->SetOpacity(
(to_state == HomeCard::VISIBLE_MINIMIZED) ? 1.0f : 0.0f);
}
} else {
// TODO(mukai): Take care of other transition.
SetState(to_state);
}
} }
void ClearGesture() { void ClearGesture() {
...@@ -209,22 +193,6 @@ class HomeCardView : public views::WidgetDelegateView { ...@@ -209,22 +193,6 @@ class HomeCardView : public views::WidgetDelegateView {
} }
// views::View: // views::View:
virtual void Layout() OVERRIDE {
for (int i = 0; i < child_count(); ++i) {
views::View* child = child_at(i);
if (child->visible()) {
if (child == minimized_view_) {
gfx::Rect minimized_bounds = bounds();
minimized_bounds.set_y(
minimized_bounds.bottom() - kHomeCardMinimizedHeight);
minimized_bounds.set_height(kHomeCardMinimizedHeight);
child->SetBoundsRect(minimized_bounds);
} else {
child->SetBoundsRect(bounds());
}
}
}
}
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
if (!gesture_manager_ && if (!gesture_manager_ &&
event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
...@@ -236,6 +204,14 @@ class HomeCardView : public views::WidgetDelegateView { ...@@ -236,6 +204,14 @@ class HomeCardView : public views::WidgetDelegateView {
if (gesture_manager_) if (gesture_manager_)
gesture_manager_->ProcessGestureEvent(event); gesture_manager_->ProcessGestureEvent(event);
} }
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
if (HomeCard::Get()->GetState() == HomeCard::VISIBLE_MINIMIZED &&
event.IsLeftMouseButton() && event.GetClickCount() == 1) {
athena::WindowManager::GetInstance()->ToggleOverview();
return true;
}
return false;
}
private: private:
// views::WidgetDelegate: // views::WidgetDelegate:
...@@ -244,10 +220,8 @@ class HomeCardView : public views::WidgetDelegateView { ...@@ -244,10 +220,8 @@ class HomeCardView : public views::WidgetDelegateView {
} }
AthenaStartPageView* main_view_; AthenaStartPageView* main_view_;
views::View* minimized_view_;
scoped_ptr<HomeCardGestureManager> gesture_manager_; scoped_ptr<HomeCardGestureManager> gesture_manager_;
HomeCardGestureManager::Delegate* gesture_delegate_; HomeCardGestureManager::Delegate* gesture_delegate_;
base::WeakPtrFactory<HomeCardView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(HomeCardView); DISALLOW_COPY_AND_ASSIGN(HomeCardView);
}; };
...@@ -268,6 +242,7 @@ class HomeCardImpl : public HomeCard, ...@@ -268,6 +242,7 @@ class HomeCardImpl : public HomeCard,
COMMAND_SHOW_HOME_CARD, COMMAND_SHOW_HOME_CARD,
}; };
void InstallAccelerators(); void InstallAccelerators();
void UpdateMinimizedHomeBounds();
// Overridden from HomeCard: // Overridden from HomeCard:
virtual void SetState(State state) OVERRIDE; virtual void SetState(State state) OVERRIDE;
...@@ -308,6 +283,7 @@ class HomeCardImpl : public HomeCard, ...@@ -308,6 +283,7 @@ class HomeCardImpl : public HomeCard,
scoped_ptr<AppListViewDelegate> view_delegate_; scoped_ptr<AppListViewDelegate> view_delegate_;
HomeCardLayoutManager* layout_manager_; HomeCardLayoutManager* layout_manager_;
aura::client::ActivationClient* activation_client_; // Not owned aura::client::ActivationClient* activation_client_; // Not owned
scoped_ptr<ui::LayerOwner> minimized_home_;
// Right now HomeCard allows only one search provider. // Right now HomeCard allows only one search provider.
// TODO(mukai): port app-list's SearchController and Mixer. // TODO(mukai): port app-list's SearchController and Mixer.
...@@ -366,6 +342,11 @@ void HomeCardImpl::Init() { ...@@ -366,6 +342,11 @@ void HomeCardImpl::Init() {
widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
home_card_widget_->Init(widget_params); home_card_widget_->Init(widget_params);
minimized_home_ = CreateMinimizedHome();
container->layer()->Add(minimized_home_->layer());
container->layer()->StackAtTop(minimized_home_->layer());
layout_manager_->SetMinimizedLayer(minimized_home_->layer());
SetState(VISIBLE_MINIMIZED); SetState(VISIBLE_MINIMIZED);
home_card_view_->Layout(); home_card_view_->Layout();
...@@ -374,11 +355,8 @@ void HomeCardImpl::Init() { ...@@ -374,11 +355,8 @@ void HomeCardImpl::Init() {
if (activation_client_) if (activation_client_)
activation_client_->AddObserver(this); activation_client_->AddObserver(this);
int work_area_bottom_inset =
GetBoundsForState(home_card_widget_->GetNativeWindow()->bounds(),
HomeCard::VISIBLE_MINIMIZED).height();
AthenaEnv::Get()->SetDisplayWorkAreaInsets( AthenaEnv::Get()->SetDisplayWorkAreaInsets(
gfx::Insets(0, 0, work_area_bottom_inset, 0)); gfx::Insets(0, 0, kHomeCardMinimizedHeight, 0));
} }
void HomeCardImpl::InstallAccelerators() { void HomeCardImpl::InstallAccelerators() {
...@@ -399,6 +377,18 @@ void HomeCardImpl::SetState(HomeCard::State state) { ...@@ -399,6 +377,18 @@ void HomeCardImpl::SetState(HomeCard::State state) {
HomeCard::State old_state = state_; HomeCard::State old_state = state_;
state_ = state; state_ = state;
original_state_ = state; original_state_ = state;
if (old_state == VISIBLE_MINIMIZED ||
state_ == VISIBLE_MINIMIZED) {
minimized_home_->layer()->SetVisible(true);
{
ui::ScopedLayerAnimationSettings settings(
minimized_home_->layer()->GetAnimator());
minimized_home_->layer()->SetVisible(state_ == VISIBLE_MINIMIZED);
minimized_home_->layer()->SetOpacity(
state_ == VISIBLE_MINIMIZED ? 1.0f : 0.0f);
}
}
if (state_ == HIDDEN) { if (state_ == HIDDEN) {
home_card_widget_->Hide(); home_card_widget_->Hide();
} else { } else {
...@@ -406,8 +396,8 @@ void HomeCardImpl::SetState(HomeCard::State state) { ...@@ -406,8 +396,8 @@ void HomeCardImpl::SetState(HomeCard::State state) {
home_card_widget_->Show(); home_card_widget_->Show();
else else
home_card_widget_->ShowInactive(); home_card_widget_->ShowInactive();
home_card_view_->SetStateWithAnimation(old_state, state); home_card_view_->SetStateWithAnimation(state);
layout_manager_->Layout(); layout_manager_->Layout(true);
} }
} }
...@@ -453,17 +443,20 @@ void HomeCardImpl::OnGestureEnded(State final_state) { ...@@ -453,17 +443,20 @@ void HomeCardImpl::OnGestureEnded(State final_state) {
SetState(final_state); SetState(final_state);
WindowManager::GetInstance()->ToggleOverview(); WindowManager::GetInstance()->ToggleOverview();
} else { } else {
HomeCard::State old_state = state_;
state_ = final_state; state_ = final_state;
home_card_view_->SetStateWithAnimation(old_state, final_state); home_card_view_->SetStateWithAnimation(state_);
layout_manager_->Layout(); layout_manager_->Layout(true);
} }
} }
void HomeCardImpl::OnGestureProgressed( void HomeCardImpl::OnGestureProgressed(
State from_state, State to_state, float progress) { State from_state, State to_state, float progress) {
home_card_view_->SetStateProgress(from_state, to_state, progress); if (from_state == VISIBLE_MINIMIZED || to_state == VISIBLE_MINIMIZED) {
minimized_home_->layer()->SetVisible(true);
float opacity =
(from_state == VISIBLE_MINIMIZED) ? 1.0f - progress : progress;
minimized_home_->layer()->SetOpacity(opacity);
}
gfx::Rect screen_bounds = gfx::Rect screen_bounds =
home_card_widget_->GetNativeWindow()->GetRootWindow()->bounds(); home_card_widget_->GetNativeWindow()->GetRootWindow()->bounds();
home_card_widget_->SetBounds(gfx::Tween::RectValueBetween( home_card_widget_->SetBounds(gfx::Tween::RectValueBetween(
...@@ -471,6 +464,8 @@ void HomeCardImpl::OnGestureProgressed( ...@@ -471,6 +464,8 @@ void HomeCardImpl::OnGestureProgressed(
GetBoundsForState(screen_bounds, from_state), GetBoundsForState(screen_bounds, from_state),
GetBoundsForState(screen_bounds, to_state))); GetBoundsForState(screen_bounds, to_state)));
home_card_view_->SetStateProgress(from_state, to_state, progress);
// TODO(mukai): signals the update to the window manager so that it shows the // TODO(mukai): signals the update to the window manager so that it shows the
// intermediate visual state of overview mode. // intermediate visual state of overview mode.
} }
......
...@@ -4,24 +4,30 @@ ...@@ -4,24 +4,30 @@
#include "athena/home/minimized_home.h" #include "athena/home/minimized_home.h"
#include "athena/wm/public/window_manager.h" #include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
namespace { namespace {
const int kDragHandleWidth = 112; const int kDragHandleWidth = 112;
const int kDragHandleHeight = 2; const int kDragHandleHeight = 2;
const char kMinimizedHomeLayerName[] = "MinimizedHome";
class MinimizedHomeBackground : public views::Background { class MinimizedHomePainter : public ui::LayerDelegate,
public ui::LayerOwner {
public: public:
MinimizedHomeBackground() {} explicit MinimizedHomePainter(ui::Layer* layer) {
virtual ~MinimizedHomeBackground() {} layer->set_name(kMinimizedHomeLayerName);
layer->set_delegate(this);
SetLayer(layer);
}
virtual ~MinimizedHomePainter() {}
private: private:
virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { // ui::LayerDelegate:
gfx::Rect bounds = view->GetLocalBounds(); virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
gfx::Rect bounds(layer()->GetTargetBounds().size());
canvas->FillRect(bounds, SK_ColorBLACK); canvas->FillRect(bounds, SK_ColorBLACK);
canvas->FillRect(gfx::Rect((bounds.width() - kDragHandleWidth) / 2, canvas->FillRect(gfx::Rect((bounds.width() - kDragHandleWidth) / 2,
bounds.bottom() - kDragHandleHeight, bounds.bottom() - kDragHandleHeight,
...@@ -30,37 +36,27 @@ class MinimizedHomeBackground : public views::Background { ...@@ -30,37 +36,27 @@ class MinimizedHomeBackground : public views::Background {
SK_ColorWHITE); SK_ColorWHITE);
} }
DISALLOW_COPY_AND_ASSIGN(MinimizedHomeBackground); virtual void OnDelegatedFrameDamage(
}; const gfx::Rect& damage_rect_in_dip) OVERRIDE {
// This View shows an instance of SmallBarView in the middle, and reacts to
// mouse and touch-gesture events.
class MinimizedHomeView : public views::View {
public:
MinimizedHomeView() {
set_background(new MinimizedHomeBackground());
} }
virtual ~MinimizedHomeView() {}
private: virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
// views::View:
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
if (event.IsLeftMouseButton() && event.GetClickCount() == 1) {
athena::WindowManager::GetInstance()->ToggleOverview();
return true;
} }
return false;
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Closure();
} }
DISALLOW_COPY_AND_ASSIGN(MinimizedHomeView); DISALLOW_COPY_AND_ASSIGN(MinimizedHomePainter);
}; };
} // namespace } // namespace
namespace athena { namespace athena {
views::View* CreateMinimizedHome() { scoped_ptr<ui::LayerOwner> CreateMinimizedHome() {
return new MinimizedHomeView(); return scoped_ptr<ui::LayerOwner>(
new MinimizedHomePainter(new ui::Layer(ui::LAYER_TEXTURED)));
} }
} // namespace athena } // namespace athena
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
#ifndef ATHENA_HOME_MINIMIZED_HOME_H_ #ifndef ATHENA_HOME_MINIMIZED_HOME_H_
#define ATHENA_HOME_MINIMIZED_HOME_H_ #define ATHENA_HOME_MINIMIZED_HOME_H_
namespace views { #include "base/memory/scoped_ptr.h"
class View;
namespace ui {
class LayerOwner;
} }
namespace athena { namespace athena {
views::View* CreateMinimizedHome(); scoped_ptr<ui::LayerOwner> CreateMinimizedHome();
} // namespace athena } // namespace athena
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment