| 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 "ui/app_list/app_list_model_view.h" | 5 #include "ui/app_list/apps_grid_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ui/app_list/app_list_item_view.h" | 9 #include "ui/app_list/app_list_item_view.h" |
| 10 #include "ui/app_list/app_list_model.h" | |
| 11 #include "ui/app_list/pagination_model.h" | 10 #include "ui/app_list/pagination_model.h" |
| 12 #include "ui/views/border.h" | 11 #include "ui/views/border.h" |
| 13 | 12 |
| 14 namespace { | 13 namespace { |
| 15 | 14 |
| 16 // Padding space in pixels for fixed layout. | 15 // Padding space in pixels for fixed layout. |
| 17 const int kTopLeftRightPadding = 15; | 16 const int kTopLeftRightPadding = 15; |
| 18 const int kBottomPadding = 30; | 17 const int kBottomPadding = 30; |
| 19 | 18 |
| 20 // Preferred tile size when showing in fixed layout. | 19 // Preferred tile size when showing in fixed layout. |
| 21 const int kPreferredTileWidth = 80; | 20 const int kPreferredTileWidth = 82; |
| 22 const int kPreferredTileHeight = 88; | 21 const int kPreferredTileHeight = 90; |
| 23 | 22 |
| 24 } // namespace | 23 } // namespace |
| 25 | 24 |
| 26 namespace app_list { | 25 namespace app_list { |
| 27 | 26 |
| 28 AppListModelView::AppListModelView(views::ButtonListener* listener, | 27 AppsGridView::AppsGridView(views::ButtonListener* listener, |
| 29 PaginationModel* pagination_model) | 28 PaginationModel* pagination_model) |
| 30 : model_(NULL), | 29 : model_(NULL), |
| 31 listener_(listener), | 30 listener_(listener), |
| 32 pagination_model_(pagination_model), | 31 pagination_model_(pagination_model), |
| 33 fixed_layout_(false), | 32 fixed_layout_(false), |
| 34 cols_(0), | 33 cols_(0), |
| 35 rows_per_page_(0), | 34 rows_per_page_(0), |
| 36 selected_item_index_(-1) { | 35 selected_item_index_(-1) { |
| 37 set_focusable(true); | 36 set_focusable(true); |
| 38 pagination_model_->AddObserver(this); | 37 pagination_model_->AddObserver(this); |
| 39 } | 38 } |
| 40 | 39 |
| 41 AppListModelView::~AppListModelView() { | 40 AppsGridView::~AppsGridView() { |
| 42 if (model_) | 41 if (model_) |
| 43 model_->RemoveObserver(this); | 42 model_->RemoveObserver(this); |
| 44 pagination_model_->RemoveObserver(this); | 43 pagination_model_->RemoveObserver(this); |
| 45 } | 44 } |
| 46 | 45 |
| 47 void AppListModelView::CalculateLayout(const gfx::Size& content_size, | 46 void AppsGridView::CalculateLayout(const gfx::Size& content_size, |
| 48 int num_of_tiles, | 47 int num_of_tiles, |
| 49 gfx::Size* icon_size, | 48 gfx::Size* icon_size, |
| 50 int* rows, | 49 int* rows, |
| 51 int* cols) { | 50 int* cols) { |
| 52 DCHECK(!content_size.IsEmpty() && num_of_tiles); | 51 DCHECK(!content_size.IsEmpty() && num_of_tiles); |
| 53 | 52 |
| 54 // Icon sizes to try. | 53 // Icon sizes to try. |
| 55 const int kIconSizes[] = { 128, 96, 64, 48, 32 }; | 54 const int kIconSizes[] = { 128, 96, 64, 48, 32 }; |
| 56 | 55 |
| 57 double aspect = static_cast<double>(content_size.width()) / | 56 double aspect = static_cast<double>(content_size.width()) / |
| (...skipping 30 matching lines...) Expand all Loading... |
| 88 | 87 |
| 89 DCHECK((*rows) * (*cols) >= num_of_tiles); | 88 DCHECK((*rows) * (*cols) >= num_of_tiles); |
| 90 return; | 89 return; |
| 91 } | 90 } |
| 92 | 91 |
| 93 // No icon size that could fit all tiles. | 92 // No icon size that could fit all tiles. |
| 94 *cols = std::max(content_size.width() / tile_size.width(), 1); | 93 *cols = std::max(content_size.width() / tile_size.width(), 1); |
| 95 *rows = (num_of_tiles - 1) / (*cols) + 1; | 94 *rows = (num_of_tiles - 1) / (*cols) + 1; |
| 96 } | 95 } |
| 97 | 96 |
| 98 void AppListModelView::SetLayout(int icon_size, int cols, int rows_per_page) { | 97 void AppsGridView::SetLayout(int icon_size, int cols, int rows_per_page) { |
| 99 fixed_layout_ = true; | 98 fixed_layout_ = true; |
| 100 | 99 |
| 101 icon_size_.SetSize(icon_size, icon_size); | 100 icon_size_.SetSize(icon_size, icon_size); |
| 102 cols_ = cols; | 101 cols_ = cols; |
| 103 rows_per_page_ = rows_per_page; | 102 rows_per_page_ = rows_per_page; |
| 104 | 103 |
| 105 set_border(views::Border::CreateEmptyBorder(kTopLeftRightPadding, | 104 set_border(views::Border::CreateEmptyBorder(kTopLeftRightPadding, |
| 106 kTopLeftRightPadding, | 105 kTopLeftRightPadding, |
| 107 kBottomPadding, | 106 kBottomPadding, |
| 108 kTopLeftRightPadding)); | 107 kTopLeftRightPadding)); |
| 109 } | 108 } |
| 110 | 109 |
| 111 void AppListModelView::SetModel(AppListModel* model) { | 110 void AppsGridView::SetModel(AppListModel::Apps* model) { |
| 112 if (model_) | 111 if (model_) |
| 113 model_->RemoveObserver(this); | 112 model_->RemoveObserver(this); |
| 114 | 113 |
| 115 model_ = model; | 114 model_ = model; |
| 116 if (model_) | 115 if (model_) |
| 117 model_->AddObserver(this); | 116 model_->AddObserver(this); |
| 118 Update(); | 117 Update(); |
| 119 } | 118 } |
| 120 | 119 |
| 121 void AppListModelView::SetSelectedItem(AppListItemView* item) { | 120 void AppsGridView::SetSelectedItem(AppListItemView* item) { |
| 122 int index = GetIndexOf(item); | 121 int index = GetIndexOf(item); |
| 123 if (index >= 0) | 122 if (index >= 0) |
| 124 SetSelectedItemByIndex(index); | 123 SetSelectedItemByIndex(index); |
| 125 } | 124 } |
| 126 | 125 |
| 127 void AppListModelView::ClearSelectedItem(AppListItemView* item) { | 126 void AppsGridView::ClearSelectedItem(AppListItemView* item) { |
| 128 int index = GetIndexOf(item); | 127 int index = GetIndexOf(item); |
| 129 if (index == selected_item_index_) | 128 if (index == selected_item_index_) |
| 130 SetSelectedItemByIndex(-1); | 129 SetSelectedItemByIndex(-1); |
| 131 } | 130 } |
| 132 | 131 |
| 133 void AppListModelView::Update() { | 132 gfx::Size AppsGridView::GetPreferredSize() { |
| 134 selected_item_index_ = -1; | |
| 135 RemoveAllChildViews(true); | |
| 136 if (!model_ || model_->item_count() == 0) | |
| 137 return; | |
| 138 | |
| 139 for (size_t i = 0; i < model_->item_count(); ++i) | |
| 140 AddChildView(new AppListItemView(this, model_->GetItemAt(i), listener_)); | |
| 141 | |
| 142 Layout(); | |
| 143 SchedulePaint(); | |
| 144 } | |
| 145 | |
| 146 AppListItemView* AppListModelView::GetItemViewAtIndex(int index) { | |
| 147 return static_cast<AppListItemView*>(child_at(index)); | |
| 148 } | |
| 149 | |
| 150 void AppListModelView::SetSelectedItemByIndex(int index) { | |
| 151 if (selected_item_index_ == index) | |
| 152 return; | |
| 153 | |
| 154 if (selected_item_index_ >= 0) | |
| 155 GetItemViewAtIndex(selected_item_index_)->SetSelected(false); | |
| 156 | |
| 157 if (index < 0 || index >= child_count()) { | |
| 158 selected_item_index_ = -1; | |
| 159 } else { | |
| 160 selected_item_index_ = index; | |
| 161 GetItemViewAtIndex(selected_item_index_)->SetSelected(true); | |
| 162 | |
| 163 if (tiles_per_page()) | |
| 164 pagination_model_->SelectPage(selected_item_index_ / tiles_per_page()); | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 gfx::Size AppListModelView::GetPreferredSize() { | |
| 169 if (!fixed_layout_) | 133 if (!fixed_layout_) |
| 170 return gfx::Size(); | 134 return gfx::Size(); |
| 171 | 135 |
| 172 gfx::Insets insets(GetInsets()); | 136 gfx::Insets insets(GetInsets()); |
| 173 gfx::Size tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); | 137 gfx::Size tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); |
| 174 return gfx::Size(tile_size.width() * cols_ + insets.width(), | 138 return gfx::Size(tile_size.width() * cols_ + insets.width(), |
| 175 tile_size.height() * rows_per_page_ + insets.height()); | 139 tile_size.height() * rows_per_page_ + insets.height()); |
| 176 } | 140 } |
| 177 | 141 |
| 178 void AppListModelView::Layout() { | 142 void AppsGridView::Layout() { |
| 179 gfx::Rect rect(GetContentsBounds()); | 143 gfx::Rect rect(GetContentsBounds()); |
| 180 if (rect.IsEmpty() || child_count() == 0) | 144 if (rect.IsEmpty() || child_count() == 0) |
| 181 return; | 145 return; |
| 182 | 146 |
| 183 gfx::Size tile_size; | 147 gfx::Size tile_size; |
| 184 if (fixed_layout_) { | 148 if (fixed_layout_) { |
| 185 tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); | 149 tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); |
| 186 } else { | 150 } else { |
| 187 int rows = 0; | 151 int rows = 0; |
| 188 CalculateLayout(rect.size(), child_count(), &icon_size_, &rows, &cols_); | 152 CalculateLayout(rect.size(), child_count(), &icon_size_, &rows, &cols_); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 view->SetVisible(rect.Contains(current_tile)); | 192 view->SetVisible(rect.Contains(current_tile)); |
| 229 | 193 |
| 230 current_tile.Offset(tile_size.width(), 0); | 194 current_tile.Offset(tile_size.width(), 0); |
| 231 if ((i + 1) % cols_ == 0) { | 195 if ((i + 1) % cols_ == 0) { |
| 232 current_tile.set_x(grid_rect.x()); | 196 current_tile.set_x(grid_rect.x()); |
| 233 current_tile.set_y(current_tile.y() + tile_size.height()); | 197 current_tile.set_y(current_tile.y() + tile_size.height()); |
| 234 } | 198 } |
| 235 } | 199 } |
| 236 } | 200 } |
| 237 | 201 |
| 238 bool AppListModelView::OnKeyPressed(const views::KeyEvent& event) { | 202 bool AppsGridView::OnKeyPressed(const views::KeyEvent& event) { |
| 239 bool handled = false; | 203 bool handled = false; |
| 240 if (selected_item_index_ >= 0) | 204 if (selected_item_index_ >= 0) |
| 241 handled = GetItemViewAtIndex(selected_item_index_)->OnKeyPressed(event); | 205 handled = GetItemViewAtIndex(selected_item_index_)->OnKeyPressed(event); |
| 242 | 206 |
| 243 if (!handled) { | 207 if (!handled) { |
| 244 switch (event.key_code()) { | 208 switch (event.key_code()) { |
| 245 case ui::VKEY_LEFT: | 209 case ui::VKEY_LEFT: |
| 246 SetSelectedItemByIndex(std::max(selected_item_index_ - 1, 0)); | 210 SetSelectedItemByIndex(std::max(selected_item_index_ - 1, 0)); |
| 247 return true; | 211 return true; |
| 248 case ui::VKEY_RIGHT: | 212 case ui::VKEY_RIGHT: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 277 } | 241 } |
| 278 } | 242 } |
| 279 default: | 243 default: |
| 280 break; | 244 break; |
| 281 } | 245 } |
| 282 } | 246 } |
| 283 | 247 |
| 284 return handled; | 248 return handled; |
| 285 } | 249 } |
| 286 | 250 |
| 287 bool AppListModelView::OnKeyReleased(const views::KeyEvent& event) { | 251 bool AppsGridView::OnKeyReleased(const views::KeyEvent& event) { |
| 288 bool handled = false; | 252 bool handled = false; |
| 289 if (selected_item_index_ >= 0) | 253 if (selected_item_index_ >= 0) |
| 290 handled = GetItemViewAtIndex(selected_item_index_)->OnKeyReleased(event); | 254 handled = GetItemViewAtIndex(selected_item_index_)->OnKeyReleased(event); |
| 291 | 255 |
| 292 return handled; | 256 return handled; |
| 293 } | 257 } |
| 294 | 258 |
| 295 void AppListModelView::OnPaintFocusBorder(gfx::Canvas* canvas) { | 259 void AppsGridView::OnPaintFocusBorder(gfx::Canvas* canvas) { |
| 296 // Override to not paint focus frame. | 260 // Override to not paint focus frame. |
| 297 } | 261 } |
| 298 | 262 |
| 299 void AppListModelView::ListItemsAdded(size_t start, size_t count) { | 263 void AppsGridView::Update() { |
| 264 selected_item_index_ = -1; |
| 265 RemoveAllChildViews(true); |
| 266 if (!model_ || model_->item_count() == 0) |
| 267 return; |
| 268 |
| 269 for (size_t i = 0; i < model_->item_count(); ++i) |
| 270 AddChildView(new AppListItemView(this, model_->GetItemAt(i), listener_)); |
| 271 |
| 272 Layout(); |
| 273 SchedulePaint(); |
| 274 } |
| 275 |
| 276 AppListItemView* AppsGridView::GetItemViewAtIndex(int index) { |
| 277 return static_cast<AppListItemView*>(child_at(index)); |
| 278 } |
| 279 |
| 280 void AppsGridView::SetSelectedItemByIndex(int index) { |
| 281 if (selected_item_index_ == index) |
| 282 return; |
| 283 |
| 284 if (selected_item_index_ >= 0) |
| 285 GetItemViewAtIndex(selected_item_index_)->SetSelected(false); |
| 286 |
| 287 if (index < 0 || index >= child_count()) { |
| 288 selected_item_index_ = -1; |
| 289 } else { |
| 290 selected_item_index_ = index; |
| 291 GetItemViewAtIndex(selected_item_index_)->SetSelected(true); |
| 292 |
| 293 if (tiles_per_page()) |
| 294 pagination_model_->SelectPage(selected_item_index_ / tiles_per_page()); |
| 295 } |
| 296 } |
| 297 |
| 298 void AppsGridView::ListItemsAdded(size_t start, size_t count) { |
| 300 for (size_t i = start; i < start + count; ++i) { | 299 for (size_t i = start; i < start + count; ++i) { |
| 301 AddChildViewAt(new AppListItemView(this, model_->GetItemAt(i), listener_), | 300 AddChildViewAt(new AppListItemView(this, model_->GetItemAt(i), listener_), |
| 302 i); | 301 i); |
| 303 } | 302 } |
| 304 Layout(); | 303 Layout(); |
| 305 SchedulePaint(); | 304 SchedulePaint(); |
| 306 } | 305 } |
| 307 | 306 |
| 308 void AppListModelView::ListItemsRemoved(size_t start, size_t count) { | 307 void AppsGridView::ListItemsRemoved(size_t start, size_t count) { |
| 309 for (size_t i = 0; i < count; ++i) | 308 for (size_t i = 0; i < count; ++i) |
| 310 delete child_at(start); | 309 delete child_at(start); |
| 311 | 310 |
| 312 Layout(); | 311 Layout(); |
| 313 SchedulePaint(); | 312 SchedulePaint(); |
| 314 } | 313 } |
| 315 | 314 |
| 316 void AppListModelView::ListItemsChanged(size_t start, size_t count) { | 315 void AppsGridView::ListItemsChanged(size_t start, size_t count) { |
| 317 NOTREACHED(); | 316 NOTREACHED(); |
| 318 } | 317 } |
| 319 | 318 |
| 320 void AppListModelView::TotalPagesChanged() { | 319 void AppsGridView::TotalPagesChanged() { |
| 321 } | 320 } |
| 322 | 321 |
| 323 void AppListModelView::SelectedPageChanged(int old_selected, int new_selected) { | 322 void AppsGridView::SelectedPageChanged(int old_selected, int new_selected) { |
| 324 Layout(); | 323 Layout(); |
| 325 } | 324 } |
| 326 | 325 |
| 327 } // namespace app_list | 326 } // namespace app_list |
| OLD | NEW |