Commit 22228929 authored by sky@chromium.org's avatar sky@chromium.org

Minor refactoring of window resize code. I wasn't too happy with

continuing to have WindowResizer expose logic for
WorkspaceWindowResizer. Instead WindowResizer is pure virtual, with
some common code in static methods that both implementations can
use. This'll make the code for multi-window resizing more centralized.

BUG=116079
TEST=refactoring covered by tests
Review URL: https://chromiumcodereview.appspot.com/9599007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124939 0039d316-1c4b-4281-b951-d872f2087c98
parent 98ffde9b
...@@ -141,6 +141,8 @@ ...@@ -141,6 +141,8 @@
'wm/compact_layout_manager.h', 'wm/compact_layout_manager.h',
'wm/compact_status_area_layout_manager.cc', 'wm/compact_status_area_layout_manager.cc',
'wm/compact_status_area_layout_manager.h', 'wm/compact_status_area_layout_manager.h',
'wm/default_window_resizer.cc',
'wm/default_window_resizer.h',
'wm/dialog_frame_view.cc', 'wm/dialog_frame_view.cc',
'wm/dialog_frame_view.h', 'wm/dialog_frame_view.h',
'wm/image_grid.cc', 'wm/image_grid.cc',
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/default_window_resizer.h"
#include "ash/shell.h"
#include "ash/wm/root_window_event_filter.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/screen.h"
namespace ash {
DefaultWindowResizer::~DefaultWindowResizer() {
if (root_filter_)
root_filter_->UnlockCursor();
}
// static
DefaultWindowResizer*
DefaultWindowResizer::Create(aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size) {
Details details(window, location, window_component, grid_size);
return details.is_resizable ? new DefaultWindowResizer(details) : NULL;
}
void DefaultWindowResizer::Drag(const gfx::Point& location) {
gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
if (bounds != details_.window->bounds()) {
did_move_or_resize_ = true;
details_.window->SetBounds(bounds);
}
}
void DefaultWindowResizer::CompleteDrag() {
if (details_.grid_size <= 1 || !did_move_or_resize_)
return;
gfx::Rect new_bounds(AdjustBoundsToGrid(details_));
if (new_bounds == details_.window->bounds())
return;
if (new_bounds.size() != details_.window->bounds().size()) {
// Don't attempt to animate a size change.
details_.window->SetBounds(new_bounds);
return;
}
ui::ScopedLayerAnimationSettings scoped_setter(
details_.window->layer()->GetAnimator());
// Use a small duration since the grid is small.
scoped_setter.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
details_.window->SetBounds(new_bounds);
}
void DefaultWindowResizer::RevertDrag() {
if (!did_move_or_resize_)
return;
details_.window->SetBounds(details_.initial_bounds);
}
DefaultWindowResizer::DefaultWindowResizer(const Details& details)
: details_(details),
did_move_or_resize_(false),
root_filter_(NULL) {
DCHECK(details_.is_resizable);
root_filter_ = Shell::GetInstance()->root_filter();
if (root_filter_)
root_filter_->LockCursor();
}
} // namespace aura
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_DEFAULT_WINDOW_RESIZER_H_
#define ASH_WM_DEFAULT_WINDOW_RESIZER_H_
#pragma once
#include "ash/wm/window_resizer.h"
#include "base/compiler_specific.h"
namespace ash {
namespace internal {
class RootWindowEventFilter;
}
// WindowResizer is used by ToplevelWindowEventFilter to handle dragging, moving
// or resizing a window. All coordinates passed to this are in the parent
// windows coordiantes.
class ASH_EXPORT DefaultWindowResizer : public WindowResizer {
public:
// Constants to identify the type of resize.
static const int kBoundsChange_None;
static const int kBoundsChange_Repositions;
static const int kBoundsChange_Resizes;
// Used to indicate which direction the resize occurs in.
static const int kBoundsChangeDirection_None;
static const int kBoundsChangeDirection_Horizontal;
static const int kBoundsChangeDirection_Vertical;
virtual ~DefaultWindowResizer();
// Creates a new DefaultWindowResizer. The caller takes ownership of the
// returned object. Returns NULL if not resizable.
static DefaultWindowResizer* Create(aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size);
// Returns true if the drag will result in changing the window in anyway.
bool is_resizable() const { return details_.is_resizable; }
// WindowResizer overides:
virtual void Drag(const gfx::Point& location) OVERRIDE;
virtual void CompleteDrag() OVERRIDE;
virtual void RevertDrag() OVERRIDE;
private:
explicit DefaultWindowResizer(const Details& details);
const Details details_;
// Set to true once Drag() is invoked and the bounds of the window change.
bool did_move_or_resize_;
internal::RootWindowEventFilter* root_filter_;
DISALLOW_COPY_AND_ASSIGN(DefaultWindowResizer);
};
} // namespace aura
#endif // ASH_WM_DEFAULT_WINDOW_RESIZER_H_
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/wm/toplevel_window_event_filter.h" #include "ash/wm/toplevel_window_event_filter.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/default_window_resizer.h"
#include "ash/wm/property_util.h" #include "ash/wm/property_util.h"
#include "ash/wm/window_resizer.h" #include "ash/wm/window_resizer.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
...@@ -22,6 +23,17 @@ ...@@ -22,6 +23,17 @@
namespace ash { namespace ash {
namespace {
gfx::Point ConvertPointToParent(aura::Window* window,
const gfx::Point& point) {
gfx::Point result(point);
aura::Window::ConvertPointToWindow(window, window->parent(), &result);
return result;
}
}
ToplevelWindowEventFilter::ToplevelWindowEventFilter(aura::Window* owner) ToplevelWindowEventFilter::ToplevelWindowEventFilter(aura::Window* owner)
: in_move_loop_(false), : in_move_loop_(false),
in_gesture_resize_(false), in_gesture_resize_(false),
...@@ -51,10 +63,10 @@ bool ToplevelWindowEventFilter::PreHandleMouseEvent(aura::Window* target, ...@@ -51,10 +63,10 @@ bool ToplevelWindowEventFilter::PreHandleMouseEvent(aura::Window* target,
int component = int component =
target->delegate()->GetNonClientComponent(event->location()); target->delegate()->GetNonClientComponent(event->location());
if (WindowResizer::GetBoundsChangeForWindowComponent(component)) { if (WindowResizer::GetBoundsChangeForWindowComponent(component)) {
gfx::Point parent_location(
ConvertPointToParent(target, event->location()));
window_resizer_.reset( window_resizer_.reset(
CreateWindowResizer(target, event->location(), component)); CreateWindowResizer(target, parent_location, component));
if (window_resizer_.get() && !window_resizer_->is_resizable())
window_resizer_.reset();
} else { } else {
window_resizer_.reset(); window_resizer_.reset();
} }
...@@ -95,7 +107,8 @@ ui::TouchStatus ToplevelWindowEventFilter::PreHandleTouchEvent( ...@@ -95,7 +107,8 @@ ui::TouchStatus ToplevelWindowEventFilter::PreHandleTouchEvent(
} }
ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent( ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent(
aura::Window* target, aura::GestureEvent* event) { aura::Window* target,
aura::GestureEvent* event) {
switch (event->type()) { switch (event->type()) {
case ui::ET_GESTURE_SCROLL_BEGIN: { case ui::ET_GESTURE_SCROLL_BEGIN: {
int component = int component =
...@@ -105,10 +118,10 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent( ...@@ -105,10 +118,10 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent(
return ui::GESTURE_STATUS_UNKNOWN; return ui::GESTURE_STATUS_UNKNOWN;
} }
in_gesture_resize_ = true; in_gesture_resize_ = true;
gfx::Point parent_location(
ConvertPointToParent(target, event->location()));
window_resizer_.reset( window_resizer_.reset(
CreateWindowResizer(target, event->location(), component)); CreateWindowResizer(target, parent_location, component));
if (window_resizer_.get() && !window_resizer_->is_resizable())
window_resizer_.reset();
break; break;
} }
case ui::ET_GESTURE_SCROLL_UPDATE: { case ui::ET_GESTURE_SCROLL_UPDATE: {
...@@ -134,11 +147,11 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent( ...@@ -134,11 +147,11 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent(
void ToplevelWindowEventFilter::RunMoveLoop(aura::Window* source) { void ToplevelWindowEventFilter::RunMoveLoop(aura::Window* source) {
DCHECK(!in_move_loop_); // Can only handle one nested loop at a time. DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
in_move_loop_ = true; in_move_loop_ = true;
gfx::Point source_mouse_location(gfx::Screen::GetCursorScreenPoint()); gfx::Point parent_mouse_location(gfx::Screen::GetCursorScreenPoint());
aura::Window::ConvertPointToWindow( aura::Window::ConvertPointToWindow(
Shell::GetRootWindow(), source, &source_mouse_location); Shell::GetRootWindow(), source->parent(), &parent_mouse_location);
window_resizer_.reset( window_resizer_.reset(
CreateWindowResizer(source, source_mouse_location, HTCAPTION)); CreateWindowResizer(source, parent_mouse_location, HTCAPTION));
#if !defined(OS_MACOSX) #if !defined(OS_MACOSX)
MessageLoopForUI::current()->RunWithDispatcher( MessageLoopForUI::current()->RunWithDispatcher(
aura::Env::GetInstance()->GetDispatcher()); aura::Env::GetInstance()->GetDispatcher());
...@@ -159,13 +172,15 @@ void ToplevelWindowEventFilter::EndMoveLoop() { ...@@ -159,13 +172,15 @@ void ToplevelWindowEventFilter::EndMoveLoop() {
Shell::GetRootWindow()->PostNativeEvent(ui::CreateNoopEvent()); Shell::GetRootWindow()->PostNativeEvent(ui::CreateNoopEvent());
} }
// static
WindowResizer* ToplevelWindowEventFilter::CreateWindowResizer( WindowResizer* ToplevelWindowEventFilter::CreateWindowResizer(
aura::Window* window, aura::Window* window,
const gfx::Point& point, const gfx::Point& point,
int window_component) { int window_component) {
if (!wm::IsWindowNormal(window)) if (!wm::IsWindowNormal(window))
return NULL; // Don't allow resizing/dragging maximized/fullscreen windows. return NULL; // Don't allow resizing/dragging maximized/fullscreen windows.
return new WindowResizer(window, point, window_component, grid_size_); return DefaultWindowResizer::Create(
window, point, window_component, grid_size_);
} }
void ToplevelWindowEventFilter::CompleteDrag(DragCompletionStatus status) { void ToplevelWindowEventFilter::CompleteDrag(DragCompletionStatus status) {
...@@ -188,7 +203,7 @@ bool ToplevelWindowEventFilter::HandleDrag(aura::Window* target, ...@@ -188,7 +203,7 @@ bool ToplevelWindowEventFilter::HandleDrag(aura::Window* target,
if (!window_resizer_.get()) if (!window_resizer_.get())
return false; return false;
window_resizer_->Drag(event->location()); window_resizer_->Drag(ConvertPointToParent(target, event->location()));
return true; return true;
} }
......
...@@ -82,15 +82,6 @@ bool IsRightEdge(int window_component) { ...@@ -82,15 +82,6 @@ bool IsRightEdge(int window_component) {
window_component == HTGROWBOX; window_component == HTGROWBOX;
} }
// Returns true for resize components in along the bottom edge, where a drag
// in positive y will make the window larger.
bool IsBottomEdge(int window_component) {
return window_component == HTBOTTOMLEFT ||
window_component == HTBOTTOM ||
window_component == HTBOTTOMRIGHT ||
window_component == HTGROWBOX;
}
// Returns the closest location to |location| that is aligned to fall on // Returns the closest location to |location| that is aligned to fall on
// increments of |grid_size|. // increments of |grid_size|.
int AlignToGridRoundUp(int location, int grid_size) { int AlignToGridRoundUp(int location, int grid_size) {
...@@ -99,13 +90,6 @@ int AlignToGridRoundUp(int location, int grid_size) { ...@@ -99,13 +90,6 @@ int AlignToGridRoundUp(int location, int grid_size) {
return (location / grid_size + 1) * grid_size; return (location / grid_size + 1) * grid_size;
} }
gfx::Point ConvertPointToParent(aura::Window* window,
const gfx::Point& point) {
gfx::Point result(point);
aura::Window::ConvertPointToWindow(window, window->parent(), &result);
return result;
}
} // namespace } // namespace
// static // static
...@@ -122,33 +106,40 @@ const int WindowResizer::kBoundsChangeDirection_Horizontal = 1; ...@@ -122,33 +106,40 @@ const int WindowResizer::kBoundsChangeDirection_Horizontal = 1;
// static // static
const int WindowResizer::kBoundsChangeDirection_Vertical = 2; const int WindowResizer::kBoundsChangeDirection_Vertical = 2;
WindowResizer::WindowResizer(aura::Window* window, WindowResizer::Details::Details()
const gfx::Point& location, : window(NULL),
int window_component, window_component(HTNOWHERE),
int grid_size) bounds_change(0),
: window_(window), position_change_direction(0),
initial_bounds_(window->bounds()), size_change_direction(0),
initial_location_in_parent_(ConvertPointToParent(window, location)), is_resizable(false),
window_component_(window_component), grid_size(0) {
bounds_change_(GetBoundsChangeForWindowComponent(window_component_)), }
position_change_direction_(
GetPositionChangeDirectionForWindowComponent(window_component_)), WindowResizer::Details::Details(aura::Window* window,
size_change_direction_( const gfx::Point& location,
GetSizeChangeDirectionForWindowComponent(window_component_)), int window_component,
is_resizable_(bounds_change_ != kBoundsChangeDirection_None), int grid_size)
grid_size_(grid_size), : window(window),
did_move_or_resize_(false), initial_bounds(window->bounds()),
root_filter_(NULL) { initial_location_in_parent(location),
if (is_resizable_) { window_component(window_component),
root_filter_ = Shell::GetInstance()->root_filter(); bounds_change(GetBoundsChangeForWindowComponent(window_component)),
if (root_filter_) position_change_direction(
root_filter_->LockCursor(); GetPositionChangeDirectionForWindowComponent(window_component)),
} size_change_direction(
GetSizeChangeDirectionForWindowComponent(window_component)),
is_resizable(bounds_change != kBoundsChangeDirection_None),
grid_size(grid_size) {
}
WindowResizer::Details::~Details() {
}
WindowResizer::WindowResizer() {
} }
WindowResizer::~WindowResizer() { WindowResizer::~WindowResizer() {
if (root_filter_)
root_filter_->UnlockCursor();
} }
// static // static
...@@ -186,71 +177,35 @@ int WindowResizer::AlignToGrid(int location, int grid_size) { ...@@ -186,71 +177,35 @@ int WindowResizer::AlignToGrid(int location, int grid_size) {
.5f) * grid_size; .5f) * grid_size;
} }
void WindowResizer::Drag(const gfx::Point& location) { // static
gfx::Rect bounds = GetBoundsForDrag(location); gfx::Rect WindowResizer::CalculateBoundsForDrag(
if (bounds != window_->bounds()) { const Details& details,
did_move_or_resize_ = true; const gfx::Point& location) {
window_->SetBounds(bounds); if (!details.is_resizable)
} return details.initial_bounds;
}
void WindowResizer::CompleteDrag() {
if (grid_size_ <= 1 || !did_move_or_resize_)
return;
gfx::Rect new_bounds(GetFinalBounds());
if (new_bounds == window_->bounds())
return;
if (new_bounds.size() != window_->bounds().size()) {
// Don't attempt to animate a size change.
window_->SetBounds(new_bounds);
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);
}
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();
// Dragging a window moves the local coordinate frame, so do arithmetic int delta_x = location.x() - details.initial_location_in_parent.x();
// in the parent coordinate frame. int delta_y = location.y() - details.initial_location_in_parent.y();
gfx::Point event_location_in_parent(location);
aura::Window::ConvertPointToWindow(window_, window_->parent(),
&event_location_in_parent);
int delta_x = event_location_in_parent.x() - initial_location_in_parent_.x();
int delta_y = event_location_in_parent.y() - initial_location_in_parent_.y();
// The minimize size constraint may limit how much we change the window // The minimize size constraint may limit how much we change the window
// position. For example, dragging the left edge to the right should stop // position. For example, dragging the left edge to the right should stop
// repositioning the window when the minimize size is reached. // repositioning the window when the minimize size is reached.
gfx::Size size = GetSizeForDrag(&delta_x, &delta_y); gfx::Size size = GetSizeForDrag(details, &delta_x, &delta_y);
gfx::Point origin = GetOriginForDrag(delta_x, delta_y); gfx::Point origin = GetOriginForDrag(details, delta_x, delta_y);
gfx::Rect new_bounds(origin, size); gfx::Rect new_bounds(origin, size);
// Update bottom edge to stay in the work area when we are resizing // Update bottom edge to stay in the work area when we are resizing
// by dragging the bottome edge or corners. // by dragging the bottome edge or corners.
if (bounds_change_ & kBoundsChange_Resizes && if (details.bounds_change & kBoundsChange_Resizes &&
origin.y() == window_->bounds().y()) { origin.y() == details.window->bounds().y()) {
gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestWindow(window_); gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestWindow(
details.window);
if (new_bounds.bottom() > work_area.bottom()) if (new_bounds.bottom() > work_area.bottom())
new_bounds.Inset(0, 0, 0, new_bounds.Inset(0, 0, 0,
new_bounds.bottom() - work_area.bottom()); new_bounds.bottom() - work_area.bottom());
} }
if (bounds_change_ & kBoundsChange_Resizes && if (details.bounds_change & kBoundsChange_Resizes &&
bounds_change_ & kBoundsChange_Repositions && new_bounds.y() < 0) { details.bounds_change & kBoundsChange_Repositions && new_bounds.y() < 0) {
int delta = new_bounds.y(); int delta = new_bounds.y();
new_bounds.set_y(0); new_bounds.set_y(0);
new_bounds.set_height(new_bounds.height() + delta); new_bounds.set_height(new_bounds.height() + delta);
...@@ -258,20 +213,32 @@ gfx::Rect WindowResizer::GetBoundsForDrag(const gfx::Point& location) { ...@@ -258,20 +213,32 @@ gfx::Rect WindowResizer::GetBoundsForDrag(const gfx::Point& location) {
return new_bounds; return new_bounds;
} }
gfx::Rect WindowResizer::GetFinalBounds() { // static
const gfx::Rect& bounds(window_->bounds()); gfx::Rect WindowResizer::AdjustBoundsToGrid(const Details& details) {
int x = AlignToGrid(bounds.x(), grid_size_); const gfx::Rect& bounds(details.window->bounds());
int y = AlignToGrid(bounds.y(), grid_size_); if (details.grid_size <= 1)
return bounds;
int x = AlignToGrid(bounds.x(), details.grid_size);
int y = AlignToGrid(bounds.y(), details.grid_size);
return gfx::Rect(x, y, bounds.width(), bounds.height()); return gfx::Rect(x, y, bounds.width(), bounds.height());
} }
gfx::Point WindowResizer::GetOriginForDrag( // static
int delta_x, bool WindowResizer::IsBottomEdge(int window_component) {
int delta_y) const { return window_component == HTBOTTOMLEFT ||
gfx::Point origin = initial_bounds_.origin(); window_component == HTBOTTOM ||
if (bounds_change_ & kBoundsChange_Repositions) { window_component == HTBOTTOMRIGHT ||
window_component == HTGROWBOX;
}
// static
gfx::Point WindowResizer::GetOriginForDrag(const Details& details,
int delta_x,
int delta_y) {
gfx::Point origin = details.initial_bounds.origin();
if (details.bounds_change & kBoundsChange_Repositions) {
int pos_change_direction = int pos_change_direction =
GetPositionChangeDirectionForWindowComponent(window_component_); GetPositionChangeDirectionForWindowComponent(details.window_component);
if (pos_change_direction & kBoundsChangeDirection_Horizontal) if (pos_change_direction & kBoundsChangeDirection_Horizontal)
origin.Offset(delta_x, 0); origin.Offset(delta_x, 0);
if (pos_change_direction & kBoundsChangeDirection_Vertical) if (pos_change_direction & kBoundsChangeDirection_Vertical)
...@@ -280,27 +247,32 @@ gfx::Point WindowResizer::GetOriginForDrag( ...@@ -280,27 +247,32 @@ gfx::Point WindowResizer::GetOriginForDrag(
return origin; return origin;
} }
gfx::Size WindowResizer::GetSizeForDrag( // static
int* delta_x, gfx::Size WindowResizer::GetSizeForDrag(const Details& details,
int* delta_y) const { int* delta_x,
gfx::Size size = initial_bounds_.size(); int* delta_y) {
if (bounds_change_ & kBoundsChange_Resizes) { gfx::Size size = details.initial_bounds.size();
gfx::Size min_size = window_->delegate()->GetMinimumSize(); if (details.bounds_change & kBoundsChange_Resizes) {
min_size.set_width(AlignToGridRoundUp(min_size.width(), grid_size_)); gfx::Size min_size = details.window->delegate()->GetMinimumSize();
min_size.set_height(AlignToGridRoundUp(min_size.height(), grid_size_)); min_size.set_width(AlignToGridRoundUp(min_size.width(), details.grid_size));
size.SetSize(GetWidthForDrag(min_size.width(), delta_x), min_size.set_height(AlignToGridRoundUp(min_size.height(),
GetHeightForDrag(min_size.height(), delta_y)); details.grid_size));
size.SetSize(GetWidthForDrag(details, min_size.width(), delta_x),
GetHeightForDrag(details, min_size.height(), delta_y));
} }
return size; return size;
} }
int WindowResizer::GetWidthForDrag(int min_width, int* delta_x) const { // static
int width = initial_bounds_.width(); int WindowResizer::GetWidthForDrag(const Details& details,
if (size_change_direction_ & kBoundsChangeDirection_Horizontal) { int min_width,
int* delta_x) {
int width = details.initial_bounds.width();
if (details.size_change_direction & kBoundsChangeDirection_Horizontal) {
// Along the right edge, positive delta_x increases the window size. // Along the right edge, positive delta_x increases the window size.
int x_multiplier = IsRightEdge(window_component_) ? 1 : -1; int x_multiplier = IsRightEdge(details.window_component) ? 1 : -1;
width += x_multiplier * (*delta_x); width += x_multiplier * (*delta_x);
int adjusted_width = AlignToGrid(width, grid_size_); int adjusted_width = AlignToGrid(width, details.grid_size);
if (adjusted_width != width) { if (adjusted_width != width) {
*delta_x += -x_multiplier * (width - adjusted_width); *delta_x += -x_multiplier * (width - adjusted_width);
width = adjusted_width; width = adjusted_width;
...@@ -310,27 +282,30 @@ int WindowResizer::GetWidthForDrag(int min_width, int* delta_x) const { ...@@ -310,27 +282,30 @@ int WindowResizer::GetWidthForDrag(int min_width, int* delta_x) const {
// for the window origin computation. // for the window origin computation.
if (width < min_width) { if (width < min_width) {
width = min_width; width = min_width;
*delta_x = -x_multiplier * (initial_bounds_.width() - min_width); *delta_x = -x_multiplier * (details.initial_bounds.width() - min_width);
} }
// And don't let the window go bigger than the monitor. // And don't let the window go bigger than the monitor.
int max_width = int max_width =
gfx::Screen::GetMonitorAreaNearestWindow(window_).width(); gfx::Screen::GetMonitorAreaNearestWindow(details.window).width();
if (width > max_width) { if (width > max_width) {
width = max_width; width = max_width;
*delta_x = -x_multiplier * (initial_bounds_.width() - max_width); *delta_x = -x_multiplier * (details.initial_bounds.width() - max_width);
} }
} }
return width; return width;
} }
int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) const { // static
int height = initial_bounds_.height(); int WindowResizer::GetHeightForDrag(const Details& details,
if (size_change_direction_ & kBoundsChangeDirection_Vertical) { int min_height,
int* delta_y) {
int height = details.initial_bounds.height();
if (details.size_change_direction & kBoundsChangeDirection_Vertical) {
// Along the bottom edge, positive delta_y increases the window size. // Along the bottom edge, positive delta_y increases the window size.
int y_multiplier = IsBottomEdge(window_component_) ? 1 : -1; int y_multiplier = IsBottomEdge(details.window_component) ? 1 : -1;
height += y_multiplier * (*delta_y); height += y_multiplier * (*delta_y);
int adjusted_height = AlignToGrid(height, grid_size_); int adjusted_height = AlignToGrid(height, details.grid_size);
if (height != adjusted_height) { if (height != adjusted_height) {
*delta_y += -y_multiplier * (height - adjusted_height); *delta_y += -y_multiplier * (height - adjusted_height);
height = adjusted_height; height = adjusted_height;
...@@ -340,14 +315,15 @@ int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) const { ...@@ -340,14 +315,15 @@ int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) const {
// for the window origin computation. // for the window origin computation.
if (height < min_height) { if (height < min_height) {
height = min_height; height = min_height;
*delta_y = -y_multiplier * (initial_bounds_.height() - min_height); *delta_y = -y_multiplier * (details.initial_bounds.height() - min_height);
} }
// And don't let the window go bigger than the monitor. // And don't let the window go bigger than the monitor.
int max_height = gfx::Screen::GetMonitorAreaNearestWindow(window_).height(); int max_height =
gfx::Screen::GetMonitorAreaNearestWindow(details.window).height();
if (height > max_height) { if (height > max_height) {
height = max_height; height = max_height;
*delta_y = -y_multiplier * (initial_bounds_.height() - max_height); *delta_y = -y_multiplier * (details.initial_bounds.height() - max_height);
} }
} }
return height; return height;
......
...@@ -16,12 +16,9 @@ class Window; ...@@ -16,12 +16,9 @@ class Window;
namespace ash { namespace ash {
namespace internal { // WindowResizer is used by ToplevelWindowEventFilter to handle dragging, moving
class RootWindowEventFilter; // or resizing a window. All coordinates passed to this are in the parent
} // windows coordinates.
// WindowResizer is used by ToplevelWindowEventFilter to handle dragging,
// moving or resizing a window.
class ASH_EXPORT WindowResizer { class ASH_EXPORT WindowResizer {
public: public:
// Constants to identify the type of resize. // Constants to identify the type of resize.
...@@ -34,10 +31,7 @@ class ASH_EXPORT WindowResizer { ...@@ -34,10 +31,7 @@ class ASH_EXPORT WindowResizer {
static const int kBoundsChangeDirection_Horizontal; static const int kBoundsChangeDirection_Horizontal;
static const int kBoundsChangeDirection_Vertical; static const int kBoundsChangeDirection_Vertical;
WindowResizer(aura::Window* window, WindowResizer();
const gfx::Point& location,
int window_component,
int grid_size);
virtual ~WindowResizer(); virtual ~WindowResizer();
// Returns a bitmask of the kBoundsChange_ values. // Returns a bitmask of the kBoundsChange_ values.
...@@ -49,84 +43,80 @@ class ASH_EXPORT WindowResizer { ...@@ -49,84 +43,80 @@ class ASH_EXPORT WindowResizer {
// Invoked to drag/move/resize the window. |location| is in the coordinates // Invoked to drag/move/resize the window. |location| is in the coordinates
// of the window supplied to the constructor. // of the window supplied to the constructor.
void Drag(const gfx::Point& location); virtual void Drag(const gfx::Point& location) = 0;
// Invoked to complete the drag. // Invoked to complete the drag.
virtual void CompleteDrag(); virtual void CompleteDrag() = 0;
// Reverts the drag. // Reverts the drag.
virtual void RevertDrag(); virtual void RevertDrag() = 0;
// Returns true if the drag will result in changing the window in anyway.
bool is_resizable() const { return is_resizable_; }
// See description above members for details.
const gfx::Rect& initial_bounds() const { return initial_bounds_; }
const gfx::Point& initial_location_in_parent() const {
return initial_location_in_parent_;
}
int window_component() const { return window_component_; }
aura::Window* window() const { return window_; }
int grid_size() const { return grid_size_; }
bool did_move_or_resize() const { return did_move_or_resize_; }
int bounds_change() const { return bounds_change_; }
protected: protected:
// Returns the bounds to give to the window once the mouse has moved to struct Details {
// |location|. Details();
virtual gfx::Rect GetBoundsForDrag(const gfx::Point& location); Details(aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size);
~Details();
// Returns the final bounds. This differs from current bounds if a grid_size // The window we're resizing.
// was specified. aura::Window* window;
virtual gfx::Rect GetFinalBounds();
private: // Initial bounds of the window.
// Returns the new origin of the window. The arguments are the difference gfx::Rect initial_bounds;
// between the current location and the initial location.
gfx::Point GetOriginForDrag(int delta_x, int delta_y) const;
// Returns the size of the window for the drag. // Location passed to the constructor, in |window->parent()|'s coordinates.
gfx::Size GetSizeForDrag(int* delta_x, int* delta_y) const; gfx::Point initial_location_in_parent;
// Returns the width of the window. // The component the user pressed on.
int GetWidthForDrag(int min_width, int* delta_x) const; int window_component;
// Returns the height of the drag. // Bitmask of the |kBoundsChange_| constants.
int GetHeightForDrag(int min_height, int* delta_y) const; int bounds_change;
// The window we're resizing. // Bitmask of the |kBoundsChangeDirection_| constants.
aura::Window* window_; int position_change_direction;
// Initial bounds of the window. // Bitmask of the |kBoundsChangeDirection_| constants.
const gfx::Rect initial_bounds_; int size_change_direction;
// Location passed to the constructor, in |window->parent()|'s coordinates. // Will the drag actually modify the window?
const gfx::Point initial_location_in_parent_; bool is_resizable;
// The component the user pressed on. // Size of the grid.
const int window_component_; int grid_size;
};
// Bitmask of the |kBoundsChange_| constants. static gfx::Rect CalculateBoundsForDrag(
const int bounds_change_; const Details& details,
const gfx::Point& location);
// Bitmask of the |kBoundsChangeDirection_| constants. static gfx::Rect AdjustBoundsToGrid(const Details& details);
const int position_change_direction_;
// Bitmask of the |kBoundsChangeDirection_| constants. static bool IsBottomEdge(int component);
const int size_change_direction_;
// Will the drag actually modify the window? private:
const bool is_resizable_; // Returns the new origin of the window. The arguments are the difference
// between the current location and the initial location.
// Size of the grid. static gfx::Point GetOriginForDrag(const Details& details,
const int grid_size_; int delta_x,
int delta_y);
// Set to true once Drag() is invoked and the bounds of the window change. // Returns the size of the window for the drag.
bool did_move_or_resize_; static gfx::Size GetSizeForDrag(const Details& details,
int* delta_x,
int* delta_y);
internal::RootWindowEventFilter* root_filter_; // Returns the width of the window.
static int GetWidthForDrag(const Details& details,
int min_width,
int* delta_x);
DISALLOW_COPY_AND_ASSIGN(WindowResizer); // Returns the height of the drag.
static int GetHeightForDrag(const Details& details,
int min_height,
int* delta_y);
}; };
} // namespace aura } // namespace aura
......
...@@ -93,8 +93,8 @@ WindowResizer* WorkspaceEventFilter::CreateWindowResizer( ...@@ -93,8 +93,8 @@ WindowResizer* WorkspaceEventFilter::CreateWindowResizer(
(window_component != HTCAPTION || GetTrackedByWorkspace(window))) { (window_component != HTCAPTION || GetTrackedByWorkspace(window))) {
return NULL; return NULL;
} }
return return WorkspaceWindowResizer::Create(
new WorkspaceWindowResizer(window, point, window_component, grid_size()); window, point, window_component, grid_size());
} }
void WorkspaceEventFilter::UpdateHoveredWindow( void WorkspaceEventFilter::UpdateHoveredWindow(
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "ash/wm/workspace/workspace_window_resizer.h" #include "ash/wm/workspace/workspace_window_resizer.h"
#include "ash/shell.h"
#include "ash/wm/root_window_event_filter.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_delegate.h" #include "ui/aura/window_delegate.h"
...@@ -25,74 +27,123 @@ const aura::WindowProperty<int> kHeightBeforeObscuredProp = {0}; ...@@ -25,74 +27,123 @@ const aura::WindowProperty<int> kHeightBeforeObscuredProp = {0};
const aura::WindowProperty<int>* const kHeightBeforeObscuredKey = const aura::WindowProperty<int>* const kHeightBeforeObscuredKey =
&kHeightBeforeObscuredProp; &kHeightBeforeObscuredProp;
} // namespace void SetHeightBeforeObscured(aura::Window* window, int height) {
window->SetProperty(kHeightBeforeObscuredKey, height);
}
WorkspaceWindowResizer::WorkspaceWindowResizer(aura::Window* window, int GetHeightBeforeObscured(aura::Window* window) {
const gfx::Point& location, return window->GetProperty(kHeightBeforeObscuredKey);
int window_component,
int grid_size)
: WindowResizer(window, location, window_component, grid_size),
constrain_size_(wm::IsWindowNormal(window)) {
if (is_resizable() && GetHeightBeforeObscured(window) &&
constrain_size_ &&
(!WindowTouchesBottomOfScreen() ||
bounds_change() != kBoundsChange_Repositions)) {
ClearHeightBeforeObscured(window);
}
} }
void ClearHeightBeforeObscured(aura::Window* window) {
window->SetProperty(kHeightBeforeObscuredKey, 0);
}
} // namespace
WorkspaceWindowResizer::~WorkspaceWindowResizer() { WorkspaceWindowResizer::~WorkspaceWindowResizer() {
if (root_filter_)
root_filter_->UnlockCursor();
} }
gfx::Rect WorkspaceWindowResizer::GetBoundsForDrag(const gfx::Point& location) { // static
if (!is_resizable()) WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
return WindowResizer::GetBoundsForDrag(location); aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size) {
Details details(window, location, window_component, grid_size);
return details.is_resizable ?
new WorkspaceWindowResizer(details) : NULL;
}
gfx::Rect bounds(WindowResizer::GetBoundsForDrag(location)); void WorkspaceWindowResizer::Drag(const gfx::Point& location) {
AdjustBounds(&bounds); gfx::Rect bounds = CalculateBoundsForDrag(details_, location);
return bounds; if (constrain_size_)
AdjustBoundsForMainWindow(&bounds);
if (bounds != details_.window->bounds()) {
did_move_or_resize_ = true;
details_.window->SetBounds(bounds);
}
} }
gfx::Rect WorkspaceWindowResizer::GetFinalBounds() { void WorkspaceWindowResizer::CompleteDrag() {
if (grid_size() <= 1 || !GetHeightBeforeObscured(window())) if (details_.grid_size <= 1 || !did_move_or_resize_ ||
return WindowResizer::GetFinalBounds(); details_.window_component != HTCAPTION)
return;
gfx::Rect initial_bounds(window()->bounds());
bool at_bottom = WindowTouchesBottomOfScreen(); gfx::Rect bounds(AdjustBoundsToGrid(details_));
gfx::Rect bounds(WindowResizer::GetFinalBounds()); if (GetHeightBeforeObscured(window()) || constrain_size_) {
if (at_bottom && bounds.y() != initial_bounds.y()) { // Two things can happen:
if (bounds.y() < initial_bounds.y()) { // . We'll snap to the grid, which may result in different bounds. When
bounds.set_height(bounds.height() + grid_size() - // dragging we only snap on release.
(initial_bounds.y() - bounds.y())); // . If the bounds are different, and the windows height was truncated
// because it touched the bottom, than snapping to the grid may cause the
// window to no longer touch the bottom. Push it back up.
gfx::Rect initial_bounds(window()->bounds());
bool at_bottom = TouchesBottomOfScreen();
if (at_bottom && bounds.y() != initial_bounds.y()) {
if (bounds.y() < initial_bounds.y()) {
bounds.set_height(bounds.height() + details_.grid_size -
(initial_bounds.y() - bounds.y()));
}
AdjustBoundsForMainWindow(&bounds);
} }
AdjustBounds(&bounds);
} }
return bounds;
}
// static if (bounds == details_.window->bounds())
void WorkspaceWindowResizer::SetHeightBeforeObscured(aura::Window* window, return;
int height) {
window->SetProperty(kHeightBeforeObscuredKey, height);
}
// static if (bounds.size() != details_.window->bounds().size()) {
void WorkspaceWindowResizer::ClearHeightBeforeObscured(aura::Window* window) { // Don't attempt to animate a size change.
window->SetProperty(kHeightBeforeObscuredKey, 0); details_.window->SetBounds(bounds);
} return;
}
// static ui::ScopedLayerAnimationSettings scoped_setter(
int WorkspaceWindowResizer::GetHeightBeforeObscured(aura::Window* window) { details_.window->layer()->GetAnimator());
return window->GetProperty(kHeightBeforeObscuredKey); // Use a small duration since the grid is small.
scoped_setter.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
details_.window->SetBounds(bounds);
} }
void WorkspaceWindowResizer::AdjustBounds(gfx::Rect* bounds) const { void WorkspaceWindowResizer::RevertDrag() {
if (!constrain_size_) if (!did_move_or_resize_)
return; return;
details_.window->SetBounds(details_.initial_bounds);
}
WorkspaceWindowResizer::WorkspaceWindowResizer(
const Details& details)
: details_(details),
constrain_size_(wm::IsWindowNormal(details.window)),
did_move_or_resize_(false),
root_filter_(NULL) {
DCHECK(details_.is_resizable);
root_filter_ = Shell::GetInstance()->root_filter();
if (root_filter_)
root_filter_->LockCursor();
if (is_resizable() && constrain_size_ &&
(!TouchesBottomOfScreen() ||
details_.bounds_change != kBoundsChange_Repositions)) {
ClearCachedHeights();
}
}
void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
gfx::Rect* bounds) const {
gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window())); gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window()));
AdjustBoundsForWindow(work_area, window(), bounds);
}
void WorkspaceWindowResizer::AdjustBoundsForWindow(
const gfx::Rect& work_area,
aura::Window* window,
gfx::Rect* bounds) const {
if (bounds->bottom() < work_area.bottom()) { if (bounds->bottom() < work_area.bottom()) {
int height = GetHeightBeforeObscured(window()); int height = GetHeightBeforeObscured(window);
if (!height) if (!height)
return; return;
height = std::max(bounds->height(), height); height = std::max(bounds->height(), height);
...@@ -103,20 +154,26 @@ void WorkspaceWindowResizer::AdjustBounds(gfx::Rect* bounds) const { ...@@ -103,20 +154,26 @@ void WorkspaceWindowResizer::AdjustBounds(gfx::Rect* bounds) const {
if (bounds->bottom() == work_area.bottom()) if (bounds->bottom() == work_area.bottom())
return; return;
if (!GetHeightBeforeObscured(window())) if (!GetHeightBeforeObscured(window))
SetHeightBeforeObscured(window(), window()->bounds().height()); SetHeightBeforeObscured(window, window->bounds().height());
gfx::Size min_size = window()->delegate()->GetMinimumSize(); gfx::Size min_size = window->delegate()->GetMinimumSize();
bounds->set_height(std::max(0, work_area.bottom() - bounds->y())); bounds->set_height(
std::max(0, work_area.bottom() - bounds->y()));
if (bounds->height() < min_size.height()) { if (bounds->height() < min_size.height()) {
bounds->set_height(min_size.height()); bounds->set_height(min_size.height());
bounds->set_y(work_area.bottom() - min_size.height()); bounds->set_y(work_area.bottom() - min_size.height());
} }
} }
bool WorkspaceWindowResizer::WindowTouchesBottomOfScreen() const { void WorkspaceWindowResizer::ClearCachedHeights() {
gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window())); ClearHeightBeforeObscured(details_.window);
return window()->bounds().bottom() == work_area.bottom(); }
bool WorkspaceWindowResizer::TouchesBottomOfScreen() const {
gfx::Rect work_area(
gfx::Screen::GetMonitorWorkAreaNearestWindow(details_.window));
return details_.window->bounds().bottom() == work_area.bottom();
} }
} // namespace internal } // namespace internal
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
namespace ash { namespace ash {
namespace internal { namespace internal {
class RootWindowEventFilter;
// WindowResizer implementation for workspaces. This enforces that windows are // WindowResizer implementation for workspaces. This enforces that windows are
// not allowed to vertically move or resize outside of the work area. As windows // not allowed to vertically move or resize outside of the work area. As windows
// are moved outside the work area they are shrunk. We remember the height of // are moved outside the work area they are shrunk. We remember the height of
...@@ -19,33 +21,56 @@ namespace internal { ...@@ -19,33 +21,56 @@ namespace internal {
// attempt to restore the old height. // attempt to restore the old height.
class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
public: public:
WorkspaceWindowResizer(aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size);
virtual ~WorkspaceWindowResizer(); virtual ~WorkspaceWindowResizer();
protected: // Creates a new WorkspaceWindowResizer. The caller takes ownership of the
// WindowResizer overrides: // returned object. Returns NULL if not resizable.
virtual gfx::Rect GetBoundsForDrag(const gfx::Point& location) OVERRIDE; static WorkspaceWindowResizer* Create(
virtual gfx::Rect GetFinalBounds() OVERRIDE; aura::Window* window,
const gfx::Point& location,
int window_component,
int grid_size);
// Returns true if the drag will result in changing the window in anyway.
bool is_resizable() const { return details_.is_resizable; }
const gfx::Point& initial_location_in_parent() const {
return details_.initial_location_in_parent;
}
// Overridden from WindowResizer:
virtual void Drag(const gfx::Point& location);
virtual void CompleteDrag();
virtual void RevertDrag();
private: private:
// Used to maintain the height of the window before we started collapsing it. explicit WorkspaceWindowResizer(const Details& details);
static void SetHeightBeforeObscured(aura::Window* window, int height);
static void ClearHeightBeforeObscured(aura::Window* window);
static int GetHeightBeforeObscured(aura::Window* window);
// Adjusts the bounds to enforce that windows are vertically contained in the // Adjusts the bounds to enforce that windows are vertically contained in the
// work area. // work area.
void AdjustBounds(gfx::Rect* bounds) const; void AdjustBoundsForMainWindow(gfx::Rect* bounds) const;
void AdjustBoundsForWindow(const gfx::Rect& work_area,
aura::Window* window,
gfx::Rect* bounds) const;
// Clears the cached height of the window being dragged.
void ClearCachedHeights();
// Returns true if the window touches the bottom of the work area. // Returns true if the window touches the bottom of the work area.
bool WindowTouchesBottomOfScreen() const; bool TouchesBottomOfScreen() const;
aura::Window* window() const { return details_.window; }
const Details details_;
// True if the window size (height) should be constrained. // True if the window size (height) should be constrained.
const bool constrain_size_; const bool constrain_size_;
// Set to true once Drag() is invoked and the bounds of the window change.
bool did_move_or_resize_;
internal::RootWindowEventFilter* root_filter_;
DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizer); DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizer);
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/string_number_conversions.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
#include "ui/aura/screen_aura.h" #include "ui/aura/screen_aura.h"
#include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_window_delegate.h"
...@@ -54,25 +55,39 @@ class WorkspaceWindowResizerTest : public test::AshTestBase { ...@@ -54,25 +55,39 @@ class WorkspaceWindowResizerTest : public test::AshTestBase {
window_.reset(new aura::Window(&delegate_)); window_.reset(new aura::Window(&delegate_));
window_->Init(ui::Layer::LAYER_NOT_DRAWN); window_->Init(ui::Layer::LAYER_NOT_DRAWN);
window_->SetParent(Shell::GetInstance()->GetRootWindow()); window_->SetParent(Shell::GetInstance()->GetRootWindow());
window2_.reset(new aura::Window(&delegate2_));
window2_->Init(ui::Layer::LAYER_NOT_DRAWN);
window2_->SetParent(Shell::GetInstance()->GetRootWindow());
window3_.reset(new aura::Window(&delegate3_));
window3_->Init(ui::Layer::LAYER_NOT_DRAWN);
window3_->SetParent(Shell::GetInstance()->GetRootWindow());
} }
virtual void TearDown() OVERRIDE { virtual void TearDown() OVERRIDE {
window_.reset(); window_.reset();
window2_.reset();
window3_.reset();
AshTestBase::TearDown(); AshTestBase::TearDown();
} }
protected: protected:
gfx::Point CalculateDragPoint(const WindowResizer& resizer, gfx::Point CalculateDragPoint(const WorkspaceWindowResizer& resizer,
int delta_x,
int delta_y) const { int delta_y) const {
gfx::Point location = resizer.initial_location_in_parent(); gfx::Point location = resizer.initial_location_in_parent();
location.set_x(location.x() + delta_x);
location.set_y(location.y() + delta_y); location.set_y(location.y() + delta_y);
aura::Window::ConvertPointToWindow(window_->parent(), window_.get(),
&location);
return location; return location;
} }
TestWindowDelegate delegate_; TestWindowDelegate delegate_;
TestWindowDelegate delegate2_;
TestWindowDelegate delegate3_;
scoped_ptr<aura::Window> window_; scoped_ptr<aura::Window> window_;
scoped_ptr<aura::Window> window2_;
scoped_ptr<aura::Window> window3_;
private: private:
DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest); DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
...@@ -86,29 +101,32 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag) { ...@@ -86,29 +101,32 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag) {
// Drag down past the bottom of the screen, height should stop when it hits // Drag down past the bottom of the screen, height should stop when it hits
// the bottom. // the bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTBOTTOM, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
EXPECT_TRUE(resizer.is_resizable()); window_.get(), gfx::Point(), HTBOTTOM, 0));
resizer.Drag(CalculateDragPoint(resizer, 600)); ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 600));
EXPECT_EQ(kRootHeight - initial_y, window_->bounds().height()); EXPECT_EQ(kRootHeight - initial_y, window_->bounds().height());
// Drag up 10 and make sure height is the same. // Drag up 10 and make sure height is the same.
resizer.Drag(CalculateDragPoint(resizer, 590)); resizer->Drag(CalculateDragPoint(*resizer, 0, 590));
EXPECT_EQ(kRootHeight - initial_y, window_->bounds().height()); EXPECT_EQ(kRootHeight - initial_y, window_->bounds().height());
} }
{ {
// Move the window down 10 pixels, the height should change. // Move the window down 10 pixels, the height should change.
int initial_height = window_->bounds().height(); int initial_height = window_->bounds().height();
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, 10)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 10));
EXPECT_EQ(initial_height - 10, window_->bounds().height()); EXPECT_EQ(initial_height - 10, window_->bounds().height());
// Move up 10, height should grow. // Move up 10, height should grow.
resizer.Drag(CalculateDragPoint(resizer, 0)); resizer->Drag(CalculateDragPoint(*resizer, 0, 0));
EXPECT_EQ(initial_height, window_->bounds().height()); EXPECT_EQ(initial_height, window_->bounds().height());
// Move up another 10, height shouldn't change. // Move up another 10, height shouldn't change.
resizer.Drag(CalculateDragPoint(resizer, -10)); resizer->Drag(CalculateDragPoint(*resizer, 0, -10));
EXPECT_EQ(initial_height, window_->bounds().height()); EXPECT_EQ(initial_height, window_->bounds().height());
} }
} }
...@@ -120,9 +138,10 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag2) { ...@@ -120,9 +138,10 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag2) {
// Drag down past the bottom of the screen, height should stop when it hits // Drag down past the bottom of the screen, height should stop when it hits
// the bottom. // the bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
EXPECT_TRUE(resizer.is_resizable()); window_.get(), gfx::Point(), HTCAPTION, 0));
resizer.Drag(CalculateDragPoint(resizer, 200)); ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 200));
EXPECT_EQ(500, window_->bounds().y()); EXPECT_EQ(500, window_->bounds().y());
EXPECT_EQ(100, window_->bounds().height()); EXPECT_EQ(100, window_->bounds().height());
// End and start a new drag session. // End and start a new drag session.
...@@ -130,8 +149,10 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag2) { ...@@ -130,8 +149,10 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkOnDrag2) {
{ {
// Drag up 400. // Drag up 400.
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, -400)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, -400));
EXPECT_EQ(100, window_->bounds().y()); EXPECT_EQ(100, window_->bounds().y());
EXPECT_EQ(300, window_->bounds().height()); EXPECT_EQ(300, window_->bounds().height());
} }
...@@ -145,18 +166,21 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkMoveThanMoveUp) { ...@@ -145,18 +166,21 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkMoveThanMoveUp) {
// Drag down past the bottom of the screen, height should stop when it hits // Drag down past the bottom of the screen, height should stop when it hits
// the bottom. // the bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
EXPECT_TRUE(resizer.is_resizable()); window_.get(), gfx::Point(), HTCAPTION, 0));
resizer.Drag(CalculateDragPoint(resizer, 200)); ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 200));
EXPECT_EQ(500, window_->bounds().y()); EXPECT_EQ(500, window_->bounds().y());
EXPECT_EQ(100, window_->bounds().height()); EXPECT_EQ(100, window_->bounds().height());
// End and start a new drag session. // End and start a new drag session.
} }
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, -400)); window_.get(), gfx::Point(), HTCAPTION, 0));
resizer.Drag(CalculateDragPoint(resizer, -450)); ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, -400));
resizer->Drag(CalculateDragPoint(*resizer, 0, -450));
EXPECT_EQ(50, window_->bounds().y()); EXPECT_EQ(50, window_->bounds().y());
EXPECT_EQ(300, window_->bounds().height()); EXPECT_EQ(300, window_->bounds().height());
} }
...@@ -166,11 +190,12 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkMoveThanMoveUp) { ...@@ -166,11 +190,12 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkMoveThanMoveUp) {
TEST_F(WorkspaceWindowResizerTest, ShrinkWithGrid) { TEST_F(WorkspaceWindowResizerTest, ShrinkWithGrid) {
window_->SetBounds(gfx::Rect(0, 300, 400, 296)); window_->SetBounds(gfx::Rect(0, 300, 400, 296));
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 5); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
EXPECT_TRUE(resizer.is_resizable()); window_.get(), gfx::Point(), HTCAPTION, 5));
ASSERT_TRUE(resizer.get());
// Drag down 8 pixels. // Drag down 8 pixels.
resizer.Drag(CalculateDragPoint(resizer, 8)); resizer->Drag(CalculateDragPoint(*resizer, 0, 8));
resizer.CompleteDrag(); resizer->CompleteDrag();
EXPECT_EQ(310, window_->bounds().y()); EXPECT_EQ(310, window_->bounds().y());
EXPECT_EQ(kRootHeight - 310, window_->bounds().height()); EXPECT_EQ(kRootHeight - 310, window_->bounds().height());
} }
...@@ -185,16 +210,20 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkThanGrow) { ...@@ -185,16 +210,20 @@ TEST_F(WorkspaceWindowResizerTest, ShrinkThanGrow) {
// Most past the bottom of the screen, height should stop when it hits the // Most past the bottom of the screen, height should stop when it hits the
// bottom. // bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, 150)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 150));
EXPECT_EQ(550, window_->bounds().y()); EXPECT_EQ(550, window_->bounds().y());
EXPECT_EQ(50, window_->bounds().height()); EXPECT_EQ(50, window_->bounds().height());
} }
// Resize the window 500 pixels up. // Resize the window 500 pixels up.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTTOP, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, -500)); window_.get(), gfx::Point(), HTTOP, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, -500));
EXPECT_EQ(50, window_->bounds().y()); EXPECT_EQ(50, window_->bounds().y());
EXPECT_EQ(550, window_->bounds().height()); EXPECT_EQ(550, window_->bounds().height());
} }
...@@ -208,31 +237,37 @@ TEST_F(WorkspaceWindowResizerTest, DontRememberAfterMove) { ...@@ -208,31 +237,37 @@ TEST_F(WorkspaceWindowResizerTest, DontRememberAfterMove) {
// Most past the bottom of the screen, height should stop when it hits the // Most past the bottom of the screen, height should stop when it hits the
// bottom. // bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, 150)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 150));
EXPECT_EQ(450, window_->bounds().y()); EXPECT_EQ(450, window_->bounds().y());
EXPECT_EQ(150, window_->bounds().height()); EXPECT_EQ(150, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, -150)); resizer->Drag(CalculateDragPoint(*resizer, 0, -150));
EXPECT_EQ(150, window_->bounds().y()); EXPECT_EQ(150, window_->bounds().y());
EXPECT_EQ(300, window_->bounds().height()); EXPECT_EQ(300, window_->bounds().height());
} }
// Resize it slightly. // Resize it slightly.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTBOTTOM, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, -100)); window_.get(), gfx::Point(), HTBOTTOM, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, -100));
EXPECT_EQ(150, window_->bounds().y()); EXPECT_EQ(150, window_->bounds().y());
EXPECT_EQ(200, window_->bounds().height()); EXPECT_EQ(200, window_->bounds().height());
} }
{ {
// Move it down then back up. // Move it down then back up.
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, 400)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 400));
EXPECT_EQ(550, window_->bounds().y()); EXPECT_EQ(550, window_->bounds().y());
EXPECT_EQ(50, window_->bounds().height()); EXPECT_EQ(50, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, 0)); resizer->Drag(CalculateDragPoint(*resizer, 0, 0));
EXPECT_EQ(150, window_->bounds().y()); EXPECT_EQ(150, window_->bounds().y());
EXPECT_EQ(200, window_->bounds().height()); EXPECT_EQ(200, window_->bounds().height());
} }
...@@ -246,24 +281,26 @@ TEST_F(WorkspaceWindowResizerTest, HonorMin) { ...@@ -246,24 +281,26 @@ TEST_F(WorkspaceWindowResizerTest, HonorMin) {
// Most past the bottom of the screen, height should stop when it hits the // Most past the bottom of the screen, height should stop when it hits the
// bottom. // bottom.
{ {
WorkspaceWindowResizer resizer(window_.get(), gfx::Point(), HTCAPTION, 0); scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
resizer.Drag(CalculateDragPoint(resizer, 350)); window_.get(), gfx::Point(), HTCAPTION, 0));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, 350));
EXPECT_EQ(500, window_->bounds().y()); EXPECT_EQ(500, window_->bounds().y());
EXPECT_EQ(100, window_->bounds().height()); EXPECT_EQ(100, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, 300)); resizer->Drag(CalculateDragPoint(*resizer, 0, 300));
EXPECT_EQ(500, window_->bounds().y()); EXPECT_EQ(500, window_->bounds().y());
EXPECT_EQ(100, window_->bounds().height()); EXPECT_EQ(100, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, 250)); resizer->Drag(CalculateDragPoint(*resizer, 0, 250));
EXPECT_EQ(500, window_->bounds().y()); EXPECT_EQ(500, window_->bounds().y());
EXPECT_EQ(100, window_->bounds().height()); EXPECT_EQ(100, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, 100)); resizer->Drag(CalculateDragPoint(*resizer, 0, 100));
EXPECT_EQ(400, window_->bounds().y()); EXPECT_EQ(400, window_->bounds().y());
EXPECT_EQ(200, window_->bounds().height()); EXPECT_EQ(200, window_->bounds().height());
resizer.Drag(CalculateDragPoint(resizer, -100)); resizer->Drag(CalculateDragPoint(*resizer, 0, -100));
EXPECT_EQ(200, window_->bounds().y()); EXPECT_EQ(200, window_->bounds().y());
EXPECT_EQ(300, window_->bounds().height()); EXPECT_EQ(300, window_->bounds().height());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment