OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |