OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/folder_image.h" | 5 #include "ui/app_list/folder_image.h" |
6 | 6 |
| 7 #include <vector> |
| 8 |
7 #include "ui/app_list/app_list_constants.h" | 9 #include "ui/app_list/app_list_constants.h" |
8 #include "ui/app_list/app_list_item.h" | 10 #include "ui/app_list/app_list_item.h" |
9 #include "ui/app_list/app_list_item_list.h" | 11 #include "ui/app_list/app_list_item_list.h" |
10 #include "ui/app_list/folder_image_source.h" | |
11 #include "ui/app_list/views/contents_view.h" | 12 #include "ui/app_list/views/contents_view.h" |
12 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
| 14 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/geometry/point.h" |
13 #include "ui/gfx/geometry/rect.h" | 16 #include "ui/gfx/geometry/rect.h" |
| 17 #include "ui/gfx/geometry/size.h" |
| 18 #include "ui/gfx/image/canvas_image_source.h" |
| 19 #include "ui/gfx/image/image_skia.h" |
| 20 #include "ui/gfx/image/image_skia_operations.h" |
14 #include "ui/strings/grit/ui_strings.h" | 21 #include "ui/strings/grit/ui_strings.h" |
15 | 22 |
16 namespace app_list { | 23 namespace app_list { |
17 | 24 |
| 25 namespace { |
| 26 |
| 27 const int kItemIconDimension = 16; |
| 28 |
| 29 // Gets the size of a small app icon inside the folder icon. |
| 30 gfx::Size ItemIconSize() { |
| 31 return gfx::Size(kItemIconDimension, kItemIconDimension); |
| 32 } |
| 33 |
| 34 // Generates the folder icon with the top 4 child item icons laid in 2x2 tile. |
| 35 class FolderImageSource : public gfx::CanvasImageSource { |
| 36 public: |
| 37 typedef std::vector<gfx::ImageSkia> Icons; |
| 38 |
| 39 FolderImageSource(const Icons& icons, const gfx::Size& size); |
| 40 ~FolderImageSource() override; |
| 41 |
| 42 private: |
| 43 void DrawIcon(gfx::Canvas* canvas, |
| 44 const gfx::ImageSkia& icon, |
| 45 const gfx::Size icon_size, |
| 46 int x, |
| 47 int y); |
| 48 |
| 49 // gfx::CanvasImageSource overrides: |
| 50 void Draw(gfx::Canvas* canvas) override; |
| 51 |
| 52 Icons icons_; |
| 53 gfx::Size size_; |
| 54 |
| 55 DISALLOW_COPY_AND_ASSIGN(FolderImageSource); |
| 56 }; |
| 57 |
| 58 FolderImageSource::FolderImageSource(const Icons& icons, const gfx::Size& size) |
| 59 : gfx::CanvasImageSource(size, false), icons_(icons), size_(size) { |
| 60 DCHECK(icons.size() <= kNumFolderTopItems); |
| 61 } |
| 62 |
| 63 FolderImageSource::~FolderImageSource() { |
| 64 } |
| 65 |
| 66 void FolderImageSource::DrawIcon(gfx::Canvas* canvas, |
| 67 const gfx::ImageSkia& icon, |
| 68 const gfx::Size icon_size, |
| 69 int x, |
| 70 int y) { |
| 71 if (icon.isNull()) |
| 72 return; |
| 73 |
| 74 gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage( |
| 75 icon, skia::ImageOperations::RESIZE_BEST, icon_size)); |
| 76 canvas->DrawImageInt(resized, 0, 0, resized.width(), resized.height(), x, y, |
| 77 resized.width(), resized.height(), true); |
| 78 } |
| 79 |
| 80 void FolderImageSource::Draw(gfx::Canvas* canvas) { |
| 81 // Draw circle for folder shadow. |
| 82 gfx::PointF shadow_center(size().width() / 2, size().height() / 2); |
| 83 SkPaint paint; |
| 84 paint.setStyle(SkPaint::kFill_Style); |
| 85 paint.setAntiAlias(true); |
| 86 paint.setColor(kFolderShadowColor); |
| 87 canvas->sk_canvas()->drawCircle(shadow_center.x(), shadow_center.y(), |
| 88 kFolderShadowRadius, paint); |
| 89 // Draw circle for folder bubble. |
| 90 gfx::PointF bubble_center(shadow_center); |
| 91 bubble_center.Offset(0, -kFolderShadowOffsetY); |
| 92 paint.setColor(kFolderBubbleColor); |
| 93 canvas->sk_canvas()->drawCircle(bubble_center.x(), bubble_center.y(), |
| 94 kFolderBubbleRadius, paint); |
| 95 |
| 96 if (icons_.size() == 0) |
| 97 return; |
| 98 |
| 99 // Draw top items' icons. |
| 100 const gfx::Size item_icon_size(ItemIconSize()); |
| 101 std::vector<gfx::Rect> top_icon_bounds = |
| 102 FolderImage::GetTopIconsBounds(gfx::Rect(size())); |
| 103 |
| 104 for (size_t i = 0; i < kNumFolderTopItems && i < icons_.size(); ++i) { |
| 105 DrawIcon(canvas, icons_[i], item_icon_size, top_icon_bounds[i].x(), |
| 106 top_icon_bounds[i].y()); |
| 107 } |
| 108 } |
| 109 |
| 110 } // namespace |
| 111 |
18 FolderImage::FolderImage(AppListItemList* item_list) : item_list_(item_list) { | 112 FolderImage::FolderImage(AppListItemList* item_list) : item_list_(item_list) { |
19 item_list_->AddObserver(this); | 113 item_list_->AddObserver(this); |
20 } | 114 } |
21 | 115 |
22 FolderImage::~FolderImage() { | 116 FolderImage::~FolderImage() { |
23 for (auto* item : top_items_) | 117 for (auto* item : top_items_) |
24 item->RemoveObserver(this); | 118 item->RemoveObserver(this); |
25 item_list_->RemoveObserver(this); | 119 item_list_->RemoveObserver(this); |
26 } | 120 } |
27 | 121 |
28 void FolderImage::UpdateIcon() { | 122 void FolderImage::UpdateIcon() { |
29 for (auto* item : top_items_) | 123 for (auto* item : top_items_) |
30 item->RemoveObserver(this); | 124 item->RemoveObserver(this); |
31 top_items_.clear(); | 125 top_items_.clear(); |
32 | 126 |
33 for (size_t i = 0; i < kNumFolderTopItems && i < item_list_->item_count(); | 127 for (size_t i = 0; i < kNumFolderTopItems && i < item_list_->item_count(); |
34 ++i) { | 128 ++i) { |
35 AppListItem* item = item_list_->item_at(i); | 129 AppListItem* item = item_list_->item_at(i); |
36 item->AddObserver(this); | 130 item->AddObserver(this); |
37 top_items_.push_back(item); | 131 top_items_.push_back(item); |
38 } | 132 } |
39 RedrawIconAndNotify(); | 133 RedrawIconAndNotify(); |
40 } | 134 } |
41 | 135 |
42 const gfx::ImageSkia& FolderImage::GetTopIcon(size_t item_index) { | 136 const gfx::ImageSkia& FolderImage::GetTopIcon(size_t item_index) { |
43 CHECK_LT(item_index, top_items_.size()); | 137 CHECK_LT(item_index, top_items_.size()); |
44 return top_items_[item_index]->icon(); | 138 return top_items_[item_index]->icon(); |
45 } | 139 } |
46 | 140 |
| 141 // static |
| 142 std::vector<gfx::Rect> FolderImage::GetTopIconsBounds( |
| 143 const gfx::Rect& folder_icon_bounds) { |
| 144 const int delta_to_center = 1; |
| 145 gfx::Point icon_center = folder_icon_bounds.CenterPoint(); |
| 146 std::vector<gfx::Rect> top_icon_bounds; |
| 147 |
| 148 // Get the top left icon bounds. |
| 149 int left_x = icon_center.x() - kItemIconDimension - delta_to_center; |
| 150 int top_y = icon_center.y() - kItemIconDimension - delta_to_center; |
| 151 gfx::Rect top_left(left_x, top_y, kItemIconDimension, kItemIconDimension); |
| 152 top_icon_bounds.push_back(top_left); |
| 153 |
| 154 // Get the top right icon bounds. |
| 155 int right_x = icon_center.x() + delta_to_center; |
| 156 gfx::Rect top_right(right_x, top_y, kItemIconDimension, kItemIconDimension); |
| 157 top_icon_bounds.push_back(top_right); |
| 158 |
| 159 // Get the bottom left icon bounds. |
| 160 int bottom_y = icon_center.y() + delta_to_center; |
| 161 gfx::Rect bottom_left(left_x, bottom_y, kItemIconDimension, |
| 162 kItemIconDimension); |
| 163 top_icon_bounds.push_back(bottom_left); |
| 164 |
| 165 // Get the bottom right icon bounds. |
| 166 gfx::Rect bottom_right(right_x, bottom_y, kItemIconDimension, |
| 167 kItemIconDimension); |
| 168 top_icon_bounds.push_back(bottom_right); |
| 169 |
| 170 return top_icon_bounds; |
| 171 } |
| 172 |
47 gfx::Rect FolderImage::GetTargetIconRectInFolderForItem( | 173 gfx::Rect FolderImage::GetTargetIconRectInFolderForItem( |
48 AppListItem* item, | 174 AppListItem* item, |
49 const gfx::Rect& folder_icon_bounds) { | 175 const gfx::Rect& folder_icon_bounds) { |
50 for (size_t i = 0; i < top_items_.size(); ++i) { | 176 for (size_t i = 0; i < top_items_.size(); ++i) { |
51 if (item->id() == top_items_[i]->id()) { | 177 if (item->id() == top_items_[i]->id()) { |
52 std::vector<gfx::Rect> rects = | 178 std::vector<gfx::Rect> rects = GetTopIconsBounds(folder_icon_bounds); |
53 FolderImageSource::GetTopIconsBounds(folder_icon_bounds); | |
54 return rects[i]; | 179 return rects[i]; |
55 } | 180 } |
56 } | 181 } |
57 | 182 |
58 gfx::Rect target_rect(folder_icon_bounds); | 183 gfx::Rect target_rect(folder_icon_bounds); |
59 target_rect.ClampToCenteredSize(FolderImageSource::ItemIconSize()); | 184 target_rect.ClampToCenteredSize(ItemIconSize()); |
60 return target_rect; | 185 return target_rect; |
61 } | 186 } |
62 | 187 |
63 void FolderImage::AddObserver(FolderImageObserver* observer) { | 188 void FolderImage::AddObserver(FolderImageObserver* observer) { |
64 observers_.AddObserver(observer); | 189 observers_.AddObserver(observer); |
65 } | 190 } |
66 | 191 |
67 void FolderImage::RemoveObserver(FolderImageObserver* observer) { | 192 void FolderImage::RemoveObserver(FolderImageObserver* observer) { |
68 observers_.RemoveObserver(observer); | 193 observers_.RemoveObserver(observer); |
69 } | 194 } |
(...skipping 29 matching lines...) Expand all Loading... |
99 top_icons.push_back(item->icon()); | 224 top_icons.push_back(item->icon()); |
100 | 225 |
101 const gfx::Size icon_size = gfx::Size(kGridIconDimension, kGridIconDimension); | 226 const gfx::Size icon_size = gfx::Size(kGridIconDimension, kGridIconDimension); |
102 icon_ = | 227 icon_ = |
103 gfx::ImageSkia(new FolderImageSource(top_icons, icon_size), icon_size); | 228 gfx::ImageSkia(new FolderImageSource(top_icons, icon_size), icon_size); |
104 | 229 |
105 FOR_EACH_OBSERVER(FolderImageObserver, observers_, OnFolderImageUpdated()); | 230 FOR_EACH_OBSERVER(FolderImageObserver, observers_, OnFolderImageUpdated()); |
106 } | 231 } |
107 | 232 |
108 } // namespace app_list | 233 } // namespace app_list |
OLD | NEW |