1 // Copyright 2013 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.
5 #include "ui/app_list/app_list_folder_item.h"
8 #include "ui/app_list/app_list_constants.h"
9 #include "ui/app_list/app_list_item_list.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/image/canvas_image_source.h"
12 #include "ui/gfx/image/image_skia_operations.h"
18 const int kItemIconDimension = 16;
20 // Generates the folder icon with the top 4 child item icons laid in 2x2 tile.
21 class FolderImageSource : public gfx::CanvasImageSource {
23 typedef std::vector<gfx::ImageSkia> Icons;
25 FolderImageSource(const Icons& icons, const gfx::Size& size)
26 : gfx::CanvasImageSource(size, false),
29 DCHECK(icons.size() <= kNumFolderTopItems);
32 virtual ~FolderImageSource() {}
35 void DrawIcon(gfx::Canvas* canvas,
36 const gfx::ImageSkia& icon,
37 const gfx::Size icon_size,
39 gfx::ImageSkia resized(
40 gfx::ImageSkiaOperations::CreateResizedImage(
41 icon, skia::ImageOperations::RESIZE_BEST, icon_size));
42 canvas->DrawImageInt(resized, 0, 0, resized.width(), resized.height(),
43 x, y, resized.width(), resized.height(), true);
46 // gfx::CanvasImageSource overrides:
47 virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
48 // Draw folder circle.
49 gfx::Point center = gfx::Point(size().width() / 2 , size().height() / 2);
51 paint.setStyle(SkPaint::kFill_Style);
52 paint.setAntiAlias(true);
53 paint.setColor(kFolderBubbleColor);
54 canvas->DrawCircle(center, size().width() / 2, paint);
56 if (icons_.size() == 0)
59 // Draw top items' icons.
60 const gfx::Size item_icon_size =
61 gfx::Size(kItemIconDimension, kItemIconDimension);
62 Rects top_icon_bounds =
63 AppListFolderItem::GetTopIconsBounds(gfx::Rect(size()));
65 for (size_t i= 0; i < kNumFolderTopItems && i < icons_.size(); ++i) {
66 DrawIcon(canvas, icons_[i], item_icon_size,
67 top_icon_bounds[i].x(), top_icon_bounds[i].y());
74 DISALLOW_COPY_AND_ASSIGN(FolderImageSource);
79 AppListFolderItem::AppListFolderItem(const std::string& id)
81 item_list_(new AppListItemList) {
82 item_list_->AddObserver(this);
85 AppListFolderItem::~AppListFolderItem() {
86 for (size_t i = 0; i < top_items_.size(); ++i)
87 top_items_[i]->RemoveObserver(this);
88 item_list_->RemoveObserver(this);
91 void AppListFolderItem::UpdateIcon() {
92 FolderImageSource::Icons top_icons;
93 for (size_t i = 0; i < top_items_.size(); ++i)
94 top_icons.push_back(top_items_[i]->icon());
96 const gfx::Size icon_size =
97 gfx::Size(kPreferredIconDimension, kPreferredIconDimension);
98 gfx::ImageSkia icon = gfx::ImageSkia(
99 new FolderImageSource(top_icons, icon_size),
101 SetIcon(icon, false);
104 const gfx::ImageSkia& AppListFolderItem::GetTopIcon(size_t item_index) {
105 DCHECK(item_index <= top_items_.size());
106 return top_items_[item_index]->icon();
109 gfx::Rect AppListFolderItem::GetTargetIconRectInFolderForItem(
111 const gfx::Rect& folder_icon_bounds) {
112 for (size_t i = 0; i < top_items_.size(); ++i) {
113 if (item->id() == top_items_[i]->id()) {
114 Rects rects = AppListFolderItem::GetTopIconsBounds(folder_icon_bounds);
119 gfx::Rect target_rect(folder_icon_bounds);
120 target_rect.ClampToCenteredSize(
121 gfx::Size(kItemIconDimension, kItemIconDimension));
125 void AppListFolderItem::Activate(int event_flags) {
126 // Folder handling is implemented by the View, so do nothing.
130 const char AppListFolderItem::kItemType[] = "FolderItem";
133 Rects AppListFolderItem::GetTopIconsBounds(
134 const gfx::Rect& folder_icon_bounds) {
135 const int delta_to_center = 1;
136 gfx::Point icon_center = folder_icon_bounds.CenterPoint();
137 Rects top_icon_bounds;
139 // Get the top left icon bounds.
140 int left_x = icon_center.x() - kItemIconDimension - delta_to_center;
141 int top_y = icon_center.y() - kItemIconDimension - delta_to_center;
142 gfx::Rect top_left(left_x, top_y, kItemIconDimension, kItemIconDimension);
143 top_icon_bounds.push_back(top_left);
145 // Get the top right icon bounds.
146 int right_x = icon_center.x() + delta_to_center;
147 gfx::Rect top_right(right_x, top_y, kItemIconDimension, kItemIconDimension);
148 top_icon_bounds.push_back(top_right);
150 // Get the bottom left icon bounds.
151 int bottom_y = icon_center.y() + delta_to_center;
152 gfx::Rect bottom_left(
153 left_x, bottom_y, kItemIconDimension, kItemIconDimension);
154 top_icon_bounds.push_back(bottom_left);
156 // Get the bottom right icon bounds.
157 gfx::Rect bottom_right(
158 right_x, bottom_y, kItemIconDimension, kItemIconDimension);
159 top_icon_bounds.push_back(bottom_right);
161 return top_icon_bounds;
164 const char* AppListFolderItem::GetItemType() const {
165 return AppListFolderItem::kItemType;
168 ui::MenuModel* AppListFolderItem::GetContextMenuModel() {
169 // TODO(stevenjb/jennyz): Implement.
173 AppListItem* AppListFolderItem::FindChildItem(const std::string& id) {
174 return item_list_->FindItem(id);
177 size_t AppListFolderItem::ChildItemCount() const {
178 return item_list_->item_count();
181 bool AppListFolderItem::CompareForTest(const AppListItem* other) const {
182 if (!AppListItem::CompareForTest(other))
184 const AppListFolderItem* other_folder =
185 static_cast<const AppListFolderItem*>(other);
186 if (other_folder->item_list()->item_count() != item_list_->item_count())
188 for (size_t i = 0; i < item_list_->item_count(); ++i) {
189 if (!item_list()->item_at(i)->CompareForTest(
190 other_folder->item_list()->item_at(i)))
196 std::string AppListFolderItem::GenerateId() {
197 return base::GenerateGUID();
200 void AppListFolderItem::ItemIconChanged() {
204 void AppListFolderItem::ItemTitleChanged() {
207 void AppListFolderItem::ItemHighlightedChanged() {
210 void AppListFolderItem::ItemIsInstallingChanged() {
213 void AppListFolderItem::ItemPercentDownloadedChanged() {
216 void AppListFolderItem::OnListItemAdded(size_t index,
218 if (index <= kNumFolderTopItems)
222 void AppListFolderItem::OnListItemRemoved(size_t index,
224 if (index <= kNumFolderTopItems)
228 void AppListFolderItem::OnListItemMoved(size_t from_index,
231 if (from_index <= kNumFolderTopItems || to_index <= kNumFolderTopItems)
235 void AppListFolderItem::UpdateTopItems() {
236 for (size_t i = 0; i < top_items_.size(); ++i)
237 top_items_[i]->RemoveObserver(this);
241 i < kNumFolderTopItems && i < item_list_->item_count(); ++i) {
242 AppListItem* item = item_list_->item_at(i);
243 item->AddObserver(this);
244 top_items_.push_back(item);
249 } // namespace app_list