diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-30 00:58:00 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-30 00:58:00 +0000 |
commit | b62d443dfd1a549986e538624bad34c3a7fe0788 (patch) | |
tree | aa042cb45005b7fdf56232bc5fe95195c182db7b /ash | |
parent | 1da7c228068078ebb0584e2b02f60b3b824b500f (diff) | |
download | chromium_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.cc | 42 | ||||
-rw-r--r-- | ash/wm/workspace/frame_maximize_button.h | 8 | ||||
-rw-r--r-- | ash/wm/workspace/phantom_window_controller.cc | 69 | ||||
-rw-r--r-- | ash/wm/workspace/phantom_window_controller.h | 27 |
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); }; |