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

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: addressed comment 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
« no previous file with comments | « ui/aura_shell/workspace/workspace.h ('k') | ui/aura_shell/workspace/workspace_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 bool Workspace::Contains(aura::Window* window) const { 67 bool Workspace::Contains(aura::Window* window) const {
64 return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); 68 return std::find(windows_.begin(), windows_.end(), window) != windows_.end();
65 } 69 }
66 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* until,
117 aura::Window* target,
118 ShiftDirection direction) {
119 DCHECK(until);
120 DCHECK(!Contains(insert));
121
122 bool shift_reached_until = GetIndexOf(until) >= 0;
123 if (shift_reached_until)
124 RemoveWindow(until);
125 aura::Window* pushed = NULL;
126 if (direction == SHIFT_TO_RIGHT) {
127 aura::Window::Windows::iterator iter =
128 std::find(windows_.begin(), windows_.end(), target);
129 // Insert at |target| position, or at the begining.
130 if (iter == windows_.end())
131 iter = windows_.begin();
132 windows_.insert(iter, insert);
133 if (!shift_reached_until) {
134 pushed = windows_.back();
135 windows_.erase(--windows_.end());
136 }
137 } else {
138 aura::Window::Windows::iterator iter =
139 std::find(windows_.begin(), windows_.end(), target);
140 // Insert after |target|, or at the end.
141 if (iter != windows_.end())
142 ++iter;
143 windows_.insert(iter, insert);
144 if (!shift_reached_until) {
145 pushed = windows_.front();
146 windows_.erase(windows_.begin());
147 }
148 }
149 Layout(shift_reached_until ? until : NULL, NULL);
150 return pushed;
151 }
152
67 void Workspace::Activate() { 153 void Workspace::Activate() {
68 workspace_manager_->SetActiveWorkspace(this); 154 workspace_manager_->SetActiveWorkspace(this);
69 } 155 }
70 156
71 void Workspace::Layout(aura::Window* no_animation) { 157 void Workspace::Layout(aura::Window* ignore, aura::Window* no_animation) {
72 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_); 158 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_);
73 int total_width = 0; 159 int total_width = GetTotalWindowsWidth();
74 for (aura::Window::Windows::const_iterator i = windows_.begin();
75 i != windows_.end();
76 ++i) {
77 if (total_width)
78 total_width += kWindowHorizontalMargin;
79 // TODO(oshima): use restored bounds.
80 total_width += (*i)->bounds().width();
81 }
82
83 if (total_width < work_area.width()) { 160 if (total_width < work_area.width()) {
84 int dx = (work_area.width() - total_width) / 2; 161 int dx = (work_area.width() - total_width) / 2;
85 for (aura::Window::Windows::iterator i = windows_.begin(); 162 for (aura::Window::Windows::iterator i = windows_.begin();
86 i != windows_.end(); 163 i != windows_.end();
87 ++i) { 164 ++i) {
88 MoveWindowTo(*i, 165 if (*i != ignore) {
89 gfx::Point(work_area.x() + dx, work_area.y()), 166 MoveWindowTo(*i,
90 no_animation != *i); 167 gfx::Point(work_area.x() + dx, work_area.y()),
168 no_animation != *i);
169 }
91 dx += (*i)->bounds().width() + kWindowHorizontalMargin; 170 dx += (*i)->bounds().width() + kWindowHorizontalMargin;
92 } 171 }
93 } else { 172 } else {
94 DCHECK_LT(windows_.size(), 3U); 173 DCHECK_LT(windows_.size(), 3U);
95 // TODO(oshima): Figure out general algorithm to layout more than 174 // TODO(oshima): This is messy. Figure out general algorithm to
96 // 2 windows. 175 // layout more than 2 windows.
97 MoveWindowTo(windows_[0], work_area.origin(), no_animation != windows_[0]); 176 if (windows_[0] != ignore) {
98 if (windows_.size() == 2) { 177 MoveWindowTo(windows_[0],
178 work_area.origin(),
179 no_animation != windows_[0]);
180 }
181 if (windows_.size() == 2 && windows_[1] != ignore) {
99 MoveWindowTo(windows_[1], 182 MoveWindowTo(windows_[1],
100 gfx::Point(work_area.right() - windows_[1]->bounds().width(), 183 gfx::Point(work_area.right() - windows_[1]->bounds().width(),
101 work_area.y()), 184 work_area.y()),
102 no_animation != windows_[1]); 185 no_animation != windows_[1]);
103 } 186 }
104 } 187 }
105 } 188 }
106 189
107 int Workspace::GetIndexOf(aura::Window* window) const { 190 int Workspace::GetIndexOf(aura::Window* window) const {
108 aura::Window::Windows::const_iterator i = 191 aura::Window::Windows::const_iterator i =
109 std::find(windows_.begin(), windows_.end(), window); 192 std::find(windows_.begin(), windows_.end(), window);
110 return i == windows_.end() ? -1 : i - windows_.begin(); 193 return i == windows_.end() ? -1 : i - windows_.begin();
111 } 194 }
112 195
113 bool Workspace::CanAdd(aura::Window* window) const { 196 bool Workspace::CanAdd(aura::Window* window) const {
114 // TODO(oshima): This should be based on available space and the 197 // TODO(oshima): This should be based on available space and the
115 // size of the |window|. 198 // size of the |window|.
116 NOTIMPLEMENTED(); 199 NOTIMPLEMENTED();
117 return windows_.size() < 2; 200 return windows_.size() < g_max_windows_per_workspace;
118 } 201 }
119 202
120 void Workspace::MoveWindowTo( 203 void Workspace::MoveWindowTo(
121 aura::Window* window, 204 aura::Window* window,
122 const gfx::Point& origin, 205 const gfx::Point& origin,
123 bool animate) { 206 bool animate) {
124 if (window->show_state() == ui::SHOW_STATE_FULLSCREEN) 207 if (window->show_state() == ui::SHOW_STATE_FULLSCREEN)
125 window->Fullscreen(); 208 window->Fullscreen();
126 else if (window->show_state() == ui::SHOW_STATE_MAXIMIZED) 209 else if (window->show_state() == ui::SHOW_STATE_MAXIMIZED)
127 window->Maximize(); 210 window->Maximize();
128 else { 211 else {
129 gfx::Rect bounds = window->GetTargetBounds(); 212 gfx::Rect bounds = window->GetTargetBounds();
130 bounds.set_origin(origin); 213 bounds.set_origin(origin);
131 if (animate) 214 if (animate)
132 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation()); 215 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation());
133 window->SetBounds(bounds); 216 window->SetBounds(bounds);
134 } 217 }
135 } 218 }
136 219
220 int Workspace::GetTotalWindowsWidth() const {
221 int total_width = 0;
222 for (aura::Window::Windows::const_iterator i = windows_.begin();
223 i != windows_.end();
224 ++i) {
225 if (total_width)
226 total_width += kWindowHorizontalMargin;
227 // TODO(oshima): use restored bounds.
228 total_width += (*i)->bounds().width();
229 }
230 return total_width;
231 }
232
233 // static
234 size_t Workspace::SetMaxWindowsCount(size_t max) {
235 int old = g_max_windows_per_workspace;
236 g_max_windows_per_workspace = max;
237 return old;
238 }
239
137 } // namespace aura_shell 240 } // namespace aura_shell
OLDNEW
« no previous file with comments | « ui/aura_shell/workspace/workspace.h ('k') | ui/aura_shell/workspace/workspace_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698