// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "athena/home/public/home_card.h"
+#include "athena/home/home_card_impl.h"
#include <cmath>
#include <limits>
-#include "athena/common/container_priorities.h"
+#include "athena/env/public/athena_env.h"
#include "athena/home/app_list_view_delegate.h"
#include "athena/home/athena_start_page_view.h"
+#include "athena/home/home_card_constants.h"
#include "athena/home/minimized_home.h"
#include "athena/home/public/app_model_builder.h"
-#include "athena/input/public/accelerator_manager.h"
#include "athena/screen/public/screen_manager.h"
+#include "athena/util/container_priorities.h"
#include "athena/wm/public/window_manager.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/views/app_list_main_view.h"
#include "ui/app_list/views/contents_view.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/window.h"
-#include "ui/compositor/closure_animation_observer.h"
+#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/views/background.h"
-#include "ui/views/layout/box_layout.h"
+#include "ui/gfx/animation/tween.h"
+#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/shadow_types.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_client.h"
namespace athena {
namespace {
HomeCard* instance = NULL;
-const int kHomeCardHeight = 100;
-const int kHomeCardMinimizedHeight = 6;
gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
HomeCard::State state) {
case HomeCard::VISIBLE_CENTERED:
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:
return gfx::Rect(0,
screen_bounds.bottom() - kHomeCardHeight,
screen_bounds.width(),
- kHomeCardHeight);
+ screen_bounds.height());
case HomeCard::VISIBLE_MINIMIZED:
return gfx::Rect(0,
screen_bounds.bottom() - kHomeCardMinimizedHeight,
screen_bounds.width(),
- kHomeCardMinimizedHeight);
+ screen_bounds.height());
}
NOTREACHED();
return gfx::Rect();
}
+} // namespace
+
// Makes sure the homecard is center-aligned horizontally and bottom-aligned
// vertically.
class HomeCardLayoutManager : public aura::LayoutManager {
public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- virtual HomeCard::State GetState() = 0;
- virtual aura::Window* GetNativeWindow() = 0;
- };
-
- explicit HomeCardLayoutManager(Delegate* delegate)
- : delegate_(delegate) {}
+ HomeCardLayoutManager()
+ : home_card_(NULL),
+ minimized_layer_(NULL) {}
virtual ~HomeCardLayoutManager() {}
- void Layout() {
- aura::Window* home_card = delegate_->GetNativeWindow();
+ void Layout(bool animate, gfx::Tween::Type tween_type) {
// |home_card| could be detached from the root window (e.g. when it is being
// destroyed).
- if (!home_card || !home_card->GetRootWindow())
+ if (!home_card_ || !home_card_->IsVisible() || !home_card_->GetRootWindow())
return;
- {
- ui::ScopedLayerAnimationSettings settings(
- home_card->layer()->GetAnimator());
- settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
- SetChildBoundsDirect(home_card, GetBoundsForState(
- home_card->GetRootWindow()->bounds(), delegate_->GetState()));
+ scoped_ptr<ui::ScopedLayerAnimationSettings> settings;
+ if (animate) {
+ settings.reset(new ui::ScopedLayerAnimationSettings(
+ home_card_->layer()->GetAnimator()));
+ settings->SetTweenType(tween_type);
}
+ SetChildBoundsDirect(home_card_, GetBoundsForState(
+ home_card_->GetRootWindow()->bounds(), HomeCard::Get()->GetState()));
+ }
+
+ void SetMinimizedLayer(ui::Layer* minimized_layer) {
+ minimized_layer_ = minimized_layer;
+ UpdateMinimizedHomeBounds();
}
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:
- virtual void OnWindowResized() OVERRIDE { Layout(); }
- virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { Layout(); }
- virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {}
+ virtual void OnWindowResized() OVERRIDE {
+ Layout(false, gfx::Tween::LINEAR);
+ UpdateMinimizedHomeBounds();
+ }
+ virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {
+ if (!home_card_) {
+ home_card_ = child;
+ Layout(false, gfx::Tween::LINEAR);
+ }
+ }
+ virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {
+ if (home_card_ == child)
+ home_card_ = NULL;
+ }
virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
- Layout();
}
virtual void OnChildWindowVisibilityChanged(aura::Window* child,
bool visible) OVERRIDE {
- Layout();
+ if (home_card_ == child)
+ Layout(false, gfx::Tween::LINEAR);
}
virtual void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) OVERRIDE {
SetChildBoundsDirect(child, requested_bounds);
}
- Delegate* delegate_;
+ aura::Window* home_card_;
+ ui::Layer* minimized_layer_;
DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager);
};
-class HomeCardGestureManager {
- public:
- class Delegate {
- public:
- // Called when the gesture has ended. The state of the home card will
- // end up with |final_state|.
- virtual void OnGestureEnded(HomeCard::State final_state) = 0;
-
- // Called when the gesture position is updated so that |delegate| should
- // update the visual. The arguments represent the state of the current
- // gesture position is switching from |from_state| to |to_state|, and
- // the level of the progress is at |progress|, which is 0 to 1.
- // |from_state| and |to_state| could be same. For example, if the user moves
- // the finger down to the bottom of the screen, both states are MINIMIZED.
- // In that case |progress| is 0.
- virtual void OnGestureProgressed(
- HomeCard::State from_state,
- HomeCard::State to_state,
- float progress) = 0;
- };
-
- HomeCardGestureManager(Delegate* delegate,
- const gfx::Rect& screen_bounds)
- : delegate_(delegate),
- last_state_(HomeCard::Get()->GetState()),
- y_offset_(0),
- last_estimated_top_(0),
- screen_bounds_(screen_bounds) {}
-
- void ProcessGestureEvent(ui::GestureEvent* event) {
- switch (event->type()) {
- case ui::ET_GESTURE_SCROLL_BEGIN:
- y_offset_ = event->location().y();
- event->SetHandled();
- break;
- case ui::ET_GESTURE_SCROLL_END:
- event->SetHandled();
- delegate_->OnGestureEnded(GetClosestState());
- break;
- case ui::ET_GESTURE_SCROLL_UPDATE:
- UpdateScrollState(*event);
- break;
- case ui::ET_SCROLL_FLING_START: {
- const ui::GestureEventDetails& details = event->details();
- const float kFlingCompletionVelocity = 100.0f;
- if (::fabs(details.velocity_y()) > kFlingCompletionVelocity) {
- int step = (details.velocity_y() > 0) ? 1 : -1;
- int new_state = static_cast<int>(last_state_) + step;
- if (new_state >= HomeCard::VISIBLE_CENTERED &&
- new_state <= HomeCard::VISIBLE_MINIMIZED) {
- last_state_ = static_cast<HomeCard::State>(new_state);
- }
- delegate_->OnGestureEnded(last_state_);
- }
- break;
- }
- default:
- // do nothing.
- break;
- }
- }
-
- private:
- HomeCard::State GetClosestState() {
- // The top position of the bounds for one smaller state than the current
- // one.
- int smaller_top = -1;
- for (int i = HomeCard::VISIBLE_MINIMIZED;
- i >= HomeCard::VISIBLE_CENTERED; --i) {
- HomeCard::State state = static_cast<HomeCard::State>(i);
- int top = GetBoundsForState(screen_bounds_, state).y();
- if (last_estimated_top_ == top) {
- return state;
- } else if (last_estimated_top_ > top) {
- if (smaller_top < 0)
- return state;
-
- if (smaller_top - last_estimated_top_ > (smaller_top - top) / 5) {
- return state;
- } else {
- return static_cast<HomeCard::State>(i + 1);
- }
- }
- smaller_top = top;
- }
-
- NOTREACHED();
- return last_state_;
- }
-
- void UpdateScrollState(const ui::GestureEvent& event) {
- last_estimated_top_ = event.root_location().y() - y_offset_;
-
- // The bounds which is at one smaller state than the current one.
- gfx::Rect smaller_bounds;
-
- for (int i = HomeCard::VISIBLE_MINIMIZED;
- i >= HomeCard::VISIBLE_CENTERED; --i) {
- HomeCard::State state = static_cast<HomeCard::State>(i);
- const gfx::Rect bounds = GetBoundsForState(screen_bounds_, state);
- if (last_estimated_top_ == bounds.y()) {
- delegate_->OnGestureProgressed(last_state_, state, 1.0f);
- last_state_ = state;
- return;
- } else if (last_estimated_top_ > bounds.y()) {
- if (smaller_bounds.IsEmpty()) {
- // Smaller than minimized -- returning the minimized bounds.
- delegate_->OnGestureProgressed(last_state_, state, 1.0f);
- } else {
- // The finger is between two states.
- float progress =
- static_cast<float>((smaller_bounds.y() - last_estimated_top_)) /
- (smaller_bounds.y() - bounds.y());
- if (last_state_ == state) {
- if (event.details().scroll_y() > 0) {
- state = static_cast<HomeCard::State>(state + 1);
- progress = 1.0f - progress;
- } else {
- last_state_ = static_cast<HomeCard::State>(last_state_ + 1);
- }
- }
- delegate_->OnGestureProgressed(last_state_, state, progress);
- }
- last_state_ = state;
- return;
- }
- smaller_bounds = bounds;
- }
- NOTREACHED();
- }
-
- Delegate* delegate_;
- HomeCard::State last_state_;
-
- // The offset from the top edge of the home card and the initial position of
- // gesture.
- int y_offset_;
-
- // The estimated top edge of the home card after the last touch event.
- int last_estimated_top_;
-
- // The bounds of the screen to compute the home card bounds.
- gfx::Rect screen_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManager);
-};
-
// The container view of home card contents of each state.
class HomeCardView : public views::WidgetDelegateView {
public:
HomeCardView(app_list::AppListViewDelegate* view_delegate,
aura::Window* container,
HomeCardGestureManager::Delegate* gesture_delegate)
- : gesture_delegate_(gesture_delegate),
- weak_factory_(this) {
- bottom_view_ = new AthenaStartPageView(view_delegate);
- AddChildView(bottom_view_);
- bottom_view_->SetPaintToLayer(true);
- bottom_view_->layer()->SetFillsBoundsOpaquely(false);
-
- main_view_ = new app_list::AppListMainView(
- view_delegate, 0 /* initial_apps_page */, container);
+ : gesture_delegate_(gesture_delegate) {
+ SetLayoutManager(new views::FillLayout());
+ // Ideally AppListMainView should be used here and have AthenaStartPageView
+ // as its child view, so that custom pages and apps grid are available in
+ // the home card.
+ // TODO(mukai): make it so after the detailed UI has been fixed.
+ main_view_ = new AthenaStartPageView(view_delegate);
AddChildView(main_view_);
- main_view_->set_background(
- views::Background::CreateSolidBackground(SK_ColorWHITE));
- main_view_->SetPaintToLayer(true);
-
- minimized_view_ = CreateMinimizedHome();
- minimized_view_->SetPaintToLayer(true);
- AddChildView(minimized_view_);
}
void SetStateProgress(HomeCard::State from_state,
HomeCard::State to_state,
float progress) {
- if (from_state == HomeCard::VISIBLE_BOTTOM &&
- to_state == HomeCard::VISIBLE_MINIMIZED) {
- SetStateProgress(to_state, from_state, 1.0 - progress);
- return;
- }
-
- // View from minimized to bottom.
- if (from_state == HomeCard::VISIBLE_MINIMIZED &&
- to_state == HomeCard::VISIBLE_BOTTOM) {
- bottom_view_->SetVisible(true);
- minimized_view_->SetVisible(true);
- minimized_view_->layer()->SetOpacity(1.0f - progress);
- return;
- }
-
- SetState(to_state);
+ // TODO(mukai): not clear the focus, but simply close the virtual keyboard.
+ GetFocusManager()->ClearFocus();
+ if (from_state == HomeCard::VISIBLE_CENTERED)
+ main_view_->SetLayoutState(1.0f - progress);
+ else if (to_state == HomeCard::VISIBLE_CENTERED)
+ main_view_->SetLayoutState(progress);
+ UpdateShadow(true);
}
- void SetState(HomeCard::State state) {
- bottom_view_->SetVisible(state == HomeCard::VISIBLE_BOTTOM);
- main_view_->SetVisible(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) {
- app_list::ContentsView* contents_view = main_view_->contents_view();
- contents_view->SetActivePage(contents_view->GetPageIndexForNamedPage(
- app_list::ContentsView::NAMED_PAGE_START));
- }
- wm::SetShadowType(GetWidget()->GetNativeView(),
- state == HomeCard::VISIBLE_MINIMIZED ?
- wm::SHADOW_TYPE_NONE :
- wm::SHADOW_TYPE_RECTANGULAR);
- }
+ void SetStateWithAnimation(HomeCard::State state,
+ gfx::Tween::Type tween_type) {
+ UpdateShadow(state != HomeCard::VISIBLE_MINIMIZED);
+ if (state == HomeCard::VISIBLE_CENTERED)
+ main_view_->RequestFocusOnSearchBox();
+ else
+ GetWidget()->GetFocusManager()->ClearFocus();
- void SetStateWithAnimation(HomeCard::State from_state,
- HomeCard::State to_state) {
- if ((from_state == HomeCard::VISIBLE_MINIMIZED &&
- to_state == HomeCard::VISIBLE_BOTTOM) ||
- (from_state == HomeCard::VISIBLE_BOTTOM &&
- to_state == HomeCard::VISIBLE_MINIMIZED)) {
- minimized_view_->SetVisible(true);
- bottom_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);
- }
+ main_view_->SetLayoutStateWithAnimation(
+ (state == HomeCard::VISIBLE_CENTERED) ? 1.0f : 0.0f, tween_type);
}
void ClearGesture() {
}
// 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 {
if (!gesture_manager_ &&
event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
if (gesture_manager_)
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::Get()->ToggleOverview();
+ return true;
+ }
+ return false;
+ }
private:
+ void UpdateShadow(bool should_show) {
+ wm::SetShadowType(
+ GetWidget()->GetNativeWindow(),
+ should_show ? wm::SHADOW_TYPE_RECTANGULAR : wm::SHADOW_TYPE_NONE);
+ }
+
// views::WidgetDelegate:
virtual views::View* GetContentsView() OVERRIDE {
return this;
}
- app_list::AppListMainView* main_view_;
- views::View* bottom_view_;
- views::View* minimized_view_;
+ AthenaStartPageView* main_view_;
scoped_ptr<HomeCardGestureManager> gesture_manager_;
HomeCardGestureManager::Delegate* gesture_delegate_;
- base::WeakPtrFactory<HomeCardView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(HomeCardView);
};
-class HomeCardImpl : public HomeCard,
- public AcceleratorHandler,
- public HomeCardLayoutManager::Delegate,
- public HomeCardGestureManager::Delegate,
- public WindowManagerObserver,
- public aura::client::ActivationChangeObserver {
- public:
- explicit HomeCardImpl(AppModelBuilder* model_builder);
- virtual ~HomeCardImpl();
-
- void Init();
-
- private:
- enum Command {
- COMMAND_SHOW_HOME_CARD,
- };
- void InstallAccelerators();
-
- // Overridden from HomeCard:
- virtual void SetState(State state) OVERRIDE;
- virtual State GetState() OVERRIDE;
- virtual void RegisterSearchProvider(
- app_list::SearchProvider* search_provider) OVERRIDE;
- virtual void UpdateVirtualKeyboardBounds(
- const gfx::Rect& bounds) OVERRIDE;
-
- // AcceleratorHandler:
- virtual bool IsCommandEnabled(int command_id) const OVERRIDE { return true; }
- virtual bool OnAcceleratorFired(int command_id,
- const ui::Accelerator& accelerator) OVERRIDE;
-
- // HomeCardLayoutManager::Delegate:
- virtual aura::Window* GetNativeWindow() OVERRIDE;
-
- // HomeCardGestureManager::Delegate:
- virtual void OnGestureEnded(State final_state) OVERRIDE;
- virtual void OnGestureProgressed(
- State from_state, State to_state, float progress) OVERRIDE;
-
- // WindowManagerObserver:
- virtual void OnOverviewModeEnter() OVERRIDE;
- virtual void OnOverviewModeExit() OVERRIDE;
-
- // aura::client::ActivationChangeObserver:
- virtual void OnWindowActivated(aura::Window* gained_active,
- aura::Window* lost_active) OVERRIDE;
-
- scoped_ptr<AppModelBuilder> model_builder_;
-
- HomeCard::State state_;
-
- // original_state_ is the state which the home card should go back to after
- // the virtual keyboard is hidden.
- HomeCard::State original_state_;
-
- views::Widget* home_card_widget_;
- HomeCardView* home_card_view_;
- scoped_ptr<AppListViewDelegate> view_delegate_;
- HomeCardLayoutManager* layout_manager_;
- aura::client::ActivationClient* activation_client_; // Not owned
-
- // Right now HomeCard allows only one search provider.
- // TODO(mukai): port app-list's SearchController and Mixer.
- scoped_ptr<app_list::SearchProvider> search_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(HomeCardImpl);
-};
-
HomeCardImpl::HomeCardImpl(AppModelBuilder* model_builder)
: model_builder_(model_builder),
state_(HIDDEN),
activation_client_(NULL) {
DCHECK(!instance);
instance = this;
- WindowManager::GetInstance()->AddObserver(this);
+ WindowManager::Get()->AddObserver(this);
}
HomeCardImpl::~HomeCardImpl() {
DCHECK(instance);
- WindowManager::GetInstance()->RemoveObserver(this);
+ WindowManager::Get()->RemoveObserver(this);
if (activation_client_)
activation_client_->RemoveObserver(this);
home_card_widget_->CloseNow();
+
+ // Reset the view delegate first as it access search provider during
+ // shutdown.
+ view_delegate_.reset();
+ search_provider_.reset();
instance = NULL;
}
ScreenManager::ContainerParams params("HomeCardContainer", CP_HOME_CARD);
params.can_activate_children = true;
aura::Window* container = ScreenManager::Get()->CreateContainer(params);
- layout_manager_ = new HomeCardLayoutManager(this);
+ layout_manager_ = new HomeCardLayoutManager();
container->SetLayoutManager(layout_manager_);
wm::SetChildWindowVisibilityChangesAnimated(container);
widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
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);
home_card_view_->Layout();
aura::client::GetActivationClient(container->GetRootWindow());
if (activation_client_)
activation_client_->AddObserver(this);
+
+ AthenaEnv::Get()->SetDisplayWorkAreaInsets(
+ gfx::Insets(0, 0, kHomeCardMinimizedHeight, 0));
+}
+
+aura::Window* HomeCardImpl::GetHomeCardWindowForTest() const {
+ return home_card_widget_ ? home_card_widget_->GetNativeWindow() : NULL;
}
void HomeCardImpl::InstallAccelerators() {
HomeCard::State old_state = state_;
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) {
home_card_widget_->Hide();
} else {
- if (state_ == VISIBLE_CENTERED)
- home_card_widget_->Show();
- else
+ if (state_ == VISIBLE_MINIMIZED)
home_card_widget_->ShowInactive();
- home_card_view_->SetStateWithAnimation(old_state, state);
- layout_manager_->Layout();
+ else
+ home_card_widget_->Show();
+ home_card_view_->SetStateWithAnimation(state, gfx::Tween::EASE_IN_OUT);
+ layout_manager_->Layout(true, gfx::Tween::EASE_IN_OUT);
}
}
}
}
+bool HomeCardImpl::IsCommandEnabled(int command_id) const {
+ return true;
+}
+
bool HomeCardImpl::OnAcceleratorFired(int command_id,
const ui::Accelerator& accelerator) {
DCHECK_EQ(COMMAND_SHOW_HOME_CARD, command_id);
return true;
}
-aura::Window* HomeCardImpl::GetNativeWindow() {
- if (state_ == HIDDEN)
- return NULL;
-
- return home_card_widget_ ? home_card_widget_->GetNativeWindow() : NULL;
-}
-
-void HomeCardImpl::OnGestureEnded(State final_state) {
+void HomeCardImpl::OnGestureEnded(State final_state, bool is_fling) {
home_card_view_->ClearGesture();
if (state_ != final_state &&
(state_ == VISIBLE_MINIMIZED || final_state == VISIBLE_MINIMIZED)) {
- WindowManager::GetInstance()->ToggleOverview();
+ SetState(final_state);
+ WindowManager::Get()->ToggleOverview();
} else {
- HomeCard::State old_state = state_;
state_ = final_state;
- home_card_view_->SetStateWithAnimation(old_state, final_state);
- layout_manager_->Layout();
+ // When the animation happens after a fling, EASE_IN_OUT would cause weird
+ // slow-down right after the finger release because of slow-in. Therefore
+ // EASE_OUT is better.
+ gfx::Tween::Type tween_type =
+ is_fling ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN_OUT;
+ home_card_view_->SetStateWithAnimation(state_, tween_type);
+ layout_manager_->Layout(true, tween_type);
}
}
void HomeCardImpl::OnGestureProgressed(
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 =
home_card_widget_->GetNativeWindow()->GetRootWindow()->bounds();
home_card_widget_->SetBounds(gfx::Tween::RectValueBetween(
GetBoundsForState(screen_bounds, from_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
// intermediate visual state of overview mode.
}
void HomeCardImpl::OnOverviewModeEnter() {
- SetState(VISIBLE_BOTTOM);
+ if (state_ == HIDDEN || state_ == VISIBLE_MINIMIZED)
+ SetState(VISIBLE_BOTTOM);
}
void HomeCardImpl::OnOverviewModeExit() {
SetState(VISIBLE_MINIMIZED);
}
+void HomeCardImpl::OnSplitViewModeEnter() {
+}
+
+void HomeCardImpl::OnSplitViewModeExit() {
+}
+
void HomeCardImpl::OnWindowActivated(aura::Window* gained_active,
aura::Window* lost_active) {
if (state_ != HIDDEN &&
}
}
-} // namespace
-
// static
HomeCard* HomeCard::Create(AppModelBuilder* model_builder) {
(new HomeCardImpl(model_builder))->Init();