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

Side by Side Diff: ui/aura_shell/workspace/workspace.cc

Issue 8391035: Drag and rotate windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rotate windows Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/aura_shell/workspace/workspace.h" 5 #include "ui/aura_shell/workspace/workspace.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ui/aura/desktop.h"
8 #include "ui/aura/window.h" 9 #include "ui/aura/window.h"
9 #include "ui/aura_shell/workspace/workspace_manager.h" 10 #include "ui/aura_shell/workspace/workspace_manager.h"
10 #include "ui/gfx/compositor/layer.h" 11 #include "ui/gfx/compositor/layer.h"
11 12
12 namespace { 13 namespace {
13 // Horizontal margin between windows. 14 // Horizontal margin between windows.
14 const int kWindowHorizontalMargin = 10; 15 const int kWindowHorizontalMargin = 10;
16
17 // Maximum number of windows a workspace can have.
18 size_t g_max_windows_per_workspace = 2;
15 } 19 }
16 20
17 namespace aura_shell { 21 namespace aura_shell {
18 22
19 Workspace::Workspace(WorkspaceManager* manager) 23 Workspace::Workspace(WorkspaceManager* manager)
20 : workspace_manager_(manager) { 24 : workspace_manager_(manager) {
21 workspace_manager_->AddWorkspace(this); 25 workspace_manager_->AddWorkspace(this);
22 } 26 }
23 27
24 Workspace::~Workspace() { 28 Workspace::~Workspace() {
25 workspace_manager_->RemoveWorkspace(this); 29 workspace_manager_->RemoveWorkspace(this);
26 } 30 }
27 31
28 void Workspace::SetBounds(const gfx::Rect& bounds) { 32 void Workspace::SetBounds(const gfx::Rect& bounds) {
29 bool bounds_changed = bounds_ != bounds; 33 bool bounds_changed = bounds_ != bounds;
30 bounds_ = bounds; 34 bounds_ = bounds;
31 if (bounds_changed) 35 if (bounds_changed)
32 Layout(NULL); 36 Layout(NULL, NULL);
33 } 37 }
34 38
35 gfx::Rect Workspace::GetWorkAreaBounds() const { 39 gfx::Rect Workspace::GetWorkAreaBounds() const {
36 return workspace_manager_->GetWorkAreaBounds(bounds_); 40 return workspace_manager_->GetWorkAreaBounds(bounds_);
37 } 41 }
38 42
39 bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) { 43 bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) {
40 if (!CanAdd(window)) 44 if (!CanAdd(window))
41 return false; 45 return false;
42 DCHECK(!Contains(window)); 46 DCHECK(!Contains(window));
43 47
44 if (!after) { // insert at the end. 48 if (!after) { // insert at the end.
45 windows_.push_back(window); 49 windows_.push_back(window);
46 } else { 50 } else {
47 DCHECK(Contains(after)); 51 DCHECK(Contains(after));
48 aura::Window::Windows::iterator i = 52 aura::Window::Windows::iterator i =
49 std::find(windows_.begin(), windows_.end(), after); 53 std::find(windows_.begin(), windows_.end(), after);
50 windows_.insert(++i, window); 54 windows_.insert(++i, window);
51 } 55 }
52 Layout(window); 56 Layout(NULL, window);
53 57
54 return true; 58 return true;
55 } 59 }
56 60
57 void Workspace::RemoveWindow(aura::Window* window) { 61 void Workspace::RemoveWindow(aura::Window* window) {
58 DCHECK(Contains(window)); 62 DCHECK(Contains(window));
59 windows_.erase(std::find(windows_.begin(), windows_.end(), window)); 63 windows_.erase(std::find(windows_.begin(), windows_.end(), window));
60 Layout(NULL); 64 Layout(NULL, NULL);
61 } 65 }
62 66
63
64 bool Workspace::Contains(aura::Window* window) const { 67 bool Workspace::Contains(aura::Window* window) const {
65 return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); 68 return std::find(windows_.begin(), windows_.end(), window) != windows_.end();
66 } 69 }
67 70
71 aura::Window* Workspace::FindRotateWindowForLocation(
72 const gfx::Point& position) {
73 aura::Window* active = aura::Desktop::GetInstance()->active_window();
74 if (GetTotalWindowsWidth() < bounds_.width()) {
75 // If all windows fit to the width of the workspace, it returns the
76 // window which contains |position|'s x coordinate.
77 for (aura::Window::Windows::const_iterator i = windows_.begin();
78 i != windows_.end();
79 ++i) {
80 if (active == *i)
81 continue;
82 gfx::Rect bounds = (*i)->GetTargetBounds();
83 if (bounds.x() < position.x() && position.x() < bounds.right())
84 return *i;
85 }
86 } else if (bounds_.x() < position.x() && position.x() < bounds_.right()) {
87 // If windows are overlapping, it divides the workspace into
88 // regions with the same width, and returns the Nth window that
89 // corresponds to the region that contains the |position|.
90 int width = bounds_.width() / windows_.size();
91 size_t index = (position.x() - bounds_.x()) / width;
92 DCHECK(index < windows_.size());
93 aura::Window* window = windows_[index];
94 if (window != active)
95 return window;
96 }
97 return NULL;
98 }
99
100 void Workspace::RotateWindows(aura::Window* source, aura::Window* target) {
101 DCHECK(Contains(source));
102 DCHECK(Contains(target));
103 aura::Window::Windows::iterator source_iter =
104 std::find(windows_.begin(), windows_.end(), source);
105 aura::Window::Windows::iterator target_iter =
106 std::find(windows_.begin(), windows_.end(), target);
107 DCHECK(source_iter != target_iter);
108 if (source_iter < target_iter)
109 std::rotate(source_iter, source_iter + 1, target_iter + 1);
110 else
111 std::rotate(target_iter, source_iter, source_iter + 1);
112 Layout(source, NULL);
113 }
114
115 aura::Window* Workspace::ShiftWindows(aura::Window* insert,
116 aura::Window* target,
117 ShiftDirection direction) {
118 DCHECK(target);
119 DCHECK(!Contains(insert));
120 bool shift_reached_target = GetIndexOf(target) >= 0;
121 if (shift_reached_target)
122 RemoveWindow(target);
123 aura::Window* pushed = NULL;
124 if (direction == SHIFT_TO_RIGHT) {
125 windows_.insert(windows_.begin(), insert);
126 if (!shift_reached_target) {
127 pushed = windows_.back();
128 windows_.erase(--windows_.end());
129 }
130 } else {
131 windows_.push_back(insert);
132 if (!shift_reached_target) {
133 pushed = windows_.front();
134 windows_.erase(windows_.begin());
135 }
136 }
137 Layout(shift_reached_target ? target : NULL, NULL);
138 return pushed;
139 }
140
68 void Workspace::Activate() { 141 void Workspace::Activate() {
69 workspace_manager_->SetActiveWorkspace(this); 142 workspace_manager_->SetActiveWorkspace(this);
70 } 143 }
71 144
72 void Workspace::Layout(aura::Window* no_animation) { 145 void Workspace::Layout(aura::Window* ignore, aura::Window* no_animation) {
73 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_); 146 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_);
74 int total_width = 0; 147 int total_width = GetTotalWindowsWidth();
75 for (aura::Window::Windows::const_iterator i = windows_.begin();
76 i != windows_.end();
77 i++) {
78 if (total_width)
79 total_width += kWindowHorizontalMargin;
80 // TODO(oshima): use restored bounds.
81 total_width += (*i)->bounds().width();
82 }
83 148
84 if (total_width < work_area.width()) { 149 if (total_width < work_area.width()) {
85 int dx = (work_area.width() - total_width) / 2; 150 int dx = (work_area.width() - total_width) / 2;
86 for (aura::Window::Windows::iterator i = windows_.begin(); 151 for (aura::Window::Windows::iterator i = windows_.begin();
87 i != windows_.end(); 152 i != windows_.end();
88 i++) { 153 ++i) {
89 MoveWindowTo(*i, 154 if (*i != ignore) {
90 gfx::Point(work_area.x() + dx, work_area.y()), 155 MoveWindowTo(*i,
91 no_animation != *i); 156 gfx::Point(work_area.x() + dx, work_area.y()),
157 no_animation != *i);
158 }
92 dx += (*i)->bounds().width() + kWindowHorizontalMargin; 159 dx += (*i)->bounds().width() + kWindowHorizontalMargin;
93 } 160 }
94 } else { 161 } else {
95 DCHECK_LT(windows_.size(), 3U); 162 DCHECK_LT(windows_.size(), 3U);
96 // TODO(oshima): Figure out general algorithm to layout more than 163 // TODO(oshima): This is messy. Figure out general algorithm to
97 // 2 windows. 164 // layout more than 2 windows.
98 MoveWindowTo(windows_[0], work_area.origin(), no_animation != windows_[0]); 165 if (windows_[0] != ignore) {
99 if (windows_.size() == 2) { 166 MoveWindowTo(windows_[0],
167 work_area.origin(),
168 no_animation != windows_[0]);
169 }
170 if (windows_.size() == 2 && windows_[1] != ignore) {
100 MoveWindowTo(windows_[1], 171 MoveWindowTo(windows_[1],
101 gfx::Point(work_area.right() - windows_[1]->bounds().width(), 172 gfx::Point(work_area.right() - windows_[1]->bounds().width(),
102 work_area.y()), 173 work_area.y()),
103 no_animation != windows_[1]); 174 no_animation != windows_[1]);
104 } 175 }
105 } 176 }
106 } 177 }
107 178
108 int Workspace::GetIndexOf(aura::Window* window) const { 179 int Workspace::GetIndexOf(aura::Window* window) const {
109 aura::Window::Windows::const_iterator i = 180 aura::Window::Windows::const_iterator i =
110 std::find(windows_.begin(), windows_.end(), window); 181 std::find(windows_.begin(), windows_.end(), window);
111 return i == windows_.end() ? -1 : i - windows_.begin(); 182 return i == windows_.end() ? -1 : i - windows_.begin();
112 } 183 }
113 184
114 bool Workspace::CanAdd(aura::Window* window) const { 185 bool Workspace::CanAdd(aura::Window* window) const {
115 // TODO(oshima): This should be based on available space and the 186 // TODO(oshima): This should be based on available space and the
116 // size of the |window|. 187 // size of the |window|.
117 NOTIMPLEMENTED(); 188 NOTIMPLEMENTED();
118 return windows_.size() < 2; 189 return windows_.size() < g_max_windows_per_workspace;
119 } 190 }
120 191
121 void Workspace::MoveWindowTo( 192 void Workspace::MoveWindowTo(
122 aura::Window* window, 193 aura::Window* window,
123 const gfx::Point& origin, 194 const gfx::Point& origin,
124 bool animate) { 195 bool animate) {
125 if (window->show_state() == ui::SHOW_STATE_FULLSCREEN) 196 if (window->show_state() == ui::SHOW_STATE_FULLSCREEN)
126 window->Fullscreen(); 197 window->Fullscreen();
127 else if (window->show_state() == ui::SHOW_STATE_MAXIMIZED) 198 else if (window->show_state() == ui::SHOW_STATE_MAXIMIZED)
128 window->Maximize(); 199 window->Maximize();
129 else { 200 else {
130 gfx::Rect bounds = window->GetTargetBounds(); 201 gfx::Rect bounds = window->GetTargetBounds();
131 bounds.set_origin(origin); 202 bounds.set_origin(origin);
132 if (animate) 203 if (animate)
133 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation()); 204 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation());
134 window->SetBounds(bounds); 205 window->SetBounds(bounds);
135 } 206 }
136 } 207 }
137 208
209 int Workspace::GetTotalWindowsWidth() const {
210 int total_width = 0;
211 for (aura::Window::Windows::const_iterator i = windows_.begin();
212 i != windows_.end();
213 ++i) {
214 if (total_width)
215 total_width += kWindowHorizontalMargin;
216 // TODO(oshima): use restored bounds.
217 total_width += (*i)->bounds().width();
218 }
219 return total_width;
220 }
221
222 // static
223 size_t Workspace::SetMaxWindowsCount(size_t max) {
224 int old = g_max_windows_per_workspace;
225 g_max_windows_per_workspace = max;
226 return old;
227 }
228
229
sky 2011/10/27 19:46:41 nit: remove on of these lines.
oshima 2011/10/27 20:25:43 Done.
138 } // namespace aura_shell 230 } // namespace aura_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698