Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: ash/wm/workspace/workspace_window_resizer.cc

Issue 9599007: Minor refactoring of window resize code. I wasn't too happy with (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/workspace/workspace_window_resizer.h" 5 #include "ash/wm/workspace/workspace_window_resizer.h"
6 6
7 #include "ash/shell.h"
8 #include "ash/wm/root_window_event_filter.h"
7 #include "ash/wm/window_util.h" 9 #include "ash/wm/window_util.h"
8 #include "ui/aura/window.h" 10 #include "ui/aura/window.h"
9 #include "ui/aura/window_delegate.h" 11 #include "ui/aura/window_delegate.h"
10 #include "ui/aura/window_property.h" 12 #include "ui/aura/window_property.h"
11 #include "ui/base/hit_test.h" 13 #include "ui/base/hit_test.h"
12 #include "ui/gfx/compositor/scoped_layer_animation_settings.h" 14 #include "ui/gfx/compositor/scoped_layer_animation_settings.h"
13 #include "ui/gfx/compositor/layer.h" 15 #include "ui/gfx/compositor/layer.h"
14 #include "ui/gfx/screen.h" 16 #include "ui/gfx/screen.h"
15 #include "ui/gfx/transform.h" 17 #include "ui/gfx/transform.h"
16 18
17 DECLARE_WINDOW_PROPERTY_TYPE(int) 19 DECLARE_WINDOW_PROPERTY_TYPE(int)
18 20
19 namespace ash { 21 namespace ash {
20 namespace internal { 22 namespace internal {
21 23
22 namespace { 24 namespace {
23 25
24 const aura::WindowProperty<int> kHeightBeforeObscuredProp = {0}; 26 const aura::WindowProperty<int> kHeightBeforeObscuredProp = {0};
25 const aura::WindowProperty<int>* const kHeightBeforeObscuredKey = 27 const aura::WindowProperty<int>* const kHeightBeforeObscuredKey =
26 &kHeightBeforeObscuredProp; 28 &kHeightBeforeObscuredProp;
27 29
30 void SetHeightBeforeObscured(aura::Window* window, int height) {
31 window->SetProperty(kHeightBeforeObscuredKey, height);
32 }
33
34 int GetHeightBeforeObscured(aura::Window* window) {
35 return window->GetProperty(kHeightBeforeObscuredKey);
36 }
37
38 void ClearHeightBeforeObscured(aura::Window* window) {
39 window->SetProperty(kHeightBeforeObscuredKey, 0);
40 }
41
28 } // namespace 42 } // namespace
29 43
30 WorkspaceWindowResizer::WorkspaceWindowResizer(aura::Window* window, 44 WorkspaceWindowResizer::~WorkspaceWindowResizer() {
31 const gfx::Point& location, 45 if (root_filter_)
32 int window_component, 46 root_filter_->UnlockCursor();
33 int grid_size) 47 }
34 : WindowResizer(window, location, window_component, grid_size), 48
35 constrain_size_(wm::IsWindowNormal(window)) { 49 // static
36 if (is_resizable() && GetHeightBeforeObscured(window) && 50 WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
37 constrain_size_ && 51 aura::Window* window,
38 (!WindowTouchesBottomOfScreen() || 52 const gfx::Point& location,
39 bounds_change() != kBoundsChange_Repositions)) { 53 int window_component,
40 ClearHeightBeforeObscured(window); 54 int grid_size) {
55 Details details(window, location, window_component, grid_size);
56 return details.is_resizable ?
57 new WorkspaceWindowResizer(details) : NULL;
58 }
59
60 void WorkspaceWindowResizer::Drag(const gfx::Point& location) {
61 gfx::Rect bounds = CalculateBoundsForDrag(details_, location);
62 if (constrain_size_)
63 AdjustBoundsForMainWindow(&bounds);
64 if (bounds != details_.window->bounds()) {
65 did_move_or_resize_ = true;
66 details_.window->SetBounds(bounds);
41 } 67 }
42 } 68 }
43 69
44 WorkspaceWindowResizer::~WorkspaceWindowResizer() { 70 void WorkspaceWindowResizer::CompleteDrag() {
71 if (details_.grid_size <= 1 || !did_move_or_resize_ ||
72 details_.window_component != HTCAPTION)
73 return;
74
75 gfx::Rect bounds(AdjustBoundsToGrid(details_));
76 if (GetHeightBeforeObscured(window()) || constrain_size_) {
77 // Two things can happen:
78 // . We'll snap to the grid, which may result in different bounds. When
79 // dragging we only snap on release.
80 // . If the bounds are different, and the windows height was truncated
81 // because it touched the bottom, than snapping to the grid may cause the
82 // window to no longer touch the bottom. Push it back up.
83 gfx::Rect initial_bounds(window()->bounds());
84 bool at_bottom = TouchesBottomOfScreen();
85 if (at_bottom && bounds.y() != initial_bounds.y()) {
86 if (bounds.y() < initial_bounds.y()) {
87 bounds.set_height(bounds.height() + details_.grid_size -
88 (initial_bounds.y() - bounds.y()));
89 }
90 AdjustBoundsForMainWindow(&bounds);
91 }
92 }
93
94 if (bounds == details_.window->bounds())
95 return;
96
97 if (bounds.size() != details_.window->bounds().size()) {
98 // Don't attempt to animate a size change.
99 details_.window->SetBounds(bounds);
100 return;
101 }
102
103 ui::ScopedLayerAnimationSettings scoped_setter(
104 details_.window->layer()->GetAnimator());
105 // Use a small duration since the grid is small.
106 scoped_setter.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
107 details_.window->SetBounds(bounds);
45 } 108 }
46 109
47 gfx::Rect WorkspaceWindowResizer::GetBoundsForDrag(const gfx::Point& location) { 110 void WorkspaceWindowResizer::RevertDrag() {
48 if (!is_resizable()) 111 if (!did_move_or_resize_)
49 return WindowResizer::GetBoundsForDrag(location); 112 return;
50 113
51 gfx::Rect bounds(WindowResizer::GetBoundsForDrag(location)); 114 details_.window->SetBounds(details_.initial_bounds);
52 AdjustBounds(&bounds);
53 return bounds;
54 } 115 }
55 116
56 gfx::Rect WorkspaceWindowResizer::GetFinalBounds() { 117 WorkspaceWindowResizer::WorkspaceWindowResizer(
57 if (grid_size() <= 1 || !GetHeightBeforeObscured(window())) 118 const Details& details)
58 return WindowResizer::GetFinalBounds(); 119 : details_(details),
120 constrain_size_(wm::IsWindowNormal(details.window)),
121 did_move_or_resize_(false),
122 root_filter_(NULL) {
123 DCHECK(details_.is_resizable);
124 root_filter_ = Shell::GetInstance()->root_filter();
125 if (root_filter_)
126 root_filter_->LockCursor();
59 127
60 gfx::Rect initial_bounds(window()->bounds()); 128 if (is_resizable() && constrain_size_ &&
61 bool at_bottom = WindowTouchesBottomOfScreen(); 129 (!TouchesBottomOfScreen() ||
62 gfx::Rect bounds(WindowResizer::GetFinalBounds()); 130 details_.bounds_change != kBoundsChange_Repositions)) {
63 if (at_bottom && bounds.y() != initial_bounds.y()) { 131 ClearCachedHeights();
64 if (bounds.y() < initial_bounds.y()) {
65 bounds.set_height(bounds.height() + grid_size() -
66 (initial_bounds.y() - bounds.y()));
67 }
68 AdjustBounds(&bounds);
69 } 132 }
70 return bounds;
71 } 133 }
72 134
73 // static 135 void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
74 void WorkspaceWindowResizer::SetHeightBeforeObscured(aura::Window* window, 136 gfx::Rect* bounds) const {
75 int height) { 137 gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window()));
76 window->SetProperty(kHeightBeforeObscuredKey, height); 138 AdjustBoundsForWindow(work_area, window(), bounds);
77 } 139 }
78 140
79 // static 141 void WorkspaceWindowResizer::AdjustBoundsForWindow(
80 void WorkspaceWindowResizer::ClearHeightBeforeObscured(aura::Window* window) { 142 const gfx::Rect& work_area,
81 window->SetProperty(kHeightBeforeObscuredKey, 0); 143 aura::Window* window,
82 } 144 gfx::Rect* bounds) const {
83
84 // static
85 int WorkspaceWindowResizer::GetHeightBeforeObscured(aura::Window* window) {
86 return window->GetProperty(kHeightBeforeObscuredKey);
87 }
88
89 void WorkspaceWindowResizer::AdjustBounds(gfx::Rect* bounds) const {
90 if (!constrain_size_)
91 return;
92
93 gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window()));
94 if (bounds->bottom() < work_area.bottom()) { 145 if (bounds->bottom() < work_area.bottom()) {
95 int height = GetHeightBeforeObscured(window()); 146 int height = GetHeightBeforeObscured(window);
96 if (!height) 147 if (!height)
97 return; 148 return;
98 height = std::max(bounds->height(), height); 149 height = std::max(bounds->height(), height);
99 bounds->set_height(std::min(work_area.bottom() - bounds->y(), height)); 150 bounds->set_height(std::min(work_area.bottom() - bounds->y(), height));
100 return; 151 return;
101 } 152 }
102 153
103 if (bounds->bottom() == work_area.bottom()) 154 if (bounds->bottom() == work_area.bottom())
104 return; 155 return;
105 156
106 if (!GetHeightBeforeObscured(window())) 157 if (!GetHeightBeforeObscured(window))
107 SetHeightBeforeObscured(window(), window()->bounds().height()); 158 SetHeightBeforeObscured(window, window->bounds().height());
108 159
109 gfx::Size min_size = window()->delegate()->GetMinimumSize(); 160 gfx::Size min_size = window->delegate()->GetMinimumSize();
110 bounds->set_height(std::max(0, work_area.bottom() - bounds->y())); 161 bounds->set_height(
162 std::max(0, work_area.bottom() - bounds->y()));
111 if (bounds->height() < min_size.height()) { 163 if (bounds->height() < min_size.height()) {
112 bounds->set_height(min_size.height()); 164 bounds->set_height(min_size.height());
113 bounds->set_y(work_area.bottom() - min_size.height()); 165 bounds->set_y(work_area.bottom() - min_size.height());
114 } 166 }
115 } 167 }
116 168
117 bool WorkspaceWindowResizer::WindowTouchesBottomOfScreen() const { 169 void WorkspaceWindowResizer::ClearCachedHeights() {
118 gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window())); 170 ClearHeightBeforeObscured(details_.window);
119 return window()->bounds().bottom() == work_area.bottom(); 171 }
172
173 bool WorkspaceWindowResizer::TouchesBottomOfScreen() const {
174 gfx::Rect work_area(
175 gfx::Screen::GetMonitorWorkAreaNearestWindow(details_.window));
176 return details_.window->bounds().bottom() == work_area.bottom();
120 } 177 }
121 178
122 } // namespace internal 179 } // namespace internal
123 } // namespace ash 180 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_window_resizer.h ('k') | ash/wm/workspace/workspace_window_resizer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698