diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 05:16:02 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 05:16:02 +0000 |
commit | f5f3c7576ee8867b562afe4c7e91820eea853730 (patch) | |
tree | 1bc99a1790b9ad2d4e66a5683c5f245b495856bb | |
parent | 9d9e7fa13a2adb5aa74eeff6e51651ff62205ab8 (diff) | |
download | chromium_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.cc | 3 | ||||
-rw-r--r-- | ash/ash_switches.h | 1 | ||||
-rw-r--r-- | ash/shell.cc | 24 | ||||
-rw-r--r-- | ash/wm/app_list_controller.cc | 130 | ||||
-rw-r--r-- | ash/wm/app_list_controller.h | 18 | ||||
-rw-r--r-- | chrome/app/generated_resources.grd | 6 | ||||
-rw-r--r-- | chrome/browser/about_flags.cc | 7 | ||||
-rw-r--r-- | ui/app_list/DEPS | 4 | ||||
-rw-r--r-- | ui/app_list/app_list.gyp | 4 | ||||
-rw-r--r-- | ui/app_list/app_list_item_view.cc | 183 | ||||
-rw-r--r-- | ui/app_list/app_list_item_view.h | 26 | ||||
-rw-r--r-- | ui/app_list/app_list_view.cc | 178 | ||||
-rw-r--r-- | ui/app_list/app_list_view.h | 20 | ||||
-rw-r--r-- | ui/app_list/apps_grid_view.cc | 94 | ||||
-rw-r--r-- | ui/app_list/apps_grid_view.h | 18 | ||||
-rw-r--r-- | ui/app_list/apps_grid_view_unittest.cc | 142 | ||||
-rw-r--r-- | ui/app_list/test/app_list_test_suite.cc | 34 | ||||
-rw-r--r-- | ui/app_list/test/app_list_test_suite.h | 31 | ||||
-rw-r--r-- | ui/app_list/test/run_all_unittests.cc | 9 |
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(); +} |