diff options
author | mukai <mukai@chromium.org> | 2014-11-06 02:09:06 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-06 10:09:34 +0000 |
commit | 6116f294a1c79805f4b9ea880d2e19d89aa5ac4e (patch) | |
tree | a4c097fc2a3f34745f79b80bbde14d0ba0992ddd /athena | |
parent | 3d1ff77b15cfa7052307e4c035f9ad39dfc44df0 (diff) | |
download | chromium_src-6116f294a1c79805f4b9ea880d2e19d89aa5ac4e.zip chromium_src-6116f294a1c79805f4b9ea880d2e19d89aa5ac4e.tar.gz chromium_src-6116f294a1c79805f4b9ea880d2e19d89aa5ac4e.tar.bz2 |
Replace the content of the home card by AppListMainView.
Athena specific AthenaStartPageView is not used anymore. We'll
share the same view as the experimental app list.
BUG=425717, 425724, 425719
R=calamity@chromium.org, oshima@chromium.org
TEST=manually
Review URL: https://codereview.chromium.org/683243004
Cr-Commit-Position: refs/heads/master@{#303001}
Diffstat (limited to 'athena')
-rw-r--r-- | athena/athena.gyp | 3 | ||||
-rw-r--r-- | athena/home/app_list_view_delegate.cc | 13 | ||||
-rw-r--r-- | athena/home/athena_start_page_view.cc | 476 | ||||
-rw-r--r-- | athena/home/athena_start_page_view.h | 128 | ||||
-rw-r--r-- | athena/home/athena_start_page_view_unittest.cc | 279 | ||||
-rw-r--r-- | athena/home/home_card_constants.cc | 2 | ||||
-rw-r--r-- | athena/home/home_card_gesture_manager_unittest.cc | 8 | ||||
-rw-r--r-- | athena/home/home_card_impl.cc | 138 | ||||
-rw-r--r-- | athena/home/home_card_impl.h | 9 | ||||
-rw-r--r-- | athena/home/home_card_unittest.cc | 35 |
10 files changed, 111 insertions, 980 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp index 25dafb0..2b334e7 100644 --- a/athena/athena.gyp +++ b/athena/athena.gyp @@ -55,8 +55,6 @@ 'env/public/athena_env.h', 'home/app_list_view_delegate.cc', 'home/app_list_view_delegate.h', - 'home/athena_start_page_view.cc', - 'home/athena_start_page_view.h', 'home/home_card_constants.cc', 'home/home_card_constants.h', 'home/home_card_gesture_manager.cc', @@ -297,7 +295,6 @@ 'activity/activity_manager_unittest.cc', 'content/app_activity_unittest.cc', 'env/athena_env_unittest.cc', - 'home/athena_start_page_view_unittest.cc', 'home/home_card_gesture_manager_unittest.cc', 'home/home_card_unittest.cc', 'input/accelerator_manager_unittest.cc', diff --git a/athena/home/app_list_view_delegate.cc b/athena/home/app_list_view_delegate.cc index eead245..06d0bdc8 100644 --- a/athena/home/app_list_view_delegate.cc +++ b/athena/home/app_list_view_delegate.cc @@ -22,10 +22,6 @@ #include "ui/app_list/search_result.h" #include "ui/app_list/speech_ui_model.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/resources/grit/ui_resources.h" -#include "ui/views/controls/image_view.h" namespace athena { @@ -144,14 +140,7 @@ void AppListViewDelegate::ShowForProfileByPath( views::View* AppListViewDelegate::CreateStartPageWebView( const gfx::Size& size) { - // A static image of the logo. This needs to support dynamic Doodles - // eventually. - views::ImageView* logo_image = new views::ImageView(); - logo_image->SetImage(ui::ResourceBundle::GetSharedInstance(). - GetImageSkiaNamed(IDR_LOCAL_NTP_IMAGES_LOGO_PNG)); - logo_image->SetHorizontalAlignment(views::ImageView::CENTER); - logo_image->SetVerticalAlignment(views::ImageView::CENTER); - return logo_image; + return NULL; } std::vector<views::View*> AppListViewDelegate::CreateCustomPageWebViews( diff --git a/athena/home/athena_start_page_view.cc b/athena/home/athena_start_page_view.cc deleted file mode 100644 index bb78ec2..0000000 --- a/athena/home/athena_start_page_view.cc +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2014 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 "athena/home/athena_start_page_view.h" - -#include "athena/home/home_card_constants.h" -#include "athena/system/public/system_ui.h" -#include "base/bind.h" -#include "base/strings/string_util.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkPath.h" -#include "ui/app_list/app_list_item.h" -#include "ui/app_list/app_list_item_list.h" -#include "ui/app_list/app_list_model.h" -#include "ui/app_list/app_list_view_delegate.h" -#include "ui/app_list/search_box_model.h" -#include "ui/app_list/views/search_box_view.h" -#include "ui/app_list/views/search_result_list_view.h" -#include "ui/compositor/closure_animation_observer.h" -#include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/gfx/canvas.h" -#include "ui/views/background.h" -#include "ui/views/border.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/round_rect_painter.h" - -namespace { - -const size_t kMaxIconNum = 3; -const int kIconSize = 50; -const int kIconMargin = 25; - -const int kTopMargin = 100; - -// Copied from ui/app_list/views/start_page_view.cc -const int kInstantContainerSpacing = 20; -const int kWebViewWidth = 500; -const int kWebViewHeight = 105; -const int kSearchBoxBorderWidth = 1; -const int kSearchBoxCornerRadius = 2; - -// Taken from the mock. The width is not specified by pixel but the search box -// covers 6 icons with margin. -const int kSearchBoxWidth = kIconSize * 6 + kIconMargin * 7; -const int kSearchBoxHeight = 40; - -gfx::Size GetIconContainerSize() { - return gfx::Size(kIconSize * kMaxIconNum + kIconMargin * (kMaxIconNum - 1), - kIconSize); -} - -class PlaceHolderButton : public views::ImageButton, - public views::ButtonListener { - public: - PlaceHolderButton() - : ImageButton(this) { - gfx::Canvas canvas(gfx::Size(kIconSize, kIconSize), 1.0f, true); - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(SkColorSetRGB(86, 119, 252)); - paint.setFlags(SkPaint::kAntiAlias_Flag); - canvas.DrawCircle( - gfx::Point(kIconSize / 2, kIconSize / 2), kIconSize / 2, paint); - - scoped_ptr<gfx::ImageSkia> image( - new gfx::ImageSkia(canvas.ExtractImageRep())); - SetImage(STATE_NORMAL, image.get()); - } - - private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override { - // Do nothing: remove these place holders. - } - - DISALLOW_COPY_AND_ASSIGN(PlaceHolderButton); -}; - -class AppIconButton : public views::ImageButton, - public views::ButtonListener { - public: - explicit AppIconButton(app_list::AppListItem* item) - : ImageButton(this), item_(nullptr) { - SetItem(item); - } - - void SetItem(app_list::AppListItem* item) { - item_ = item; - // TODO(mukai): icon should be resized. - SetImage(STATE_NORMAL, &item->icon()); - } - - private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override { - DCHECK_EQ(sender, this); - item_->Activate(event.flags()); - } - - app_list::AppListItem* item_; - - DISALLOW_COPY_AND_ASSIGN(AppIconButton); -}; - -// The background to paint the round rectangle of the view area. -class RoundRectBackground : public views::Background { - public: - RoundRectBackground(SkColor color, int corner_radius) - : color_(color), - corner_radius_(corner_radius) {} - ~RoundRectBackground() override {} - - private: - // views::Background: - void Paint(gfx::Canvas* canvas, views::View* view) const override { - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(color_); - canvas->DrawRoundRect(view->GetContentsBounds(), corner_radius_, paint); - } - - SkColor color_; - int corner_radius_; - - DISALLOW_COPY_AND_ASSIGN(RoundRectBackground); -}; - -class SearchBoxContainer : public views::View { - public: - explicit SearchBoxContainer(app_list::SearchBoxView* search_box) - : search_box_(search_box) { - search_box->set_background( - new RoundRectBackground(SK_ColorWHITE, kSearchBoxCornerRadius)); - search_box->SetBorder(views::Border::CreateBorderPainter( - new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius), - gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth, - kSearchBoxBorderWidth, kSearchBoxBorderWidth))); - SetLayoutManager(new views::FillLayout()); - AddChildView(search_box_); - } - ~SearchBoxContainer() override {} - - private: - // views::View: - gfx::Size GetPreferredSize() const override { - return gfx::Size(kSearchBoxWidth, kSearchBoxHeight); - } - - // Owned by the views hierarchy. - app_list::SearchBoxView* search_box_; - - DISALLOW_COPY_AND_ASSIGN(SearchBoxContainer); -}; - -} // namespace - -namespace athena { - -// static -const char AthenaStartPageView::kViewClassName[] = "AthenaStartPageView"; - -AthenaStartPageView::LayoutData::LayoutData() - : system_info_opacity(1.0f), logo_opacity(1.0f) { -} - -AthenaStartPageView::AthenaStartPageView( - app_list::AppListViewDelegate* view_delegate) - : delegate_(view_delegate), - layout_state_(0.0f), - weak_factory_(this) { - system_info_view_ = - SystemUI::Get()->CreateSystemInfoView(SystemUI::COLOR_SCHEME_DARK); - system_info_view_->SetPaintToLayer(true); - system_info_view_->SetFillsBoundsOpaquely(false); - AddChildView(system_info_view_); - - logo_ = view_delegate->CreateStartPageWebView( - gfx::Size(kWebViewWidth, kWebViewHeight)); - logo_->SetPaintToLayer(true); - logo_->SetFillsBoundsOpaquely(false); - logo_->SetSize(gfx::Size(kWebViewWidth, kWebViewHeight)); - AddChildView(logo_); - - search_results_view_ = - new app_list::SearchResultListView(nullptr, view_delegate); - // search_results_view_'s size will shrink after settings results. - search_results_height_ = static_cast<views::View*>( - search_results_view_)->GetHeightForWidth(kSearchBoxWidth); - search_results_view_->SetResults(view_delegate->GetModel()->results()); - - search_results_view_->SetVisible(false); - search_results_view_->SetPaintToLayer(true); - search_results_view_->SetFillsBoundsOpaquely(false); - AddChildView(search_results_view_); - - app_icon_container_ = new views::View(); - AddChildView(app_icon_container_); - app_icon_container_->SetPaintToLayer(true); - app_icon_container_->layer()->SetFillsBoundsOpaquely(false); - app_icon_container_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); - app_icon_container_->SetSize(GetIconContainerSize()); - UpdateAppIcons(); - view_delegate->GetModel()->top_level_item_list()->AddObserver(this); - - control_icon_container_ = new views::View(); - control_icon_container_->SetPaintToLayer(true); - control_icon_container_->SetFillsBoundsOpaquely(false); - AddChildView(control_icon_container_); - control_icon_container_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); - for (size_t i = 0; i < kMaxIconNum; ++i) - control_icon_container_->AddChildView(new PlaceHolderButton()); - control_icon_container_->SetSize(GetIconContainerSize()); - - search_box_view_ = new app_list::SearchBoxView(this, view_delegate); - search_box_view_->set_contents_view(this); - search_box_view_->search_box()->set_id(kHomeCardSearchBoxId); - 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() { - delegate_->GetModel()->top_level_item_list()->RemoveObserver(this); -} - -void AthenaStartPageView::RequestFocusOnSearchBox() { - search_box_view_->search_box()->RequestFocus(); -} - -void AthenaStartPageView::SetLayoutState(float layout_state) { - layout_state_ = layout_state; - Layout(); - FOR_EACH_OBSERVER(Observer, observers_, OnLayoutStateChanged(layout_state)); -} - -void AthenaStartPageView::SetLayoutStateWithAnimation( - float layout_state, - gfx::Tween::Type tween_type) { - ui::ScopedLayerAnimationSettings system_info( - system_info_view_->layer()->GetAnimator()); - 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()); - - system_info.SetTweenType(tween_type); - logo.SetTweenType(tween_type); - search_box.SetTweenType(tween_type); - icons.SetTweenType(tween_type); - controls.SetTweenType(tween_type); - - SetLayoutState(layout_state); -} - -void AthenaStartPageView::AddObserver(AthenaStartPageView::Observer* observer) { - observers_.AddObserver(observer); -} - -void AthenaStartPageView::RemoveObserver( - AthenaStartPageView::Observer* observer) { - observers_.RemoveObserver(observer); -} - -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); - - int search_box_max_width = - state.controls.x() - state.icons.right() - kIconMargin * 2; - state.search_box.set_width(std::min(search_box_max_width, kSearchBoxWidth)); - state.search_box.set_height(search_box_container_->height()); - state.search_box.set_x((width - state.search_box.width()) / 2); - state.search_box.set_y((kHomeCardHeight - state.search_box.height()) / 2); - - state.system_info_opacity = 0.0f; - state.logo_opacity = 0.0f; - return state; -} - -AthenaStartPageView::LayoutData AthenaStartPageView::CreateCenteredBounds( - int width) { - LayoutData state; - - state.search_box.set_size(search_box_container_->GetPreferredSize()); - 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.system_info_opacity = 1.0f; - state.logo_opacity = 1.0f; - return state; -} - -void AthenaStartPageView::UpdateAppIcons() { - app_list::AppListItemList* top_level = - delegate_->GetModel()->top_level_item_list(); - size_t max_items = std::min(top_level->item_count(), kMaxIconNum); - for (size_t i = 0; i < max_items; ++i) { - if (i < static_cast<size_t>(app_icon_container_->child_count())) { - AppIconButton* button = - static_cast<AppIconButton*>(app_icon_container_->child_at(i)); - button->SetItem(top_level->item_at(i)); - } else { - app_icon_container_->AddChildView( - new AppIconButton(top_level->item_at(i))); - } - } - - while (max_items < static_cast<size_t>(app_icon_container_->child_count())) { - scoped_ptr<views::View> remover( - app_icon_container_->child_at(app_icon_container_->child_count() - 1)); - app_icon_container_->RemoveChildView(remover.get()); - } -} - -void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) { - if (should_show_search_results == - search_results_view_->layer()->GetTargetVisibility()) { - return; - } - if (should_show_search_results && layout_state_ != 1.0f) - SetLayoutState(1.0f); - - gfx::Rect search_box_bounds = search_box_container_->bounds(); - if (!search_results_view_->visible()) { - search_results_view_->SetVisible(true); - search_results_view_->SetBounds( - search_box_bounds.x(), search_box_bounds.bottom(), - search_box_bounds.width(), 0); - } - logo_->SetVisible(true); - - { - ui::ScopedLayerAnimationSettings logo_settings( - logo_->layer()->GetAnimator()); - logo_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - logo_settings.AddObserver(new ui::ClosureAnimationObserver( - base::Bind(&AthenaStartPageView::OnSearchResultLayoutAnimationCompleted, - weak_factory_.GetWeakPtr(), - should_show_search_results))); - - ui::ScopedLayerAnimationSettings search_box_settings( - search_box_container_->layer()->GetAnimator()); - search_box_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - - ui::ScopedLayerAnimationSettings search_results_settings( - search_results_view_->layer()->GetAnimator()); - search_results_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - - if (should_show_search_results) { - logo_->layer()->SetOpacity(0.0f); - search_box_bounds.set_y( - search_box_bounds.y() - search_results_height_ - - kInstantContainerSpacing); - search_box_container_->SetBoundsRect(search_box_bounds); - search_results_view_->SetBounds( - search_box_bounds.x(), - search_box_bounds.bottom() + kInstantContainerSpacing, - search_box_bounds.width(), - search_results_height_); - } else { - logo_->layer()->SetOpacity(1.0f); - search_box_bounds.set_y( - logo_->bounds().bottom() + kInstantContainerSpacing); - search_box_container_->SetBoundsRect(search_box_bounds); - - gfx::Rect search_results_bounds = search_results_view_->bounds(); - search_results_bounds.set_y(search_results_bounds.bottom()); - search_results_bounds.set_height(0); - search_results_view_->SetBoundsRect(search_results_bounds); - } - } -} - -void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted( - bool should_show_search_results) { - logo_->SetVisible(!should_show_search_results); - search_results_view_->SetVisible(should_show_search_results); -} - -void AthenaStartPageView::Layout() { - search_results_view_->SetVisible(false); - - system_info_view_->SetBounds( - 0, 0, width(), system_info_view_->GetPreferredSize().height()); - - gfx::Rect logo_bounds(x() + width() / 2 - kWebViewWidth / 2, y() + kTopMargin, - kWebViewWidth, kWebViewHeight); - logo_->SetBoundsRect(logo_bounds); - - LayoutData bottom_bounds = CreateBottomBounds(width()); - LayoutData centered_bounds = CreateCenteredBounds(width()); - - system_info_view_->layer()->SetOpacity(gfx::Tween::FloatValueBetween( - gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_), - bottom_bounds.system_info_opacity, centered_bounds.system_info_opacity)); - system_info_view_->SetVisible( - system_info_view_->layer()->GetTargetOpacity() != 0.0f); - - logo_->layer()->SetOpacity(gfx::Tween::FloatValueBetween( - gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_), - bottom_bounds.logo_opacity, centered_bounds.logo_opacity)); - logo_->SetVisible(logo_->layer()->GetTargetOpacity() != 0.0f); - - app_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.icons, centered_bounds.icons)); - control_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.controls, centered_bounds.controls)); - search_box_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.search_box, centered_bounds.search_box)); -} - -bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) { - return search_results_view_->visible() && - search_results_view_->OnKeyPressed(key_event); -} - -void AthenaStartPageView::QueryChanged(app_list::SearchBoxView* sender) { - delegate_->StartSearch(); - - base::string16 query; - base::TrimWhitespace( - delegate_->GetModel()->search_box()->text(), base::TRIM_ALL, &query); - - if (!query.empty()) - search_results_view_->SetSelectedIndex(0); - - LayoutSearchResults(!query.empty()); -} - -void AthenaStartPageView::OnListItemAdded(size_t index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -void AthenaStartPageView::OnListItemRemoved(size_t index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -void AthenaStartPageView::OnListItemMoved(size_t from_index, - size_t to_index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -// static -size_t AthenaStartPageView::GetMaxIconNumForTest() { - return kMaxIconNum; -} - -} // namespace athena diff --git a/athena/home/athena_start_page_view.h b/athena/home/athena_start_page_view.h deleted file mode 100644 index fd15dca..0000000 --- a/athena/home/athena_start_page_view.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2014 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 ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ -#define ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ - -#include "athena/athena_export.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "ui/app_list/app_list_item_list_observer.h" -#include "ui/app_list/views/search_box_view_delegate.h" -#include "ui/gfx/animation/tween.h" -#include "ui/views/view.h" - -namespace app_list { -class AppListModelObserver; -class AppListViewDelegate; -class SearchBoxView; -class SearchResultListView; -} - -namespace athena { - -class ATHENA_EXPORT AthenaStartPageView - : public views::View, - public app_list::SearchBoxViewDelegate, - public app_list::AppListItemListObserver { - public: - class Observer { - public: - virtual void OnLayoutStateChanged(float new_state) = 0; - }; - - explicit AthenaStartPageView(app_list::AppListViewDelegate* delegate); - ~AthenaStartPageView() override; - - // Requests the focus on the search box in the start page view. - 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, - gfx::Tween::Type tween_type); - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - private: - friend class AthenaStartPageViewTest; - - static const char kViewClassName[]; - - static size_t GetMaxIconNumForTest(); - - // A struct which bundles the layout data of subviews. - struct LayoutData { - gfx::Rect search_box; - gfx::Rect icons; - gfx::Rect controls; - float system_info_opacity; - float logo_opacity; - - LayoutData(); - }; - - // Returns the bounds for |VISIBLE_BOTTOM|. - LayoutData CreateBottomBounds(int width); - - // Returns the bounds for |VISIBLE_CENTERED|. - LayoutData CreateCenteredBounds(int width); - - void UpdateAppIcons(); - - // Schedules the animation for the layout the search box and the search - // results. - void LayoutSearchResults(bool should_show_search_results); - - // Called when the animation of search box / search results layout has - // completed. - void OnSearchResultLayoutAnimationCompleted(bool should_show_search_results); - - // views::View: - void Layout() override; - bool OnKeyPressed(const ui::KeyEvent& key_event) override; - - // app_list::SearchBoxViewDelegate: - void QueryChanged(app_list::SearchBoxView* sender) override; - - // app_list::AppListItemListObserver: - void OnListItemAdded(size_t index, app_list::AppListItem* item) override; - void OnListItemRemoved(size_t index, app_list::AppListItem* item) override; - void OnListItemMoved(size_t from_index, - size_t to_index, - app_list::AppListItem* item) override; - - // Not owned. - app_list::AppListViewDelegate* delegate_; - - // Views are owned through its hierarchy. - views::View* system_info_view_; - views::View* app_icon_container_; - views::View* search_box_container_; - views::View* control_icon_container_; - views::View* logo_; - app_list::SearchBoxView* search_box_view_; - app_list::SearchResultListView* search_results_view_; - - // The expected height of |search_results_view_| - 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_; - - ObserverList<Observer> observers_; - - base::WeakPtrFactory<AthenaStartPageView> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AthenaStartPageView); -}; - -} // namespace athena - -#endif // ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ diff --git a/athena/home/athena_start_page_view_unittest.cc b/athena/home/athena_start_page_view_unittest.cc deleted file mode 100644 index 9019999..0000000 --- a/athena/home/athena_start_page_view_unittest.cc +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2014 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 "athena/home/athena_start_page_view.h" - -#include "athena/home/home_card_constants.h" -#include "athena/test/base/athena_test_base.h" -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/app_list/app_list_switches.h" -#include "ui/app_list/search_box_model.h" -#include "ui/app_list/test/app_list_test_model.h" -#include "ui/app_list/test/app_list_test_view_delegate.h" -#include "ui/app_list/views/search_box_view.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/controls/textfield/textfield.h" - -namespace athena { - -class AthenaTestViewDelegate : public app_list::test::AppListTestViewDelegate { - public: - AthenaTestViewDelegate() {} - ~AthenaTestViewDelegate() override {} - - private: - // app_list::AppListViewDelegate: - views::View* CreateStartPageWebView(const gfx::Size& size) override { - return new views::View(); - } - - DISALLOW_COPY_AND_ASSIGN(AthenaTestViewDelegate); -}; - -class AthenaStartPageViewTest : public test::AthenaTestBase { - public: - AthenaStartPageViewTest() {} - ~AthenaStartPageViewTest() override {} - - // testing::Test: - void SetUp() override { - test::AthenaTestBase::SetUp(); - for (size_t i = 0; i < GetMaxIconNum(); ++i) - AddTestItem(i); - - view_.reset(new AthenaStartPageView(&view_delegate_)); - SetSize(gfx::Size(1280, 800)); - } - void TearDown() override { - view_.reset(); - test::AthenaTestBase::TearDown(); - } - - protected: - void SetSize(const gfx::Size& new_size) { - view_->SetSize(new_size); - view_->Layout(); - } - - void AddTestItem(size_t index) { - app_list::test::AppListTestModel* model = view_delegate_.GetTestModel(); - model->AddItem(new app_list::test::AppListTestModel::AppListTestItem( - GetAppIdFor(index), model)); - } - - static size_t GetMaxIconNum() { - return AthenaStartPageView::GetMaxIconNumForTest(); - } - - static std::string GetAppIdFor(size_t index) { - return base::StringPrintf("id-%" PRIuS, index); - } - - app_list::AppListModel* GetModel() { return view_delegate_.GetTestModel(); } - - views::View* GetIconsContainer() { return view_->app_icon_container_; } - - gfx::Rect GetIconsBounds() const { - return view_->app_icon_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetControlBounds() const { - return view_->control_icon_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetSearchBoxBounds() const { - return view_->search_box_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetLogoBounds() const { - return view_->logo_->layer()->GetTargetBounds(); - } - - bool IsLogoVisible() const { - return view_->logo_->layer()->GetTargetOpacity() > 0 && - view_->logo_->layer()->GetTargetVisibility(); - } - - gfx::Size GetSearchBoxPreferredSize() { - return view_->search_box_container_->GetPreferredSize(); - } - - void SetSearchQuery(const base::string16& query) { - view_delegate_.GetModel()->search_box()->SetText(query); - } - - base::string16 GetVisibleQuery() { - return view_->search_box_view_->search_box()->text(); - } - - float layout_state() { return view_->layout_state_; } - - scoped_ptr<AthenaStartPageView> view_; - - private: - AthenaTestViewDelegate view_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AthenaStartPageViewTest); -}; - -TEST_F(AthenaStartPageViewTest, BasicLayout) { - // BOTTOM state. logo is invisible. icons, search box, and controls are - // arranged horizontally. - EXPECT_FALSE(IsLogoVisible()); - - // Three components are aligned at the middle point. - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetControlBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetControlBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - - // Horizonttaly aligned in the order of icons, search_box, and controls. - EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); - EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); - EXPECT_LE(0, GetIconsBounds().y()); - - // Search box should appear in the middle. - EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), - view_->bounds().CenterPoint().x(), - 1); - - // Should fit inside of the home card height. - EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); - EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); - EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); - - // CENTERED state. logo is visible. search box appears below the logo, - // icons and controls are arranged horizontally and below the search box. - view_->SetLayoutState(1.0f); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_NEAR(GetLogoBounds().x() + GetLogoBounds().width() / 2, - GetSearchBoxBounds().x() + GetSearchBoxBounds().width() / 2, - 1); - EXPECT_LE(GetLogoBounds().bottom(), GetSearchBoxBounds().y()); - EXPECT_EQ(GetIconsBounds().y(), GetControlBounds().y()); - EXPECT_LE(GetIconsBounds().right(), GetControlBounds().x()); - EXPECT_LE(GetSearchBoxBounds().bottom(), GetIconsBounds().y()); -} - -TEST_F(AthenaStartPageViewTest, NarrowLayout) { - SetSize(gfx::Size(800, 1280)); - - // BOTTOM state. Similar to BasicLayout. - EXPECT_FALSE(IsLogoVisible()); - // Three components are aligned at the middle point. - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetControlBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetControlBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - - // Horizonttaly aligned in the order of icons, search_box, and controls. - EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); - EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); - EXPECT_LE(0, GetIconsBounds().y()); - - // Search box should appear in the middle. - EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), - view_->bounds().CenterPoint().x(), - 1); - - // Should fit inside of the home card height. - EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); - EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); - EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); - - // Search box is narrower because of the size is too narrow. - EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); - EXPECT_EQ(GetSearchBoxPreferredSize().height(), - GetSearchBoxBounds().height()); - - // CENTERED state. Search box should be back to the preferred size. - view_->SetLayoutState(1.0f); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); - - // Back to BOTTOM state, the search box shrinks again. - view_->SetLayoutState(0.0f); - EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); - - // Then set back to the original size, now the size is wide enough so the - // search box bounds becomes as preferred. - SetSize(gfx::Size(1280, 800)); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); -} - -TEST_F(AthenaStartPageViewTest, SearchBox) { - view_->SetLayoutState(1.0f); - EXPECT_TRUE(IsLogoVisible()); - - const gfx::Rect base_search_box_bounds = GetSearchBoxBounds(); - - const base::string16 query = base::UTF8ToUTF16("test"); - SetSearchQuery(query); - - EXPECT_FALSE(IsLogoVisible()); - EXPECT_GT(base_search_box_bounds.y(), GetSearchBoxBounds().y()); - EXPECT_EQ(query, GetVisibleQuery()); - - SetSearchQuery(base::string16()); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_EQ(base_search_box_bounds.ToString(), GetSearchBoxBounds().ToString()); - EXPECT_TRUE(GetVisibleQuery().empty()); -} - -TEST_F(AthenaStartPageViewTest, SearchFromBottom) { - view_->SetLayoutState(0.0f); - - const base::string16 query = base::UTF8ToUTF16("test"); - SetSearchQuery(query); - - EXPECT_FALSE(IsLogoVisible()); - EXPECT_EQ(query, GetVisibleQuery()); - EXPECT_EQ(1.0f, layout_state()); - - SetSearchQuery(base::string16()); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_TRUE(GetVisibleQuery().empty()); - EXPECT_EQ(1.0f, layout_state()); -} - -TEST_F(AthenaStartPageViewTest, AppAddRemove) { - gfx::Rect icons_bounds = GetIconsBounds(); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - - GetModel()->DeleteItem(GetAppIdFor(1)); - - // The removed icon disappear, however its bound should not change. - EXPECT_EQ(GetMaxIconNum() - 1, - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); - - AddTestItem(GetMaxIconNum() + 1); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); - - // Adding more doesn't cause any effects. - AddTestItem(GetMaxIconNum() + 2); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); -} - -} // namespace athena diff --git a/athena/home/home_card_constants.cc b/athena/home/home_card_constants.cc index 1bf2875..2a951c6 100644 --- a/athena/home/home_card_constants.cc +++ b/athena/home/home_card_constants.cc @@ -6,7 +6,7 @@ namespace athena { -const int kHomeCardHeight = 100; +const int kHomeCardHeight = 212; const int kHomeCardDragIndicatorHeight = 2; const int kHomeCardDragIndicatorWidth = 48; const int kHomeCardDragIndicatorMarginHeight = 7; diff --git a/athena/home/home_card_gesture_manager_unittest.cc b/athena/home/home_card_gesture_manager_unittest.cc index c5c40fc..91d7030 100644 --- a/athena/home/home_card_gesture_manager_unittest.cc +++ b/athena/home/home_card_gesture_manager_unittest.cc @@ -186,8 +186,8 @@ TEST_F(HomeCardGestureManagerTest, StartCentered) { EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_); EXPECT_EQ(1.0f, last_progress_); - ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 900); - ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 910); + ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 700); + ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 710); EXPECT_EQ(2, GetProgressCountAndReset()); EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_); EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_); @@ -218,13 +218,13 @@ TEST_F(HomeCardGestureManagerTest, StartBottom) { EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_); // State change for the bigger moves. - EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950)); + EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 850)); ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1000); EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 1000)); EXPECT_EQ(1, GetEndCountAndReset()); EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, final_state_); - EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950)); + EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 850)); ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 300); EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 300)); EXPECT_EQ(1, GetEndCountAndReset()); diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc index f6a64f3..c0603d2 100644 --- a/athena/home/home_card_impl.cc +++ b/athena/home/home_card_impl.cc @@ -9,14 +9,14 @@ #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/public/app_model_builder.h" #include "athena/screen/public/screen_manager.h" #include "athena/util/container_priorities.h" #include "athena/wm/public/window_manager.h" +#include "ui/app_list/search_box_model.h" #include "ui/app_list/views/app_list_main_view.h" -#include "ui/app_list/views/contents_view.h" +#include "ui/app_list/views/search_box_view.h" #include "ui/aura/layout_manager.h" #include "ui/aura/window.h" #include "ui/compositor/closure_animation_observer.h" @@ -36,6 +36,8 @@ namespace { HomeCard* instance = nullptr; const float kMinimizedHomeOpacity = 0.65f; +const int kIndicatorOffset = 24; +const int kAppListOffset = -128; gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds, HomeCard::State state) { @@ -122,14 +124,15 @@ class HomeCardLayoutManager : public aura::LayoutManager { }; // The container view of home card contents of each state. -class HomeCardView : public views::WidgetDelegateView, - public AthenaStartPageView::Observer { +class HomeCardView : public views::WidgetDelegateView { public: HomeCardView(app_list::AppListViewDelegate* view_delegate, aura::Window* container, HomeCardGestureManager::Delegate* gesture_delegate) : background_(new views::View), - main_view_(new AthenaStartPageView(view_delegate)), + main_view_(new app_list::AppListMainView(view_delegate)), + search_box_view_( + new app_list::SearchBoxView(main_view_, view_delegate)), minimized_background_(new views::View()), drag_indicator_(new views::View()), gesture_delegate_(gesture_delegate), @@ -141,13 +144,16 @@ class HomeCardView : public views::WidgetDelegateView, background_->SetFillsBoundsOpaquely(false); AddChildView(background_); - // 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_->AddObserver(this); + main_view_->SetPaintToLayer(true); + main_view_->SetFillsBoundsOpaquely(false); + main_view_->layer()->SetMasksToBounds(true); AddChildView(main_view_); + search_box_view_->SetPaintToLayer(true); + search_box_view_->SetFillsBoundsOpaquely(false); + search_box_view_->layer()->SetMasksToBounds(true); + AddChildView(search_box_view_); + minimized_background_->set_background( views::Background::CreateSolidBackground( SkColorSetA(SK_ColorBLACK, 256 * kMinimizedHomeOpacity))); @@ -162,17 +168,28 @@ class HomeCardView : public views::WidgetDelegateView, AddChildView(drag_indicator_); } - ~HomeCardView() override { main_view_->RemoveObserver(this); } + void Init() { + main_view_->Init(GetWidget()->GetNativeView(), -1, search_box_view_); + } void SetStateProgress(HomeCard::State from_state, HomeCard::State to_state, float progress) { // 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); + + gfx::Rect from_main_bounds = GetMainViewBounds(from_state); + gfx::Rect to_main_bounds = GetMainViewBounds(to_state); + if (from_main_bounds != to_main_bounds) { + DCHECK_EQ(from_main_bounds.size().ToString(), + to_main_bounds.size().ToString()); + gfx::Rect main_bounds = gfx::Tween::RectValueBetween( + progress, from_main_bounds, to_main_bounds); + main_view_->SetBoundsRect(main_bounds); + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } float background_opacity = 1.0f; if (from_state == HomeCard::VISIBLE_MINIMIZED || @@ -207,7 +224,8 @@ class HomeCardView : public views::WidgetDelegateView, } void SetStateWithAnimation(HomeCard::State state, - gfx::Tween::Type tween_type) { + gfx::Tween::Type tween_type, + const base::Closure& on_animation_ended) { float minimized_opacity = (state == HomeCard::VISIBLE_MINIMIZED) ? 1.0f : 0.0f; // |minimized_background_| needs to be visible before scheduling animation. @@ -241,20 +259,27 @@ class HomeCardView : public views::WidgetDelegateView, background_->layer()->SetOpacity(background_opacity); } - if (state == HomeCard::VISIBLE_CENTERED) - main_view_->RequestFocusOnSearchBox(); - else - GetWidget()->GetFocusManager()->ClearFocus(); - { ui::ScopedLayerAnimationSettings settings( drag_indicator_->layer()->GetAnimator()); - settings.SetTweenType(gfx::Tween::EASE_IN_OUT); + settings.SetTweenType(tween_type); drag_indicator_->SetBoundsRect(GetDragIndicatorBounds(state)); } - main_view_->SetLayoutStateWithAnimation( - (state == HomeCard::VISIBLE_CENTERED) ? 1.0f : 0.0f, tween_type); + { + ui::ScopedLayerAnimationSettings settings( + main_view_->layer()->GetAnimator()); + settings.SetTweenType(tween_type); + settings.AddObserver( + new ui::ClosureAnimationObserver(on_animation_ended)); + gfx::Rect main_bounds = GetMainViewBounds(state); + main_view_->SetBoundsRect(main_bounds); + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } + + main_view_->UpdateSearchBoxVisibility(); } void ClearGesture() { @@ -282,6 +307,23 @@ class HomeCardView : public views::WidgetDelegateView, return false; } + void Layout() override { + const gfx::Rect contents_bounds = GetContentsBounds(); + background_->SetBoundsRect(contents_bounds); + minimized_background_->SetBoundsRect(contents_bounds); + const gfx::Rect drag_indicator_bounds = + GetDragIndicatorBounds(HomeCard::Get()->GetState()); + drag_indicator_->SetBoundsRect(drag_indicator_bounds); + + gfx::Rect main_bounds(GetMainViewBounds(HomeCard::Get()->GetState())); + main_view_->SetBoundsRect(main_bounds); + + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } + + private: gfx::Rect GetDragIndicatorBounds(HomeCard::State state) { gfx::Rect drag_indicator_bounds( GetContentsBounds().CenterPoint().x() - kHomeCardDragIndicatorWidth / 2, @@ -293,13 +335,19 @@ class HomeCardView : public views::WidgetDelegateView, return drag_indicator_bounds; } - void Layout() override { - gfx::Rect contents_bounds = GetContentsBounds(); - background_->SetBoundsRect(contents_bounds); - main_view_->SetBoundsRect(contents_bounds); - minimized_background_->SetBoundsRect(contents_bounds); - drag_indicator_->SetBoundsRect( - GetDragIndicatorBounds(HomeCard::Get()->GetState())); + gfx::Rect GetMainViewBounds(HomeCard::State state) { + const gfx::Rect contents_bounds = GetContentsBounds(); + const int main_width = main_view_->GetPreferredSize().width(); + gfx::Rect main_bounds( + contents_bounds.CenterPoint().x() - main_width / 2, + GetDragIndicatorBounds(state).bottom() + kIndicatorOffset, + main_width, + contents_bounds.height()); + // This is a bit hacky but slightly shifting up the main_view to fit + // the search box and app icons in the home card. + if (state != HomeCard::VISIBLE_CENTERED) + main_bounds.set_y(kAppListOffset); + return main_bounds; } private: @@ -311,14 +359,9 @@ class HomeCardView : public views::WidgetDelegateView, // views::WidgetDelegate: views::View* GetContentsView() override { return this; } - // AthenaStartPageView::Observer: - void OnLayoutStateChanged(float new_state) override { - if (new_state == 1.0f) - HomeCard::Get()->SetState(HomeCard::VISIBLE_CENTERED); - } - views::View* background_; - AthenaStartPageView* main_view_; + app_list::AppListMainView* main_view_; + app_list::SearchBoxView* search_box_view_; views::View* minimized_background_; views::View* drag_indicator_; HomeCard::State state_; @@ -376,7 +419,9 @@ void HomeCardImpl::Init() { widget_params.delegate = home_card_view_; widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; home_card_widget_->Init(widget_params); + home_card_widget_->GetNativeWindow()->layer()->SetMasksToBounds(true); + home_card_view_->Init(); SetState(VISIBLE_MINIMIZED); home_card_view_->Layout(); @@ -388,6 +433,10 @@ aura::Window* HomeCardImpl::GetHomeCardWindowForTest() const { return home_card_widget_ ? home_card_widget_->GetNativeWindow() : nullptr; } +void HomeCardImpl::ResetQuery() { + view_delegate_->GetModel()->search_box()->SetText(base::string16()); +} + void HomeCardImpl::InstallAccelerators() { const AcceleratorData accelerator_data[] = { {TRIGGER_ON_PRESS, ui::VKEY_L, ui::EF_CONTROL_DOWN, @@ -413,7 +462,13 @@ void HomeCardImpl::SetState(HomeCard::State state) { home_card_widget_->ShowInactive(); else home_card_widget_->Show(); - home_card_view_->SetStateWithAnimation(state, gfx::Tween::EASE_IN_OUT); + + // Query should be reset on state change to reset the main_view. Also it's + // not possible to invoke ResetQuery() here, it causes a crash on search. + home_card_view_->SetStateWithAnimation( + state, + gfx::Tween::EASE_IN_OUT, + base::Bind(&HomeCardImpl::ResetQuery, base::Unretained(this))); layout_manager_->Layout(true, gfx::Tween::EASE_IN_OUT); } } @@ -469,7 +524,10 @@ void HomeCardImpl::OnGestureEnded(State final_state, bool is_fling) { // 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); + home_card_view_->SetStateWithAnimation( + state_, + tween_type, + base::Bind(&HomeCardImpl::ResetQuery, base::Unretained(this))); layout_manager_->Layout(true, tween_type); } } diff --git a/athena/home/home_card_impl.h b/athena/home/home_card_impl.h index f330b10..a35c31b5 100644 --- a/athena/home/home_card_impl.h +++ b/athena/home/home_card_impl.h @@ -12,6 +12,10 @@ #include "athena/input/public/accelerator_manager.h" #include "athena/wm/public/window_manager_observer.h" +namespace app_list { +class AppListViewDelegate; +} + namespace aura { class Window; } @@ -30,7 +34,6 @@ class Widget; namespace athena { class AppModelBuilder; -class AppListViewDelegate; class HomeCardLayoutManager; class HomeCardView; @@ -53,6 +56,8 @@ class ATHENA_EXPORT HomeCardImpl : public HomeCard, }; void InstallAccelerators(); + void ResetQuery(); + // Overridden from HomeCard: void SetState(HomeCard::State state) override; State GetState() override; @@ -86,7 +91,7 @@ class ATHENA_EXPORT HomeCardImpl : public HomeCard, views::Widget* home_card_widget_; HomeCardView* home_card_view_; - scoped_ptr<AppListViewDelegate> view_delegate_; + scoped_ptr<app_list::AppListViewDelegate> view_delegate_; HomeCardLayoutManager* layout_manager_; DISALLOW_COPY_AND_ASSIGN(HomeCardImpl); diff --git a/athena/home/home_card_unittest.cc b/athena/home/home_card_unittest.cc index abbdbdf..d8a630f 100644 --- a/athena/home/home_card_unittest.cc +++ b/athena/home/home_card_unittest.cc @@ -28,12 +28,6 @@ aura::Window* GetHomeCardWindow() { GetHomeCardWindowForTest(); } -// Returns true if the keyboard focus is on the search box. -bool IsSearchBoxFocused(aura::Window* home_card) { - return views::Widget::GetWidgetForNativeWindow(home_card)-> - GetContentsView()->GetViewByID(kHomeCardSearchBoxId)->HasFocus(); -} - typedef test::AthenaTestBase HomeCardTest; TEST_F(HomeCardTest, BasicTransition) { @@ -265,35 +259,6 @@ TEST_F(HomeCardTest, GesturesToFullDirectly) { EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive()); } -TEST_F(HomeCardTest, KeyboardFocus) { - ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState()); - aura::Window* home_card = GetHomeCardWindow(); - ASSERT_FALSE(IsSearchBoxFocused(home_card)); - - WindowManager::Get()->EnterOverview(); - ASSERT_FALSE(IsSearchBoxFocused(home_card)); - - ui::test::EventGenerator generator(root_window()); - gfx::Rect screen_rect(root_window()->bounds()); - - const int bottom = screen_rect.bottom(); - const int x = screen_rect.x() + 1; - - generator.GestureScrollSequence(gfx::Point(x, bottom - 40), - gfx::Point(x, 10), - base::TimeDelta::FromSeconds(1), - 10); - EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState()); - EXPECT_TRUE(IsSearchBoxFocused(home_card)); - - generator.GestureScrollSequence(gfx::Point(x, 10), - gfx::Point(x, bottom - 100), - base::TimeDelta::FromSeconds(1), - 10); - EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState()); - EXPECT_FALSE(IsSearchBoxFocused(home_card)); -} - TEST_F(HomeCardTest, DontMinimizeWithModalWindow) { aura::Window* home_card = GetHomeCardWindow(); |