Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(611)

Side by Side Diff: athena/home/athena_start_page_view.cc

Issue 478293004: Refactor the home card structure and introduce animation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rease Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "athena/home/athena_start_page_view.h" 5 #include "athena/home/athena_start_page_view.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "third_party/skia/include/core/SkPaint.h" 9 #include "third_party/skia/include/core/SkPaint.h"
10 #include "third_party/skia/include/core/SkPath.h" 10 #include "third_party/skia/include/core/SkPath.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 class SearchBoxContainer : public views::View { 122 class SearchBoxContainer : public views::View {
123 public: 123 public:
124 explicit SearchBoxContainer(app_list::SearchBoxView* search_box) 124 explicit SearchBoxContainer(app_list::SearchBoxView* search_box)
125 : search_box_(search_box) { 125 : search_box_(search_box) {
126 search_box->set_background( 126 search_box->set_background(
127 new RoundRectBackground(SK_ColorWHITE, kSearchBoxCornerRadius)); 127 new RoundRectBackground(SK_ColorWHITE, kSearchBoxCornerRadius));
128 search_box->SetBorder(views::Border::CreateBorderPainter( 128 search_box->SetBorder(views::Border::CreateBorderPainter(
129 new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius), 129 new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius),
130 gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth, 130 gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth,
131 kSearchBoxBorderWidth, kSearchBoxBorderWidth))); 131 kSearchBoxBorderWidth, kSearchBoxBorderWidth)));
132 SetLayoutManager(new views::FillLayout());
132 AddChildView(search_box_); 133 AddChildView(search_box_);
133 } 134 }
134 virtual ~SearchBoxContainer() {} 135 virtual ~SearchBoxContainer() {}
135 136
136 private: 137 private:
137 // views::View: 138 // views::View:
138 virtual void Layout() OVERRIDE {
139 gfx::Rect search_box_bounds = GetContentsBounds();
140 search_box_bounds.ClampToCenteredSize(GetPreferredSize());
141 search_box_->SetBoundsRect(search_box_bounds);
142 }
143 virtual gfx::Size GetPreferredSize() const OVERRIDE { 139 virtual gfx::Size GetPreferredSize() const OVERRIDE {
144 return gfx::Size(kSearchBoxWidth, kSearchBoxHeight); 140 return gfx::Size(kSearchBoxWidth, kSearchBoxHeight);
145 } 141 }
146 142
147 // Owned by the views hierarchy. 143 // Owned by the views hierarchy.
148 app_list::SearchBoxView* search_box_; 144 app_list::SearchBoxView* search_box_;
149 145
150 DISALLOW_COPY_AND_ASSIGN(SearchBoxContainer); 146 DISALLOW_COPY_AND_ASSIGN(SearchBoxContainer);
151 }; 147 };
152 148
153 } // namespace 149 } // namespace
154 150
155 namespace athena { 151 namespace athena {
156 152
153 // static
154 const char AthenaStartPageView::kViewClassName[] = "AthenaStartPageView";
155
156 AthenaStartPageView::LayoutData::LayoutData()
157 : logo_opacity(1.0f),
158 background_opacity(1.0f) {
159 }
160
157 AthenaStartPageView::AthenaStartPageView( 161 AthenaStartPageView::AthenaStartPageView(
158 app_list::AppListViewDelegate* view_delegate) 162 app_list::AppListViewDelegate* view_delegate)
159 : delegate_(view_delegate), 163 : delegate_(view_delegate),
164 layout_state_(0.0f),
160 weak_factory_(this) { 165 weak_factory_(this) {
166 background_ = new views::View();
167 background_->set_background(
168 views::Background::CreateSolidBackground(SK_ColorWHITE));
169 background_->SetPaintToLayer(true);
170 background_->SetFillsBoundsOpaquely(false);
171 AddChildView(background_);
172
161 logo_ = view_delegate->CreateStartPageWebView( 173 logo_ = view_delegate->CreateStartPageWebView(
162 gfx::Size(kWebViewWidth, kWebViewHeight)); 174 gfx::Size(kWebViewWidth, kWebViewHeight));
163 logo_->SetPaintToLayer(true); 175 logo_->SetPaintToLayer(true);
176 logo_->SetSize(logo_->GetPreferredSize());
164 AddChildView(logo_); 177 AddChildView(logo_);
165 178
166 search_results_view_ = new app_list::SearchResultListView( 179 search_results_view_ = new app_list::SearchResultListView(
167 NULL, view_delegate); 180 NULL, view_delegate);
168 // search_results_view_'s size will shrink after settings results. 181 // search_results_view_'s size will shrink after settings results.
169 search_results_height_ = static_cast<views::View*>( 182 search_results_height_ = static_cast<views::View*>(
170 search_results_view_)->GetHeightForWidth(kSearchBoxWidth); 183 search_results_view_)->GetHeightForWidth(kSearchBoxWidth);
171 search_results_view_->SetResults(view_delegate->GetModel()->results()); 184 search_results_view_->SetResults(view_delegate->GetModel()->results());
172 185
173 search_results_view_->SetVisible(false); 186 search_results_view_->SetVisible(false);
174 search_results_view_->SetPaintToLayer(true); 187 search_results_view_->SetPaintToLayer(true);
175 search_results_view_->SetFillsBoundsOpaquely(false); 188 search_results_view_->SetFillsBoundsOpaquely(false);
176 AddChildView(search_results_view_); 189 AddChildView(search_results_view_);
177 190
178 app_icon_container_ = new views::View(); 191 app_icon_container_ = new views::View();
179 AddChildView(app_icon_container_); 192 AddChildView(app_icon_container_);
180 app_icon_container_->SetPaintToLayer(true); 193 app_icon_container_->SetPaintToLayer(true);
181 app_icon_container_->layer()->SetFillsBoundsOpaquely(false); 194 app_icon_container_->layer()->SetFillsBoundsOpaquely(false);
182 app_icon_container_->SetLayoutManager(new views::BoxLayout( 195 app_icon_container_->SetLayoutManager(new views::BoxLayout(
183 views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); 196 views::BoxLayout::kHorizontal, 0, 0, kIconMargin));
184 app_list::AppListItemList* top_level = 197 app_list::AppListItemList* top_level =
185 view_delegate->GetModel()->top_level_item_list(); 198 view_delegate->GetModel()->top_level_item_list();
186 for (size_t i = 0; i < std::min(top_level->item_count(), kMaxIconNum); ++i) 199 for (size_t i = 0; i < std::min(top_level->item_count(), kMaxIconNum); ++i)
187 app_icon_container_->AddChildView(new AppIconButton(top_level->item_at(i))); 200 app_icon_container_->AddChildView(new AppIconButton(top_level->item_at(i)));
188 201 app_icon_container_->SetSize(app_icon_container_->GetPreferredSize());
189 search_box_view_ = new app_list::SearchBoxView(this, view_delegate);
190 search_box_view_->set_contents_view(this);
191 search_box_container_ = new SearchBoxContainer(search_box_view_);
192 search_box_container_->SetPaintToLayer(true);
193 search_box_container_->SetFillsBoundsOpaquely(false);
194 AddChildView(search_box_container_);
195 202
196 control_icon_container_ = new views::View(); 203 control_icon_container_ = new views::View();
197 control_icon_container_->SetPaintToLayer(true); 204 control_icon_container_->SetPaintToLayer(true);
198 control_icon_container_->SetFillsBoundsOpaquely(false); 205 control_icon_container_->SetFillsBoundsOpaquely(false);
199 AddChildView(control_icon_container_); 206 AddChildView(control_icon_container_);
200 control_icon_container_->SetLayoutManager(new views::BoxLayout( 207 control_icon_container_->SetLayoutManager(new views::BoxLayout(
201 views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); 208 views::BoxLayout::kHorizontal, 0, 0, kIconMargin));
202 for (size_t i = 0; i < kMaxIconNum; ++i) 209 for (size_t i = 0; i < kMaxIconNum; ++i)
203 control_icon_container_->AddChildView(new PlaceHolderButton()); 210 control_icon_container_->AddChildView(new PlaceHolderButton());
211 control_icon_container_->SetSize(control_icon_container_->GetPreferredSize());
212
213 search_box_view_ = new app_list::SearchBoxView(this, view_delegate);
214 search_box_view_->set_contents_view(this);
215 search_box_container_ = new SearchBoxContainer(search_box_view_);
216 search_box_container_->SetPaintToLayer(true);
217 search_box_container_->SetFillsBoundsOpaquely(false);
218 search_box_container_->SetSize(search_box_container_->GetPreferredSize());
219 AddChildView(search_box_container_);
204 } 220 }
205 221
206 AthenaStartPageView::~AthenaStartPageView() {} 222 AthenaStartPageView::~AthenaStartPageView() {}
207 223
208 void AthenaStartPageView::RequestFocusOnSearchBox() { 224 void AthenaStartPageView::RequestFocusOnSearchBox() {
209 search_box_view_->search_box()->RequestFocus(); 225 search_box_view_->search_box()->RequestFocus();
210 } 226 }
211 227
228 void AthenaStartPageView::SetLayoutState(float layout_state) {
229 layout_state_ = layout_state;
230 Layout();
231 }
232
233 void AthenaStartPageView::SetLayoutStateWithAnimation(float layout_state) {
234 ui::ScopedLayerAnimationSettings logo(logo_->layer()->GetAnimator());
235 ui::ScopedLayerAnimationSettings search_box(
236 search_box_container_->layer()->GetAnimator());
237 ui::ScopedLayerAnimationSettings icons(
238 app_icon_container_->layer()->GetAnimator());
239 ui::ScopedLayerAnimationSettings controls(
240 control_icon_container_->layer()->GetAnimator());
241
242 logo.SetTweenType(gfx::Tween::EASE_IN_OUT);
243 search_box.SetTweenType(gfx::Tween::EASE_IN_OUT);
244 icons.SetTweenType(gfx::Tween::EASE_IN_OUT);
245 controls.SetTweenType(gfx::Tween::EASE_IN_OUT);
246
247 SetLayoutState(layout_state);
248 }
249
250 AthenaStartPageView::LayoutData AthenaStartPageView::CreateBottomBounds(
251 int width) {
252 LayoutData state;
253 state.icons.set_size(app_icon_container_->size());
254 state.icons.set_x(kIconMargin);
255 state.icons.set_y(kIconMargin);
256
257 state.controls.set_size(control_icon_container_->size());
258 state.controls.set_x(width - kIconMargin - state.controls.width());
259 state.controls.set_y(kIconMargin);
260
261 state.search_box.set_size(search_box_container_->size());
262 state.search_box.set_x((width - state.search_box.width()) / 2);
263 state.search_box.set_y(
264 (kPreferredHeightBottom - state.search_box.height()) / 2);
265
266 state.logo_opacity = 0.0f;
267 state.background_opacity = 0.9f;
268 return state;
269 }
270
271 AthenaStartPageView::LayoutData AthenaStartPageView::CreateCenteredBounds(
272 int width) {
273 LayoutData state;
274
275 state.search_box.set_size(search_box_container_->size());
276 state.search_box.set_x((width - state.search_box.width()) / 2);
277 state.search_box.set_y(logo_->bounds().bottom() + kInstantContainerSpacing);
278
279 state.icons.set_size(app_icon_container_->size());
280 state.icons.set_x(width / 2 - state.icons.width() - kIconMargin / 2);
281 state.icons.set_y(state.search_box.bottom() + kInstantContainerSpacing);
282
283 state.controls.set_size(control_icon_container_->size());
284 state.controls.set_x(width / 2 + kIconMargin / 2 + kIconMargin % 2);
285 state.controls.set_y(state.icons.y());
286
287 state.logo_opacity = 1.0f;
288 state.background_opacity = 1.0f;
289 return state;
290 }
291
212 void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) { 292 void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) {
213 if (should_show_search_results == 293 if (should_show_search_results ==
214 search_results_view_->layer()->GetTargetVisibility()) { 294 search_results_view_->layer()->GetTargetVisibility()) {
215 return; 295 return;
216 } 296 }
217 if (GetContentsBounds().height() <= kPreferredHeightBottom) { 297 if (GetContentsBounds().height() <= kPreferredHeightBottom) {
218 search_results_view_->SetVisible(false); 298 search_results_view_->SetVisible(false);
219 Layout(); 299 Layout();
220 return; 300 return;
221 } 301 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 } 351 }
272 } 352 }
273 353
274 void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted( 354 void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted(
275 bool should_show_search_results) { 355 bool should_show_search_results) {
276 logo_->SetVisible(!should_show_search_results); 356 logo_->SetVisible(!should_show_search_results);
277 search_results_view_->SetVisible(should_show_search_results); 357 search_results_view_->SetVisible(should_show_search_results);
278 } 358 }
279 359
280 void AthenaStartPageView::Layout() { 360 void AthenaStartPageView::Layout() {
281 gfx::Rect bounds = GetContentsBounds();
282 search_results_view_->SetVisible(false); 361 search_results_view_->SetVisible(false);
362 gfx::Rect logo_bounds(x() + width() / 2 - kWebViewWidth / 2, y() + kTopMargin,
363 kWebViewWidth, kWebViewHeight);
364 logo_->SetBoundsRect(logo_bounds);
283 365
284 if (bounds.height() <= kPreferredHeightBottom) { 366 LayoutData bottom_bounds = CreateBottomBounds(width());
285 logo_->SetVisible(false); 367 LayoutData centered_bounds = CreateCenteredBounds(width());
286 gfx::Rect icon_bounds(app_icon_container_->GetPreferredSize());
287 icon_bounds.set_x(bounds.x() + kIconMargin);
288 icon_bounds.set_y(bounds.x() + kIconMargin);
289 app_icon_container_->SetBoundsRect(icon_bounds);
290 368
291 gfx::Rect control_bounds(control_icon_container_->GetPreferredSize()); 369 logo_->layer()->SetOpacity(gfx::Tween::FloatValueBetween(
292 control_bounds.set_x( 370 gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_),
293 bounds.right() - kIconMargin - control_bounds.width()); 371 bottom_bounds.logo_opacity, centered_bounds.logo_opacity));
294 control_bounds.set_y(bounds.y() + kIconMargin); 372 logo_->SetVisible(logo_->layer()->GetTargetOpacity() != 0.0f);
295 control_icon_container_->SetBoundsRect(control_bounds);
296 373
297 search_box_container_->SetBounds( 374 app_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
298 icon_bounds.right(), bounds.y(), 375 layout_state_, bottom_bounds.icons, centered_bounds.icons));
299 control_bounds.x() - icon_bounds.right(), kPreferredHeightBottom); 376 control_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
377 layout_state_, bottom_bounds.controls, centered_bounds.controls));
378 search_box_container_->SetBoundsRect(gfx::Tween::RectValueBetween(
379 layout_state_, bottom_bounds.search_box, centered_bounds.search_box));
300 380
301 set_background(views::Background::CreateSolidBackground( 381 background_->SetBoundsRect(bounds());
302 255, 255, 255, 255 * 0.9)); 382 background_->layer()->SetOpacity(gfx::Tween::FloatValueBetween(
303 } else { 383 layout_state_,
304 // TODO(mukai): set the intermediate state. 384 bottom_bounds.background_opacity,
305 logo_->SetVisible(true); 385 centered_bounds.background_opacity));
306 logo_->layer()->SetOpacity(1.0f);
307 set_background(views::Background::CreateSolidBackground(SK_ColorWHITE));
308 gfx::Rect logo_bounds(bounds.x() + bounds.width() / 2 - kWebViewWidth / 2,
309 bounds.y() + kTopMargin,
310 kWebViewWidth,
311 kWebViewHeight);
312 logo_->SetBoundsRect(logo_bounds);
313
314 gfx::Rect search_box_bounds(search_box_container_->GetPreferredSize());
315 search_box_bounds.set_x(
316 bounds.x() + bounds.width() / 2 - search_box_bounds.width() / 2);
317 search_box_bounds.set_y(logo_bounds.bottom() + kInstantContainerSpacing);
318 search_box_container_->SetBoundsRect(search_box_bounds);
319
320 gfx::Rect icon_bounds(app_icon_container_->GetPreferredSize());
321 icon_bounds.set_x(bounds.x() + bounds.width() / 2 -
322 icon_bounds.width() - kIconMargin / 2);
323 icon_bounds.set_y(search_box_bounds.bottom() + kInstantContainerSpacing);
324 app_icon_container_->SetBoundsRect(icon_bounds);
325
326 gfx::Rect control_bounds(control_icon_container_->GetPreferredSize());
327 control_bounds.set_x(bounds.x() + bounds.width() / 2 +
328 kIconMargin / 2 + kIconMargin % 2);
329 control_bounds.set_y(icon_bounds.y());
330 control_icon_container_->SetBoundsRect(control_bounds);
331 }
332 } 386 }
333 387
334 bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) { 388 bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) {
335 return search_results_view_->visible() && 389 return search_results_view_->visible() &&
336 search_results_view_->OnKeyPressed(key_event); 390 search_results_view_->OnKeyPressed(key_event);
337 } 391 }
338 392
339 void AthenaStartPageView::QueryChanged(app_list::SearchBoxView* sender) { 393 void AthenaStartPageView::QueryChanged(app_list::SearchBoxView* sender) {
340 delegate_->StartSearch(); 394 delegate_->StartSearch();
341 395
342 base::string16 query; 396 base::string16 query;
343 base::TrimWhitespace( 397 base::TrimWhitespace(
344 delegate_->GetModel()->search_box()->text(), base::TRIM_ALL, &query); 398 delegate_->GetModel()->search_box()->text(), base::TRIM_ALL, &query);
345 399
346 if (!query.empty()) 400 if (!query.empty())
347 search_results_view_->SetSelectedIndex(0); 401 search_results_view_->SetSelectedIndex(0);
348 402
349 LayoutSearchResults(!query.empty()); 403 LayoutSearchResults(!query.empty());
350 } 404 }
351 405
352 } // namespace athena 406 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698