| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ash/app_list/app_list_model_view.h" | 5 #include "ash/app_list/app_list_model_view.h" |
| 6 | 6 |
| 7 #include "ash/app_list/app_list_item_view.h" | 7 #include "ash/app_list/app_list_item_view.h" |
| 8 #include "ash/app_list/app_list_model.h" | 8 #include "ash/app_list/app_list_model.h" |
| 9 #include "ash/app_list/pagination_model.h" |
| 9 | 10 |
| 10 namespace ash { | 11 namespace ash { |
| 11 | 12 |
| 12 AppListModelView::AppListModelView(views::ButtonListener* listener) | 13 AppListModelView::AppListModelView(views::ButtonListener* listener, |
| 14 PaginationModel* pagination_model) |
| 13 : model_(NULL), | 15 : model_(NULL), |
| 14 listener_(listener), | 16 listener_(listener), |
| 15 selected_item_index_(-1), | 17 pagination_model_(pagination_model), |
| 16 cols_(0) { | 18 fixed_layout_(false), |
| 19 cols_(0), |
| 20 rows_per_page_(0), |
| 21 selected_item_index_(-1) { |
| 17 set_focusable(true); | 22 set_focusable(true); |
| 23 pagination_model_->AddObserver(this); |
| 18 } | 24 } |
| 19 | 25 |
| 20 AppListModelView::~AppListModelView() { | 26 AppListModelView::~AppListModelView() { |
| 21 if (model_) | 27 if (model_) |
| 22 model_->RemoveObserver(this); | 28 model_->RemoveObserver(this); |
| 29 pagination_model_->RemoveObserver(this); |
| 30 } |
| 31 |
| 32 void AppListModelView::SetLayout(int icon_size, int cols, int rows_per_page) { |
| 33 fixed_layout_ = true; |
| 34 |
| 35 icon_size_.SetSize(icon_size, icon_size); |
| 36 cols_ = cols; |
| 37 rows_per_page_ = rows_per_page; |
| 23 } | 38 } |
| 24 | 39 |
| 25 void AppListModelView::CalculateLayout(const gfx::Size& content_size, | 40 void AppListModelView::CalculateLayout(const gfx::Size& content_size, |
| 26 int num_of_tiles, | 41 int num_of_tiles, |
| 27 gfx::Size* icon_size, | 42 gfx::Size* icon_size, |
| 28 int* rows, | 43 int* rows, |
| 29 int* cols) { | 44 int* cols) { |
| 30 DCHECK(!content_size.IsEmpty() && num_of_tiles); | 45 DCHECK(!content_size.IsEmpty() && num_of_tiles); |
| 31 | 46 |
| 32 // Icon sizes to try. | 47 // Icon sizes to try. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 return; | 132 return; |
| 118 | 133 |
| 119 if (selected_item_index_ >= 0) | 134 if (selected_item_index_ >= 0) |
| 120 GetItemViewAtIndex(selected_item_index_)->SetSelected(false); | 135 GetItemViewAtIndex(selected_item_index_)->SetSelected(false); |
| 121 | 136 |
| 122 if (index < 0 || index >= child_count()) { | 137 if (index < 0 || index >= child_count()) { |
| 123 selected_item_index_ = -1; | 138 selected_item_index_ = -1; |
| 124 } else { | 139 } else { |
| 125 selected_item_index_ = index; | 140 selected_item_index_ = index; |
| 126 GetItemViewAtIndex(selected_item_index_)->SetSelected(true); | 141 GetItemViewAtIndex(selected_item_index_)->SetSelected(true); |
| 142 |
| 143 if (tiles_per_page()) |
| 144 pagination_model_->SelectPage(selected_item_index_ / tiles_per_page()); |
| 127 } | 145 } |
| 128 } | 146 } |
| 129 | 147 |
| 148 gfx::Size AppListModelView::GetPreferredSize() { |
| 149 if (!fixed_layout_) |
| 150 return gfx::Size(); |
| 151 |
| 152 gfx::Size tile_size = AppListItemView::GetPreferredSizeForIconSize( |
| 153 icon_size_); |
| 154 return gfx::Size(tile_size.width() * cols_, |
| 155 tile_size.height() * rows_per_page_); |
| 156 } |
| 157 |
| 130 void AppListModelView::Layout() { | 158 void AppListModelView::Layout() { |
| 131 gfx::Rect rect(GetContentsBounds()); | 159 gfx::Rect rect(GetContentsBounds()); |
| 132 if (rect.IsEmpty() || child_count() == 0) { | 160 if (rect.IsEmpty() || child_count() == 0) |
| 133 cols_ = 0; | |
| 134 return; | 161 return; |
| 162 |
| 163 gfx::Size tile_size; |
| 164 if (fixed_layout_) { |
| 165 tile_size = AppListItemView::GetPreferredSizeForIconSize(icon_size_); |
| 166 } else { |
| 167 int rows = 0; |
| 168 CalculateLayout(rect.size(), child_count(), &icon_size_, &rows, &cols_); |
| 169 |
| 170 tile_size = AppListItemView::GetPreferredSizeForIconSize( |
| 171 icon_size_); |
| 172 rows_per_page_ = tile_size.height() ? |
| 173 std::max(rect.height() / tile_size.height(), 1) : 1; |
| 174 |
| 175 tile_size.set_width(std::max(rect.width() / (cols_ + 1), |
| 176 tile_size.width())); |
| 177 tile_size.set_height(std::max(rect.height() / (rows_per_page_ + 1), |
| 178 tile_size.height())); |
| 135 } | 179 } |
| 136 | 180 |
| 137 gfx::Size icon_size; | 181 if (!tiles_per_page()) |
| 138 int rows = 0; | |
| 139 CalculateLayout(rect.size(), child_count(), &icon_size, &rows, &cols_); | |
| 140 if (rows == 0 || cols_ == 0) | |
| 141 return; | 182 return; |
| 142 | 183 |
| 143 gfx::Size tile_size = AppListItemView::GetPreferredSizeForIconSize(icon_size); | 184 pagination_model_->SetTotalPages((child_count() - 1) / tiles_per_page() + 1); |
| 144 tile_size.set_width(std::max(rect.width() / (cols_ + 1), | 185 if (pagination_model_->selected_page() < 0) |
| 145 tile_size.width())); | 186 pagination_model_->SelectPage(0); |
| 146 tile_size.set_height(std::max(rect.height() / (rows + 1), | |
| 147 tile_size.height())); | |
| 148 | 187 |
| 149 gfx::Rect grid_rect = rect.Center(gfx::Size(tile_size.width() * cols_, | 188 gfx::Rect grid_rect = rect.Center( |
| 150 tile_size.height() * rows)); | 189 gfx::Size(tile_size.width() * cols_, |
| 190 tile_size.height() * rows_per_page_)); |
| 151 grid_rect = grid_rect.Intersect(rect); | 191 grid_rect = grid_rect.Intersect(rect); |
| 152 | 192 |
| 153 // Layouts items. | 193 // Layouts items. |
| 194 const int page = pagination_model_->selected_page(); |
| 195 const int first_visible_index = page * tiles_per_page(); |
| 196 const int last_visible_index = (page + 1) * tiles_per_page() - 1; |
| 154 gfx::Rect current_tile(grid_rect.origin(), tile_size); | 197 gfx::Rect current_tile(grid_rect.origin(), tile_size); |
| 155 for (int i = 0; i < child_count(); ++i) { | 198 for (int i = 0; i < child_count(); ++i) { |
| 156 views::View* view = child_at(i); | 199 views::View* view = child_at(i); |
| 157 static_cast<AppListItemView*>(view)->SetIconSize(icon_size); | 200 static_cast<AppListItemView*>(view)->SetIconSize(icon_size_); |
| 201 |
| 202 if (i < first_visible_index || i > last_visible_index) { |
| 203 view->SetVisible(false); |
| 204 continue; |
| 205 } |
| 206 |
| 158 view->SetBoundsRect(current_tile); | 207 view->SetBoundsRect(current_tile); |
| 159 view->SetVisible(rect.Contains(current_tile)); | 208 view->SetVisible(rect.Contains(current_tile)); |
| 160 | 209 |
| 161 current_tile.Offset(tile_size.width(), 0); | 210 current_tile.Offset(tile_size.width(), 0); |
| 162 if ((i + 1) % cols_ == 0) { | 211 if ((i + 1) % cols_ == 0) { |
| 163 current_tile.set_x(grid_rect.x()); | 212 current_tile.set_x(grid_rect.x()); |
| 164 current_tile.set_y(current_tile.y() + tile_size.height()); | 213 current_tile.set_y(current_tile.y() + tile_size.height()); |
| 165 } | 214 } |
| 166 } | 215 } |
| 167 } | 216 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 185 0)); | 234 0)); |
| 186 return true; | 235 return true; |
| 187 case ui::VKEY_DOWN: | 236 case ui::VKEY_DOWN: |
| 188 if (selected_item_index_ < 0) { | 237 if (selected_item_index_ < 0) { |
| 189 SetSelectedItemByIndex(0); | 238 SetSelectedItemByIndex(0); |
| 190 } else { | 239 } else { |
| 191 SetSelectedItemByIndex(std::min(selected_item_index_ + cols_, | 240 SetSelectedItemByIndex(std::min(selected_item_index_ + cols_, |
| 192 child_count() - 1)); | 241 child_count() - 1)); |
| 193 } | 242 } |
| 194 return true; | 243 return true; |
| 244 case ui::VKEY_PRIOR: { |
| 245 SetSelectedItemByIndex( |
| 246 std::max(selected_item_index_ - tiles_per_page(), |
| 247 0)); |
| 248 return true; |
| 249 } |
| 250 case ui::VKEY_NEXT: { |
| 251 if (selected_item_index_ < 0) { |
| 252 SetSelectedItemByIndex(0); |
| 253 } else { |
| 254 SetSelectedItemByIndex( |
| 255 std::min(selected_item_index_ + tiles_per_page(), |
| 256 child_count() - 1)); |
| 257 } |
| 258 } |
| 195 default: | 259 default: |
| 196 break; | 260 break; |
| 197 } | 261 } |
| 198 } | 262 } |
| 199 | 263 |
| 200 return handled; | 264 return handled; |
| 201 } | 265 } |
| 202 | 266 |
| 203 bool AppListModelView::OnKeyReleased(const views::KeyEvent& event) { | 267 bool AppListModelView::OnKeyReleased(const views::KeyEvent& event) { |
| 204 bool handled = false; | 268 bool handled = false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 226 delete child_at(start); | 290 delete child_at(start); |
| 227 | 291 |
| 228 Layout(); | 292 Layout(); |
| 229 SchedulePaint(); | 293 SchedulePaint(); |
| 230 } | 294 } |
| 231 | 295 |
| 232 void AppListModelView::ListItemsChanged(int start, int count) { | 296 void AppListModelView::ListItemsChanged(int start, int count) { |
| 233 NOTREACHED(); | 297 NOTREACHED(); |
| 234 } | 298 } |
| 235 | 299 |
| 300 void AppListModelView::TotalPagesChanged() { |
| 301 } |
| 302 |
| 303 void AppListModelView::SelectedPageChanged(int old_selected, int new_selected) { |
| 304 Layout(); |
| 305 } |
| 306 |
| 236 } // namespace ash | 307 } // namespace ash |
| OLD | NEW |