summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 00:58:00 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 00:58:00 +0000
commitb62d443dfd1a549986e538624bad34c3a7fe0788 (patch)
treeaa042cb45005b7fdf56232bc5fe95195c182db7b /ash
parent1da7c228068078ebb0584e2b02f60b3b824b500f (diff)
downloadchromium_src-b62d443dfd1a549986e538624bad34c3a7fe0788.zip
chromium_src-b62d443dfd1a549986e538624bad34c3a7fe0788.tar.gz
chromium_src-b62d443dfd1a549986e538624bad34c3a7fe0788.tar.bz2
Makes the phantom window animate between positions. Additionally if
you click and hold for 400 milliseconds we'll force showing the phantom location. BUG=120689 TEST=none R=derat@chromium.org Review URL: http://codereview.chromium.org/9910022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129746 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/wm/workspace/frame_maximize_button.cc42
-rw-r--r--ash/wm/workspace/frame_maximize_button.h8
-rw-r--r--ash/wm/workspace/phantom_window_controller.cc69
-rw-r--r--ash/wm/workspace/phantom_window_controller.h27
4 files changed, 103 insertions, 43 deletions
diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc
index f4572d3..6b63310 100644
--- a/ash/wm/workspace/frame_maximize_button.cc
+++ b/ash/wm/workspace/frame_maximize_button.cc
@@ -25,6 +25,13 @@ using ash::internal::SnapSizer;
namespace ash {
+namespace {
+
+// Delay before forcing an update of the snap location.
+const int kUpdateDelayMS = 400;
+
+}
+
// EscapeEventFilter is installed on the RootWindow to track when the escape key
// is pressed. We use an EventFilter for this as the FrameMaximizeButton
// normally does not get focus.
@@ -116,6 +123,10 @@ bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) {
snap_type_ = SNAP_NONE;
press_location_ = event.location();
exceeded_drag_threshold_ = false;
+ update_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kUpdateDelayMS),
+ this, &FrameMaximizeButton::UpdateSnapFromCursorScreenPoint);
}
ImageButton::OnMousePressed(event);
return true;
@@ -144,6 +155,7 @@ bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) {
}
void FrameMaximizeButton::OnMouseReleased(const views::MouseEvent& event) {
+ update_timer_.Stop();
UninstallEventFilter();
bool should_snap = is_snap_enabled_;
is_snap_enabled_ = false;
@@ -184,6 +196,7 @@ SkBitmap FrameMaximizeButton::GetImageToPaint() {
id = IDR_AURA_WINDOW_MAXIMIZED_RESTORE_SNAP_RIGHT_P;
break;
case SNAP_MAXIMIZE:
+ case SNAP_RESTORE:
case SNAP_NONE:
id = IDR_AURA_WINDOW_MAXIMIZED_RESTORE_SNAP_P;
break;
@@ -202,6 +215,7 @@ SkBitmap FrameMaximizeButton::GetImageToPaint() {
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_RIGHT_P;
break;
case SNAP_MAXIMIZE:
+ case SNAP_RESTORE:
case SNAP_NONE:
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_P;
break;
@@ -225,6 +239,7 @@ void FrameMaximizeButton::Cancel() {
is_snap_enabled_ = false;
phantom_window_.reset();
snap_sizer_.reset();
+ update_timer_.Stop();
SchedulePaint();
}
@@ -239,6 +254,16 @@ void FrameMaximizeButton::UninstallEventFilter() {
escape_event_filter_.reset(NULL);
}
+void FrameMaximizeButton::UpdateSnapFromCursorScreenPoint() {
+ // If the drag threshold has been exceeded the snap location is up to date.
+ if (exceeded_drag_threshold_)
+ return;
+ exceeded_drag_threshold_ = true;
+ gfx::Point cursor_point(gfx::Screen::GetCursorScreenPoint());
+ ConvertPointFromScreen(this, &cursor_point);
+ UpdateSnap(cursor_point);
+}
+
void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) {
SnapType type = SnapTypeForLocation(location);
if (type == snap_type_) {
@@ -282,16 +307,14 @@ FrameMaximizeButton::SnapType FrameMaximizeButton::SnapTypeForLocation(
int delta_x = location.x() - press_location_.x();
int delta_y = location.y() - press_location_.y();
if (!views::View::ExceededDragThreshold(delta_x, delta_y))
- return AllowMaximize() ? SNAP_MAXIMIZE : SNAP_NONE;
+ return AllowMaximize() ? SNAP_MAXIMIZE : SNAP_RESTORE;
else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x)
return is_left_right_enabled_ ? SNAP_LEFT : SNAP_NONE;
else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x)
return is_left_right_enabled_ ? SNAP_RIGHT : SNAP_NONE;
else if (delta_y > 0)
return SNAP_MINIMIZE;
- else if (AllowMaximize())
- return SNAP_MAXIMIZE;
- return SNAP_NONE;
+ return AllowMaximize() ? SNAP_MAXIMIZE : SNAP_RESTORE;
}
gfx::Rect FrameMaximizeButton::BoundsForType(SnapType type) const {
@@ -313,7 +336,11 @@ gfx::Rect FrameMaximizeButton::BoundsForType(SnapType type) const {
}
return launcher->widget()->GetWindowScreenBounds();
}
- default:
+ case SNAP_RESTORE: {
+ const gfx::Rect* restore = GetRestoreBounds(window);
+ return restore ? *restore : frame_->GetWidget()->GetWindowScreenBounds();
+ }
+ case SNAP_NONE:
NOTREACHED();
}
return gfx::Rect();
@@ -344,7 +371,10 @@ void FrameMaximizeButton::Snap() {
case SNAP_MINIMIZE:
frame_->GetWidget()->Minimize();
break;
- default:
+ case SNAP_RESTORE:
+ frame_->GetWidget()->Restore();
+ break;
+ case SNAP_NONE:
NOTREACHED();
}
}
diff --git a/ash/wm/workspace/frame_maximize_button.h b/ash/wm/workspace/frame_maximize_button.h
index 5019489..04892b8 100644
--- a/ash/wm/workspace/frame_maximize_button.h
+++ b/ash/wm/workspace/frame_maximize_button.h
@@ -7,6 +7,7 @@
#include "ash/ash_export.h"
#include "base/memory/scoped_ptr.h"
+#include "base/timer.h"
#include "ui/views/controls/button/image_button.h"
namespace views {
@@ -53,6 +54,7 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
SNAP_RIGHT,
SNAP_MAXIMIZE,
SNAP_MINIMIZE,
+ SNAP_RESTORE,
SNAP_NONE
};
@@ -63,6 +65,10 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
void InstallEventFilter();
void UninstallEventFilter();
+ // Updates the snap position from the current location. This is invoked by
+ // |update_timer_|.
+ void UpdateSnapFromCursorScreenPoint();
+
// Updates |snap_type_| based on a mouse drag.
void UpdateSnap(const gfx::Point& location);
@@ -109,6 +115,8 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
scoped_ptr<EscapeEventFilter> escape_event_filter_;
+ base::OneShotTimer<FrameMaximizeButton> update_timer_;
+
DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButton);
};
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc
index b491ddf..a23948f 100644
--- a/ash/wm/workspace/phantom_window_controller.cc
+++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -9,6 +9,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
+#include "ui/base/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
@@ -82,11 +83,16 @@ void PhantomWindowController::Show(const gfx::Rect& bounds) {
if (bounds == bounds_)
return;
bounds_ = bounds;
- if (phantom_widget_.get()) {
- phantom_widget_->SetBounds(bounds);
- return;
+ if (!phantom_widget_.get()) {
+ // Show the phantom at the bounds of the window. We'll animate to the target
+ // bounds.
+ start_bounds_ = window_->bounds();
+ CreatePhantomWidget(start_bounds_);
+ } else {
+ start_bounds_ = phantom_widget_->GetWindowScreenBounds();
}
- ShowNow();
+ animation_.reset(new ui::SlideAnimation(this));
+ animation_->Show();
}
void PhantomWindowController::Hide() {
@@ -97,34 +103,35 @@ bool PhantomWindowController::IsShowing() const {
return phantom_widget_.get() != NULL;
}
-void PhantomWindowController::ShowNow() {
- if (!phantom_widget_.get()) {
- phantom_widget_.reset(new views::Widget);
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
- params.transparent = true;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- // This is used by FrameMaximizeButton to highlight the launcher button,
- // make sure the phantom appears over the launcher.
- params.parent =
- Shell::GetInstance()->GetContainer(kShellWindowId_LauncherContainer);
- params.can_activate = false;
- params.keep_on_top = true;
- phantom_widget_->set_focus_on_creation(false);
- phantom_widget_->Init(params);
- phantom_widget_->SetVisibilityChangedAnimationsEnabled(false);
- phantom_widget_->GetNativeWindow()->SetName("PhantomWindow");
- views::View* content_view = new views::View;
- views::Painter* painter = static_cast<views::Painter*>(new EdgePainter);
- content_view->set_background(
- views::Background::CreateBackgroundPainter(true, painter));
- phantom_widget_->SetContentsView(content_view);
- phantom_widget_->SetBounds(bounds_);
- phantom_widget_->StackAbove(window_);
- phantom_widget_->Show();
- return;
- }
+void PhantomWindowController::AnimationProgressed(
+ const ui::Animation* animation) {
+ phantom_widget_->SetBounds(
+ animation->CurrentValueBetween(start_bounds_, bounds_));
+}
- phantom_widget_->SetBounds(bounds_);
+void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
+ DCHECK(!phantom_widget_.get());
+ phantom_widget_.reset(new views::Widget);
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+ params.transparent = true;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ // PhantomWindowController is used by FrameMaximizeButton to highlight the
+ // launcher button. Put the phantom in the same window as the launcher so that
+ // the phantom is visible.
+ params.parent =
+ Shell::GetInstance()->GetContainer(kShellWindowId_LauncherContainer);
+ params.can_activate = false;
+ params.keep_on_top = true;
+ phantom_widget_->set_focus_on_creation(false);
+ phantom_widget_->Init(params);
+ phantom_widget_->SetVisibilityChangedAnimationsEnabled(false);
+ phantom_widget_->GetNativeWindow()->SetName("PhantomWindow");
+ views::View* content_view = new views::View;
+ content_view->set_background(
+ views::Background::CreateBackgroundPainter(true, new EdgePainter));
+ phantom_widget_->SetContentsView(content_view);
+ phantom_widget_->SetBounds(bounds);
+ phantom_widget_->StackAbove(window_);
phantom_widget_->Show();
// Fade the window in.
ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer();
diff --git a/ash/wm/workspace/phantom_window_controller.h b/ash/wm/workspace/phantom_window_controller.h
index 6991872..a154493 100644
--- a/ash/wm/workspace/phantom_window_controller.h
+++ b/ash/wm/workspace/phantom_window_controller.h
@@ -8,12 +8,17 @@
#include "ash/ash_export.h"
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "ui/base/animation/animation_delegate.h"
#include "ui/gfx/rect.h"
namespace aura {
class Window;
}
+namespace ui {
+class SlideAnimation;
+}
+
namespace views {
class Widget;
}
@@ -21,9 +26,9 @@ class Widget;
namespace ash {
namespace internal {
-// PhantomWindowController is responsible for showing a phantom above a window.
-// It's used used during dragging a window to show a snap location.
-class ASH_EXPORT PhantomWindowController {
+// PhantomWindowController is responsible for showing a phantom representation
+// of a window. It's used used during dragging a window to show a snap location.
+class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
public:
explicit PhantomWindowController(aura::Window* window);
~PhantomWindowController();
@@ -41,18 +46,28 @@ class ASH_EXPORT PhantomWindowController {
// Returns true if the phantom is showing.
bool IsShowing() const;
+ // ui::AnimationDelegate overrides:
+ virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
+
private:
- // Shows the window immediately.
- void ShowNow();
+ // Creates and shows the |phantom_widget_| at |bounds|.
+ void CreatePhantomWidget(const gfx::Rect& bounds);
// Window the phantom is placed beneath.
aura::Window* window_;
- // Last bounds passed to Show().
+ // Initially the bounds of |window_|. Each time Show() is invoked
+ // |start_bounds_| is then reset to the bounds of |phantom_widget_| and
+ // |bounds_| is set to the value passed into Show(). The animation animates
+ // between these two values.
+ gfx::Rect start_bounds_;
gfx::Rect bounds_;
scoped_ptr<views::Widget> phantom_widget_;
+ // Used to transition the bounds.
+ scoped_ptr<ui::SlideAnimation> animation_;
+
DISALLOW_COPY_AND_ASSIGN(PhantomWindowController);
};