OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/app_list_folder_item.h" | 5 #include "ui/app_list/app_list_folder_item.h" |
6 | 6 |
7 #include "ui/app_list/app_list_constants.h" | 7 #include "ui/app_list/app_list_constants.h" |
8 #include "ui/app_list/app_list_item_list.h" | 8 #include "ui/app_list/app_list_item_list.h" |
9 #include "ui/gfx/canvas.h" | 9 #include "ui/gfx/canvas.h" |
10 #include "ui/gfx/image/canvas_image_source.h" | 10 #include "ui/gfx/image/canvas_image_source.h" |
11 #include "ui/gfx/image/image_skia_operations.h" | 11 #include "ui/gfx/image/image_skia_operations.h" |
12 | 12 |
13 namespace app_list { | 13 namespace app_list { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 const int kIconDimension = 48; | |
18 const size_t kNumTopApps = 4; | |
19 const int kItemIconDimension = 16; | 17 const int kItemIconDimension = 16; |
20 | 18 |
21 // Generates the folder icon with the top 4 child item icons laid in 2x2 tile. | 19 // Generates the folder icon with the top 4 child item icons laid in 2x2 tile. |
22 class FolderImageSource : public gfx::CanvasImageSource { | 20 class FolderImageSource : public gfx::CanvasImageSource { |
23 public: | 21 public: |
24 typedef std::vector<gfx::ImageSkia> Icons; | 22 typedef std::vector<gfx::ImageSkia> Icons; |
25 | 23 |
26 FolderImageSource(const Icons& icons, const gfx::Size& size) | 24 FolderImageSource(const Icons& icons, const gfx::Size& size) |
27 : gfx::CanvasImageSource(size, false), | 25 : gfx::CanvasImageSource(size, false), |
28 icons_(icons), | 26 icons_(icons), |
29 size_(size) { | 27 size_(size) { |
30 DCHECK(icons.size() <= kNumTopApps); | 28 DCHECK(icons.size() <= kNumFolderTopItems); |
31 } | 29 } |
32 | 30 |
33 virtual ~FolderImageSource() {} | 31 virtual ~FolderImageSource() {} |
34 | 32 |
35 private: | 33 private: |
36 void DrawIcon(gfx::Canvas* canvas, | 34 void DrawIcon(gfx::Canvas* canvas, |
37 const gfx::ImageSkia& icon, | 35 const gfx::ImageSkia& icon, |
38 const gfx::Size icon_size, | 36 const gfx::Size icon_size, |
39 int x, int y) { | 37 int x, int y) { |
40 gfx::ImageSkia resized( | 38 gfx::ImageSkia resized( |
41 gfx::ImageSkiaOperations::CreateResizedImage( | 39 gfx::ImageSkiaOperations::CreateResizedImage( |
42 icon, skia::ImageOperations::RESIZE_BEST, icon_size)); | 40 icon, skia::ImageOperations::RESIZE_BEST, icon_size)); |
43 canvas->DrawImageInt(resized, 0, 0, resized.width(), resized.height(), | 41 canvas->DrawImageInt(resized, 0, 0, resized.width(), resized.height(), |
44 x, y, resized.width(), resized.height(), true); | 42 x, y, resized.width(), resized.height(), true); |
45 } | 43 } |
46 | 44 |
47 // gfx::CanvasImageSource overrides: | 45 // gfx::CanvasImageSource overrides: |
48 virtual void Draw(gfx::Canvas* canvas) OVERRIDE { | 46 virtual void Draw(gfx::Canvas* canvas) OVERRIDE { |
49 // Draw folder circle. | 47 // Draw folder circle. |
50 gfx::Point center = gfx::Point(size().width() / 2 , size().height() / 2); | 48 gfx::Point center = gfx::Point(size().width() / 2 , size().height() / 2); |
51 SkPaint paint; | 49 SkPaint paint; |
52 paint.setStyle(SkPaint::kFill_Style); | 50 paint.setStyle(SkPaint::kFill_Style); |
53 paint.setAntiAlias(true); | 51 paint.setAntiAlias(true); |
54 paint.setColor(kFolderBubbleColor); | 52 paint.setColor(kFolderBubbleColor); |
55 canvas->DrawCircle(center, size().width() / 2, paint); | 53 canvas->DrawCircle(center, size().width() / 2, paint); |
56 | 54 |
57 if (icons_.size() == 0) | 55 if (icons_.size() == 0) |
58 return; | 56 return; |
59 | 57 |
60 // Tiled icon coordinates. | 58 // Draw top items' icons. |
61 const int delta_to_center = 1; | |
62 const gfx::Size item_icon_size = | 59 const gfx::Size item_icon_size = |
63 gfx::Size(kItemIconDimension, kItemIconDimension); | 60 gfx::Size(kItemIconDimension, kItemIconDimension); |
64 int left_x = center.x() - item_icon_size.width() - delta_to_center; | 61 Rects top_icon_bounds = |
65 int top_y = center.y() - item_icon_size.height() - delta_to_center; | 62 AppListFolderItem::GetTopIconsBounds(gfx::Rect(size())); |
66 int right_x = center.x() + delta_to_center; | |
67 int bottom_y = center.y() + delta_to_center; | |
68 | 63 |
69 // top left icon | 64 for (size_t i= 0; i < kNumFolderTopItems && i < icons_.size(); ++i) { |
70 size_t i = 0; | 65 DrawIcon(canvas, icons_[i], item_icon_size, |
71 DrawIcon(canvas, icons_[i++], item_icon_size, left_x, top_y); | 66 top_icon_bounds[i].x(), top_icon_bounds[i].y()); |
72 | 67 } |
73 // top right icon | |
74 if (i < icons_.size()) | |
75 DrawIcon(canvas, icons_[i++], item_icon_size, right_x, top_y); | |
76 | |
77 // left bottm icon | |
78 if (i < icons_.size()) | |
79 DrawIcon(canvas, icons_[i++], item_icon_size, left_x, bottom_y); | |
80 | |
81 // right bottom icon | |
82 if (i < icons_.size()) | |
83 DrawIcon(canvas, icons_[i], item_icon_size, right_x, bottom_y); | |
84 } | 68 } |
85 | 69 |
86 Icons icons_; | 70 Icons icons_; |
87 gfx::Size size_; | 71 gfx::Size size_; |
88 | 72 |
89 DISALLOW_COPY_AND_ASSIGN(FolderImageSource); | 73 DISALLOW_COPY_AND_ASSIGN(FolderImageSource); |
90 }; | 74 }; |
91 | 75 |
92 } // namespace | 76 } // namespace |
93 | 77 |
94 AppListFolderItem::AppListFolderItem(const std::string& id) | 78 AppListFolderItem::AppListFolderItem(const std::string& id) |
95 : AppListItem(id), | 79 : AppListItem(id), |
96 item_list_(new AppListItemList) { | 80 item_list_(new AppListItemList) { |
97 item_list_->AddObserver(this); | 81 item_list_->AddObserver(this); |
98 } | 82 } |
99 | 83 |
100 AppListFolderItem::~AppListFolderItem() { | 84 AppListFolderItem::~AppListFolderItem() { |
101 for (size_t i = 0; i < top_items_.size(); ++i) | 85 for (size_t i = 0; i < top_items_.size(); ++i) |
102 top_items_[i]->RemoveObserver(this); | 86 top_items_[i]->RemoveObserver(this); |
103 item_list_->RemoveObserver(this); | 87 item_list_->RemoveObserver(this); |
104 } | 88 } |
105 | 89 |
106 void AppListFolderItem::UpdateIcon() { | 90 void AppListFolderItem::UpdateIcon() { |
107 FolderImageSource::Icons top_icons; | 91 FolderImageSource::Icons top_icons; |
108 for (size_t i = 0; i < top_items_.size(); ++i) | 92 for (size_t i = 0; i < top_items_.size(); ++i) |
109 top_icons.push_back(top_items_[i]->icon()); | 93 top_icons.push_back(top_items_[i]->icon()); |
110 | 94 |
111 const gfx::Size icon_size = gfx::Size(kIconDimension, kIconDimension); | 95 const gfx::Size icon_size = |
| 96 gfx::Size(kPreferredIconDimension, kPreferredIconDimension); |
112 gfx::ImageSkia icon = gfx::ImageSkia( | 97 gfx::ImageSkia icon = gfx::ImageSkia( |
113 new FolderImageSource(top_icons, icon_size), | 98 new FolderImageSource(top_icons, icon_size), |
114 icon_size); | 99 icon_size); |
115 SetIcon(icon, false); | 100 SetIcon(icon, false); |
116 } | 101 } |
117 | 102 |
| 103 const gfx::ImageSkia& AppListFolderItem::GetTopIcon(size_t item_index) { |
| 104 DCHECK(item_index <= top_items_.size()); |
| 105 return top_items_[item_index]->icon(); |
| 106 } |
| 107 |
118 void AppListFolderItem::Activate(int event_flags) { | 108 void AppListFolderItem::Activate(int event_flags) { |
119 // Folder handling is implemented by the View, so do nothing. | 109 // Folder handling is implemented by the View, so do nothing. |
120 } | 110 } |
121 | 111 |
122 // static | 112 // static |
123 const char AppListFolderItem::kAppType[] = "FolderItem"; | 113 const char AppListFolderItem::kAppType[] = "FolderItem"; |
124 | 114 |
| 115 // static |
| 116 Rects AppListFolderItem::GetTopIconsBounds( |
| 117 const gfx::Rect& folder_icon_bounds) { |
| 118 const int delta_to_center = 1; |
| 119 gfx::Point icon_center = folder_icon_bounds.CenterPoint(); |
| 120 Rects top_icon_bounds; |
| 121 |
| 122 // Get the top left icon bounds. |
| 123 int left_x = icon_center.x() - kItemIconDimension - delta_to_center; |
| 124 int top_y = icon_center.y() - kItemIconDimension - delta_to_center; |
| 125 gfx::Rect top_left(left_x, top_y, kItemIconDimension, kItemIconDimension); |
| 126 top_icon_bounds.push_back(top_left); |
| 127 |
| 128 // Get the top right icon bounds. |
| 129 int right_x = icon_center.x() + delta_to_center; |
| 130 gfx::Rect top_right(right_x, top_y, kItemIconDimension, kItemIconDimension); |
| 131 top_icon_bounds.push_back(top_right); |
| 132 |
| 133 // Get the bottom left icon bounds. |
| 134 int bottom_y = icon_center.y() + delta_to_center; |
| 135 gfx::Rect bottom_left( |
| 136 left_x, bottom_y, kItemIconDimension, kItemIconDimension); |
| 137 top_icon_bounds.push_back(bottom_left); |
| 138 |
| 139 // Get the bottom right icon bounds. |
| 140 gfx::Rect bottom_right( |
| 141 right_x, bottom_y, kItemIconDimension, kItemIconDimension); |
| 142 top_icon_bounds.push_back(bottom_right); |
| 143 |
| 144 return top_icon_bounds; |
| 145 } |
| 146 |
125 const char* AppListFolderItem::GetAppType() const { | 147 const char* AppListFolderItem::GetAppType() const { |
126 return AppListFolderItem::kAppType; | 148 return AppListFolderItem::kAppType; |
127 } | 149 } |
128 | 150 |
129 ui::MenuModel* AppListFolderItem::GetContextMenuModel() { | 151 ui::MenuModel* AppListFolderItem::GetContextMenuModel() { |
130 // TODO(stevenjb/jennyz): Implement. | 152 // TODO(stevenjb/jennyz): Implement. |
131 return NULL; | 153 return NULL; |
132 } | 154 } |
133 | 155 |
134 void AppListFolderItem::ItemIconChanged() { | 156 void AppListFolderItem::ItemIconChanged() { |
135 UpdateIcon(); | 157 UpdateIcon(); |
136 } | 158 } |
137 | 159 |
138 void AppListFolderItem::ItemTitleChanged() { | 160 void AppListFolderItem::ItemTitleChanged() { |
139 } | 161 } |
140 | 162 |
141 void AppListFolderItem::ItemHighlightedChanged() { | 163 void AppListFolderItem::ItemHighlightedChanged() { |
142 } | 164 } |
143 | 165 |
144 void AppListFolderItem::ItemIsInstallingChanged() { | 166 void AppListFolderItem::ItemIsInstallingChanged() { |
145 } | 167 } |
146 | 168 |
147 void AppListFolderItem::ItemPercentDownloadedChanged() { | 169 void AppListFolderItem::ItemPercentDownloadedChanged() { |
148 } | 170 } |
149 | 171 |
150 void AppListFolderItem::OnListItemAdded(size_t index, | 172 void AppListFolderItem::OnListItemAdded(size_t index, |
151 AppListItem* item) { | 173 AppListItem* item) { |
152 if (index <= kNumTopApps) | 174 if (index <= kNumFolderTopItems) |
153 UpdateTopItems(); | 175 UpdateTopItems(); |
154 } | 176 } |
155 | 177 |
156 void AppListFolderItem::OnListItemRemoved(size_t index, | 178 void AppListFolderItem::OnListItemRemoved(size_t index, |
157 AppListItem* item) { | 179 AppListItem* item) { |
158 if (index <= kNumTopApps) | 180 if (index <= kNumFolderTopItems) |
159 UpdateTopItems(); | 181 UpdateTopItems(); |
160 } | 182 } |
161 | 183 |
162 void AppListFolderItem::OnListItemMoved(size_t from_index, | 184 void AppListFolderItem::OnListItemMoved(size_t from_index, |
163 size_t to_index, | 185 size_t to_index, |
164 AppListItem* item) { | 186 AppListItem* item) { |
165 if (from_index <= kNumTopApps || to_index <= kNumTopApps) | 187 if (from_index <= kNumFolderTopItems || to_index <= kNumFolderTopItems) |
166 UpdateTopItems(); | 188 UpdateTopItems(); |
167 } | 189 } |
168 | 190 |
169 void AppListFolderItem::UpdateTopItems() { | 191 void AppListFolderItem::UpdateTopItems() { |
170 for (size_t i = 0; i < top_items_.size(); ++i) | 192 for (size_t i = 0; i < top_items_.size(); ++i) |
171 top_items_[i]->RemoveObserver(this); | 193 top_items_[i]->RemoveObserver(this); |
172 top_items_.clear(); | 194 top_items_.clear(); |
173 | 195 |
174 for (size_t i = 0; | 196 for (size_t i = 0; |
175 i < kNumTopApps && i < item_list_->item_count(); ++i) { | 197 i < kNumFolderTopItems && i < item_list_->item_count(); ++i) { |
176 AppListItem* item = item_list_->item_at(i); | 198 AppListItem* item = item_list_->item_at(i); |
177 item->AddObserver(this); | 199 item->AddObserver(this); |
178 top_items_.push_back(item); | 200 top_items_.push_back(item); |
179 } | 201 } |
180 UpdateIcon(); | 202 UpdateIcon(); |
181 } | 203 } |
182 | 204 |
183 } // namespace app_list | 205 } // namespace app_list |
OLD | NEW |