| 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/apps_grid_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/pagination_model.h" | 10 #include "ui/app_list/pagination_model.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 } // namespace | 23 } // namespace |
| 24 | 24 |
| 25 namespace app_list { | 25 namespace app_list { |
| 26 | 26 |
| 27 AppsGridView::AppsGridView(views::ButtonListener* listener, | 27 AppsGridView::AppsGridView(views::ButtonListener* listener, |
| 28 PaginationModel* pagination_model) | 28 PaginationModel* pagination_model) |
| 29 : model_(NULL), | 29 : model_(NULL), |
| 30 listener_(listener), | 30 listener_(listener), |
| 31 pagination_model_(pagination_model), | 31 pagination_model_(pagination_model), |
| 32 fixed_layout_(false), | |
| 33 cols_(0), | 32 cols_(0), |
| 34 rows_per_page_(0), | 33 rows_per_page_(0), |
| 35 selected_item_index_(-1) { | 34 selected_item_index_(-1) { |
| 36 set_focusable(true); | 35 set_focusable(true); |
| 37 pagination_model_->AddObserver(this); | 36 pagination_model_->AddObserver(this); |
| 38 } | 37 } |
| 39 | 38 |
| 40 AppsGridView::~AppsGridView() { | 39 AppsGridView::~AppsGridView() { |
| 41 if (model_) | 40 if (model_) |
| 42 model_->RemoveObserver(this); | 41 model_->RemoveObserver(this); |
| 43 pagination_model_->RemoveObserver(this); | 42 pagination_model_->RemoveObserver(this); |
| 44 } | 43 } |
| 45 | 44 |
| 46 void AppsGridView::CalculateLayout(const gfx::Size& content_size, | |
| 47 int num_of_tiles, | |
| 48 gfx::Size* icon_size, | |
| 49 int* rows, | |
| 50 int* cols) { | |
| 51 DCHECK(!content_size.IsEmpty() && num_of_tiles); | |
| 52 | |
| 53 // Icon sizes to try. | |
| 54 const int kIconSizes[] = { 128, 96, 64, 48, 32 }; | |
| 55 | |
| 56 double aspect = static_cast<double>(content_size.width()) / | |
| 57 content_size.height(); | |
| 58 | |
| 59 // Chooses the biggest icon size that could fit all tiles. | |
| 60 gfx::Size tile_size; | |
| 61 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { | |
| 62 icon_size->SetSize(kIconSizes[i], kIconSizes[i]); | |
| 63 tile_size = AppListItemView::GetPreferredSizeForIconSize( | |
| 64 *icon_size); | |
| 65 | |
| 66 int max_cols = content_size.width() / tile_size.width(); | |
| 67 int max_rows = content_size.height() / tile_size.height(); | |
| 68 | |
| 69 // Skip if |tile_size| could not fit into |content_size|. | |
| 70 if (max_cols * max_rows < num_of_tiles) | |
| 71 continue; | |
| 72 | |
| 73 // Find a rows/cols pair that has a aspect ratio closest to |aspect|. | |
| 74 double min_aspect_diff = 1e5; | |
| 75 for (int c = std::max(max_cols / 2, 1); c <= max_cols; ++c) { | |
| 76 int r = std::min((num_of_tiles - 1) / c + 1, max_rows); | |
| 77 if (c * r < num_of_tiles) | |
| 78 continue; | |
| 79 | |
| 80 double aspect_diff = fabs(static_cast<double>(c) / r - aspect); | |
| 81 if (aspect_diff < min_aspect_diff) { | |
| 82 *cols = c; | |
| 83 *rows = r; | |
| 84 min_aspect_diff = aspect_diff; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 DCHECK((*rows) * (*cols) >= num_of_tiles); | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 // No icon size that could fit all tiles. | |
| 93 *cols = std::max(content_size.width() / tile_size.width(), 1); | |
| 94 *rows = (num_of_tiles - 1) / (*cols) + 1; | |
| 95 } | |
| 96 | |
| 97 void AppsGridView::SetLayout(int icon_size, int cols, int rows_per_page) { | 45 void AppsGridView::SetLayout(int icon_size, int cols, int rows_per_page) { |
| 98 fixed_layout_ = true; | |
| 99 | |
| 100 icon_size_.SetSize(icon_size, icon_size); | 46 icon_size_.SetSize(icon_size, icon_size); |
| 101 cols_ = cols; | 47 cols_ = cols; |
| 102 rows_per_page_ = rows_per_page; | 48 rows_per_page_ = rows_per_page; |
| 103 | 49 |
| 104 set_border(views::Border::CreateEmptyBorder(kTopPadding, | 50 set_border(views::Border::CreateEmptyBorder(kTopPadding, |
| 105 kLeftRightPadding, | 51 kLeftRightPadding, |
| 106 0, | 52 0, |
| 107 kLeftRightPadding)); | 53 kLeftRightPadding)); |
| 108 } | 54 } |
| 109 | 55 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 122 if (index >= 0) | 68 if (index >= 0) |
| 123 SetSelectedItemByIndex(index); | 69 SetSelectedItemByIndex(index); |
| 124 } | 70 } |
| 125 | 71 |
| 126 void AppsGridView::ClearSelectedItem(AppListItemView* item) { | 72 void AppsGridView::ClearSelectedItem(AppListItemView* item) { |
| 127 int index = GetIndexOf(item); | 73 int index = GetIndexOf(item); |
| 128 if (index == selected_item_index_) | 74 if (index == selected_item_index_) |
| 129 SetSelectedItemByIndex(-1); | 75 SetSelectedItemByIndex(-1); |
| 130 } | 76 } |
| 131 | 77 |
| 78 bool AppsGridView::IsSelectedItem(const AppListItemView* item) const { |
| 79 return selected_item_index_ != -1 && |
| 80 selected_item_index_ == GetIndexOf(item); |
| 81 } |
| 82 |
| 83 void AppsGridView::EnsureItemVisible(const AppListItemView* item) { |
| 84 int index = GetIndexOf(item); |
| 85 if (index >= 0 && tiles_per_page()) |
| 86 pagination_model_->SelectPage(index / tiles_per_page()); |
| 87 } |
| 88 |
| 132 gfx::Size AppsGridView::GetPreferredSize() { | 89 gfx::Size AppsGridView::GetPreferredSize() { |
| 133 if (!fixed_layout_) | |
| 134 return gfx::Size(); | |
| 135 | |
| 136 gfx::Insets insets(GetInsets()); | 90 gfx::Insets insets(GetInsets()); |
| 137 gfx::Size tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); | 91 gfx::Size tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); |
| 138 return gfx::Size(tile_size.width() * cols_ + insets.width(), | 92 return gfx::Size(tile_size.width() * cols_ + insets.width(), |
| 139 tile_size.height() * rows_per_page_ + insets.height()); | 93 tile_size.height() * rows_per_page_ + insets.height()); |
| 140 } | 94 } |
| 141 | 95 |
| 142 void AppsGridView::Layout() { | 96 void AppsGridView::Layout() { |
| 143 gfx::Rect rect(GetContentsBounds()); | 97 gfx::Rect rect(GetContentsBounds()); |
| 144 if (rect.IsEmpty() || child_count() == 0) | 98 if (rect.IsEmpty() || child_count() == 0 || !tiles_per_page()) |
| 145 return; | 99 return; |
| 146 | 100 |
| 147 gfx::Size tile_size; | 101 gfx::Size tile_size(kPreferredTileWidth, kPreferredTileHeight); |
| 148 if (fixed_layout_) { | |
| 149 tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight); | |
| 150 } else { | |
| 151 int rows = 0; | |
| 152 CalculateLayout(rect.size(), child_count(), &icon_size_, &rows, &cols_); | |
| 153 | 102 |
| 154 tile_size = AppListItemView::GetPreferredSizeForIconSize( | |
| 155 icon_size_); | |
| 156 rows_per_page_ = tile_size.height() ? | |
| 157 std::max(rect.height() / tile_size.height(), 1) : 1; | |
| 158 | |
| 159 tile_size.set_width(std::max(rect.width() / (cols_ + 1), | |
| 160 tile_size.width())); | |
| 161 tile_size.set_height(std::max(rect.height() / (rows_per_page_ + 1), | |
| 162 tile_size.height())); | |
| 163 } | |
| 164 | |
| 165 if (!tiles_per_page()) | |
| 166 return; | |
| 167 | 103 |
| 168 pagination_model_->SetTotalPages((child_count() - 1) / tiles_per_page() + 1); | 104 pagination_model_->SetTotalPages((child_count() - 1) / tiles_per_page() + 1); |
| 169 if (pagination_model_->selected_page() < 0) | 105 if (pagination_model_->selected_page() < 0) |
| 170 pagination_model_->SelectPage(0); | 106 pagination_model_->SelectPage(0); |
| 171 | 107 |
| 172 gfx::Rect grid_rect = rect.Center( | 108 gfx::Rect grid_rect = rect.Center( |
| 173 gfx::Size(tile_size.width() * cols_, | 109 gfx::Size(tile_size.width() * cols_, |
| 174 tile_size.height() * rows_per_page_)); | 110 tile_size.height() * rows_per_page_)); |
| 175 grid_rect = grid_rect.Intersect(rect); | 111 grid_rect = grid_rect.Intersect(rect); |
| 176 | 112 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 | 211 |
| 276 AppListItemView* AppsGridView::GetItemViewAtIndex(int index) { | 212 AppListItemView* AppsGridView::GetItemViewAtIndex(int index) { |
| 277 return static_cast<AppListItemView*>(child_at(index)); | 213 return static_cast<AppListItemView*>(child_at(index)); |
| 278 } | 214 } |
| 279 | 215 |
| 280 void AppsGridView::SetSelectedItemByIndex(int index) { | 216 void AppsGridView::SetSelectedItemByIndex(int index) { |
| 281 if (selected_item_index_ == index) | 217 if (selected_item_index_ == index) |
| 282 return; | 218 return; |
| 283 | 219 |
| 284 if (selected_item_index_ >= 0) | 220 if (selected_item_index_ >= 0) |
| 285 GetItemViewAtIndex(selected_item_index_)->SetSelected(false); | 221 GetItemViewAtIndex(selected_item_index_)->SchedulePaint(); |
| 286 | 222 |
| 287 if (index < 0 || index >= child_count()) { | 223 if (index < 0 || index >= child_count()) { |
| 288 selected_item_index_ = -1; | 224 selected_item_index_ = -1; |
| 289 } else { | 225 } else { |
| 290 selected_item_index_ = index; | 226 selected_item_index_ = index; |
| 291 GetItemViewAtIndex(selected_item_index_)->SetSelected(true); | 227 GetItemViewAtIndex(selected_item_index_)->SchedulePaint(); |
| 292 | 228 |
| 293 if (tiles_per_page()) | 229 if (tiles_per_page()) |
| 294 pagination_model_->SelectPage(selected_item_index_ / tiles_per_page()); | 230 pagination_model_->SelectPage(selected_item_index_ / tiles_per_page()); |
| 295 } | 231 } |
| 296 } | 232 } |
| 297 | 233 |
| 298 void AppsGridView::ListItemsAdded(size_t start, size_t count) { | 234 void AppsGridView::ListItemsAdded(size_t start, size_t count) { |
| 299 for (size_t i = start; i < start + count; ++i) { | 235 for (size_t i = start; i < start + count; ++i) { |
| 300 AddChildViewAt(new AppListItemView(this, model_->GetItemAt(i), listener_), | 236 AddChildViewAt(new AppListItemView(this, model_->GetItemAt(i), listener_), |
| 301 i); | 237 i); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 317 } | 253 } |
| 318 | 254 |
| 319 void AppsGridView::TotalPagesChanged() { | 255 void AppsGridView::TotalPagesChanged() { |
| 320 } | 256 } |
| 321 | 257 |
| 322 void AppsGridView::SelectedPageChanged(int old_selected, int new_selected) { | 258 void AppsGridView::SelectedPageChanged(int old_selected, int new_selected) { |
| 323 Layout(); | 259 Layout(); |
| 324 } | 260 } |
| 325 | 261 |
| 326 } // namespace app_list | 262 } // namespace app_list |
| OLD | NEW |