Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / app_list_folder_item.cc
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.
4
5 #include "ui/app_list/app_list_folder_item.h"
6
7 #include "base/guid.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"
13
14 namespace app_list {
15
16 namespace {
17
18 const int kItemIconDimension = 16;
19
20 // Generates the folder icon with the top 4 child item icons laid in 2x2 tile.
21 class FolderImageSource : public gfx::CanvasImageSource {
22  public:
23   typedef std::vector<gfx::ImageSkia> Icons;
24
25   FolderImageSource(const Icons& icons, const gfx::Size& size)
26       : gfx::CanvasImageSource(size, false),
27         icons_(icons),
28         size_(size) {
29     DCHECK(icons.size() <= kNumFolderTopItems);
30   }
31
32   virtual ~FolderImageSource() {}
33
34  private:
35   void DrawIcon(gfx::Canvas* canvas,
36                 const gfx::ImageSkia& icon,
37                 const gfx::Size icon_size,
38                 int x, int y) {
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);
44   }
45
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);
50     SkPaint paint;
51     paint.setStyle(SkPaint::kFill_Style);
52     paint.setAntiAlias(true);
53     paint.setColor(kFolderBubbleColor);
54     canvas->DrawCircle(center, size().width() / 2, paint);
55
56     if (icons_.size() == 0)
57       return;
58
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()));
64
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());
68     }
69   }
70
71   Icons icons_;
72   gfx::Size size_;
73
74   DISALLOW_COPY_AND_ASSIGN(FolderImageSource);
75 };
76
77 }  // namespace
78
79 AppListFolderItem::AppListFolderItem(const std::string& id)
80     : AppListItem(id),
81       item_list_(new AppListItemList) {
82   item_list_->AddObserver(this);
83 }
84
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);
89 }
90
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());
95
96   const gfx::Size icon_size =
97       gfx::Size(kPreferredIconDimension, kPreferredIconDimension);
98   gfx::ImageSkia icon = gfx::ImageSkia(
99       new FolderImageSource(top_icons, icon_size),
100       icon_size);
101   SetIcon(icon, false);
102 }
103
104 const gfx::ImageSkia& AppListFolderItem::GetTopIcon(size_t item_index) {
105   DCHECK(item_index <= top_items_.size());
106   return top_items_[item_index]->icon();
107 }
108
109 gfx::Rect AppListFolderItem::GetTargetIconRectInFolderForItem(
110     AppListItem* item,
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);
115       return rects[i];
116     }
117   }
118
119   gfx::Rect target_rect(folder_icon_bounds);
120   target_rect.ClampToCenteredSize(
121       gfx::Size(kItemIconDimension, kItemIconDimension));
122   return target_rect;
123 }
124
125 void AppListFolderItem::Activate(int event_flags) {
126   // Folder handling is implemented by the View, so do nothing.
127 }
128
129 // static
130 const char AppListFolderItem::kItemType[] = "FolderItem";
131
132 // static
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;
138
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);
144
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);
149
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);
155
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);
160
161   return top_icon_bounds;
162 }
163
164 const char* AppListFolderItem::GetItemType() const {
165   return AppListFolderItem::kItemType;
166 }
167
168 ui::MenuModel* AppListFolderItem::GetContextMenuModel() {
169   // TODO(stevenjb/jennyz): Implement.
170   return NULL;
171 }
172
173 AppListItem* AppListFolderItem::FindChildItem(const std::string& id) {
174   return item_list_->FindItem(id);
175 }
176
177 size_t AppListFolderItem::ChildItemCount() const {
178   return item_list_->item_count();
179 }
180
181 bool AppListFolderItem::CompareForTest(const AppListItem* other) const {
182   if (!AppListItem::CompareForTest(other))
183     return false;
184   const AppListFolderItem* other_folder =
185       static_cast<const AppListFolderItem*>(other);
186   if (other_folder->item_list()->item_count() != item_list_->item_count())
187     return false;
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)))
191       return false;
192   }
193   return true;
194 }
195
196 std::string AppListFolderItem::GenerateId() {
197   return base::GenerateGUID();
198 }
199
200 void AppListFolderItem::ItemIconChanged() {
201   UpdateIcon();
202 }
203
204 void AppListFolderItem::ItemTitleChanged() {
205 }
206
207 void AppListFolderItem::ItemHighlightedChanged() {
208 }
209
210 void AppListFolderItem::ItemIsInstallingChanged() {
211 }
212
213 void AppListFolderItem::ItemPercentDownloadedChanged() {
214 }
215
216 void AppListFolderItem::OnListItemAdded(size_t index,
217                                         AppListItem* item) {
218   if (index <= kNumFolderTopItems)
219     UpdateTopItems();
220 }
221
222 void AppListFolderItem::OnListItemRemoved(size_t index,
223                                           AppListItem* item) {
224   if (index <= kNumFolderTopItems)
225     UpdateTopItems();
226 }
227
228 void AppListFolderItem::OnListItemMoved(size_t from_index,
229                                         size_t to_index,
230                                         AppListItem* item) {
231   if (from_index <= kNumFolderTopItems || to_index <= kNumFolderTopItems)
232     UpdateTopItems();
233 }
234
235 void AppListFolderItem::UpdateTopItems() {
236   for (size_t i = 0; i < top_items_.size(); ++i)
237     top_items_[i]->RemoveObserver(this);
238   top_items_.clear();
239
240   for (size_t i = 0;
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);
245   }
246   UpdateIcon();
247 }
248
249 }  // namespace app_list