summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorvarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-07 01:00:07 +0000
committervarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-07 01:00:07 +0000
commit494b1ef49c473b675e12c119bcaa3912b810ec86 (patch)
tree0502205d25ffefd44f2c1a46212dc129cb31c825 /ash
parent733ce08c0d3fe3c60e7acaee63c817bf5cddec46 (diff)
downloadchromium_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.cc1
-rw-r--r--ash/launcher/launcher_types.h3
-rw-r--r--ash/resources/ash_resources.grd1
-rw-r--r--ash/resources/default_100_percent/common/launcher/launcher_corner.pngbin0 -> 1064 bytes
-rw-r--r--ash/resources/default_200_percent/common/launcher/launcher_corner.pngbin0 -> 1073 bytes
-rw-r--r--ash/shelf/background_animator.cc5
-rw-r--r--ash/shelf/background_animator.h15
-rw-r--r--ash/shelf/shelf_layout_manager.cc22
-rw-r--r--ash/shelf/shelf_layout_manager.h7
-rw-r--r--ash/shelf/shelf_layout_manager_observer.h6
-rw-r--r--ash/shelf/shelf_widget.cc63
-rw-r--r--ash/shelf/shelf_widget.h7
-rw-r--r--ash/system/tray/tray_background_view.cc19
-rw-r--r--ash/system/tray/tray_background_view.h5
-rw-r--r--ash/wm/dock/docked_window_layout_manager.cc162
-rw-r--r--ash/wm/dock/docked_window_layout_manager.h10
-rw-r--r--ash/wm/workspace_controller.cc14
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
new file mode 100644
index 0000000..d730065
--- /dev/null
+++ b/ash/resources/default_100_percent/common/launcher/launcher_corner.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_corner.png b/ash/resources/default_200_percent/common/launcher/launcher_corner.png
new file mode 100644
index 0000000..e5f8c96
--- /dev/null
+++ b/ash/resources/default_200_percent/common/launcher/launcher_corner.png
Binary files differ
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)