#include <algorithm>
#include "base/strings/utf_string_conversions.h"
-#include "grit/ui_strings.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/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"
const int kIconTitleSpacing = 7;
const int kProgressBarHorizontalPadding = 12;
-// 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;
-#else
-const int kFontSizeDelta = 0;
-#endif
-
// Radius of the folder dropping preview circle.
const int kFolderPreviewRadius = 40;
// 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
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).DeriveWithSizeDelta(kFontSizeDelta));
+
+ static const gfx::FontList font_list = GetFontList();
+ title_->SetFontList(font_list);
title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- title_->SetVisible(!item_->is_installing());
title_->Invalidate();
SetTitleSubpixelAA();
- const gfx::ShadowValue kIconShadows[] = {
- gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0)),
- };
- icon_shadows_.assign(kIconShadows, kIconShadows + arraysize(kIconShadows));
-
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);
}
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;
}
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;
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);
void AppListItemView::SetTitleSubpixelAA() {
// TODO(tapted): Enable AA for folders as well, taking care to play nice with
// the folder bubble animation.
- bool enable_aa = !item_->IsInFolder() && ui_state_ == UI_STATE_NORMAL &&
- !item_->highlighted() &&
- !apps_grid_view_->IsSelectedView(this) &&
+ 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;
return;
if (enable_aa) {
- title_->SetBackgroundColor(app_list::kContentsBackgroundColor);
+ title_->SetBackgroundColor(app_list::kLabelBackgroundColor);
title_->set_background(views::Background::CreateSolidBackground(
- app_list::kContentsBackgroundColor));
+ app_list::kLabelBackgroundColor));
} else {
// In other cases, keep the background transparent to ensure correct
// interactions with animations. This will temporarily disable subpixel AA.
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(item_->GetItemType() == AppListFolderItem::kItemType
- ? l10n_util::GetStringFUTF16(
- IDS_APP_LIST_FOLDER_BUTTON_ACCESSIBILE_NAME,
- base::UTF8ToUTF16(item_->name()))
- : 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 {
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);
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);
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));
+ 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::HAS_MNEMONICS) ==
+ 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();
} 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();
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