Index: ash/app_list/app_list_model_view.cc |
diff --git a/ash/app_list/app_list_model_view.cc b/ash/app_list/app_list_model_view.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..34ffabd05e110fcdbe54312db4ebca46a2337901 |
--- /dev/null |
+++ b/ash/app_list/app_list_model_view.cc |
@@ -0,0 +1,109 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ash/app_list/app_list_model_view.h" |
+ |
+#include "ash/app_list/app_list_item_view.h" |
+#include "ash/app_list/app_list_model.h" |
+#include "base/utf_string_conversions.h" |
+#include "ui/views/controls/button/text_button.h" |
+#include "ui/views/layout/grid_layout.h" |
+ |
+namespace ash { |
+ |
+namespace { |
+ |
+// Minimum label width |
+const int kMinLabelWidth = 150; |
+ |
+// Calculate preferred tile size for given |content_size| and |num_of_tiles|. |
+gfx::Size CalculateTileSize(const gfx::Size& content_size, int num_of_tiles) { |
+ const int kIconSizes[] = { 64, 48, 32, 16 }; |
+ |
+ int tile_height = 0; |
+ int tile_width = 0; |
+ for (size_t i = 0; i < arraysize(kIconSizes); ++i) { |
+ int icon_size = kIconSizes[i]; |
+ tile_height = icon_size + 2 * AppListItemView::kPadding; |
+ tile_width = icon_size + std::min(kMinLabelWidth, icon_size * 2) + |
+ 2 * AppListItemView::kPadding; |
+ |
+ int rows = content_size.height() / tile_height; |
+ int cols = content_size.width() / tile_width; |
+ if (rows * cols >= num_of_tiles) |
+ break; |
+ } |
+ |
+ return gfx::Size(tile_width, tile_height); |
+} |
+ |
+} // namespace |
+ |
+AppListModelView::AppListModelView(views::ButtonListener* listener) |
+ : model_(NULL), |
+ listener_(listener) { |
+} |
+ |
+AppListModelView::~AppListModelView() { |
+ if (model_) |
+ model_->RemoveObserver(this); |
+} |
+ |
+void AppListModelView::SetModel(AppListModel* model) { |
+ DCHECK(model); |
+ |
+ if (model_) |
+ model_->RemoveObserver(this); |
+ |
+ model_ = model; |
+ model_->AddObserver(this); |
+ Update(); |
+} |
+ |
+void AppListModelView::Update() { |
+ RemoveAllChildViews(true); |
+ if (!model_ || model_->item_count() == 0) |
+ return; |
+ |
+ for (int i = 0; i < model_->item_count(); ++i) |
+ AddChildView(new AppListItemView(model_->GetItem(i), listener_)); |
+ |
+ Layout(); |
+ SchedulePaint(); |
+} |
+ |
+void AppListModelView::Layout() { |
+ gfx::Rect rect(GetContentsBounds()); |
+ |
+ gfx::Size tile_size = CalculateTileSize(rect.size(), child_count()); |
+ |
+ int col_bottom = rect.bottom(); |
+ gfx::Rect current_tile(rect.x(), rect.y(), |
tfarina
2012/02/29 22:59:43
nit: Shorter:
gfx::Rect current_tile(rect.origin(
xiyuan
2012/02/29 23:05:46
Done.
|
+ tile_size.width(), tile_size.height()); |
+ |
+ for (int i = 0; i < child_count(); ++i) { |
+ views::View* view = child_at(i); |
+ view->SetBoundsRect(current_tile); |
+ |
+ current_tile.Offset(0, tile_size.height()); |
+ if (current_tile.bottom() >= col_bottom) { |
+ current_tile.set_x(current_tile.x() + tile_size.width()); |
+ current_tile.set_y(rect.y()); |
+ } |
+ } |
+} |
+ |
+void AppListModelView::ListItemsAdded(int start, int count) { |
+ Update(); |
+} |
+ |
+void AppListModelView::ListItemsRemoved(int start, int count) { |
+ Update(); |
+} |
+ |
+void AppListModelView::ListItemsChanged(int start, int count) { |
+ NOTREACHED(); |
+} |
+ |
+} // namespace ash |