diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-28 17:54:31 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-28 17:54:31 +0000 |
commit | 7f90ce6e6ebaca0e3a6236beb4dd778fd7cb586a (patch) | |
tree | 7a242ec1dc2a83600e78bf3dcb076ebe26ca9860 /ash | |
parent | cb776d3949174aa836b10a6011067ed990da3c65 (diff) | |
download | chromium_src-7f90ce6e6ebaca0e3a6236beb4dd778fd7cb586a.zip chromium_src-7f90ce6e6ebaca0e3a6236beb4dd778fd7cb586a.tar.gz chromium_src-7f90ce6e6ebaca0e3a6236beb4dd778fd7cb586a.tar.bz2 |
Makes windows scale slightly when dragging the caption. Also wired
through reverting drag logic.
BUG=none
TEST=none
R=ben@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9455063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/wm/toplevel_window_event_filter.cc | 31 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_filter.h | 9 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_filter_unittest.cc | 27 | ||||
-rw-r--r-- | ash/wm/window_resizer.cc | 7 | ||||
-rw-r--r-- | ash/wm/window_resizer.h | 5 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer.cc | 63 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer.h | 12 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer_unittest.cc | 2 |
8 files changed, 139 insertions, 17 deletions
diff --git a/ash/wm/toplevel_window_event_filter.cc b/ash/wm/toplevel_window_event_filter.cc index 78645fef..353ed18 100644 --- a/ash/wm/toplevel_window_event_filter.cc +++ b/ash/wm/toplevel_window_event_filter.cc @@ -34,6 +34,10 @@ ToplevelWindowEventFilter::~ToplevelWindowEventFilter() { bool ToplevelWindowEventFilter::PreHandleKeyEvent(aura::Window* target, aura::KeyEvent* event) { + if (window_resizer_.get() && event->type() == ui::ET_KEY_PRESSED && + event->key_code() == ui::VKEY_ESCAPE) { + CompleteDrag(DRAG_REVERT); + } return false; } @@ -62,11 +66,19 @@ bool ToplevelWindowEventFilter::PreHandleMouseEvent(aura::Window* target, return HandleDrag(target, event); case ui::ET_MOUSE_CAPTURE_CHANGED: case ui::ET_MOUSE_RELEASED: - CompleteDrag(target); + CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ? + DRAG_COMPLETE : DRAG_REVERT); if (in_move_loop_) { MessageLoop::current()->Quit(); in_move_loop_ = false; } + // Completing the drag may result in hiding the window. If this happens + // return true so no other filters/observers see the event. Otherwise they + // see the event on a hidden window. + if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED && + !target->IsVisible()) { + return true; + } break; default: break; @@ -106,7 +118,7 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent( case ui::ET_GESTURE_SCROLL_END: { if (!in_gesture_resize_) return ui::GESTURE_STATUS_UNKNOWN; - CompleteDrag(target); + CompleteDrag(DRAG_COMPLETE); in_gesture_resize_ = false; break; } @@ -137,7 +149,10 @@ void ToplevelWindowEventFilter::EndMoveLoop() { return; in_move_loop_ = false; - window_resizer_.reset(); + if (window_resizer_.get()) { + window_resizer_->RevertDrag(); + window_resizer_.reset(); + } MessageLoopForUI::current()->Quit(); Shell::GetRootWindow()->PostNativeEvent(ui::CreateNoopEvent()); } @@ -149,10 +164,14 @@ WindowResizer* ToplevelWindowEventFilter::CreateWindowResizer( return new WindowResizer(window, point, window_component, grid_size_); } -void ToplevelWindowEventFilter::CompleteDrag(aura::Window* window) { +void ToplevelWindowEventFilter::CompleteDrag(DragCompletionStatus status) { scoped_ptr<WindowResizer> resizer(window_resizer_.release()); - if (resizer.get()) - resizer->CompleteDrag(); + if (resizer.get()) { + if (status == DRAG_COMPLETE) + resizer->CompleteDrag(); + else + resizer->RevertDrag(); + } } bool ToplevelWindowEventFilter::HandleDrag(aura::Window* target, diff --git a/ash/wm/toplevel_window_event_filter.h b/ash/wm/toplevel_window_event_filter.h index 01bced7..a7fdaf6 100644 --- a/ash/wm/toplevel_window_event_filter.h +++ b/ash/wm/toplevel_window_event_filter.h @@ -61,8 +61,13 @@ class ASH_EXPORT ToplevelWindowEventFilter : int window_component); private: - // Invoked when the mouse is released to cleanup after a drag. - void CompleteDrag(aura::Window* window); + enum DragCompletionStatus { + DRAG_COMPLETE, + DRAG_REVERT + }; + + // Finishes the drag. + void CompleteDrag(DragCompletionStatus status); // Called during a drag to resize/position the window. // The return value is returned by OnMouseEvent() above. diff --git a/ash/wm/toplevel_window_event_filter_unittest.cc b/ash/wm/toplevel_window_event_filter_unittest.cc index 2f436a7..15bcc12 100644 --- a/ash/wm/toplevel_window_event_filter_unittest.cc +++ b/ash/wm/toplevel_window_event_filter_unittest.cc @@ -14,6 +14,7 @@ #include "ui/aura/root_window.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/event_generator.h" +#include "ui/aura/test/test_activation_client.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/base/hit_test.h" #include "ui/gfx/screen.h" @@ -408,8 +409,6 @@ TEST_F(ToplevelWindowEventFilterTest, ResizeSnaps) { DragFromCenterBy(target.get(), 11, 21); EXPECT_EQ(112, target->bounds().width()); EXPECT_EQ(120, target->bounds().height()); - // TODO(sky): enable when test animations complete immediately. - /* target.reset(CreateWindow(HTTOPLEFT)); target->SetBounds(gfx::Rect(48, 96, 100, 100)); DragFromCenterBy(target.get(), -11, -21); @@ -417,7 +416,6 @@ TEST_F(ToplevelWindowEventFilterTest, ResizeSnaps) { EXPECT_EQ(80, target->bounds().y()); EXPECT_EQ(112, target->bounds().width()); EXPECT_EQ(120, target->bounds().height()); - */ } // Verifies that when a grid size is set dragging snaps to the grid. @@ -429,14 +427,29 @@ TEST_F(ToplevelWindowEventFilterTest, DragSnaps) { generator.MoveMouseTo(generator.current_location().Add(gfx::Point(11, 21))); EXPECT_EQ(11, target->bounds().x()); EXPECT_EQ(21, target->bounds().y()); - // TODO(sky): enable when test animations complete immediately. - /* // We only snap moves to the grid on release. generator.ReleaseLeftButton(); EXPECT_EQ(8, target->bounds().x()); EXPECT_EQ(24, target->bounds().y()); - */ +} + +// Verifies pressing escape resets the bounds to the original bounds. +TEST_F(ToplevelWindowEventFilterTest, EscapeReverts) { + aura::RootWindow* root = Shell::GetRootWindow(); + aura::client::ActivationClient* original_client = + aura::client::GetActivationClient(root); + aura::test::TestActivationClient activation_client(root); + scoped_ptr<aura::Window> target(CreateWindow(HTBOTTOMRIGHT)); + target->Focus(); + aura::test::EventGenerator generator(Shell::GetRootWindow(), target.get()); + generator.PressLeftButton(); + generator.MoveMouseTo(generator.current_location().Add(gfx::Point(10, 11))); + EXPECT_EQ("0,0 110x111", target->bounds().ToString()); + generator.PressKey(ui::VKEY_ESCAPE, 0); + generator.ReleaseKey(ui::VKEY_ESCAPE, 0); + EXPECT_EQ("0,0 100x100", target->bounds().ToString()); + aura::client::SetActivationClient(root, original_client); } } // namespace test -} // namespace aura +} // namespace ash diff --git a/ash/wm/window_resizer.cc b/ash/wm/window_resizer.cc index fbb523c..e2838e9 100644 --- a/ash/wm/window_resizer.cc +++ b/ash/wm/window_resizer.cc @@ -222,6 +222,13 @@ void WindowResizer::CompleteDrag() { window_->SetBounds(new_bounds); } +void WindowResizer::RevertDrag() { + if (!did_move_or_resize_) + return; + + window_->SetBounds(initial_bounds_); +} + gfx::Rect WindowResizer::GetBoundsForDrag(const gfx::Point& location) { if (!is_resizable()) return window_->bounds(); diff --git a/ash/wm/window_resizer.h b/ash/wm/window_resizer.h index 777eff3..f34e46c 100644 --- a/ash/wm/window_resizer.h +++ b/ash/wm/window_resizer.h @@ -52,7 +52,10 @@ class ASH_EXPORT WindowResizer { void Drag(const gfx::Point& location); // Invoked to complete the drag. - void CompleteDrag(); + virtual void CompleteDrag(); + + // Reverts the drag. + virtual void RevertDrag(); // Returns true if the drag will result in changing the window in anyway. bool is_resizable() const { return is_resizable_; } diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index a16178c..699617f 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc @@ -7,7 +7,11 @@ #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_property.h" +#include "ui/base/hit_test.h" +#include "ui/gfx/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/compositor/layer.h" #include "ui/gfx/screen.h" +#include "ui/gfx/transform.h" DECLARE_WINDOW_PROPERTY_TYPE(int) @@ -22,21 +26,78 @@ const aura::WindowProperty<int>* const kHeightBeforeObscuredKey = } // namespace +// static +bool WorkspaceWindowResizer::scale_windows_ = true; + WorkspaceWindowResizer::WorkspaceWindowResizer(aura::Window* window, const gfx::Point& location, int window_component, int grid_size) - : WindowResizer(window, location, window_component, grid_size) { + : WindowResizer(window, location, window_component, grid_size), + scale_window_(scale_windows_ && is_resizable() && + window_component == HTCAPTION) { if (is_resizable() && GetHeightBeforeObscured(window) && (!WindowTouchesBottomOfScreen() || bounds_change() != kBoundsChange_Repositions)) { ClearHeightBeforeObscured(window); } + if (scale_window_) { + // When dragging the caption scale slightly from the center. + float scale = 1.01f; + float x_offset = + static_cast<float>(window->bounds().width()) * (scale - 1) / 2.0f; + float y_offset = + (static_cast<float>(window->bounds().width()) * (scale - 1) / 2.0f); + ui::Transform transform; + transform.SetTranslate(-x_offset, -y_offset); + transform.SetScaleX(scale); + transform.SetScaleY(scale); + window->layer()->SetTransform(transform); + } } WorkspaceWindowResizer::~WorkspaceWindowResizer() { } +// static +void WorkspaceWindowResizer::SetScaleWindowsForTest(bool value) { + scale_windows_ = value; +} + +void WorkspaceWindowResizer::CompleteDrag() { + if (!did_move_or_resize() || grid_size() <= 1) { + if (scale_window_) { + ui::ScopedLayerAnimationSettings scoped_setter( + window()->layer()->GetAnimator()); + window()->layer()->SetTransform(ui::Transform()); + } + return; + } + + gfx::Rect new_bounds(GetFinalBounds()); + if (new_bounds.size() != window()->bounds().size()) { + // Don't attempt to animate a size change. + window()->SetBounds(new_bounds); + if (scale_window_) + window()->layer()->SetTransform(ui::Transform()); + return; + } + + ui::ScopedLayerAnimationSettings scoped_setter( + window()->layer()->GetAnimator()); + // Use a small duration since the grid is small. + scoped_setter.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100)); + window()->SetBounds(new_bounds); + if (scale_window_) + window()->layer()->SetTransform(ui::Transform()); +} + +void WorkspaceWindowResizer::RevertDrag() { + if (scale_window_) + window()->layer()->SetTransform(ui::Transform()); + WindowResizer::RevertDrag(); +} + gfx::Rect WorkspaceWindowResizer::GetBoundsForDrag(const gfx::Point& location) { if (!is_resizable()) return WindowResizer::GetBoundsForDrag(location); diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h index d32b0be..4815291 100644 --- a/ash/wm/workspace/workspace_window_resizer.h +++ b/ash/wm/workspace/workspace_window_resizer.h @@ -25,6 +25,13 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { int grid_size); virtual ~WorkspaceWindowResizer(); + // Sets whether windows should be scaled when dragging from the caption. + static void SetScaleWindowsForTest(bool value); + + // WindowResizer overrides: + virtual void CompleteDrag() OVERRIDE; + virtual void RevertDrag() OVERRIDE; + protected: // WindowResizer overrides: virtual gfx::Rect GetBoundsForDrag(const gfx::Point& location) OVERRIDE; @@ -43,6 +50,11 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { // Returns true if the window touches the bottom of the work area. bool WindowTouchesBottomOfScreen() const; + // True if we scaled the window. + const bool scale_window_; + + static bool scale_windows_; + DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizer); }; diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc index 7787ddc..d417dcc 100644 --- a/ash/wm/workspace/workspace_window_resizer_unittest.cc +++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc @@ -45,6 +45,7 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { virtual ~WorkspaceWindowResizerTest() {} virtual void SetUp() OVERRIDE { + WorkspaceWindowResizer::SetScaleWindowsForTest(false); AshTestBase::SetUp(); aura::RootWindow* root = Shell::GetInstance()->GetRootWindow(); root->SetBounds(gfx::Rect(0, 0, 800, kRootHeight)); @@ -57,6 +58,7 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { } virtual void TearDown() OVERRIDE { + WorkspaceWindowResizer::SetScaleWindowsForTest(true); window_.reset(); AshTestBase::TearDown(); } |