Commit 298bf4d0 authored by calamity@chromium.org's avatar calamity@chromium.org

Add a DummySearchBoxView to the experimental app list start page.

This CL adds a DummySearchBoxView to the experimental app list which
forwards its input to the AppListMainView search box in a similar way
to the NTP's fakebox.

BUG=349727

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278588 0039d316-1c4b-4281-b951-d872f2087c98
parent eee45130
......@@ -33,6 +33,9 @@ const SkColor kResultURLTextColor = SkColorSetRGB(0x00, 0x99, 0x33);
const SkColor kGridTitleColor = SkColorSetRGB(0x5A, 0x5A, 0x5A);
const SkColor kGridTitleHoverColor = SkColorSetRGB(0x3C, 0x3C, 0x3C);
// Color of the borders used in the experimental app list start page.
const SkColor kStartPageBorderColor = SkColorSetRGB(0xEE, 0xEE, 0xEE);
// Color of the folder ink bubble.
const SkColor kFolderBubbleColor = SkColorSetRGB(0xD7, 0xD7, 0xD7);
......
......@@ -36,6 +36,8 @@ APP_LIST_EXPORT extern const SkColor kResultURLTextColor;
APP_LIST_EXPORT extern const SkColor kGridTitleColor;
APP_LIST_EXPORT extern const SkColor kGridTitleHoverColor;
APP_LIST_EXPORT extern const SkColor kStartPageBorderColor;
APP_LIST_EXPORT extern const SkColor kFolderBubbleColor;
APP_LIST_EXPORT extern const int kPageTransitionDurationInMs;
......
......@@ -174,15 +174,19 @@ void AppListMainView::ModelChanged() {
}
void AppListMainView::UpdateSearchBoxVisibility() {
search_box_view_->SetVisible(
bool visible =
!contents_view_->IsNamedPageActive(ContentsView::NAMED_PAGE_START) ||
contents_view_->IsShowingSearchResults());
contents_view_->IsShowingSearchResults();
search_box_view_->SetVisible(visible);
if (visible)
search_box_view_->search_box()->RequestFocus();
}
void AppListMainView::OnStartPageSearchButtonPressed() {
void AppListMainView::OnStartPageSearchTextfieldChanged(
const base::string16& new_contents) {
search_box_view_->SetVisible(true);
search_box_view_->search_box()->SetText(base::string16());
search_box_view_->RequestFocus();
search_box_view_->search_box()->SetText(new_contents);
search_box_view_->search_box()->RequestFocus();
}
void AppListMainView::SetDragAndDropHostOfCurrentAppList(
......
......@@ -56,7 +56,7 @@ class APP_LIST_EXPORT AppListMainView : public views::View,
void UpdateSearchBoxVisibility();
void OnStartPageSearchButtonPressed();
void OnStartPageSearchTextfieldChanged(const base::string16& new_contents);
SearchBoxView* search_box_view() const { return search_box_view_; }
......
......@@ -7,9 +7,11 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/pagination_model.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/app_list_folder_view.h"
......@@ -25,6 +27,7 @@
#include "ui/app_list/views/tile_item_view.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
......@@ -104,6 +107,10 @@ class AppListViewTestContext {
}
private:
// Switches the active launcher page in the contents view and lays out to
// ensure all launcher pages are in the correct position.
void ShowContentsViewPageAndVerify(int index);
// Shows the app list and waits until a paint occurs.
void Show();
......@@ -187,6 +194,15 @@ void AppListViewTestContext::CheckView(views::View* subview) {
EXPECT_TRUE(subview->IsDrawn());
}
void AppListViewTestContext::ShowContentsViewPageAndVerify(int index) {
ContentsView* contents_view = view_->app_list_main_view()->contents_view();
contents_view->SetActivePage(index);
contents_view->Layout();
for (int i = 0; i < contents_view->NumLauncherPages(); ++i) {
EXPECT_EQ(i == index, IsViewAtOrigin(contents_view->GetPageView(i)));
}
}
void AppListViewTestContext::Show() {
view_->GetWidget()->Show();
run_loop_.reset(new base::RunLoop);
......@@ -292,20 +308,14 @@ void AppListViewTestContext::RunStartPageTest() {
EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
ContentsView* contents_view = main_view->contents_view();
contents_view->SetActivePage(contents_view->GetPageIndexForNamedPage(
ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage(
ContentsView::NAMED_PAGE_START));
contents_view->Layout();
EXPECT_FALSE(main_view->search_box_view()->visible());
EXPECT_TRUE(IsViewAtOrigin(start_page_view));
EXPECT_FALSE(IsViewAtOrigin(contents_view->apps_container_view()));
EXPECT_EQ(3u, GetVisibleTileItemViews(start_page_view->tile_views()));
contents_view->SetActivePage(
ShowContentsViewPageAndVerify(
contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS));
contents_view->Layout();
EXPECT_TRUE(main_view->search_box_view()->visible());
EXPECT_FALSE(IsViewAtOrigin(start_page_view));
EXPECT_TRUE(IsViewAtOrigin(contents_view->apps_container_view()));
// Check tiles hide and show on deletion and addition.
model->CreateAndAddItem("Test app");
......@@ -422,7 +432,7 @@ void AppListViewTestContext::RunSearchResultsTest() {
AppListMainView* main_view = view_->app_list_main_view();
ContentsView* contents_view = main_view->contents_view();
contents_view->SetActivePage(
ShowContentsViewPageAndVerify(
contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS));
EXPECT_TRUE(IsViewAtOrigin(contents_view->apps_container_view()));
EXPECT_TRUE(main_view->search_box_view()->visible());
......@@ -459,6 +469,50 @@ void AppListViewTestContext::RunSearchResultsTest() {
EXPECT_TRUE(main_view->search_box_view()->visible());
}
if (test_type_ == EXPERIMENTAL) {
// Check that typing into the dummy search box triggers the search page.
base::string16 search_text = base::UTF8ToUTF16("test");
SearchBoxView* dummy_search_box =
contents_view->start_page_view()->dummy_search_box_view();
EXPECT_TRUE(dummy_search_box->IsDrawn());
dummy_search_box->search_box()->InsertText(search_text);
contents_view->Layout();
// Check that the current search is using |search_text|.
EXPECT_EQ(search_text, delegate_->GetTestModel()->search_box()->text());
EXPECT_TRUE(contents_view->IsShowingSearchResults());
EXPECT_FALSE(dummy_search_box->IsDrawn());
EXPECT_TRUE(main_view->search_box_view()->visible());
EXPECT_EQ(search_text, main_view->search_box_view()->search_box()->text());
EXPECT_TRUE(
contents_view->IsNamedPageActive(ContentsView::NAMED_PAGE_START));
EXPECT_TRUE(IsViewAtOrigin(contents_view->start_page_view()));
// Check that typing into the real search box triggers the search page.
ShowContentsViewPageAndVerify(
contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS));
EXPECT_TRUE(IsViewAtOrigin(contents_view->apps_container_view()));
base::string16 new_search_text = base::UTF8ToUTF16("apple");
main_view->search_box_view()->search_box()->SetText(base::string16());
main_view->search_box_view()->search_box()->InsertText(new_search_text);
// Check that the current search is using |search_text|.
EXPECT_EQ(new_search_text, delegate_->GetTestModel()->search_box()->text());
EXPECT_EQ(new_search_text,
main_view->search_box_view()->search_box()->text());
EXPECT_TRUE(contents_view->IsShowingSearchResults());
EXPECT_FALSE(dummy_search_box->IsDrawn());
EXPECT_TRUE(main_view->search_box_view()->visible());
EXPECT_TRUE(dummy_search_box->search_box()->text().empty());
// Check that the dummy search box is clear when reshowing the start page.
ShowContentsViewPageAndVerify(
contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS));
ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage(
ContentsView::NAMED_PAGE_START));
EXPECT_TRUE(dummy_search_box->IsDrawn());
EXPECT_TRUE(dummy_search_box->search_box()->text().empty());
}
Close();
}
......
......@@ -10,64 +10,83 @@
#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_view_delegate.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/search_result_list_view.h"
#include "ui/app_list/views/tile_item_view.h"
#include "ui/gfx/canvas.h"
#include "ui/views/controls/button/custom_button.h"
#include "ui/views/background.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/box_layout.h"
namespace app_list {
namespace {
// Layout constants.
const int kTopMargin = 30;
const int kInstantContainerSpacing = 20;
// WebView constants.
const int kWebViewWidth = 200;
const int kWebViewHeight = 105;
const int kInstantContainerSpacing = 20;
const int kBarPlaceholderWidth = 490;
const int kBarPlaceholderHeight = 30;
// DummySearchBoxView constants.
const int kDummySearchBoxWidth = 490;
const int kDummySearchBoxHeight = 40;
const int kDummySearchBoxBorderWidth = 1;
const int kDummySearchBoxBorderBottomWidth = 2;
const int kDummySearchBoxBorderCornerRadius = 2;
// Tile container constants.
const size_t kNumStartPageTiles = 5;
const int kTileSpacing = 10;
// A button that is the placeholder for the search bar in the start page view.
class BarPlaceholderButton : public views::CustomButton {
// A background that paints a solid white rounded rect with a thin grey border.
class DummySearchBoxBackground : public views::Background {
public:
explicit BarPlaceholderButton(views::ButtonListener* listener)
: views::CustomButton(listener) {}
DummySearchBoxBackground() {}
virtual ~DummySearchBoxBackground() {}
virtual ~BarPlaceholderButton() {}
private:
// views::Background overrides:
virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
gfx::Rect bounds = view->GetContentsBounds();
// Overridden from views::View:
virtual gfx::Size GetPreferredSize() const OVERRIDE {
return gfx::Size(kBarPlaceholderWidth, kBarPlaceholderHeight);
SkPaint paint;
paint.setFlags(SkPaint::kAntiAlias_Flag);
paint.setColor(kStartPageBorderColor);
canvas->DrawRoundRect(bounds, kDummySearchBoxBorderCornerRadius, paint);
bounds.Inset(kDummySearchBoxBorderWidth,
kDummySearchBoxBorderWidth,
kDummySearchBoxBorderWidth,
kDummySearchBoxBorderBottomWidth);
paint.setColor(SK_ColorWHITE);
canvas->DrawRoundRect(bounds, kDummySearchBoxBorderCornerRadius, paint);
}
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
PaintButton(
canvas,
state() == STATE_HOVERED ? kPagerHoverColor : kPagerNormalColor);
DISALLOW_COPY_AND_ASSIGN(DummySearchBoxBackground);
};
// A placeholder search box which is sized to fit within the start page view.
class DummySearchBoxView : public SearchBoxView {
public:
DummySearchBoxView(SearchBoxViewDelegate* delegate,
AppListViewDelegate* view_delegate)
: SearchBoxView(delegate, view_delegate) {
set_background(new DummySearchBoxBackground());
}
private:
// Paints a rectangular button.
void PaintButton(gfx::Canvas* canvas, SkColor base_color) {
gfx::Rect rect(GetContentsBounds());
rect.ClampToCenteredSize(
gfx::Size(kBarPlaceholderWidth, kBarPlaceholderHeight));
virtual ~DummySearchBoxView() {}
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kFill_Style);
paint.setColor(base_color);
canvas->DrawRect(rect, paint);
// Overridden from views::View:
virtual gfx::Size GetPreferredSize() const OVERRIDE {
return gfx::Size(kDummySearchBoxWidth, kDummySearchBoxHeight);
}
DISALLOW_COPY_AND_ASSIGN(BarPlaceholderButton);
private:
DISALLOW_COPY_AND_ASSIGN(DummySearchBoxView);
};
} // namespace
......@@ -77,13 +96,34 @@ StartPageView::StartPageView(AppListMainView* app_list_main_view,
: app_list_main_view_(app_list_main_view),
model_(NULL),
view_delegate_(view_delegate),
search_box_view_(new DummySearchBoxView(this, view_delegate_)),
results_view_(
new SearchResultListView(app_list_main_view, view_delegate)),
instant_container_(new views::View),
tiles_container_(new views::View),
show_state_(SHOW_START_PAGE) {
// The view containing the start page WebContents and the BarPlaceholder.
// The view containing the start page WebContents and DummySearchBoxView.
InitInstantContainer();
AddChildView(instant_container_);
// The view containing the search results.
AddChildView(results_view_);
// The view containing the start page tiles.
InitTilesContainer();
AddChildView(tiles_container_);
SetModel(view_delegate_->GetModel());
view_delegate_->AddObserver(this);
}
StartPageView::~StartPageView() {
view_delegate_->RemoveObserver(this);
if (model_)
model_->RemoveObserver(this);
}
void StartPageView::InitInstantContainer() {
views::BoxLayout* instant_layout_manager = new views::BoxLayout(
views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing);
instant_layout_manager->set_inside_border_insets(
......@@ -92,17 +132,25 @@ StartPageView::StartPageView(AppListMainView* app_list_main_view,
views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
instant_container_->SetLayoutManager(instant_layout_manager);
views::View* web_view = view_delegate->CreateStartPageWebView(
views::View* web_view = view_delegate_->CreateStartPageWebView(
gfx::Size(kWebViewWidth, kWebViewHeight));
if (web_view)
instant_container_->AddChildView(web_view);
instant_container_->AddChildView(new BarPlaceholderButton(this));
// The view containing the search results.
AddChildView(results_view_);
// TODO(calamity): This container is needed to horizontally center the search
// box view. Remove this container once BoxLayout supports CrossAxisAlignment.
views::View* search_box_container = new views::View();
views::BoxLayout* layout_manager =
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
layout_manager->set_main_axis_alignment(
views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
search_box_container->SetLayoutManager(layout_manager);
search_box_container->AddChildView(search_box_view_);
// The view containing the start page tiles.
AddChildView(tiles_container_);
instant_container_->AddChildView(search_box_container);
}
void StartPageView::InitTilesContainer() {
views::BoxLayout* tiles_layout_manager =
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, kTileSpacing);
tiles_layout_manager->set_main_axis_alignment(
......@@ -113,15 +161,6 @@ StartPageView::StartPageView(AppListMainView* app_list_main_view,
tiles_container_->AddChildView(tile_item);
tile_views_.push_back(tile_item);
}
SetModel(view_delegate_->GetModel());
view_delegate_->AddObserver(this);
}
StartPageView::~StartPageView() {
view_delegate_->RemoveObserver(this);
if (model_)
model_->RemoveObserver(this);
}
void StartPageView::SetModel(AppListModel* model) {
......@@ -155,6 +194,9 @@ void StartPageView::SetShowState(ShowState show_state) {
instant_container_->SetVisible(show_state == SHOW_START_PAGE);
results_view_->SetVisible(show_state == SHOW_SEARCH_RESULTS);
if (show_state == SHOW_START_PAGE)
search_box_view_->search_box()->RequestFocus();
if (show_state_ == show_state)
return;
......@@ -189,9 +231,12 @@ void StartPageView::Layout() {
tiles_container_->SetBoundsRect(bounds);
}
void StartPageView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
app_list_main_view_->OnStartPageSearchButtonPressed();
void StartPageView::QueryChanged(SearchBoxView* sender) {
// Forward the search terms on to the real search box and clear the dummy
// search box.
app_list_main_view_->OnStartPageSearchTextfieldChanged(
sender->search_box()->text());
sender->search_box()->SetText(base::string16());
}
void StartPageView::OnProfilesChanged() {
......
......@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "ui/app_list/app_list_model_observer.h"
#include "ui/app_list/app_list_view_delegate_observer.h"
#include "ui/views/controls/button/button.h"
#include "ui/app_list/views/search_box_view_delegate.h"
#include "ui/views/view.h"
namespace app_list {
......@@ -21,7 +21,7 @@ class TileItemView;
// The start page for the experimental app list.
class StartPageView : public views::View,
public views::ButtonListener,
public SearchBoxViewDelegate,
public AppListViewDelegateObserver,
public AppListModelObserver {
public:
......@@ -35,6 +35,7 @@ class StartPageView : public views::View,
bool IsShowingSearchResults() const;
const std::vector<TileItemView*>& tile_views() const { return tile_views_; }
SearchBoxView* dummy_search_box_view() { return search_box_view_; }
// Overridden from views::View:
virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
......@@ -42,16 +43,18 @@ class StartPageView : public views::View,
private:
enum ShowState {
SHOW_SEARCH_RESULTS,
SHOW_START_PAGE,
SHOW_SEARCH_RESULTS,
};
void InitInstantContainer();
void InitTilesContainer();
void SetShowState(ShowState show_state);
void SetModel(AppListModel* model);
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
// Overridden from SearchBoxViewDelegate:
virtual void QueryChanged(SearchBoxView* sender) OVERRIDE;
// Overridden from AppListViewDelegateObserver:
virtual void OnProfilesChanged() OVERRIDE;
......@@ -69,6 +72,7 @@ class StartPageView : public views::View,
AppListViewDelegate* view_delegate_; // Owned by AppListView.
SearchBoxView* search_box_view_; // Owned by views hierarchy.
SearchResultListView* results_view_; // Owned by views hierarchy.
views::View* instant_container_; // Owned by views hierarchy.
views::View* tiles_container_; // Owned by views hierarchy.
......
......@@ -25,7 +25,6 @@ const int kTileHorizontalPadding = 10;
const int kTileImageSize = 48;
const SkColor kTileBackgroundColor = SK_ColorWHITE;
const SkColor kTileBorderColor = SkColorSetARGB(0x30, 0xD0, 0xD0, 0xD0);
const int kTileColorStripHeight = 2;
const SkAlpha kTileColorStripOpacity = 0X5F;
const int kTileCornerRadius = 2;
......@@ -49,7 +48,7 @@ class TileItemView::TileItemBackground : public views::Background {
paint.setFlags(SkPaint::kAntiAlias_Flag);
// Paint the border.
paint.setColor(kTileBorderColor);
paint.setColor(kStartPageBorderColor);
canvas->DrawRoundRect(view->GetContentsBounds(), kTileCornerRadius, paint);
// Paint a rectangle for the color strip.
......
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