Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/app_list/contents_view.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "ui/app_list/app_list_view.h" | |
| 10 #include "ui/app_list/apps_grid_view.h" | |
| 11 #include "ui/app_list/page_switcher.h" | |
| 12 #include "ui/app_list/search_result_list_view.h" | |
| 13 #include "ui/views/animation/bounds_animator.h" | |
| 14 #include "ui/views/view_model.h" | |
| 15 #include "ui/views/view_model_utils.h" | |
| 16 | |
| 17 namespace app_list { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 const int kPreferredIconDimension = 48; | |
| 22 const int kPreferredCols = 4; | |
| 23 const int kPreferredRows = 4; | |
| 24 | |
| 25 // Indexes of interesting views in ViewModel of ContentsView. | |
| 26 const int kIndexAppsGrid = 0; | |
| 27 const int kIndexPageSwitcher = 1; | |
| 28 const int kIndexSearchResults = 2; | |
| 29 | |
| 30 // Helpers to get certain child view from |model|. | |
| 31 AppsGridView* GetAppsGridView(views::ViewModel* model) { | |
| 32 return static_cast<AppsGridView*>(model->view_at(kIndexAppsGrid)); | |
| 33 } | |
| 34 | |
| 35 PageSwitcher* GetPageSwitcherView(views::ViewModel* model) { | |
| 36 return static_cast<PageSwitcher*>(model->view_at(kIndexPageSwitcher)); | |
| 37 } | |
| 38 | |
| 39 SearchResultListView* GetSearchResultListView(views::ViewModel* model) { | |
| 40 return static_cast<SearchResultListView*>( | |
| 41 model->view_at(kIndexSearchResults)); | |
| 42 } | |
| 43 | |
| 44 } // namespace | |
| 45 | |
| 46 ContentsView::ContentsView(AppListView* app_list_view, | |
| 47 PaginationModel* pagination_model) | |
| 48 : show_state_(SHOW_APPS), | |
| 49 view_model_(new views::ViewModel) { | |
| 50 bounds_animator_.reset(new views::BoundsAnimator(this)); | |
|
tfarina
2012/06/08 04:18:51
nit: you should probably initialize this in the co
xiyuan
2012/06/08 16:16:54
ALLOW_THIS_IN_INITIALIZER_LIST always makes me fee
| |
| 51 | |
| 52 AppsGridView* apps_grid_view = new AppsGridView(app_list_view, | |
| 53 pagination_model); | |
| 54 apps_grid_view->SetLayout(kPreferredIconDimension, | |
| 55 kPreferredCols, | |
| 56 kPreferredRows); | |
| 57 AddChildView(apps_grid_view); | |
| 58 view_model_->Add(apps_grid_view, kIndexAppsGrid); | |
| 59 | |
| 60 PageSwitcher* page_switcher_view = new PageSwitcher(pagination_model); | |
| 61 AddChildView(page_switcher_view); | |
| 62 view_model_->Add(page_switcher_view, kIndexPageSwitcher); | |
| 63 | |
| 64 SearchResultListView* search_results_view = new SearchResultListView( | |
| 65 app_list_view); | |
| 66 AddChildView(search_results_view); | |
| 67 view_model_->Add(search_results_view, kIndexSearchResults); | |
| 68 } | |
| 69 | |
| 70 ContentsView::~ContentsView() { | |
| 71 } | |
| 72 | |
| 73 void ContentsView::SetModel(AppListModel* model) { | |
| 74 if (model) { | |
| 75 GetAppsGridView(view_model_.get())->SetModel(model->apps()); | |
| 76 GetSearchResultListView(view_model_.get())->SetResults(model->results()); | |
| 77 } else { | |
| 78 GetAppsGridView(view_model_.get())->SetModel(NULL); | |
| 79 GetSearchResultListView(view_model_.get())->SetResults(NULL); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 void ContentsView::SetShowState(ShowState show_state) { | |
| 84 if (show_state_ == show_state) | |
| 85 return; | |
| 86 | |
| 87 show_state_ = show_state; | |
| 88 ShowStateChanged(); | |
| 89 } | |
| 90 | |
| 91 void ContentsView::ShowStateChanged() { | |
| 92 if (show_state_ == SHOW_SEARCH_RESULTS) { | |
| 93 // TODO(xiyuan): Highlight default match instead of the first. | |
| 94 SearchResultListView* results_view = | |
| 95 GetSearchResultListView(view_model_.get()); | |
| 96 if (results_view->visible()) | |
| 97 results_view->SetSelectedIndex(0); | |
| 98 } | |
| 99 | |
| 100 AnimateToIdealBounds(); | |
| 101 } | |
| 102 | |
| 103 void ContentsView::CalculateIdealBounds() { | |
| 104 gfx::Rect rect(GetContentsBounds()); | |
| 105 if (rect.IsEmpty()) | |
| 106 return; | |
| 107 | |
| 108 const int x = rect.x(); | |
| 109 const int width = rect.width(); | |
| 110 | |
| 111 // AppsGridView and PageSwitcher uses a vertical box layout. | |
| 112 int y = rect.y(); | |
| 113 const int grid_height = | |
| 114 GetAppsGridView(view_model_.get())->GetPreferredSize().height(); | |
| 115 gfx::Rect grid_frame(gfx::Point(x, y), gfx::Size(width, grid_height)); | |
| 116 grid_frame = rect.Intersect(grid_frame); | |
| 117 | |
| 118 y = grid_frame.bottom(); | |
| 119 const int page_switcher_height = rect.bottom() - y; | |
| 120 gfx::Rect page_switcher_frame(gfx::Point(x, y), | |
| 121 gfx::Size(width, page_switcher_height)); | |
| 122 page_switcher_frame = rect.Intersect(page_switcher_frame); | |
| 123 | |
| 124 // SearchResultListView occupies the whole space when visible. | |
| 125 gfx::Rect results_frame(rect); | |
| 126 | |
| 127 // Offsets apps grid, page switcher and result list based on |show_state_|. | |
| 128 // SearchResultListView is on top of apps grid + page switcher. Visible view | |
| 129 // is left in visible area and invisible ones is put out of the visible area. | |
| 130 int contents_area_height = rect.height(); | |
| 131 switch (show_state_) { | |
| 132 case SHOW_APPS: | |
| 133 results_frame.Offset(0, -contents_area_height); | |
| 134 break; | |
| 135 case SHOW_SEARCH_RESULTS: | |
| 136 grid_frame.Offset(0, contents_area_height); | |
| 137 page_switcher_frame.Offset(0, contents_area_height); | |
| 138 break; | |
| 139 default: | |
| 140 NOTREACHED() << "Unknown show_state_ " << show_state_; | |
| 141 break; | |
| 142 } | |
| 143 | |
| 144 view_model_->set_ideal_bounds(kIndexAppsGrid, grid_frame); | |
| 145 view_model_->set_ideal_bounds(kIndexPageSwitcher, page_switcher_frame); | |
| 146 view_model_->set_ideal_bounds(kIndexSearchResults, results_frame); | |
| 147 } | |
| 148 | |
| 149 void ContentsView::AnimateToIdealBounds() { | |
| 150 CalculateIdealBounds(); | |
| 151 for (int i = 0; i < view_model_->view_size(); ++i) { | |
| 152 bounds_animator_->AnimateViewTo(view_model_->view_at(i), | |
| 153 view_model_->ideal_bounds(i)); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 void ContentsView::ShowSearchResults(bool show) { | |
| 158 SetShowState(show ? SHOW_SEARCH_RESULTS : SHOW_APPS); | |
| 159 } | |
| 160 | |
| 161 gfx::Size ContentsView::GetPreferredSize() { | |
| 162 const gfx::Size grid_size = | |
| 163 GetAppsGridView(view_model_.get())->GetPreferredSize(); | |
| 164 const gfx::Size page_switcher_size = | |
| 165 GetPageSwitcherView(view_model_.get())->GetPreferredSize(); | |
| 166 const gfx::Size results_size = | |
| 167 GetSearchResultListView(view_model_.get())->GetPreferredSize(); | |
| 168 | |
| 169 int width = std::max( | |
| 170 std::max(grid_size.width(), page_switcher_size.width()), | |
| 171 results_size.width()); | |
| 172 int height = std::max(grid_size.height() + page_switcher_size.height(), | |
| 173 results_size.height()); | |
| 174 return gfx::Size(width, height); | |
| 175 } | |
| 176 | |
| 177 void ContentsView::Layout() { | |
| 178 CalculateIdealBounds(); | |
| 179 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); | |
| 180 } | |
| 181 | |
| 182 bool ContentsView::OnKeyPressed(const views::KeyEvent& event) { | |
| 183 switch (show_state_) { | |
| 184 case SHOW_APPS: | |
| 185 return GetAppsGridView(view_model_.get())->OnKeyPressed(event); | |
| 186 case SHOW_SEARCH_RESULTS: | |
| 187 return GetSearchResultListView(view_model_.get())->OnKeyPressed(event); | |
| 188 default: | |
| 189 NOTREACHED() << "Unknown show state " << show_state_; | |
| 190 } | |
| 191 return false; | |
| 192 } | |
| 193 | |
| 194 } // namespace app_list | |
| OLD | NEW |