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

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

Powered by Google App Engine
This is Rietveld 408576698