diff options
author | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-07 01:00:07 +0000 |
---|---|---|
committer | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-07 01:00:07 +0000 |
commit | 494b1ef49c473b675e12c119bcaa3912b810ec86 (patch) | |
tree | 0502205d25ffefd44f2c1a46212dc129cb31c825 /ash | |
parent | 733ce08c0d3fe3c60e7acaee63c817bf5cddec46 (diff) | |
download | chromium_src-494b1ef49c473b675e12c119bcaa3912b810ec86.zip chromium_src-494b1ef49c473b675e12c119bcaa3912b810ec86.tar.gz chromium_src-494b1ef49c473b675e12c119bcaa3912b810ec86.tar.bz2 |
Animating docked background in sync with shelf
BUG=267582
TEST=Visual.
Dock a window.
Verify that docked background is same as the launcher background.
Open a second browser window.
Maximize it.
Verify that both docked background and the shelf background become opaque black.
Review URL: https://codereview.chromium.org/98373006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/launcher/launcher_types.cc | 1 | ||||
-rw-r--r-- | ash/launcher/launcher_types.h | 3 | ||||
-rw-r--r-- | ash/resources/ash_resources.grd | 1 | ||||
-rw-r--r-- | ash/resources/default_100_percent/common/launcher/launcher_corner.png | bin | 0 -> 1064 bytes | |||
-rw-r--r-- | ash/resources/default_200_percent/common/launcher/launcher_corner.png | bin | 0 -> 1073 bytes | |||
-rw-r--r-- | ash/shelf/background_animator.cc | 5 | ||||
-rw-r--r-- | ash/shelf/background_animator.h | 15 | ||||
-rw-r--r-- | ash/shelf/shelf_layout_manager.cc | 22 | ||||
-rw-r--r-- | ash/shelf/shelf_layout_manager.h | 7 | ||||
-rw-r--r-- | ash/shelf/shelf_layout_manager_observer.h | 6 | ||||
-rw-r--r-- | ash/shelf/shelf_widget.cc | 63 | ||||
-rw-r--r-- | ash/shelf/shelf_widget.h | 7 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.cc | 19 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.h | 5 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.cc | 162 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.h | 10 | ||||
-rw-r--r-- | ash/wm/workspace_controller.cc | 14 |
17 files changed, 259 insertions, 81 deletions
diff --git a/ash/launcher/launcher_types.cc b/ash/launcher/launcher_types.cc index 37aa7cc3..67dc572 100644 --- a/ash/launcher/launcher_types.cc +++ b/ash/launcher/launcher_types.cc @@ -10,6 +10,7 @@ const int kLauncherPreferredSize = 48; const int kLauncherBackgroundAlpha = 204; const int kInvalidImageResourceID = -1; const int kInvalidLauncherID = 0; +const int kTimeToSwitchBackgroundMs = 1000; LauncherItem::LauncherItem() : type(TYPE_UNDEFINED), diff --git a/ash/launcher/launcher_types.h b/ash/launcher/launcher_types.h index 2d09dae..bbb1bbc 100644 --- a/ash/launcher/launcher_types.h +++ b/ash/launcher/launcher_types.h @@ -27,6 +27,9 @@ extern const int kInvalidImageResourceID; extern const int kInvalidLauncherID; +// Animation duration for switching black shelf and dock background on and off. +ASH_EXPORT extern const int kTimeToSwitchBackgroundMs; + // Type the LauncherItem represents. enum LauncherItemType { // Represents a running app panel. diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd index 5447785..6fec31b 100644 --- a/ash/resources/ash_resources.grd +++ b/ash/resources/ash_resources.grd @@ -20,6 +20,7 @@ BECAUSE YOUR RESOURCES ARE FUNCTIONALLY RELATED OR FALL UNDER THE SAME CONDITIONALS. --> <structure type="chrome_scaled_image" name="IDR_AURA_LAUNCHER_BACKGROUND" file="common/launcher/launcher_background.png" /> + <structure type="chrome_scaled_image" name="IDR_AURA_LAUNCHER_CORNER" file="common/launcher/launcher_corner.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_LAUNCHER_DIMMING" file="common/launcher/launcher_dimming.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_LAUNCHER_ICON_APPLIST" file="common/launcher/launcher_appmenu.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_LAUNCHER_ICON_APPLIST_ALTERNATE" file="common/alt_launcher/status_app_menu_icon.png" /> diff --git a/ash/resources/default_100_percent/common/launcher/launcher_corner.png b/ash/resources/default_100_percent/common/launcher/launcher_corner.png Binary files differnew file mode 100644 index 0000000..d730065 --- /dev/null +++ b/ash/resources/default_100_percent/common/launcher/launcher_corner.png diff --git a/ash/resources/default_200_percent/common/launcher/launcher_corner.png b/ash/resources/default_200_percent/common/launcher/launcher_corner.png Binary files differnew file mode 100644 index 0000000..e5f8c96 --- /dev/null +++ b/ash/resources/default_200_percent/common/launcher/launcher_corner.png diff --git a/ash/shelf/background_animator.cc b/ash/shelf/background_animator.cc index 35e5fba..8137d60 100644 --- a/ash/shelf/background_animator.cc +++ b/ash/shelf/background_animator.cc @@ -34,11 +34,12 @@ void BackgroundAnimator::SetDuration(int time_in_ms) { animation_.SetSlideDuration(time_in_ms); } -void BackgroundAnimator::SetPaintsBackground(bool value, ChangeType type) { +void BackgroundAnimator::SetPaintsBackground( + bool value, BackgroundAnimatorChangeType type) { if (paints_background_ == value) return; paints_background_ = value; - if (type == CHANGE_IMMEDIATE && !animation_.is_animating()) { + if (type == BACKGROUND_CHANGE_IMMEDIATE && !animation_.is_animating()) { animation_.Reset(value ? 1.0f : 0.0f); AnimationProgressed(&animation_); return; diff --git a/ash/shelf/background_animator.h b/ash/shelf/background_animator.h index 7436b30..805f7d5 100644 --- a/ash/shelf/background_animator.h +++ b/ash/shelf/background_animator.h @@ -11,6 +11,13 @@ #include "ui/gfx/animation/slide_animation.h" namespace ash { + +// How the background can be changed. +enum BackgroundAnimatorChangeType { + BACKGROUND_CHANGE_ANIMATE, + BACKGROUND_CHANGE_IMMEDIATE +}; + namespace internal { // Delegate is notified any time the background changes. @@ -25,12 +32,6 @@ class ASH_EXPORT BackgroundAnimatorDelegate { // BackgroundAnimator is used by the shelf to animate the background (alpha). class ASH_EXPORT BackgroundAnimator : public gfx::AnimationDelegate { public: - // How the background can be changed. - enum ChangeType { - CHANGE_ANIMATE, - CHANGE_IMMEDIATE - }; - BackgroundAnimator(BackgroundAnimatorDelegate* delegate, int min_alpha, int max_alpha); @@ -42,7 +43,7 @@ class ASH_EXPORT BackgroundAnimator : public gfx::AnimationDelegate { // Sets whether a background is rendered. Initial value is false. If |type| // is |CHANGE_IMMEDIATE| and an animation is not in progress this notifies // the delegate immediately (synchronously from this method). - void SetPaintsBackground(bool value, ChangeType type); + void SetPaintsBackground(bool value, BackgroundAnimatorChangeType type); bool paints_background() const { return paints_background_; } // Current alpha. diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 566db94..9fb6b88 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc @@ -175,9 +175,8 @@ class ShelfLayoutManager::UpdateShelfObserver } virtual void OnImplicitAnimationsCompleted() OVERRIDE { - if (shelf_) { - shelf_->UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE); - } + if (shelf_) + shelf_->UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); delete this; } @@ -366,7 +365,7 @@ void ShelfLayoutManager::UpdateAutoHideState() { void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { window_overlaps_shelf_ = value; - UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE); + UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); } void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) { @@ -385,7 +384,7 @@ void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { gesture_drag_amount_ = 0.f; gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ? auto_hide_state() : SHELF_AUTO_HIDE_SHOWN; - UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE); + UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); } ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag( @@ -598,8 +597,7 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { State old_state = state_; state_ = state; - BackgroundAnimator::ChangeType change_type = - BackgroundAnimator::CHANGE_ANIMATE; + BackgroundAnimatorChangeType change_type = BACKGROUND_CHANGE_ANIMATE; bool delay_background_change = false; // Do not animate the background when: @@ -610,7 +608,7 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { if (state.visibility_state == SHELF_VISIBLE && state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED && old_state.visibility_state != SHELF_VISIBLE) { - change_type = BackgroundAnimator::CHANGE_IMMEDIATE; + change_type = BACKGROUND_CHANGE_IMMEDIATE; } else { // Delay the animation when the shelf was hidden, and has just been made // visible (e.g. using a gesture-drag). @@ -930,8 +928,11 @@ void ShelfLayoutManager::UpdateTargetBoundsForGesture( } void ShelfLayoutManager::UpdateShelfBackground( - BackgroundAnimator::ChangeType type) { - shelf_->SetPaintsBackground(GetShelfBackgroundType(), type); + BackgroundAnimatorChangeType type) { + const ShelfBackgroundType background_type(GetShelfBackgroundType()); + shelf_->SetPaintsBackground(background_type, type); + FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, + OnBackgroundUpdated(background_type, type)); } ShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const { @@ -1134,6 +1135,7 @@ void ShelfLayoutManager::OnDockBoundsChanging( if (dock_bounds_ != dock_bounds) { dock_bounds_ = dock_bounds; OnWindowResized(); + UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); } } diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 13f90b6..e9615a8 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h @@ -122,6 +122,9 @@ class ASH_EXPORT ShelfLayoutManager : // Returns the ideal bounds of the shelf assuming it is visible. gfx::Rect GetIdealBounds(); + // Returns the docked area bounds. + const gfx::Rect& dock_bounds() const { return dock_bounds_; } + // Stops any animations and sets the bounds of the launcher and status // widgets. void LayoutShelf(); @@ -292,7 +295,7 @@ class ASH_EXPORT ShelfLayoutManager : void UpdateTargetBoundsForGesture(TargetBounds* target_bounds) const; // Updates the background of the shelf. - void UpdateShelfBackground(BackgroundAnimator::ChangeType type); + void UpdateShelfBackground(BackgroundAnimatorChangeType type); // Returns how the shelf background is painted. ShelfBackgroundType GetShelfBackgroundType() const; @@ -331,7 +334,7 @@ class ASH_EXPORT ShelfLayoutManager : virtual void OnKeyboardBoundsChanging( const gfx::Rect& keyboard_bounds) OVERRIDE; - // Overridden from dock::DockObserver: + // Overridden from DockedWindowLayoutManagerObserver: virtual void OnDockBoundsChanging( const gfx::Rect& dock_bounds, DockedWindowLayoutManagerObserver::Reason reason) OVERRIDE; diff --git a/ash/shelf/shelf_layout_manager_observer.h b/ash/shelf/shelf_layout_manager_observer.h index 6209980..8a2d583 100644 --- a/ash/shelf/shelf_layout_manager_observer.h +++ b/ash/shelf/shelf_layout_manager_observer.h @@ -6,6 +6,7 @@ #define ASH_SHELF_SHELF_LAYOUT_MANAGER_OBSERVER_H_ #include "ash/ash_export.h" +#include "ash/shelf/background_animator.h" #include "ash/shelf/shelf_types.h" namespace aura { @@ -30,6 +31,11 @@ class ASH_EXPORT ShelfLayoutManagerObserver { // Called when the auto hide behavior is changed. virtual void OnAutoHideBehaviorChanged(aura::Window* root_window, ShelfAutoHideBehavior new_behavior) {} + + // Called when shelf background animation is started. + virtual void OnBackgroundUpdated( + ShelfBackgroundType background_type, + BackgroundAnimatorChangeType change_type) {} }; } // namespace ash diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 8dc737a..a4de0256 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc @@ -46,7 +46,6 @@ const int kDimAlpha = 128; // The time to dim and un-dim. const int kTimeToDimMs = 3000; // Slow in dimming. const int kTimeToUnDimMs = 200; // Fast in activating. -const int kTimeToSwitchBackgroundMs = 1000; // Class used to slightly dim shelf items when maximized and visible. class DimmerView : public views::View, @@ -145,7 +144,7 @@ DimmerView::DimmerView(ash::ShelfWidget* shelf_widget, // Make sure it is undimmed at the beginning and then fire off the dimming // animation. background_animator_.SetPaintsBackground(false, - ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE); + ash::BACKGROUND_CHANGE_IMMEDIATE); SetHovered(false); } @@ -161,8 +160,7 @@ void DimmerView::SetHovered(bool hovered) { background_animator_.SetDuration(hovered ? kTimeToUnDimMs : kTimeToDimMs); background_animator_.SetPaintsBackground(!hovered, disable_dimming_animations_for_test_ ? - ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE : - ash::internal::BackgroundAnimator::CHANGE_ANIMATE); + ash::BACKGROUND_CHANGE_IMMEDIATE : ash::BACKGROUND_CHANGE_ANIMATE); } void DimmerView::ForceUndimming(bool force) { @@ -391,22 +389,55 @@ void ShelfWidget::DelegateView::OnPaintBackground(gfx::Canvas* canvas) { SkBitmapOperations::ROTATION_90_CW, SkBitmapOperations::ROTATION_270_CW, SkBitmapOperations::ROTATION_180_CW)); - - gfx::Rect black_rect = - shelf_->shelf_layout_manager()->SelectValueForShelfAlignment( - gfx::Rect(0, height() - kNumBlackPixels, width(), kNumBlackPixels), - gfx::Rect(0, 0, kNumBlackPixels, height()), - gfx::Rect(width() - kNumBlackPixels, 0, kNumBlackPixels, height()), - gfx::Rect(0, 0, width(), kNumBlackPixels)); - + const gfx::Rect dock_bounds(shelf_->shelf_layout_manager()->dock_bounds()); SkPaint paint; paint.setAlpha(alpha_); canvas->DrawImageInt( launcher_background, 0, 0, launcher_background.width(), launcher_background.height(), - 0, 0, width(), height(), + (SHELF_ALIGNMENT_BOTTOM == shelf_->GetAlignment() && + dock_bounds.x() == 0 && dock_bounds.width() > 0) ? + dock_bounds.width() : 0, 0, + SHELF_ALIGNMENT_BOTTOM == shelf_->GetAlignment() ? + width() - dock_bounds.width() : width(), height(), false, paint); + if (SHELF_ALIGNMENT_BOTTOM == shelf_->GetAlignment() && + dock_bounds.width() > 0) { + // The part of the shelf background that is in the corner below the docked + // windows close to the work area is an arched gradient that blends + // vertically oriented docked background and horizontal shelf. + gfx::ImageSkia launcher_corner = + *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_CORNER); + if (dock_bounds.x() == 0) { + launcher_corner = gfx::ImageSkiaOperations::CreateRotatedImage( + launcher_corner, SkBitmapOperations::ROTATION_90_CW); + } + canvas->DrawImageInt( + launcher_corner, + 0, 0, launcher_corner.width(), launcher_corner.height(), + dock_bounds.x() > 0 ? dock_bounds.x() : dock_bounds.width() - height(), + 0, + height(), height(), + false, + paint); + // The part of the shelf background that is just below the docked windows + // is drawn using the last (lowest) 1-pixel tall strip of the image asset. + // This avoids showing the border 3D shadow between the shelf and the dock. + canvas->DrawImageInt( + launcher_background, + 0, launcher_background.height() - 1, launcher_background.width(), 1, + dock_bounds.x() > 0 ? dock_bounds.x() + height() : 0, 0, + dock_bounds.width() - height(), height(), + false, + paint); + } + gfx::Rect black_rect = + shelf_->shelf_layout_manager()->SelectValueForShelfAlignment( + gfx::Rect(0, height() - kNumBlackPixels, width(), kNumBlackPixels), + gfx::Rect(0, 0, kNumBlackPixels, height()), + gfx::Rect(width() - kNumBlackPixels, 0, kNumBlackPixels, height()), + gfx::Rect(0, 0, width(), kNumBlackPixels)); canvas->FillRect(black_rect, SK_ColorBLACK); } @@ -521,12 +552,12 @@ ShelfWidget::~ShelfWidget() { void ShelfWidget::SetPaintsBackground( ShelfBackgroundType background_type, - internal::BackgroundAnimator::ChangeType change_type) { + BackgroundAnimatorChangeType change_type) { ui::Layer* opaque_background = delegate_view_->opaque_background(); float target_opacity = (background_type == SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f; scoped_ptr<ui::ScopedLayerAnimationSettings> opaque_background_animation; - if (change_type != internal::BackgroundAnimator::CHANGE_IMMEDIATE) { + if (change_type != BACKGROUND_CHANGE_IMMEDIATE) { opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings( opaque_background->GetAnimator())); opaque_background_animation->SetTransitionDuration( @@ -536,9 +567,11 @@ void ShelfWidget::SetPaintsBackground( // TODO(mukai): use ui::Layer on both opaque_background and normal background // retire background_animator_ at all. It would be simpler. + // See also DockedBackgroundWidget::SetPaintsBackground. background_animator_.SetPaintsBackground( background_type != SHELF_BACKGROUND_DEFAULT, change_type); + delegate_view_->SchedulePaint(); } ShelfBackgroundType ShelfWidget::GetBackgroundType() const { diff --git a/ash/shelf/shelf_widget.h b/ash/shelf/shelf_widget.h index c7adb74..83d4a8d 100644 --- a/ash/shelf/shelf_widget.h +++ b/ash/shelf/shelf_widget.h @@ -43,12 +43,11 @@ class ASH_EXPORT ShelfWidget : public views::Widget, ShelfAlignment GetAlignment() const; // Sets the shelf's background type. - void SetPaintsBackground( - ShelfBackgroundType background_type, - internal::BackgroundAnimator::ChangeType change_type); + void SetPaintsBackground(ShelfBackgroundType background_type, + BackgroundAnimatorChangeType change_type); ShelfBackgroundType GetBackgroundType() const; - // Causes shelf items to be slightly dimmed (eg when a window is maximized). + // Causes shelf items to be slightly dimmed (e.g. when a window is maximized). void SetDimsShelf(bool dimming); bool GetDimsShelf() const; diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc index 9eb80c1..80cac07 100644 --- a/ash/system/tray/tray_background_view.cc +++ b/ash/system/tray/tray_background_view.cc @@ -333,10 +333,10 @@ TrayBackgroundView::TrayBackgroundView( set_notify_enter_exit_on_child(true); // Initially we want to paint the background, but without the hover effect. - hide_background_animator_.SetPaintsBackground(true, - internal::BackgroundAnimator::CHANGE_IMMEDIATE); - hover_background_animator_.SetPaintsBackground(false, - internal::BackgroundAnimator::CHANGE_IMMEDIATE); + hide_background_animator_.SetPaintsBackground( + true, BACKGROUND_CHANGE_IMMEDIATE); + hover_background_animator_.SetPaintsBackground( + false, BACKGROUND_CHANGE_IMMEDIATE); tray_container_ = new TrayContainer(shelf_alignment_); SetContents(tray_container_); @@ -362,8 +362,8 @@ void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent& event) { if (!background_ || draw_background_as_active_ || ash::switches::UseAlternateShelfLayout()) return; - hover_background_animator_.SetPaintsBackground(true, - internal::BackgroundAnimator::CHANGE_ANIMATE); + hover_background_animator_.SetPaintsBackground( + true, BACKGROUND_CHANGE_ANIMATE); } void TrayBackgroundView::OnMouseExited(const ui::MouseEvent& event) { @@ -371,8 +371,8 @@ void TrayBackgroundView::OnMouseExited(const ui::MouseEvent& event) { if (!background_ || draw_background_as_active_ || ash::switches::UseAlternateShelfLayout()) return; - hover_background_animator_.SetPaintsBackground(false, - internal::BackgroundAnimator::CHANGE_ANIMATE); + hover_background_animator_.SetPaintsBackground( + false, BACKGROUND_CHANGE_ANIMATE); } void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) { @@ -418,8 +418,7 @@ void TrayBackgroundView::SetContents(views::View* contents) { } void TrayBackgroundView::SetPaintsBackground( - bool value, - internal::BackgroundAnimator::ChangeType change_type) { + bool value, BackgroundAnimatorChangeType change_type) { DCHECK(!ash::switches::UseAlternateShelfLayout()); hide_background_animator_.SetPaintsBackground(value, change_type); } diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h index 0f6e2f7..5adaf4e 100644 --- a/ash/system/tray/tray_background_view.h +++ b/ash/system/tray/tray_background_view.h @@ -108,9 +108,8 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView, // Sets whether the tray paints a background. Default is true, but is set to // false if a window overlaps the shelf. - void SetPaintsBackground( - bool value, - internal::BackgroundAnimator::ChangeType change_type); + void SetPaintsBackground(bool value, + BackgroundAnimatorChangeType change_type); // Initializes animations for the bubble. void InitializeBubbleAnimations(views::Widget* bubble_widget); diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc index a224a12..884e331 100644 --- a/ash/wm/dock/docked_window_layout_manager.cc +++ b/ash/wm/dock/docked_window_layout_manager.cc @@ -21,14 +21,19 @@ #include "base/auto_reset.h" #include "base/command_line.h" #include "base/metrics/histogram.h" +#include "grit/ash_resources.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPaint.h" #include "ui/aura/client/activation_client.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/client/window_tree_client.h" #include "ui/aura/root_window.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/rect.h" namespace ash { @@ -48,22 +53,87 @@ const int kSlideDurationMs = 120; const int kFadeDurationMs = 60; const int kMinimizeDurationMs = 720; -namespace { - -const SkColor kDockBackgroundColor = SkColorSetARGB(0xff, 0x10, 0x10, 0x10); -const float kDockBackgroundOpacity = 0.5f; - -class DockedBackgroundWidget : public views::Widget { +class DockedBackgroundWidget : public views::Widget, + public internal::BackgroundAnimatorDelegate { public: - explicit DockedBackgroundWidget(aura::Window* container) { + explicit DockedBackgroundWidget(aura::Window* container) + : alignment_(DOCKED_ALIGNMENT_NONE), + background_animator_(this, 0, kLauncherBackgroundAlpha), + alpha_(0), + opaque_background_(ui::LAYER_SOLID_COLOR) { InitWidget(container); } + // Sets widget bounds and sizes opaque background layer to fill the widget. + void SetBackgroundBounds(const gfx::Rect bounds, DockedAlignment alignment) { + SetBounds(bounds); + opaque_background_.SetBounds(gfx::Rect(bounds.size())); + alignment_ = alignment; + } + + // Sets the docked area background type and starts transition animation. + void SetPaintsBackground( + ShelfBackgroundType background_type, + BackgroundAnimatorChangeType change_type) { + float target_opacity = + (background_type == SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f; + scoped_ptr<ui::ScopedLayerAnimationSettings> opaque_background_animation; + if (change_type != BACKGROUND_CHANGE_IMMEDIATE) { + opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings( + opaque_background_.GetAnimator())); + opaque_background_animation->SetTransitionDuration( + base::TimeDelta::FromMilliseconds(kTimeToSwitchBackgroundMs)); + } + opaque_background_.SetOpacity(target_opacity); + + // TODO(varkha): use ui::Layer on both opaque_background and normal + // background retire background_animator_ at all. It would be simpler. + // See also ShelfWidget::SetPaintsBackground. + background_animator_.SetPaintsBackground( + background_type != SHELF_BACKGROUND_DEFAULT, + change_type); + SchedulePaintInRect(gfx::Rect(GetWindowBoundsInScreen().size())); + } + + // views::Widget: + virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE { + const gfx::ImageSkia& launcher_background( + alignment_ == DOCKED_ALIGNMENT_LEFT ? + launcher_background_left_ : launcher_background_right_); + gfx::Rect rect = gfx::Rect(GetWindowBoundsInScreen().size()); + SkPaint paint; + paint.setAlpha(alpha_); + canvas->DrawImageInt( + launcher_background, + 0, 0, launcher_background.width(), launcher_background.height(), + alignment_ == DOCKED_ALIGNMENT_LEFT ? + rect.width() - launcher_background.width() : 0, 0, + launcher_background.width(), rect.height(), + false, + paint); + canvas->DrawImageInt( + launcher_background, + alignment_ == DOCKED_ALIGNMENT_LEFT ? + 0 : launcher_background.width() - 1, 0, + 1, launcher_background.height(), + alignment_ == DOCKED_ALIGNMENT_LEFT ? + 0 : launcher_background.width(), 0, + rect.width() - launcher_background.width(), rect.height(), + false, + paint); + } + + // BackgroundAnimatorDelegate: + virtual void UpdateBackground(int alpha) OVERRIDE { + alpha_ = alpha; + SchedulePaintInRect(gfx::Rect(GetWindowBoundsInScreen().size())); + } + private: void InitWidget(aura::Window* parent) { views::Widget::InitParams params; params.type = views::Widget::InitParams::TYPE_POPUP; - params.opacity = views::Widget::InitParams::OPAQUE_WINDOW; + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.can_activate = false; params.keep_on_top = false; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; @@ -72,17 +142,41 @@ class DockedBackgroundWidget : public views::Widget { set_focus_on_creation(false); Init(params); GetNativeWindow()->SetProperty(internal::kStayInSameRootWindowKey, true); - DCHECK_EQ(GetNativeView()->GetRootWindow(), parent->GetRootWindow()); - views::View* content_view = new views::View; - content_view->set_background( - views::Background::CreateSolidBackground(kDockBackgroundColor)); - SetContentsView(content_view); + opaque_background_.SetColor(SK_ColorBLACK); + opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); + opaque_background_.SetOpacity(0.0f); + GetNativeWindow()->layer()->Add(&opaque_background_); Hide(); + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::ImageSkia launcher_background = + *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_BACKGROUND); + launcher_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( + launcher_background, SkBitmapOperations::ROTATION_90_CW); + launcher_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( + launcher_background, SkBitmapOperations::ROTATION_270_CW); } + DockedAlignment alignment_; + + // The animator for the background transitions. + internal::BackgroundAnimator background_animator_; + + // The alpha to use for drawing image assets covering the docked background. + int alpha_; + + // Solid black background that can be made fully opaque. + ui::Layer opaque_background_; + + // Backgrounds created from shelf background by 90 or 270 degree rotation. + gfx::ImageSkia launcher_background_left_; + gfx::ImageSkia launcher_background_right_; + DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); }; +namespace { + // Returns true if a window is a popup or a transient child. bool IsPopupOrTransient(const aura::Window* window) { return (window->type() == aura::client::WINDOW_TYPE_POPUP || @@ -225,7 +319,7 @@ struct CompareWindowPos { } // namespace //////////////////////////////////////////////////////////////////////////////// -// DockLayoutManager public implementation: +// DockedWindowLayoutManager public implementation: DockedWindowLayoutManager::DockedWindowLayoutManager( aura::Window* dock_container, WorkspaceController* workspace_controller) : dock_container_(dock_container), @@ -253,6 +347,11 @@ DockedWindowLayoutManager::~DockedWindowLayoutManager() { } void DockedWindowLayoutManager::Shutdown() { + if (launcher_ && launcher_->shelf_widget()) { + ShelfLayoutManager* shelf_layout_manager = ShelfLayoutManager::ForLauncher( + launcher_->shelf_widget()->GetNativeWindow()); + shelf_layout_manager->RemoveObserver(this); + } launcher_ = NULL; for (size_t i = 0; i < dock_container_->children().size(); ++i) { aura::Window* child = dock_container_->children()[i]; @@ -333,6 +432,11 @@ void DockedWindowLayoutManager::FinishDragging(DockedAction action, void DockedWindowLayoutManager::SetLauncher(ash::Launcher* launcher) { DCHECK(!launcher_); launcher_ = launcher; + if (launcher_->shelf_widget()) { + ShelfLayoutManager* shelf_layout_manager = ShelfLayoutManager::ForLauncher( + launcher_->shelf_widget()->GetNativeWindow()); + shelf_layout_manager->AddObserver(this); + } } DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( @@ -418,7 +522,7 @@ bool DockedWindowLayoutManager::CanDockWindow(aura::Window* window, } //////////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, aura::LayoutManager implementation: +// DockedWindowLayoutManager, aura::LayoutManager implementation: void DockedWindowLayoutManager::OnWindowResized() { MaybeMinimizeChildrenExcept(dragged_window_); Relayout(); @@ -492,7 +596,7 @@ void DockedWindowLayoutManager::SetChildBounds( } //////////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, ash::ShellObserver implementation: +// DockedWindowLayoutManager, ash::ShellObserver implementation: void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { Relayout(); @@ -558,7 +662,15 @@ void DockedWindowLayoutManager::OnShelfAlignmentChanged( } ///////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, WindowStateObserver implementation: +// DockedWindowLayoutManager, ShelfLayoutManagerObserver implementation: +void DockedWindowLayoutManager::OnBackgroundUpdated( + ShelfBackgroundType background_type, + BackgroundAnimatorChangeType change_type) { + background_widget_->SetPaintsBackground(background_type, change_type); +} + +///////////////////////////////////////////////////////////////////////////// +// DockedWindowLayoutManager, WindowStateObserver implementation: void DockedWindowLayoutManager::OnWindowShowTypeChanged( wm::WindowState* window_state, @@ -584,7 +696,7 @@ void DockedWindowLayoutManager::OnWindowShowTypeChanged( } ///////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, WindowObserver implementation: +// DockedWindowLayoutManager, WindowObserver implementation: void DockedWindowLayoutManager::OnWindowBoundsChanged( aura::Window* window, @@ -623,7 +735,8 @@ void DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) { //////////////////////////////////////////////////////////////////////////////// -// DockLayoutManager, aura::client::ActivationChangeObserver implementation: +// DockedWindowLayoutManager, aura::client::ActivationChangeObserver +// implementation: void DockedWindowLayoutManager::OnWindowActivated(aura::Window* gained_active, aura::Window* lost_active) { @@ -643,7 +756,7 @@ void DockedWindowLayoutManager::OnWindowActivated(aura::Window* gained_active, } //////////////////////////////////////////////////////////////////////////////// -// DockLayoutManager private implementation: +// DockedWindowLayoutManager private implementation: void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( aura::Window* child) { @@ -998,14 +1111,11 @@ void DockedWindowLayoutManager::UpdateDockBounds( observer_list_, OnDockBoundsChanging(bounds, reason)); // Show or hide background for docked area. - background_widget_->SetBounds(docked_bounds_); - if (docked_width_ > 0) { + background_widget_->SetBackgroundBounds(docked_bounds_, alignment_); + if (docked_width_ > 0) background_widget_->Show(); - background_widget_->GetNativeWindow()->layer()->SetOpacity( - kDockBackgroundOpacity); - } else { + else background_widget_->Hide(); - } } void DockedWindowLayoutManager::UpdateStacking(aura::Window* active_window) { diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h index 9cb3826..8e6238e 100644 --- a/ash/wm/dock/docked_window_layout_manager.h +++ b/ash/wm/dock/docked_window_layout_manager.h @@ -41,6 +41,7 @@ namespace ash { class Launcher; namespace internal { +class DockedBackgroundWidget; class DockedWindowLayoutManagerObserver; class DockedWindowResizerTest; class ShelfLayoutManager; @@ -74,6 +75,7 @@ class ASH_EXPORT DockedWindowLayoutManager public aura::WindowObserver, public aura::client::ActivationChangeObserver, public keyboard::KeyboardControllerObserver, + public ShelfLayoutManagerObserver, public wm::WindowStateObserver { public: // Maximum width of the docked windows area. @@ -148,6 +150,11 @@ class ASH_EXPORT DockedWindowLayoutManager aura::Window* root_window) OVERRIDE; virtual void OnShelfAlignmentChanged(aura::Window* root_window) OVERRIDE; + // ShelfLayoutManagerObserver: + virtual void OnBackgroundUpdated( + ShelfBackgroundType background_type, + BackgroundAnimatorChangeType change_type) OVERRIDE; + // wm::WindowStateObserver: virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, wm::WindowShowType old_type) OVERRIDE; @@ -255,6 +262,7 @@ class ASH_EXPORT DockedWindowLayoutManager // The launcher to respond to launcher alignment changes. Launcher* launcher_; + // Workspace controller that can be checked for fullscreen mode. WorkspaceController* workspace_controller_; // Tracks if any window in the same root window is in fullscreen mode. @@ -280,7 +288,7 @@ class ASH_EXPORT DockedWindowLayoutManager base::Time last_action_time_; // Widget used to paint a background for the docked area. - scoped_ptr<views::Widget> background_widget_; + scoped_ptr<DockedBackgroundWidget> background_widget_; // Observers of dock bounds changes. ObserverList<DockedWindowLayoutManagerObserver> observer_list_; diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc index 64a23a9..be22812 100644 --- a/ash/wm/workspace_controller.cc +++ b/ash/wm/workspace_controller.cc @@ -30,6 +30,15 @@ namespace { // animation (when logging in). const int kInitialPauseTimeMS = 750; +// Returns true if the |window| is docked and visible. +bool IsDockedAndVisible(const aura::Window* window) { + return (window->parent()->id() == kShellWindowId_DockedContainer && + window->IsVisible() && + !wm::GetWindowState(window)->IsMinimized() && + window->type() != aura::client::WINDOW_TYPE_POPUP && + !window->transient_parent()); +} + } // namespace WorkspaceController::WorkspaceController(aura::Window* viewport) @@ -86,8 +95,11 @@ WorkspaceWindowState WorkspaceController::GetWindowState() const { } else if (window_state->IsFullscreen()) { return WORKSPACE_WINDOW_STATE_FULL_SCREEN; } - if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds)) + if (!window_overlaps_launcher && + ((*i)->bounds().Intersects(shelf_bounds) || + IsDockedAndVisible(*i))) { window_overlaps_launcher = true; + } } } if (has_maximized_window) |