summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 05:16:02 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 05:16:02 +0000
commitf5f3c7576ee8867b562afe4c7e91820eea853730 (patch)
tree1bc99a1790b9ad2d4e66a5683c5f245b495856bb
parent9d9e7fa13a2adb5aa74eeff6e51651ff62205ab8 (diff)
downloadchromium_src-f5f3c7576ee8867b562afe4c7e91820eea853730.zip
chromium_src-f5f3c7576ee8867b562afe4c7e91820eea853730.tar.gz
chromium_src-f5f3c7576ee8867b562afe4c7e91820eea853730.tar.bz2
Reland 140878 - cleanup: Remove applist v1 code.
- Remove obsolete v1 code and test; - Grid rid of selected_ in AppListItemModel and solely use selected_item_index_ in AppsGridView; - Fix a bug that highlighted item might not be visible and add test to cover it; - Update DEPS; - Fix broken ExtensionInstallUIBrowserTest.AppInstallConfirmation casued by wrong destruction order introduced by r140878 moving app list container on top of launcher container. Fix is to explicitly release app list contoller before launcher container. BUG=125964 TEST=Verify app list always show up as bubble and app_list_unittests should pass. Review URL: https://chromiumcodereview.appspot.com/10533032 TBR=sky@chromium.org Review URL: https://chromiumcodereview.appspot.com/10539038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140959 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/ash_switches.cc3
-rw-r--r--ash/ash_switches.h1
-rw-r--r--ash/shell.cc24
-rw-r--r--ash/wm/app_list_controller.cc130
-rw-r--r--ash/wm/app_list_controller.h18
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--ui/app_list/DEPS4
-rw-r--r--ui/app_list/app_list.gyp4
-rw-r--r--ui/app_list/app_list_item_view.cc183
-rw-r--r--ui/app_list/app_list_item_view.h26
-rw-r--r--ui/app_list/app_list_view.cc178
-rw-r--r--ui/app_list/app_list_view.h20
-rw-r--r--ui/app_list/apps_grid_view.cc94
-rw-r--r--ui/app_list/apps_grid_view.h18
-rw-r--r--ui/app_list/apps_grid_view_unittest.cc142
-rw-r--r--ui/app_list/test/app_list_test_suite.cc34
-rw-r--r--ui/app_list/test/app_list_test_suite.h31
-rw-r--r--ui/app_list/test/run_all_unittests.cc9
19 files changed, 287 insertions, 645 deletions
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index 9626f03..e83b02c 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -34,8 +34,5 @@ const char kAuraNoShadows[] = "aura-no-shadows";
// Use Aura to manage windows of type WINDOW_TYPE_PANEL.
const char kAuraPanelManager[] = "aura-panels";
-// Enables applist v2.
-const char kEnableAppListV2[] = "enable-applist-v2";
-
} // namespace switches
} // namespace ash
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 4edbd0d..14eb279 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -24,7 +24,6 @@ ASH_EXPORT extern const char kAuraGoogleDialogFrames[];
ASH_EXPORT extern const char kAuraLegacyPowerButton[];
ASH_EXPORT extern const char kAuraNoShadows[];
ASH_EXPORT extern const char kAuraPanelManager[];
-ASH_EXPORT extern const char kEnableAppListV2[];
} // namespace switches
} // namespace ash
diff --git a/ash/shell.cc b/ash/shell.cc
index 1da2922..f1f72fd 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -173,24 +173,13 @@ void CreateSpecialContainers(aura::RootWindow* root_window) {
"PanelContainer",
non_lock_screen_containers);
- // V1 Applist container is below launcher container.
- bool use_v2_applist = internal::AppListController::UseAppListV2();
- if (!use_v2_applist) {
- CreateContainer(internal::kShellWindowId_AppListContainer,
- "AppListContainer",
- non_lock_screen_containers);
- }
-
CreateContainer(internal::kShellWindowId_LauncherContainer,
"LauncherContainer",
non_lock_screen_containers);
- // V2 Applist container is above launcher container.
- if (use_v2_applist) {
- CreateContainer(internal::kShellWindowId_AppListContainer,
- "AppListContainer",
- non_lock_screen_containers);
- }
+ CreateContainer(internal::kShellWindowId_AppListContainer,
+ "AppListContainer",
+ non_lock_screen_containers);
aura::Window* modal_container = CreateContainer(
internal::kShellWindowId_SystemModalContainer,
@@ -618,6 +607,12 @@ Shell::~Shell() {
system_tray_.reset();
tray_delegate_.reset();
+ // AppList needs to be released before shelf layout manager, which is
+ // destroyed with launcher container in the loop below. However, app list
+ // container is now on top of launcher container and released after it.
+ // TODO(xiyuan): Move it back when app list container is no longer needed.
+ app_list_controller_.reset();
+
// Destroy secondary monitor's widgets before all the windows are destroyed.
monitor_controller_.reset();
@@ -632,7 +627,6 @@ Shell::~Shell() {
// These need a valid Shell instance to clean up properly, so explicitly
// delete them before invalidating the instance.
// Alphabetical.
- app_list_controller_.reset();
drag_drop_controller_.reset();
event_client_.reset();
magnification_controller_.reset();
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index a8c227b..6a2888f 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -5,13 +5,10 @@
#include "ash/wm/app_list_controller.h"
#include "ash/ash_switches.h"
-#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/shelf_layout_manager.h"
-#include "ash/wm/window_util.h"
-#include "base/command_line.h"
#include "ui/app_list/app_list_view.h"
#include "ui/app_list/icon_cache.h"
#include "ui/aura/event.h"
@@ -20,7 +17,6 @@
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/transform_util.h"
namespace ash {
@@ -30,33 +26,13 @@ namespace {
const float kContainerAnimationScaleFactor = 1.05f;
-// Duration for both default container and app list animation in milliseconds.
-const int kAnimationDurationMs = 130;
-
-// Delayed time of 2nd animation in milliseconds.
-const int kSecondAnimationStartDelay = kAnimationDurationMs - 20;
+// Duration for show/hide animation in milliseconds.
+const int kAnimationDurationMs = 150;
ui::Layer* GetLayer(views::Widget* widget) {
return widget->GetNativeView()->layer();
}
-// Bounds returned is used for full screen app list. Use full monitor rect
-// so that the app list shade goes behind the launcher.
-gfx::Rect GetFullScreenBoundsForWidget(views::Widget* widget) {
- gfx::NativeView window = widget->GetNativeView();
- return gfx::Screen::GetMonitorNearestWindow(window).bounds();
-}
-
-// Return work area rect for full screen app list layout. This function is
-// needed to get final work area in one shot instead of waiting for shelf
-// animation to finish.
-gfx::Rect GetWorkAreaBoundsForWidget(views::Widget* widget) {
- gfx::NativeView window = widget->GetNativeView();
- return Shell::GetInstance()->shelf()->IsVisible() ?
- ScreenAsh::GetUnmaximizedWorkAreaBounds(window) :
- gfx::Screen::GetMonitorNearestWindow(window).work_area();
-}
-
// Gets arrow location based on shelf alignment.
views::BubbleBorder::ArrowLocation GetBubbleArrowLocation() {
DCHECK(Shell::HasInstance());
@@ -91,12 +67,6 @@ AppListController::~AppListController() {
Shell::GetInstance()->RemoveShellObserver(this);
}
-// static
-bool AppListController::UseAppListV2() {
- return CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableAppListV2);
-}
-
void AppListController::SetVisible(bool visible) {
if (visible == is_visible_)
return;
@@ -114,19 +84,10 @@ void AppListController::SetVisible(bool visible) {
// will be released with AppListView on close.
app_list::AppListView* view = new app_list::AppListView(
Shell::GetInstance()->delegate()->CreateAppListViewDelegate());
- if (UseAppListV2()) {
- view->InitAsBubble(
- Shell::GetInstance()->GetContainer(kShellWindowId_AppListContainer),
- Shell::GetInstance()->launcher()->GetAppListButtonView(),
- GetBubbleArrowLocation());
- } else {
- views::Widget* launcher_widget =
- Shell::GetInstance()->launcher()->widget();
- view->InitAsFullscreenWidget(Shell::GetInstance()->GetContainer(
- kShellWindowId_AppListContainer),
- GetFullScreenBoundsForWidget(launcher_widget),
- GetWorkAreaBoundsForWidget(launcher_widget));
- }
+ view->InitAsBubble(
+ Shell::GetInstance()->GetContainer(kShellWindowId_AppListContainer),
+ Shell::GetInstance()->launcher()->GetAppListButtonView(),
+ GetBubbleArrowLocation());
SetView(view);
}
}
@@ -184,84 +145,17 @@ void AppListController::ScheduleAnimation() {
// Stop observing previous animation.
StopObservingImplicitAnimations();
- ScheduleDimmingAnimation();
-
- // No browser window fading and app list secondary animation for v2.
- if (UseAppListV2())
- return;
-
- if (is_visible_) {
- ScheduleBrowserWindowsAnimation();
- second_animation_timer_.Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay),
- this,
- &AppListController::ScheduleAppListAnimation);
- } else {
- ScheduleAppListAnimation();
- second_animation_timer_.Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay),
- this,
- &AppListController::ScheduleBrowserWindowsAnimation);
- }
-}
-
-void AppListController::ScheduleBrowserWindowsAnimationForContainer(
- aura::Window* container) {
- DCHECK(container);
- ui::Layer* layer = container->layer();
- layer->GetAnimator()->StopAnimating();
-
- ui::ScopedLayerAnimationSettings animation(layer->GetAnimator());
- animation.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(kAnimationDurationMs));
- animation.SetTweenType(
- is_visible_ ? ui::Tween::EASE_IN : ui::Tween::EASE_OUT);
-
- layer->SetOpacity(is_visible_ ? 0.0 : 1.0);
- layer->SetTransform(is_visible_ ?
- ui::GetScaleTransform(
- gfx::Point(layer->bounds().width() / 2,
- layer->bounds().height() / 2),
- kContainerAnimationScaleFactor) :
- ui::Transform());
-}
-
-void AppListController::ScheduleBrowserWindowsAnimation() {
- // Note: containers could be NULL during Shell shutdown.
- aura::Window* default_container = Shell::GetInstance()->GetContainer(
- kShellWindowId_DefaultContainer);
- if (default_container)
- ScheduleBrowserWindowsAnimationForContainer(default_container);
- aura::Window* always_on_top_container = Shell::GetInstance()->
- GetContainer(kShellWindowId_AlwaysOnTopContainer);
- if (always_on_top_container)
- ScheduleBrowserWindowsAnimationForContainer(always_on_top_container);
-}
-
-void AppListController::ScheduleDimmingAnimation() {
ui::Layer* layer = GetLayer(view_->GetWidget());
layer->GetAnimator()->StopAnimating();
- int duration = UseAppListV2() ?
- kAnimationDurationMs : 2 * kAnimationDurationMs;
-
ui::ScopedLayerAnimationSettings animation(layer->GetAnimator());
animation.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(duration));
+ base::TimeDelta::FromMilliseconds(kAnimationDurationMs));
animation.AddObserver(this);
layer->SetOpacity(is_visible_ ? 1.0 : 0.0);
}
-void AppListController::ScheduleAppListAnimation() {
- if (is_visible_)
- view_->AnimateShow(kAnimationDurationMs);
- else
- view_->AnimateHide(kAnimationDurationMs);
-}
-
////////////////////////////////////////////////////////////////////////////////
// AppListController, aura::EventFilter implementation:
@@ -312,12 +206,8 @@ void AppListController::OnWindowFocused(aura::Window* window) {
// AppListController, aura::RootWindowObserver implementation:
void AppListController::OnRootWindowResized(const aura::RootWindow* root,
const gfx::Size& old_size) {
- if (view_ && is_visible_) {
- views::Widget* launcher_widget =
- Shell::GetInstance()->launcher()->widget();
- view_->UpdateBounds(GetFullScreenBoundsForWidget(launcher_widget),
- GetWorkAreaBoundsForWidget(launcher_widget));
- }
+ if (view_ && is_visible_)
+ view_->UpdateBounds();
}
////////////////////////////////////////////////////////////////////////////////
@@ -343,7 +233,7 @@ void AppListController::OnWidgetClosing(views::Widget* widget) {
////////////////////////////////////////////////////////////////////////////////
// AppListController, ShellObserver implementation:
void AppListController::OnShelfAlignmentChanged() {
- if (view_ && view_->bubble_style())
+ if (view_)
view_->SetBubbleArrowLocation(GetBubbleArrowLocation());
}
diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h
index bf6e863..d464841 100644
--- a/ash/wm/app_list_controller.h
+++ b/ash/wm/app_list_controller.h
@@ -37,9 +37,6 @@ class AppListController : public aura::EventFilter,
AppListController();
virtual ~AppListController();
- // Returns true if AppListV2 is enabled.
- static bool UseAppListV2();
-
// Show/hide app list window.
void SetVisible(bool visible);
@@ -61,22 +58,9 @@ class AppListController : public aura::EventFilter,
// Forgets the view.
void ResetView();
- // Starts show/hide animation. ScheduleAnimation is the master who manages
- // when to call sub animations. There are three sub animations: background
- // dimming, browser windows scale/fade and app list scale/fade. The background
- // dimming runs in parallel with the other two and spans the whole animation
- // time. The rest sub animations run in two steps. On showing, the first step
- // is browser windows scale-out and fade-out and the 2nd step is app list
- // scale-in and fade-in. The 2nd step animation is started via a timer and
- // there is is a little overlap between the two animations. Hiding animation
- // is the reverse of the showing animation.
+ // Starts show/hide animation.
void ScheduleAnimation();
- void ScheduleBrowserWindowsAnimationForContainer(aura::Window* container);
- void ScheduleBrowserWindowsAnimation();
- void ScheduleDimmingAnimation();
- void ScheduleAppListAnimation();
-
// aura::EventFilter overrides:
virtual bool PreHandleKeyEvent(aura::Window* target,
aura::KeyEvent* event) OVERRIDE;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 0d42c51..d2ab149 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5712,12 +5712,6 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_ALLOW_NACL_SOCKET_API_DESCRIPTION" desc="Description for the NaCl Socket API feature.">
Allows applications to use NaCl Socket API. Use only to test NaCl plugins.
</message>
- <message name="IDS_FLAGS_ENABLE_APPLIST_V2_NAME" desc="Name of the flag to enable applist v2 in ash.">
- Enable AppList v2.
- </message>
- <message name="IDS_FLAGS_ENABLE_APPLIST_V2_DESCRIPTION" desc="Description of the flag to enable applist v2 in ash.">
- Enables the bubble-style applist v2.
- </message>
<message name="IDS_FLAGS_EXPERIMENTAL_WALLPAPER_UI_NAME" desc="Name of the flag to enable experimental wallpaper picker ui in chromeos.">
Experimental Wallpaper UI.
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index d0277b2..ae1bad8 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -709,13 +709,6 @@ const Experiment kExperiments[] = {
},
#if defined(USE_ASH)
{
- "enable-applist-v2",
- IDS_FLAGS_ENABLE_APPLIST_V2_NAME,
- IDS_FLAGS_ENABLE_APPLIST_V2_DESCRIPTION,
- kOsAll,
- SINGLE_VALUE_TYPE(ash::switches::kEnableAppListV2),
- },
- {
"show-launcher-alignment-menu",
IDS_FLAGS_SHOW_LAUNCHER_ALIGNMENT_MENU_NAME,
IDS_FLAGS_SHOW_LAUNCHER_ALIGNMENT_MENU_DESCRIPTION,
diff --git a/ui/app_list/DEPS b/ui/app_list/DEPS
index 428414c..376f8b4 100644
--- a/ui/app_list/DEPS
+++ b/ui/app_list/DEPS
@@ -1,6 +1,6 @@
include_rules = [
"+base",
- "+ui",
- "+testing",
+ "+skia",
"+third_party/skia",
+ "+ui",
]
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index ec5ff6d..07aea59 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -76,7 +76,9 @@
],
'sources': [
'apps_grid_view_unittest.cc',
- 'run_all_unittests.cc',
+ 'test/app_list_test_suite.cc',
+ 'test/app_list_test_suite.h',
+ 'test/run_all_unittests.cc',
],
},
],
diff --git a/ui/app_list/app_list_item_view.cc b/ui/app_list/app_list_item_view.cc
index 3e8f3c9..703efea 100644
--- a/ui/app_list/app_list_item_view.cc
+++ b/ui/app_list/app_list_item_view.cc
@@ -32,58 +32,31 @@ namespace app_list {
namespace {
const int kTopBottomPadding = 10;
-const int kTopPaddingV2 = 20;
+const int kTopPadding = 20;
const int kIconTitleSpacing = 7;
-const SkColor kTitleColor = SK_ColorWHITE;
-const SkColor kTitleColorV2 = SkColorSetRGB(0x5A, 0x5A, 0x5A);
-const SkColor kTitleColorHoverV2 = SkColorSetRGB(0x3C, 0x3C, 0x3C);
-const SkColor kTitleBackgroundColorV2 = SkColorSetRGB(0xFC, 0xFC, 0xFC);
-
-const SkColor kHoverAndPushedColor = SkColorSetARGB(0x55, 0, 0, 0);
-const SkColor kHoverAndPushedColorV2 = SkColorSetARGB(0x19, 0, 0, 0);
-
-const SkColor kSelectedColor = SkColorSetARGB(0x2A, 0, 0, 0);
-const SkColor kSelectedColorV2 = SkColorSetARGB(0x0D, 0, 0, 0);
+const SkColor kTitleColor = SkColorSetRGB(0x5A, 0x5A, 0x5A);
+const SkColor kTitleHoverColor = SkColorSetRGB(0x3C, 0x3C, 0x3C);
+const SkColor kTitleBackgroundColor = SkColorSetRGB(0xFC, 0xFC, 0xFC);
+const SkColor kHoverAndPushedColor = SkColorSetARGB(0x19, 0, 0, 0);
+const SkColor kSelectedColor = SkColorSetARGB(0x0D, 0, 0, 0);
const SkColor kHighlightedColor = kHoverAndPushedColor;
-const SkColor kHighlightedColorV2 = kHoverAndPushedColorV2;
-
-// FontSize/IconSize ratio = 24 / 128, which means we should get 24 font size
-// when icon size is 128.
-const float kFontSizeToIconSizeRatio = 0.1875f;
-
-// Font smaller than kBoldFontSize needs to be bold.
-const int kBoldFontSize = 14;
-
-const int kMinFontSize = 12;
-
-const int kFixedFontSize = 11; // Font size for fixed layout.
-
-const int kMinTitleChars = 15;
+const int kTitleFontSize = 11;
const int kLeftRightPaddingChars = 1;
-const gfx::Font& GetTitleFontForIconSize(const gfx::Size& size, bool fixed) {
- static int icon_height;
+const gfx::Font& GetTitleFont() {
static gfx::Font* font = NULL;
- // Reuses current font for fixed layout or icon height is the same.
- if (font && (fixed || icon_height == size.height()))
+ // Reuses current font.
+ if (font)
return *font;
- delete font;
-
- icon_height = size.height();
- int font_size = fixed ? kFixedFontSize :
- std::max(static_cast<int>(icon_height * kFontSizeToIconSizeRatio),
- kMinFontSize);
-
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
gfx::Font title_font(rb.GetFont(ui::ResourceBundle::BaseFont).GetFontName(),
- font_size);
- if (font_size <= kBoldFontSize)
- title_font = title_font.DeriveFont(0, gfx::Font::BOLD);
+ kTitleFontSize);
+ title_font = title_font.DeriveFont(0, gfx::Font::BOLD);
font = new gfx::Font(title_font);
return *font;
}
@@ -103,10 +76,6 @@ class StaticImageView : public views::ImageView {
DISALLOW_COPY_AND_ASSIGN(StaticImageView);
};
-// A minimum title width set by test to override the default logic that derives
-// the min width from font.
-int g_min_title_width = 0;
-
} // namespace
// static
@@ -171,36 +140,15 @@ AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
apps_grid_view_(apps_grid_view),
icon_(new StaticImageView),
title_(new DropShadowLabel),
- selected_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(apply_shadow_factory_(this)) {
+ title_->SetBackgroundColor(kTitleBackgroundColor);
+ title_->SetEnabledColor(kTitleColor);
+ title_->SetFont(GetTitleFont());
- if (IsV2()) {
- title_->SetBackgroundColor(kTitleBackgroundColorV2);
- title_->SetEnabledColor(kTitleColorV2);
-
- const gfx::ShadowValue kIconShadows[] = {
- gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0)),
- };
- icon_shadows_.assign(kIconShadows, kIconShadows + arraysize(kIconShadows));
- } else {
- title_->SetBackgroundColor(0);
- title_->SetEnabledColor(kTitleColor);
- const gfx::ShadowValue kTitleShadows[] = {
- gfx::ShadowValue(gfx::Point(0, 0), 1, SkColorSetARGB(0x66, 0, 0, 0)),
- gfx::ShadowValue(gfx::Point(0, 0), 10, SkColorSetARGB(0x66, 0, 0, 0)),
- gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x66, 0, 0, 0)),
- gfx::ShadowValue(gfx::Point(0, 2), 4, SkColorSetARGB(0x66, 0, 0, 0)),
- };
- title_->SetTextShadows(arraysize(kTitleShadows), kTitleShadows);
-
- const gfx::ShadowValue kIconShadows[] = {
- gfx::ShadowValue(gfx::Point(0, 0), 2, SkColorSetARGB(0xCC, 0, 0, 0)),
- gfx::ShadowValue(gfx::Point(0, 4), 4, SkColorSetARGB(0x33, 0, 0, 0)),
- gfx::ShadowValue(gfx::Point(0, 5), 10, SkColorSetARGB(0x4C, 0, 0, 0)),
- };
- icon_shadows_.assign(kIconShadows, kIconShadows + arraysize(kIconShadows));
- }
-
+ 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_);
@@ -211,10 +159,6 @@ AppListItemView::AppListItemView(AppsGridView* apps_grid_view,
set_context_menu_controller(this);
set_request_focus_on_press(false);
-
- // Don't take focus for v2 so that focus stays with the search box.
- if (!IsV2())
- set_focusable(true);
}
AppListItemView::~AppListItemView() {
@@ -222,60 +166,14 @@ AppListItemView::~AppListItemView() {
CancelPendingIconOperation();
}
-// static
-gfx::Size AppListItemView::GetPreferredSizeForIconSize(
- const gfx::Size& icon_size) {
- int min_title_width = g_min_title_width;
- // Fixed 20px is used for left/right padding before switching to padding
- // based on number of chars. It is also a number used for test case
- // AppList.ModelViewCalculateLayout.
- int left_right_padding = 20;
- if (min_title_width == 0) {
- // Assumes fixed layout is false since this function should only be called
- // for dynamic layout.
- const gfx::Font& title_font = GetTitleFontForIconSize(icon_size,
- false /* fixed */);
- // Use big char such as 'G' to calculate min title width.
- min_title_width = kMinTitleChars *
- title_font.GetStringWidth(ASCIIToUTF16("G"));
- left_right_padding = kLeftRightPaddingChars *
- title_font.GetAverageCharacterWidth();
- }
-
- int dimension = std::max(icon_size.width() * 2, min_title_width);
- gfx::Size size(dimension, dimension);
- size.Enlarge(left_right_padding, kTopBottomPadding);
- return size;
-}
-
-// static
-void AppListItemView::SetMinTitleWidth(int width) {
- g_min_title_width = width;
-}
-
void AppListItemView::SetIconSize(const gfx::Size& size) {
if (icon_size_ == size)
return;
icon_size_ = size;
- title_->SetFont(GetTitleFontForIconSize(size, IsV2()));
UpdateIcon();
}
-void AppListItemView::SetSelected(bool selected) {
- if (selected == selected_)
- return;
-
- if (focusable())
- RequestFocus();
- selected_ = selected;
- SchedulePaint();
-}
-
-bool AppListItemView::IsV2() const {
- return apps_grid_view_->fixed_layout();
-}
-
void AppListItemView::UpdateIcon() {
// Skip if |icon_size_| has not been determined.
if (icon_size_.IsEmpty())
@@ -332,6 +230,7 @@ void AppListItemView::ItemTitleChanged() {
}
void AppListItemView::ItemHighlightedChanged() {
+ apps_grid_view_->EnsureItemVisible(this);
SchedulePaint();
}
@@ -339,10 +238,6 @@ std::string AppListItemView::GetClassName() const {
return kViewClassName;
}
-gfx::Size AppListItemView::GetPreferredSize() {
- return GetPreferredSizeForIconSize(icon_size_);
-}
-
void AppListItemView::Layout() {
gfx::Rect rect(GetContentsBounds());
@@ -350,19 +245,8 @@ void AppListItemView::Layout() {
title_->font().GetAverageCharacterWidth();
gfx::Size title_size = title_->GetPreferredSize();
- int y = 0;
- if (IsV2()) {
- // Layout for v2, starting at kTopPaddingV2.
- rect.Inset(left_right_padding, kTopPaddingV2);
- y = rect.y();
- } else {
- // Layout for v1, vertically centered.
- rect.Inset(left_right_padding, kTopBottomPadding);
-
- int height = icon_size_.height() + kIconTitleSpacing +
- title_size.height();
- y = rect.y() + (rect.height() - height) / 2;
- }
+ rect.Inset(left_right_padding, kTopPadding);
+ int y = rect.y();
gfx::Rect icon_bounds(rect.x(), y, rect.width(), icon_size_.height());
icon_bounds.Inset(gfx::ShadowValue::GetMargin(icon_shadows_));
@@ -377,21 +261,18 @@ void AppListItemView::Layout() {
void AppListItemView::OnPaint(gfx::Canvas* canvas) {
gfx::Rect rect(GetContentsBounds());
- const SkColor highlighted = IsV2() ? kHighlightedColorV2 : kHighlightedColor;
- const SkColor hover_push = IsV2() ? kHoverAndPushedColorV2 :
- kHoverAndPushedColor;
- const SkColor selected = IsV2() ? kSelectedColorV2 : kSelectedColor;
+ bool selected = apps_grid_view_->IsSelectedItem(this);
if (model_->highlighted()) {
- canvas->FillRect(rect, highlighted);
+ canvas->FillRect(rect, kHighlightedColor);
} else if (hover_animation_->is_animating()) {
- int alpha = SkColorGetA(hover_push) *
+ int alpha = SkColorGetA(kHoverAndPushedColor) *
hover_animation_->GetCurrentValue();
- canvas->FillRect(rect, SkColorSetA(hover_push, alpha));
+ canvas->FillRect(rect, SkColorSetA(kHoverAndPushedColor, alpha));
} else if (state() == BS_HOT || state() == BS_PUSHED) {
- canvas->FillRect(rect, hover_push);
- } else if (selected_) {
- canvas->FillRect(rect, selected);
+ canvas->FillRect(rect, kHoverAndPushedColor);
+ } else if (selected) {
+ canvas->FillRect(rect, kSelectedColor);
}
}
@@ -420,13 +301,11 @@ void AppListItemView::ShowContextMenuForView(views::View* source,
void AppListItemView::StateChanged() {
if (state() == BS_HOT || state() == BS_PUSHED) {
apps_grid_view_->SetSelectedItem(this);
- if (IsV2())
- title_->SetEnabledColor(kTitleColorHoverV2);
+ title_->SetEnabledColor(kTitleHoverColor);
} else {
apps_grid_view_->ClearSelectedItem(this);
model_->SetHighlighted(false);
- if (IsV2())
- title_->SetEnabledColor(kTitleColorV2);
+ title_->SetEnabledColor(kTitleColor);
}
}
diff --git a/ui/app_list/app_list_item_view.h b/ui/app_list/app_list_item_view.h
index 00479242..3b7e9b3 100644
--- a/ui/app_list/app_list_item_view.h
+++ b/ui/app_list/app_list_item_view.h
@@ -34,37 +34,21 @@ class APP_LIST_EXPORT AppListItemView : public views::CustomButton,
public views::ContextMenuController,
public AppListItemModelObserver {
public:
+ // Internal class name.
+ static const char kViewClassName[];
+
AppListItemView(AppsGridView* apps_grid_view,
AppListItemModel* model,
views::ButtonListener* listener);
virtual ~AppListItemView();
- static gfx::Size GetPreferredSizeForIconSize(const gfx::Size& icon_size);
-
- // For testing. Testing calls this function to set minimum title width in
- // pixels to get rid dependency on default font width.
- static void SetMinTitleWidth(int width);
-
- void SetSelected(bool selected);
- bool selected() const {
- return selected_;
- }
-
void SetIconSize(const gfx::Size& size);
- AppListItemModel* model() const {
- return model_;
- }
-
- // Internal class name.
- static const char kViewClassName[];
+ AppListItemModel* model() const { return model_; }
private:
class IconOperation;
- // Returns true for v2 UI.
- bool IsV2() const;
-
// Get icon from model and schedule background processing.
void UpdateIcon();
@@ -82,7 +66,6 @@ class APP_LIST_EXPORT AppListItemView : public views::CustomButton,
// views::View overrides:
virtual std::string GetClassName() const OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual void Layout() OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
@@ -103,7 +86,6 @@ class APP_LIST_EXPORT AppListItemView : public views::CustomButton,
scoped_ptr<views::MenuRunner> context_menu_runner_;
gfx::Size icon_size_;
- bool selected_;
scoped_refptr<IconOperation> icon_op_;
base::WeakPtrFactory<AppListItemView> apply_shadow_factory_;
diff --git a/ui/app_list/app_list_view.cc b/ui/app_list/app_list_view.cc
index 6724955..c66ba69 100644
--- a/ui/app_list/app_list_view.cc
+++ b/ui/app_list/app_list_view.cc
@@ -5,7 +5,6 @@
#include "ui/app_list/app_list_view.h"
#include <algorithm>
-#include <string>
#include "ui/app_list/app_list_bubble_border.h"
#include "ui/app_list/app_list_item_view.h"
@@ -17,11 +16,8 @@
#include "ui/app_list/search_box_model.h"
#include "ui/app_list/search_box_view.h"
#include "ui/app_list/search_result_list_view.h"
-#include "ui/compositor/layer.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/transform_util.h"
-#include "ui/views/background.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/widget/widget.h"
@@ -56,9 +52,8 @@ ui::Transform GetScaleTransform(AppsGridView* model_view) {
AppListView::AppListView(AppListViewDelegate* delegate)
: delegate_(delegate),
pagination_model_(new PaginationModel),
- bubble_style_(false),
bubble_border_(NULL),
- apps_view_(NULL),
+ apps_grid_view_(NULL),
page_switcher_view_(NULL),
search_box_view_(NULL),
search_results_view_(NULL) {
@@ -69,53 +64,20 @@ AppListView::~AppListView() {
RemoveAllChildViews(true);
}
-void AppListView::InitAsFullscreenWidget(gfx::NativeView parent,
- const gfx::Rect& screen_bounds,
- const gfx::Rect& work_area) {
- bubble_style_ = false;
- set_background(views::Background::CreateSolidBackground(
- kWidgetBackgroundColor));
- work_area_ = work_area;
-
- apps_view_ = new AppsGridView(this, pagination_model_.get());
- apps_view_->SetPaintToLayer(true);
- apps_view_->layer()->SetFillsBoundsOpaquely(false);
- AddChildView(apps_view_);
-
- views::Widget::InitParams widget_params(
- views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- widget_params.delegate = this;
- widget_params.transparent = true;
- widget_params.parent = parent;
-
- views::Widget* widget = new views::Widget;
- widget->Init(widget_params);
- widget->SetContentsView(this);
- widget->SetBounds(screen_bounds);
-
- // Turns off default animation.
- widget->SetVisibilityChangedAnimationsEnabled(false);
-
- // Sets initial transform. AnimateShow changes it back to identity transform.
- apps_view_->SetTransform(GetScaleTransform(apps_view_));
- CreateModel();
-}
-
void AppListView::InitAsBubble(
gfx::NativeView parent,
views::View* anchor,
views::BubbleBorder::ArrowLocation arrow_location) {
- bubble_style_ = true;
set_background(NULL);
search_box_view_ = new SearchBoxView(this);
AddChildView(search_box_view_);
- apps_view_ = new AppsGridView(this, pagination_model_.get());
- apps_view_->SetLayout(kPreferredIconDimension,
- kPreferredCols,
- kPreferredRows);
- AddChildView(apps_view_);
+ apps_grid_view_ = new AppsGridView(this, pagination_model_.get());
+ apps_grid_view_->SetLayout(kPreferredIconDimension,
+ kPreferredCols,
+ kPreferredRows);
+ AddChildView(apps_grid_view_);
search_results_view_ = new SearchResultListView(this);
search_results_view_->SetVisible(false);
@@ -124,7 +86,7 @@ void AppListView::InitAsBubble(
page_switcher_view_ = new PageSwitcher(pagination_model_.get());
AddChildView(page_switcher_view_);
- search_box_view_->set_grid_view(apps_view_);
+ search_box_view_->set_grid_view(apps_grid_view_);
search_box_view_->set_results_view(search_results_view_);
set_anchor_view(anchor);
@@ -139,7 +101,7 @@ void AppListView::InitAsBubble(
// Overrides border with AppListBubbleBorder.
bubble_border_ = new AppListBubbleBorder(this,
search_box_view_,
- apps_view_,
+ apps_grid_view_,
search_results_view_);
GetBubbleFrameView()->SetBubbleBorder(bubble_border_);
SetBubbleArrowLocation(arrow_location);
@@ -154,30 +116,6 @@ void AppListView::SetBubbleArrowLocation(
SizeToContents(); // Recalcuates with new border.
}
-void AppListView::AnimateShow(int duration_ms) {
- if (bubble_style_)
- return;
-
- ui::Layer* layer = apps_view_->layer();
- ui::ScopedLayerAnimationSettings animation(layer->GetAnimator());
- animation.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(duration_ms));
- animation.SetTweenType(ui::Tween::EASE_OUT);
- apps_view_->SetTransform(ui::Transform());
-}
-
-void AppListView::AnimateHide(int duration_ms) {
- if (bubble_style_)
- return;
-
- ui::Layer* layer = apps_view_->layer();
- ui::ScopedLayerAnimationSettings animation(layer->GetAnimator());
- animation.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(duration_ms));
- animation.SetTweenType(ui::Tween::EASE_IN);
- apps_view_->SetTransform(GetScaleTransform(apps_view_));
-}
-
void AppListView::Close() {
if (delegate_.get())
delegate_->Close();
@@ -185,14 +123,8 @@ void AppListView::Close() {
GetWidget()->Close();
}
-void AppListView::UpdateBounds(const gfx::Rect& screen_bounds,
- const gfx::Rect& work_area) {
- if (bubble_style_) {
- SizeToContents();
- } else {
- work_area_ = work_area;
- GetWidget()->SetBounds(screen_bounds);
- }
+void AppListView::UpdateBounds() {
+ SizeToContents();
}
void AppListView::CreateModel() {
@@ -201,7 +133,7 @@ void AppListView::CreateModel() {
scoped_ptr<AppListModel> new_model(new AppListModel);
delegate_->SetModel(new_model.get());
- apps_view_->SetModel(new_model->apps());
+ apps_grid_view_->SetModel(new_model->apps());
// search_box_view_ etc are not created for v1.
// TODO(xiyuan): Update this after v2 is ready.
@@ -215,18 +147,12 @@ void AppListView::CreateModel() {
}
views::View* AppListView::GetInitiallyFocusedView() {
- if (bubble_style_)
- return search_box_view_->search_box();
- else
- return apps_view_;
+ return search_box_view_->search_box();
}
gfx::Size AppListView::GetPreferredSize() {
- if (!bubble_style_)
- return View::GetPreferredSize();
-
const gfx::Size search_box_size = search_box_view_->GetPreferredSize();
- const gfx::Size grid_size = apps_view_->GetPreferredSize();
+ const gfx::Size grid_size = apps_grid_view_->GetPreferredSize();
const gfx::Size page_switcher_size = page_switcher_view_->GetPreferredSize();
const gfx::Size results_size = search_results_view_->GetPreferredSize();
@@ -245,46 +171,33 @@ void AppListView::Layout() {
if (rect.IsEmpty())
return;
- if (bubble_style_) {
- rect.Inset(kInnerPadding, kInnerPadding);
-
- const int x = rect.x();
- const int width = rect.width();
-
- // SeachBoxView, AppsGridView and PageSwitcher uses a vertical box layout.
- int y = rect.y();
- const int search_box_height = search_box_view_->GetPreferredSize().height();
- gfx::Rect search_box_frame(gfx::Point(x, y),
- gfx::Size(width, search_box_height));
- search_box_view_->SetBoundsRect(rect.Intersect(search_box_frame));
-
- y = search_box_view_->bounds().bottom();
- const int grid_height = apps_view_->GetPreferredSize().height();
- gfx::Rect grid_frame(gfx::Point(x, y), gfx::Size(width, grid_height));
- apps_view_->SetBoundsRect(rect.Intersect(grid_frame));
-
- y = apps_view_->bounds().bottom();
- const int page_switcher_height = rect.bottom() - y;
- gfx::Rect page_switcher_frame(gfx::Point(x, y),
- gfx::Size(width, page_switcher_height));
- page_switcher_view_->SetBoundsRect(rect.Intersect(page_switcher_frame));
-
- // Results view is mutually exclusive with AppsGridView and PageSwitcher.
- // It occupies the same space as those two views.
- gfx::Rect results_frame(grid_frame.Union(page_switcher_frame));
- search_results_view_->SetBoundsRect(rect.Intersect(results_frame));
- } else {
- // Gets work area rect, which is in screen coordinates.
- gfx::Rect workarea(work_area_);
-
- // Converts |workarea| into view's coordinates.
- gfx::Point origin(workarea.origin());
- views::View::ConvertPointFromScreen(this, &origin);
- workarea.Offset(-origin.x(), -origin.y());
-
- rect = rect.Intersect(workarea);
- apps_view_->SetBoundsRect(rect);
- }
+ rect.Inset(kInnerPadding, kInnerPadding);
+
+ const int x = rect.x();
+ const int width = rect.width();
+
+ // SeachBoxView, AppsGridView and PageSwitcher uses a vertical box layout.
+ int y = rect.y();
+ const int search_box_height = search_box_view_->GetPreferredSize().height();
+ gfx::Rect search_box_frame(gfx::Point(x, y),
+ gfx::Size(width, search_box_height));
+ search_box_view_->SetBoundsRect(rect.Intersect(search_box_frame));
+
+ y = search_box_view_->bounds().bottom();
+ const int grid_height = apps_grid_view_->GetPreferredSize().height();
+ gfx::Rect grid_frame(gfx::Point(x, y), gfx::Size(width, grid_height));
+ apps_grid_view_->SetBoundsRect(rect.Intersect(grid_frame));
+
+ y = apps_grid_view_->bounds().bottom();
+ const int page_switcher_height = rect.bottom() - y;
+ gfx::Rect page_switcher_frame(gfx::Point(x, y),
+ gfx::Size(width, page_switcher_height));
+ page_switcher_view_->SetBoundsRect(rect.Intersect(page_switcher_frame));
+
+ // Results view is mutually exclusive with AppsGridView and PageSwitcher.
+ // It occupies the same space as those two views.
+ gfx::Rect results_frame(grid_frame.Union(page_switcher_frame));
+ search_results_view_->SetBoundsRect(rect.Intersect(results_frame));
}
bool AppListView::OnKeyPressed(const views::KeyEvent& event) {
@@ -296,15 +209,6 @@ bool AppListView::OnKeyPressed(const views::KeyEvent& event) {
return false;
}
-bool AppListView::OnMousePressed(const views::MouseEvent& event) {
- // For full screen mode, if mouse click reaches us, this means user clicks
- // on blank area. So close.
- if (!bubble_style_)
- Close();
-
- return true;
-}
-
void AppListView::ButtonPressed(views::Button* sender,
const views::Event& event) {
if (sender->GetClassName() != AppListItemView::kViewClassName)
@@ -374,7 +278,7 @@ void AppListView::QueryChanged(SearchBoxView* sender) {
if (showing_search != should_show_search) {
// TODO(xiyuan): Animate this transition.
- apps_view_->SetVisible(!should_show_search);
+ apps_grid_view_->SetVisible(!should_show_search);
page_switcher_view_->SetVisible(!should_show_search);
search_results_view_->SetVisible(should_show_search);
diff --git a/ui/app_list/app_list_view.h b/ui/app_list/app_list_view.h
index de14cb9..d2aa5e9 100644
--- a/ui/app_list/app_list_view.h
+++ b/ui/app_list/app_list_view.h
@@ -40,9 +40,6 @@ class APP_LIST_EXPORT AppListView : public views::BubbleDelegateView,
virtual ~AppListView();
// Initializes the widget.
- void InitAsFullscreenWidget(gfx::NativeView parent,
- const gfx::Rect& screen_bounds,
- const gfx::Rect& work_area);
void InitAsBubble(gfx::NativeView parent,
views::View* anchor,
views::BubbleBorder::ArrowLocation arrow_location);
@@ -50,16 +47,9 @@ class APP_LIST_EXPORT AppListView : public views::BubbleDelegateView,
void SetBubbleArrowLocation(
views::BubbleBorder::ArrowLocation arrow_location);
- void AnimateShow(int duration_ms);
- void AnimateHide(int duration_ms);
-
void Close();
- void UpdateBounds(const gfx::Rect& screen_bounds,
- const gfx::Rect& work_area);
-
- bool bubble_style() const { return bubble_style_; }
- SearchBoxView* search_box() const { return search_box_view_; }
+ void UpdateBounds();
private:
// Creates models to use.
@@ -72,7 +62,6 @@ class APP_LIST_EXPORT AppListView : public views::BubbleDelegateView,
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual void Layout() OVERRIDE;
virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
- virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
@@ -94,18 +83,13 @@ class APP_LIST_EXPORT AppListView : public views::BubbleDelegateView,
// PaginationModel for model view and page switcher.
scoped_ptr<PaginationModel> pagination_model_;
- bool bubble_style_;
AppListBubbleBorder* bubble_border_; // Owned by views hierarchy.
- AppsGridView* apps_view_; // Owned by views hierarchy.
+ AppsGridView* apps_grid_view_; // Owned by views hierarchy.
PageSwitcher* page_switcher_view_; // Owned by views hierarchy.
SearchBoxView* search_box_view_; // Owned by views hierarchy.
SearchResultListView* search_results_view_; // Owned by views hierarchy.
- // Work area in screen coordinates to layout app list. This is used for
- // full screen mode.
- gfx::Rect work_area_;
-
DISALLOW_COPY_AND_ASSIGN(AppListView);
};
diff --git a/ui/app_list/apps_grid_view.cc b/ui/app_list/apps_grid_view.cc
index fa50325..1c7143d 100644
--- a/ui/app_list/apps_grid_view.cc
+++ b/ui/app_list/apps_grid_view.cc
@@ -29,7 +29,6 @@ AppsGridView::AppsGridView(views::ButtonListener* listener,
: model_(NULL),
listener_(listener),
pagination_model_(pagination_model),
- fixed_layout_(false),
cols_(0),
rows_per_page_(0),
selected_item_index_(-1) {
@@ -43,60 +42,7 @@ AppsGridView::~AppsGridView() {
pagination_model_->RemoveObserver(this);
}
-void AppsGridView::CalculateLayout(const gfx::Size& content_size,
- int num_of_tiles,
- gfx::Size* icon_size,
- int* rows,
- int* cols) {
- DCHECK(!content_size.IsEmpty() && num_of_tiles);
-
- // Icon sizes to try.
- const int kIconSizes[] = { 128, 96, 64, 48, 32 };
-
- double aspect = static_cast<double>(content_size.width()) /
- content_size.height();
-
- // Chooses the biggest icon size that could fit all tiles.
- gfx::Size tile_size;
- for (size_t i = 0; i < arraysize(kIconSizes); ++i) {
- icon_size->SetSize(kIconSizes[i], kIconSizes[i]);
- tile_size = AppListItemView::GetPreferredSizeForIconSize(
- *icon_size);
-
- int max_cols = content_size.width() / tile_size.width();
- int max_rows = content_size.height() / tile_size.height();
-
- // Skip if |tile_size| could not fit into |content_size|.
- if (max_cols * max_rows < num_of_tiles)
- continue;
-
- // Find a rows/cols pair that has a aspect ratio closest to |aspect|.
- double min_aspect_diff = 1e5;
- for (int c = std::max(max_cols / 2, 1); c <= max_cols; ++c) {
- int r = std::min((num_of_tiles - 1) / c + 1, max_rows);
- if (c * r < num_of_tiles)
- continue;
-
- double aspect_diff = fabs(static_cast<double>(c) / r - aspect);
- if (aspect_diff < min_aspect_diff) {
- *cols = c;
- *rows = r;
- min_aspect_diff = aspect_diff;
- }
- }
-
- DCHECK((*rows) * (*cols) >= num_of_tiles);
- return;
- }
-
- // No icon size that could fit all tiles.
- *cols = std::max(content_size.width() / tile_size.width(), 1);
- *rows = (num_of_tiles - 1) / (*cols) + 1;
-}
-
void AppsGridView::SetLayout(int icon_size, int cols, int rows_per_page) {
- fixed_layout_ = true;
-
icon_size_.SetSize(icon_size, icon_size);
cols_ = cols;
rows_per_page_ = rows_per_page;
@@ -129,10 +75,18 @@ void AppsGridView::ClearSelectedItem(AppListItemView* item) {
SetSelectedItemByIndex(-1);
}
-gfx::Size AppsGridView::GetPreferredSize() {
- if (!fixed_layout_)
- return gfx::Size();
+bool AppsGridView::IsSelectedItem(const AppListItemView* item) const {
+ return selected_item_index_ != -1 &&
+ selected_item_index_ == GetIndexOf(item);
+}
+
+void AppsGridView::EnsureItemVisible(const AppListItemView* item) {
+ int index = GetIndexOf(item);
+ if (index >= 0 && tiles_per_page())
+ pagination_model_->SelectPage(index / tiles_per_page());
+}
+gfx::Size AppsGridView::GetPreferredSize() {
gfx::Insets insets(GetInsets());
gfx::Size tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight);
return gfx::Size(tile_size.width() * cols_ + insets.width(),
@@ -141,29 +95,11 @@ gfx::Size AppsGridView::GetPreferredSize() {
void AppsGridView::Layout() {
gfx::Rect rect(GetContentsBounds());
- if (rect.IsEmpty() || child_count() == 0)
+ if (rect.IsEmpty() || child_count() == 0 || !tiles_per_page())
return;
- gfx::Size tile_size;
- if (fixed_layout_) {
- tile_size = gfx::Size(kPreferredTileWidth, kPreferredTileHeight);
- } else {
- int rows = 0;
- CalculateLayout(rect.size(), child_count(), &icon_size_, &rows, &cols_);
-
- tile_size = AppListItemView::GetPreferredSizeForIconSize(
- icon_size_);
- rows_per_page_ = tile_size.height() ?
- std::max(rect.height() / tile_size.height(), 1) : 1;
-
- tile_size.set_width(std::max(rect.width() / (cols_ + 1),
- tile_size.width()));
- tile_size.set_height(std::max(rect.height() / (rows_per_page_ + 1),
- tile_size.height()));
- }
+ gfx::Size tile_size(kPreferredTileWidth, kPreferredTileHeight);
- if (!tiles_per_page())
- return;
pagination_model_->SetTotalPages((child_count() - 1) / tiles_per_page() + 1);
if (pagination_model_->selected_page() < 0)
@@ -282,13 +218,13 @@ void AppsGridView::SetSelectedItemByIndex(int index) {
return;
if (selected_item_index_ >= 0)
- GetItemViewAtIndex(selected_item_index_)->SetSelected(false);
+ GetItemViewAtIndex(selected_item_index_)->SchedulePaint();
if (index < 0 || index >= child_count()) {
selected_item_index_ = -1;
} else {
selected_item_index_ = index;
- GetItemViewAtIndex(selected_item_index_)->SetSelected(true);
+ GetItemViewAtIndex(selected_item_index_)->SchedulePaint();
if (tiles_per_page())
pagination_model_->SelectPage(selected_item_index_ / tiles_per_page());
diff --git a/ui/app_list/apps_grid_view.h b/ui/app_list/apps_grid_view.h
index a3862c6..7eeb087 100644
--- a/ui/app_list/apps_grid_view.h
+++ b/ui/app_list/apps_grid_view.h
@@ -30,14 +30,6 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
PaginationModel* pagination_model);
virtual ~AppsGridView();
- // Calculate preferred icon size, rows and cols for given |content_size| and
- // |num_of_tiles|.
- static void CalculateLayout(const gfx::Size& content_size,
- int num_of_tiles,
- gfx::Size* icon_size,
- int* rows,
- int* cols);
-
// Sets fixed layout parameters. After setting this, CalculateLayout below
// is no longer called to dynamically choosing those layout params.
void SetLayout(int icon_size, int cols, int rows_per_page);
@@ -47,14 +39,11 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
void SetSelectedItem(AppListItemView* item);
void ClearSelectedItem(AppListItemView* item);
+ bool IsSelectedItem(const AppListItemView* item) const;
- int tiles_per_page() const {
- return cols_ * rows_per_page_;
- }
+ void EnsureItemVisible(const AppListItemView* item);
- bool fixed_layout() const {
- return fixed_layout_;
- }
+ int tiles_per_page() const { return cols_ * rows_per_page_; }
// Overridden from views::View:
virtual gfx::Size GetPreferredSize() OVERRIDE;
@@ -83,7 +72,6 @@ class APP_LIST_EXPORT AppsGridView : public views::View,
views::ButtonListener* listener_;
PaginationModel* pagination_model_; // Owned by AppListView.
- bool fixed_layout_;
gfx::Size icon_size_;
int cols_;
int rows_per_page_;
diff --git a/ui/app_list/apps_grid_view_unittest.cc b/ui/app_list/apps_grid_view_unittest.cc
index 70a330a..a1beb61 100644
--- a/ui/app_list/apps_grid_view_unittest.cc
+++ b/ui/app_list/apps_grid_view_unittest.cc
@@ -4,66 +4,108 @@
#include "ui/app_list/apps_grid_view.h"
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/app_list/app_list_item_model.h"
+#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_item_view.h"
+#include "ui/app_list/pagination_model.h"
+
+namespace app_list {
+namespace test {
namespace {
-struct ModelViewCalculateLayoutCase {
- gfx::Size screen_size;
- int num_of_tiles;
- gfx::Size expected_icon_size;
- int expected_rows;
- int expected_cols;
-};
+const int kIconDimension = 48;
+const int kCols = 2;
+const int kRows = 2;
+
+const int kWidth = 320;
+const int kHeight = 240;
} // namespace
-namespace app_list {
+class AppsGridViewTest : public testing::Test {
+ public:
+ AppsGridViewTest() {}
+ virtual ~AppsGridViewTest() {}
+
+ // testing::Test overrides:
+ virtual void SetUp() OVERRIDE {
+ apps_model_.reset(new AppListModel::Apps);
+ pagination_model_.reset(new PaginationModel);
+
+ apps_grid_view_.reset(new AppsGridView(NULL, pagination_model_.get()));
+ apps_grid_view_->SetLayout(kIconDimension, kCols, kRows);
+ apps_grid_view_->SetBoundsRect(gfx::Rect(gfx::Size(kWidth, kHeight)));
+ apps_grid_view_->SetModel(apps_model_.get());
+ }
+ virtual void TearDown() OVERRIDE {
+ apps_grid_view_.reset(); // Release apps grid view before models.
+ }
+
+ protected:
+ void PopulateApps(int n) {
+ for (int i = 0; i < n; ++i) {
+ std::string title = base::StringPrintf("Item %d", i);
+ apps_model_->Add(CreateItem(title));
+ }
+ }
-TEST(AppsGridViewTest, ModelViewCalculateLayout) {
- // kMinTitleWidth is the average width of 15 chars of default size 12 font in
- // chromeos. Override here to avoid flakiness from different default font on
- // bots.
- const int kMinTitleWidth = 90;
- AppListItemView::SetMinTitleWidth(kMinTitleWidth);
-
- const int kLauncherHeight = 50;
- const ModelViewCalculateLayoutCase kCases[] = {
- { gfx::Size(1024, 768), 4, gfx::Size(128, 128), 2, 3 },
- { gfx::Size(1024, 768), 29, gfx::Size(64, 64), 5, 6 },
- { gfx::Size(1024, 768), 40, gfx::Size(48, 48), 5, 8 },
- { gfx::Size(1024, 768), 48, gfx::Size(48, 48), 6, 8 },
-
- { gfx::Size(1280, 1024), 4, gfx::Size(128, 128), 2, 3 },
- { gfx::Size(1280, 1024), 29, gfx::Size(64, 64), 5, 7 },
- { gfx::Size(1280, 1024), 50, gfx::Size(64, 64), 7, 8 },
- { gfx::Size(1280, 1024), 70, gfx::Size(48, 48), 7, 10 },
- { gfx::Size(1280, 1024), 99, gfx::Size(48, 48), 9, 11 },
-
- { gfx::Size(1600, 900), 4, gfx::Size(128, 128), 2, 3 },
- { gfx::Size(1600, 900), 29, gfx::Size(64, 64), 4, 8 },
-
- // Not able to fit into screen case.
- { gfx::Size(1024, 768), 50, gfx::Size(32, 32), 6, 9 },
- { gfx::Size(1280, 1024), 100, gfx::Size(32, 32), 10, 11 },
- };
-
- for (size_t i = 0; i < arraysize(kCases); ++i) {
- gfx::Size icon_size;
- int rows = 0;
- int cols = 0;
- gfx::Size content_size(kCases[i].screen_size.width(),
- kCases[i].screen_size.height() - kLauncherHeight);
- AppsGridView::CalculateLayout(content_size,
- kCases[i].num_of_tiles,
- &icon_size,
- &rows,
- &cols);
- EXPECT_EQ(kCases[i].expected_icon_size, icon_size) << "i=" << i;
- EXPECT_EQ(kCases[i].expected_rows, rows) << "i=" << i;
- EXPECT_EQ(kCases[i].expected_cols, cols) << "i=" << i;
+ AppListItemModel* CreateItem(const std::string& title) {
+ AppListItemModel* item = new AppListItemModel;
+ item->SetTitle(title);
+ return item;
}
+
+ void HighlightItemAt(int index) {
+ AppListItemModel* item = apps_model_->GetItemAt(index);
+ item->SetHighlighted(true);
+ }
+
+ scoped_ptr<AppListModel::Apps> apps_model_;
+ scoped_ptr<PaginationModel> pagination_model_;
+ scoped_ptr<AppsGridView> apps_grid_view_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest);
+};
+
+TEST_F(AppsGridViewTest, CreatePage) {
+ // Fully populates a page.
+ const int kPages = 1;
+ PopulateApps(kPages * apps_grid_view_->tiles_per_page());
+ EXPECT_EQ(kPages, pagination_model_->total_pages());
+
+ // Adds one more and gets a new page created.
+ apps_model_->Add(CreateItem(std::string("Extra")));
+ EXPECT_EQ(kPages + 1, pagination_model_->total_pages());
+}
+
+TEST_F(AppsGridViewTest, EnsureHighlightedVisible) {
+ const int kPages = 3;
+ PopulateApps(kPages * apps_grid_view_->tiles_per_page());
+ EXPECT_EQ(kPages, pagination_model_->total_pages());
+ EXPECT_EQ(0, pagination_model_->selected_page());
+
+ // Highlight first one and last one one first page and first page should be
+ // selected.
+ HighlightItemAt(0);
+ EXPECT_EQ(0, pagination_model_->selected_page());
+ HighlightItemAt(apps_grid_view_->tiles_per_page() - 1);
+ EXPECT_EQ(0, pagination_model_->selected_page());
+
+ // Highlight first one on 2nd page and 2nd page should be selected.
+ HighlightItemAt(apps_grid_view_->tiles_per_page() + 1);
+ EXPECT_EQ(1, pagination_model_->selected_page());
+
+ // Highlight last one in the model and last page should be selected.
+ HighlightItemAt(apps_model_->item_count() - 1);
+ EXPECT_EQ(kPages - 1, pagination_model_->selected_page());
}
+} // namespace test
} // namespace app_list
diff --git a/ui/app_list/test/app_list_test_suite.cc b/ui/app_list/test/app_list_test_suite.cc
new file mode 100644
index 0000000..b1c78d4
--- /dev/null
+++ b/ui/app_list/test/app_list_test_suite.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/app_list/test/app_list_test_suite.h"
+
+#include "ui/base/ui_base_paths.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace app_list {
+namespace test {
+
+AppListTestSuite::AppListTestSuite(int argc, char** argv)
+ : TestSuite(argc, argv) {
+}
+
+void AppListTestSuite::Initialize() {
+ base::TestSuite::Initialize();
+
+ ui::RegisterPathProvider();
+
+ // Force unittests to run using en-US so if we test against string
+ // output, it'll pass regardless of the system language.
+ ui::ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL);
+}
+
+void AppListTestSuite::Shutdown() {
+ ui::ResourceBundle::CleanupSharedInstance();
+
+ base::TestSuite::Shutdown();
+}
+
+} // namespace test
+} // namespace app_list
diff --git a/ui/app_list/test/app_list_test_suite.h b/ui/app_list/test/app_list_test_suite.h
new file mode 100644
index 0000000..ece107e
--- /dev/null
+++ b/ui/app_list/test/app_list_test_suite.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_APP_LIST_TEST_APP_LIST_TEST_SUITE_H_
+#define UI_APP_LIST_TEST_APP_LIST_TEST_SUITE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/test/test_suite.h"
+
+namespace app_list {
+namespace test {
+
+class AppListTestSuite : public base::TestSuite {
+ public:
+ AppListTestSuite(int argc, char** argv);
+
+ protected:
+ // base::TestSuite overrides:
+ virtual void Initialize() OVERRIDE;
+ virtual void Shutdown() OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(AppListTestSuite);
+};
+
+} // namespace test
+} // namespace app_list
+
+#endif // UI_APP_LIST_TEST_APP_LIST_TEST_SUITE_H_
diff --git a/ui/app_list/test/run_all_unittests.cc b/ui/app_list/test/run_all_unittests.cc
new file mode 100644
index 0000000..d4e94e0
--- /dev/null
+++ b/ui/app_list/test/run_all_unittests.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/app_list/test/app_list_test_suite.h"
+
+int main(int argc, char** argv) {
+ return app_list::test::AppListTestSuite(argc, argv).Run();
+}