Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / views / app_list_item_view.cc
index 667a018..ba5f4ad 100644 (file)
@@ -9,12 +9,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "ui/accessibility/ax_view_state.h"
 #include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/app_list_item.h"
-#include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/apps_grid_view.h"
 #include "ui/app_list/views/cached_label.h"
 #include "ui/app_list/views/progress_bar_view.h"
 #include "ui/base/dragdrop/drag_utils.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/point.h"
+#include "ui/gfx/shadow_value.h"
 #include "ui/gfx/transform_util.h"
+#include "ui/strings/grit/ui_strings.h"
+#include "ui/views/background.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
-#include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/drag_controller.h"
 
@@ -49,6 +52,29 @@ const float kDraggingIconScale = 1.5f;
 // Delay in milliseconds of when the dragging UI should be shown for mouse drag.
 const int kMouseDragUIDelayInMs = 200;
 
+const gfx::ShadowValues& GetIconShadows() {
+  CR_DEFINE_STATIC_LOCAL(
+      const gfx::ShadowValues,
+      icon_shadows,
+      (1,
+       gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0))));
+  return icon_shadows;
+}
+
+gfx::FontList GetFontList() {
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  const gfx::FontList& font_list = rb.GetFontList(kItemTextFontStyle);
+// The font is different on each platform. The font size is adjusted on some
+// platforms to keep a consistent look.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  // Reducing the font size by 2 makes it the same as the Windows font size.
+  const int kFontSizeDelta = -2;
+  return font_list.DeriveWithSizeDelta(kFontSizeDelta);
+#else
+  return font_list;
+#endif
+}
+
 }  // namespace
 
 // static
@@ -57,37 +83,39 @@ const char AppListItemView::kViewClassName[] = "ui/app_list/AppListItemView";
 AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
                                  AppListItem* item)
     : CustomButton(apps_grid_view),
-      item_(item),
+      is_folder_(item->GetItemType() == AppListFolderItem::kItemType),
+      is_in_folder_(item->IsInFolder()),
+      item_weak_(item),
       apps_grid_view_(apps_grid_view),
       icon_(new views::ImageView),
       title_(new CachedLabel),
       progress_bar_(new ProgressBarView),
       ui_state_(UI_STATE_NORMAL),
-      touch_dragging_(false) {
+      touch_dragging_(false),
+      is_installing_(false),
+      is_highlighted_(false) {
   icon_->set_interactive(false);
 
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   title_->SetBackgroundColor(0);
   title_->SetAutoColorReadabilityEnabled(false);
   title_->SetEnabledColor(kGridTitleColor);
-  title_->SetFontList(rb.GetFontList(kItemTextFontStyle));
+
+  static const gfx::FontList font_list = GetFontList();
+  title_->SetFontList(font_list);
   title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  title_->SetVisible(!item_->is_installing());
   title_->Invalidate();
-
-  const gfx::ShadowValue kIconShadows[] = {
-    gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0)),
-  };
-  icon_shadows_.assign(kIconShadows, kIconShadows + arraysize(kIconShadows));
+  SetTitleSubpixelAA();
 
   AddChildView(icon_);
   AddChildView(title_);
   AddChildView(progress_bar_);
 
-  ItemIconChanged();
-  ItemNameChanged();
-  ItemIsInstallingChanged();
-  item_->AddObserver(this);
+  SetIcon(item->icon(), item->has_shadow());
+  SetItemName(base::UTF8ToUTF16(item->GetDisplayName()),
+              base::UTF8ToUTF16(item->name()));
+  SetItemIsInstalling(item->is_installing());
+  SetItemIsHighlighted(item->highlighted());
+  item->AddObserver(this);
 
   set_context_menu_controller(this);
   set_request_focus_on_press(false);
@@ -96,35 +124,24 @@ AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
 }
 
 AppListItemView::~AppListItemView() {
-  item_->RemoveObserver(this);
+  if (item_weak_)
+    item_weak_->RemoveObserver(this);
 }
 
-void AppListItemView::SetIconSize(const gfx::Size& size) {
-  if (icon_size_ == size)
-    return;
-
-  icon_size_ = size;
-  UpdateIcon();
-}
-
-void AppListItemView::UpdateIcon() {
-  // Skip if |icon_size_| has not been determined.
-  if (icon_size_.IsEmpty())
-    return;
-
-  gfx::ImageSkia icon = item_->icon();
+void AppListItemView::SetIcon(const gfx::ImageSkia& icon, bool has_shadow) {
   // Clear icon and bail out if item icon is empty.
   if (icon.isNull()) {
     icon_->SetImage(NULL);
     return;
   }
 
-  gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage(icon,
-      skia::ImageOperations::RESIZE_BEST, icon_size_));
-  if (item_->has_shadow()) {
-    gfx::ImageSkia shadow(
-        gfx::ImageSkiaOperations::CreateImageWithDropShadow(resized,
-                                                            icon_shadows_));
+  gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage(
+      icon,
+      skia::ImageOperations::RESIZE_BEST,
+      gfx::Size(kGridIconDimension, kGridIconDimension)));
+  if (has_shadow) {
+    gfx::ImageSkia shadow(gfx::ImageSkiaOperations::CreateImageWithDropShadow(
+        resized, GetIconShadows()));
     icon_->SetImage(shadow);
     return;
   }
@@ -132,23 +149,16 @@ void AppListItemView::UpdateIcon() {
   icon_->SetImage(resized);
 }
 
-void AppListItemView::UpdateTooltip() {
-  std::string display_name = item_->GetDisplayName();
-  title_->SetTooltipText(display_name == item_->name() ? base::string16()
-                         : base::UTF8ToUTF16(item_->name()));
-}
-
 void AppListItemView::SetUIState(UIState state) {
   if (ui_state_ == state)
     return;
 
   ui_state_ = state;
 
-#if defined(USE_AURA)
   switch (ui_state_) {
     case UI_STATE_NORMAL:
-      title_->SetVisible(!item_->is_installing());
-      progress_bar_->SetVisible(item_->is_installing());
+      title_->SetVisible(!is_installing_);
+      progress_bar_->SetVisible(is_installing_);
       break;
     case UI_STATE_DRAGGING:
       title_->SetVisible(false);
@@ -173,10 +183,9 @@ void AppListItemView::SetUIState(UIState state) {
     case UI_STATE_DROPPING_IN_FOLDER:
       break;
   }
+#endif  // !OS_WIN
 
   SchedulePaint();
-#endif  // !OS_WIN
-#endif  // USE_AURA
 }
 
 void AppListItemView::SetTouchDragging(bool touch_dragging) {
@@ -192,6 +201,31 @@ void AppListItemView::OnMouseDragTimer() {
   SetUIState(UI_STATE_DRAGGING);
 }
 
+void AppListItemView::SetTitleSubpixelAA() {
+  // TODO(tapted): Enable AA for folders as well, taking care to play nice with
+  // the folder bubble animation.
+  bool enable_aa = !is_in_folder_ && ui_state_ == UI_STATE_NORMAL &&
+                   !is_highlighted_ && !apps_grid_view_->IsSelectedView(this) &&
+                   !apps_grid_view_->IsAnimatingView(this);
+
+  bool currently_enabled = title_->background() != NULL;
+  if (currently_enabled == enable_aa)
+    return;
+
+  if (enable_aa) {
+    title_->SetBackgroundColor(app_list::kLabelBackgroundColor);
+    title_->set_background(views::Background::CreateSolidBackground(
+        app_list::kLabelBackgroundColor));
+  } else {
+    // In other cases, keep the background transparent to ensure correct
+    // interactions with animations. This will temporarily disable subpixel AA.
+    title_->SetBackgroundColor(0);
+    title_->set_background(NULL);
+  }
+  title_->Invalidate();
+  title_->SchedulePaint();
+}
+
 void AppListItemView::Prerender() {
   title_->PaintToBackingImage();
 }
@@ -222,39 +256,43 @@ void AppListItemView::SetAsAttemptedFolderTarget(bool is_target_folder) {
     SetUIState(UI_STATE_NORMAL);
 }
 
-void AppListItemView::ItemIconChanged() {
-  UpdateIcon();
-}
-
-void AppListItemView::ItemNameChanged() {
-  title_->SetText(base::UTF8ToUTF16(item_->GetDisplayName()));
+void AppListItemView::SetItemName(const base::string16& display_name,
+                                  const base::string16& full_name) {
+  title_->SetText(display_name);
   title_->Invalidate();
-  UpdateTooltip();
+
+  title_->SetTooltipText(display_name == full_name ? base::string16()
+                                                   : full_name);
+
   // Use full name for accessibility.
-  SetAccessibleName(base::UTF8ToUTF16(item_->name()));
+  SetAccessibleName(
+      is_folder_ ? l10n_util::GetStringFUTF16(
+                       IDS_APP_LIST_FOLDER_BUTTON_ACCESSIBILE_NAME, full_name)
+                 : full_name);
   Layout();
 }
 
-void AppListItemView::ItemHighlightedChanged() {
-  apps_grid_view_->EnsureViewVisible(this);
+void AppListItemView::SetItemIsHighlighted(bool is_highlighted) {
+  is_highlighted_ = is_highlighted;
   SchedulePaint();
 }
 
-void AppListItemView::ItemIsInstallingChanged() {
-  if (item_->is_installing())
-    apps_grid_view_->EnsureViewVisible(this);
-  title_->SetVisible(!item_->is_installing());
-  progress_bar_->SetVisible(item_->is_installing());
+void AppListItemView::SetItemIsInstalling(bool is_installing) {
+  is_installing_ = is_installing;
+  if (ui_state_ == UI_STATE_NORMAL) {
+    title_->SetVisible(!is_installing);
+    progress_bar_->SetVisible(is_installing);
+  }
   SchedulePaint();
 }
 
-void AppListItemView::ItemPercentDownloadedChanged() {
+void AppListItemView::SetItemPercentDownloaded(int percent_downloaded) {
   // A percent_downloaded() of -1 can mean it's not known how much percent is
   // completed, or the download hasn't been marked complete, as is the case
   // while an extension is being installed after being downloaded.
-  if (item_->percent_downloaded() == -1)
+  if (percent_downloaded == -1)
     return;
-  progress_bar_->SetValue(item_->percent_downloaded() / 100.0);
+  progress_bar_->SetValue(percent_downloaded / 100.0);
 }
 
 const char* AppListItemView::GetClassName() const {
@@ -272,7 +310,7 @@ void AppListItemView::Layout() {
   icon_->SetBoundsRect(GetIconBoundsForTargetViewBounds(GetContentsBounds()));
   const gfx::Size title_size = title_->GetPreferredSize();
   gfx::Rect title_bounds(rect.x() + (rect.width() - title_size.width()) / 2,
-                         y + icon_size_.height() + kIconTitleSpacing,
+                         y + kGridIconDimension + kIconTitleSpacing,
                          title_size.width(),
                          title_size.height());
   title_bounds.Intersect(rect);
@@ -285,25 +323,26 @@ void AppListItemView::Layout() {
   progress_bar_->SetBoundsRect(progress_bar_bounds);
 }
 
+void AppListItemView::SchedulePaintInRect(const gfx::Rect& r) {
+  SetTitleSubpixelAA();
+  views::CustomButton::SchedulePaintInRect(r);
+}
+
 void AppListItemView::OnPaint(gfx::Canvas* canvas) {
   if (apps_grid_view_->IsDraggedView(this))
     return;
 
   gfx::Rect rect(GetContentsBounds());
-  if (item_->highlighted() && !item_->is_installing()) {
+  if (is_highlighted_ && !is_installing_) {
     canvas->FillRect(rect, kHighlightedColor);
     return;
-  } else if (apps_grid_view_->IsSelectedView(this)) {
-      canvas->FillRect(rect, kSelectedColor);
   }
+  if (apps_grid_view_->IsSelectedView(this))
+    canvas->FillRect(rect, kSelectedColor);
+
+  if (ui_state_ == UI_STATE_DROPPING_IN_FOLDER) {
+    DCHECK(apps_grid_view_->model()->folders_enabled());
 
-  if (!switches::IsFolderUIEnabled()) {
-    if (apps_grid_view_->IsSelectedView(this)) {
-      canvas->FillRect(rect, kSelectedColor);
-    } else if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
-      canvas->FillRect(rect, kHighlightedColor);
-    }
-  } else if (ui_state_ == UI_STATE_DROPPING_IN_FOLDER) {
     // Draw folder dropping preview circle.
     gfx::Point center = gfx::Point(icon_->x() + icon_->size().width() / 2,
                                    icon_->y() + icon_->size().height() / 2);
@@ -318,21 +357,25 @@ void AppListItemView::OnPaint(gfx::Canvas* canvas) {
 void AppListItemView::ShowContextMenuForView(views::View* source,
                                              const gfx::Point& point,
                                              ui::MenuSourceType source_type) {
-  ui::MenuModel* menu_model = item_->GetContextMenuModel();
+  ui::MenuModel* menu_model =
+      item_weak_ ? item_weak_->GetContextMenuModel() : NULL;
   if (!menu_model)
     return;
 
-  context_menu_runner_.reset(new views::MenuRunner(menu_model));
-  if (context_menu_runner_->RunMenuAt(
-          GetWidget(), NULL, gfx::Rect(point, gfx::Size()),
-          views::MenuItemView::TOPLEFT, source_type,
-          views::MenuRunner::HAS_MNEMONICS) ==
-      views::MenuRunner::MENU_DELETED)
+  context_menu_runner_.reset(
+      new views::MenuRunner(menu_model, views::MenuRunner::HAS_MNEMONICS));
+  if (context_menu_runner_->RunMenuAt(GetWidget(),
+                                      NULL,
+                                      gfx::Rect(point, gfx::Size()),
+                                      views::MENU_ANCHOR_TOPLEFT,
+                                      source_type) ==
+      views::MenuRunner::MENU_DELETED) {
     return;
+  }
 }
 
 void AppListItemView::StateChanged() {
-  const bool is_folder_ui_enabled = switches::IsFolderUIEnabled();
+  const bool is_folder_ui_enabled = apps_grid_view_->model()->folders_enabled();
   if (is_folder_ui_enabled)
     apps_grid_view_->ClearAnySelectedView();
 
@@ -343,7 +386,9 @@ void AppListItemView::StateChanged() {
   } else {
     if (!is_folder_ui_enabled)
       apps_grid_view_->ClearSelectedView(this);
-    item_->SetHighlighted(false);
+    SetItemIsHighlighted(false);
+    if (item_weak_)
+      item_weak_->set_highlighted(false);
     title_->SetEnabledColor(kGridTitleColor);
   }
   title_->Invalidate();
@@ -480,9 +525,32 @@ gfx::Rect AppListItemView::GetIconBoundsForTargetViewBounds(
       title_->font_list().GetExpectedTextWidth(kLeftRightPaddingChars);
   rect.Inset(left_right_padding, kTopPadding, left_right_padding, 0);
 
-  gfx::Rect icon_bounds(rect.x(), rect.y(), rect.width(), icon_size_.height());
-  icon_bounds.Inset(gfx::ShadowValue::GetMargin(icon_shadows_));
+  gfx::Rect icon_bounds(rect.x(), rect.y(), rect.width(), kGridIconDimension);
+  icon_bounds.Inset(gfx::ShadowValue::GetMargin(GetIconShadows()));
   return icon_bounds;
 }
 
+void AppListItemView::ItemIconChanged() {
+  SetIcon(item_weak_->icon(), item_weak_->has_shadow());
+}
+
+void AppListItemView::ItemNameChanged() {
+  SetItemName(base::UTF8ToUTF16(item_weak_->GetDisplayName()),
+              base::UTF8ToUTF16(item_weak_->name()));
+}
+
+void AppListItemView::ItemIsInstallingChanged() {
+  SetItemIsInstalling(item_weak_->is_installing());
+}
+
+void AppListItemView::ItemPercentDownloadedChanged() {
+  SetItemPercentDownloaded(item_weak_->percent_downloaded());
+}
+
+void AppListItemView::ItemBeingDestroyed() {
+  DCHECK(item_weak_);
+  item_weak_->RemoveObserver(this);
+  item_weak_ = NULL;
+}
+
 }  // namespace app_list