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