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
,
42 gfx::ImageSkia
resized(
43 gfx::ImageSkiaOperations::CreateResizedImage(
44 icon
, skia::ImageOperations::RESIZE_BEST
, icon_size
));
45 canvas
->DrawImageInt(resized
, 0, 0, resized
.width(), resized
.height(),
46 x
, y
, resized
.width(), resized
.height(), true);
49 // gfx::CanvasImageSource overrides:
50 virtual void Draw(gfx::Canvas
* canvas
) OVERRIDE
{
51 // Draw folder circle.
52 gfx::Point center
= gfx::Point(size().width() / 2 , size().height() / 2);
54 paint
.setStyle(SkPaint::kFill_Style
);
55 paint
.setAntiAlias(true);
56 paint
.setColor(kFolderBubbleColor
);
57 canvas
->DrawCircle(center
, size().width() / 2, paint
);
59 if (icons_
.size() == 0)
62 // Draw top items' icons.
63 const gfx::Size item_icon_size
=
64 gfx::Size(kItemIconDimension
, kItemIconDimension
);
65 Rects top_icon_bounds
=
66 AppListFolderItem::GetTopIconsBounds(gfx::Rect(size()));
68 for (size_t i
= 0; i
< kNumFolderTopItems
&& i
< icons_
.size(); ++i
) {
69 DrawIcon(canvas
, icons_
[i
], item_icon_size
,
70 top_icon_bounds
[i
].x(), top_icon_bounds
[i
].y());
77 DISALLOW_COPY_AND_ASSIGN(FolderImageSource
);
82 AppListFolderItem::AppListFolderItem(const std::string
& id
,
83 FolderType folder_type
)
85 folder_type_(folder_type
),
86 item_list_(new AppListItemList
) {
87 item_list_
->AddObserver(this);
90 AppListFolderItem::~AppListFolderItem() {
91 for (size_t i
= 0; i
< top_items_
.size(); ++i
)
92 top_items_
[i
]->RemoveObserver(this);
93 item_list_
->RemoveObserver(this);
96 void AppListFolderItem::UpdateIcon() {
97 FolderImageSource::Icons top_icons
;
98 for (size_t i
= 0; i
< top_items_
.size(); ++i
)
99 top_icons
.push_back(top_items_
[i
]->icon());
101 const gfx::Size icon_size
= gfx::Size(kGridIconDimension
, kGridIconDimension
);
102 gfx::ImageSkia icon
= gfx::ImageSkia(
103 new FolderImageSource(top_icons
, icon_size
),
105 SetIcon(icon
, false);
108 const gfx::ImageSkia
& AppListFolderItem::GetTopIcon(size_t item_index
) {
109 DCHECK(item_index
<= top_items_
.size());
110 return top_items_
[item_index
]->icon();
113 gfx::Rect
AppListFolderItem::GetTargetIconRectInFolderForItem(
115 const gfx::Rect
& folder_icon_bounds
) {
116 for (size_t i
= 0; i
< top_items_
.size(); ++i
) {
117 if (item
->id() == top_items_
[i
]->id()) {
118 Rects rects
= AppListFolderItem::GetTopIconsBounds(folder_icon_bounds
);
123 gfx::Rect
target_rect(folder_icon_bounds
);
124 target_rect
.ClampToCenteredSize(
125 gfx::Size(kItemIconDimension
, kItemIconDimension
));
129 void AppListFolderItem::Activate(int event_flags
) {
130 // Folder handling is implemented by the View, so do nothing.
134 const char AppListFolderItem::kItemType
[] = "FolderItem";
137 Rects
AppListFolderItem::GetTopIconsBounds(
138 const gfx::Rect
& folder_icon_bounds
) {
139 const int delta_to_center
= 1;
140 gfx::Point icon_center
= folder_icon_bounds
.CenterPoint();
141 Rects top_icon_bounds
;
143 // Get the top left icon bounds.
144 int left_x
= icon_center
.x() - kItemIconDimension
- delta_to_center
;
145 int top_y
= icon_center
.y() - kItemIconDimension
- delta_to_center
;
146 gfx::Rect
top_left(left_x
, top_y
, kItemIconDimension
, kItemIconDimension
);
147 top_icon_bounds
.push_back(top_left
);
149 // Get the top right icon bounds.
150 int right_x
= icon_center
.x() + delta_to_center
;
151 gfx::Rect
top_right(right_x
, top_y
, kItemIconDimension
, kItemIconDimension
);
152 top_icon_bounds
.push_back(top_right
);
154 // Get the bottom left icon bounds.
155 int bottom_y
= icon_center
.y() + delta_to_center
;
156 gfx::Rect
bottom_left(
157 left_x
, bottom_y
, kItemIconDimension
, kItemIconDimension
);
158 top_icon_bounds
.push_back(bottom_left
);
160 // Get the bottom right icon bounds.
161 gfx::Rect
bottom_right(
162 right_x
, bottom_y
, kItemIconDimension
, kItemIconDimension
);
163 top_icon_bounds
.push_back(bottom_right
);
165 return top_icon_bounds
;
168 const char* AppListFolderItem::GetItemType() const {
169 return AppListFolderItem::kItemType
;
172 ui::MenuModel
* AppListFolderItem::GetContextMenuModel() {
173 // TODO(stevenjb/jennyz): Implement.
177 AppListItem
* AppListFolderItem::FindChildItem(const std::string
& id
) {
178 return item_list_
->FindItem(id
);
181 size_t AppListFolderItem::ChildItemCount() const {
182 return item_list_
->item_count();
185 void AppListFolderItem::OnExtensionPreferenceChanged() {
186 for (size_t i
= 0; i
< item_list_
->item_count(); ++i
)
187 item_list_
->item_at(i
)->OnExtensionPreferenceChanged();
190 bool AppListFolderItem::CompareForTest(const AppListItem
* other
) const {
191 if (!AppListItem::CompareForTest(other
))
193 const AppListFolderItem
* other_folder
=
194 static_cast<const AppListFolderItem
*>(other
);
195 if (other_folder
->item_list()->item_count() != item_list_
->item_count())
197 for (size_t i
= 0; i
< item_list_
->item_count(); ++i
) {
198 if (!item_list()->item_at(i
)->CompareForTest(
199 other_folder
->item_list()->item_at(i
)))
205 std::string
AppListFolderItem::GenerateId() {
206 return base::GenerateGUID();
209 void AppListFolderItem::ItemIconChanged() {
213 void AppListFolderItem::OnListItemAdded(size_t index
,
215 if (index
<= kNumFolderTopItems
)
219 void AppListFolderItem::OnListItemRemoved(size_t index
,
221 if (index
<= kNumFolderTopItems
)
225 void AppListFolderItem::OnListItemMoved(size_t from_index
,
228 if (from_index
<= kNumFolderTopItems
|| to_index
<= kNumFolderTopItems
)
232 void AppListFolderItem::UpdateTopItems() {
233 for (size_t i
= 0; i
< top_items_
.size(); ++i
)
234 top_items_
[i
]->RemoveObserver(this);
238 i
< kNumFolderTopItems
&& i
< item_list_
->item_count(); ++i
) {
239 AppListItem
* item
= item_list_
->item_at(i
);
240 item
->AddObserver(this);
241 top_items_
.push_back(item
);
246 } // namespace app_list