| 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 |