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

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

Issue 9035001: Move some more WM functionality down into ash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 12 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/aura_shell/workspace/workspace_manager.h"
6
7 #include <algorithm>
8
9 #include "base/auto_reset.h"
10 #include "base/logging.h"
11 #include "base/stl_util.h"
12 #include "ui/aura/root_window.h"
13 #include "ui/aura/screen_aura.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura_shell/workspace/workspace.h"
16 #include "ui/aura_shell/workspace/workspace_observer.h"
17 #include "ui/gfx/compositor/layer.h"
18 #include "ui/gfx/compositor/layer_animator.h"
19 #include "ui/gfx/screen.h"
20 #include "ui/gfx/transform.h"
21
22 namespace {
23
24 // The horizontal margein between workspaces in pixels.
25 const int kWorkspaceHorizontalMargin = 50;
26
27 // Minimum/maximum scale for overview mode.
28 const float kMaxOverviewScale = 0.9f;
29 const float kMinOverviewScale = 0.3f;
30
31 }
32
33 namespace aura_shell {
34 namespace internal {
35
36 ////////////////////////////////////////////////////////////////////////////////
37 // WindowManager, public:
38
39 WorkspaceManager::WorkspaceManager(aura::Window* contents_view)
40 : contents_view_(contents_view),
41 active_workspace_(NULL),
42 workspace_size_(
43 gfx::Screen::GetMonitorAreaNearestWindow(contents_view_).size()),
44 is_overview_(false),
45 layout_in_progress_(false),
46 ignored_window_(NULL) {
47 DCHECK(contents_view);
48 }
49
50 WorkspaceManager::~WorkspaceManager() {
51 std::vector<Workspace*> copy_to_delete(workspaces_);
52 STLDeleteElements(&copy_to_delete);
53 }
54
55 Workspace* WorkspaceManager::CreateWorkspace() {
56 Workspace* workspace = new Workspace(this);
57 LayoutWorkspaces();
58 return workspace;
59 }
60
61 Workspace* WorkspaceManager::GetActiveWorkspace() const {
62 return active_workspace_;
63 }
64
65 Workspace* WorkspaceManager::FindBy(aura::Window* window) const {
66 int index = GetWorkspaceIndexContaining(window);
67 return index < 0 ? NULL : workspaces_[index];
68 }
69
70 aura::Window* WorkspaceManager::FindRotateWindowForLocation(
71 const gfx::Point& point) {
72 for (Workspaces::const_iterator i = workspaces_.begin();
73 i != workspaces_.end();
74 ++i) {
75 aura::Window* window = (*i)->FindRotateWindowForLocation(point);
76 if (window)
77 return window;
78 }
79 return NULL;
80 }
81
82 void WorkspaceManager::LayoutWorkspaces() {
83 UpdateContentsView();
84
85 gfx::Rect bounds(workspace_size_);
86 int x = 0;
87 for (Workspaces::const_iterator i = workspaces_.begin();
88 i != workspaces_.end();
89 ++i) {
90 Workspace* workspace = *i;
91 bounds.set_x(x);
92 workspace->SetBounds(bounds);
93 x += bounds.width() + kWorkspaceHorizontalMargin;
94 }
95 }
96
97 gfx::Rect WorkspaceManager::GetDragAreaBounds() {
98 return GetWorkAreaBounds(gfx::Rect(contents_view_->bounds().size()));
99 }
100
101 void WorkspaceManager::SetOverview(bool overview) {
102 if (is_overview_ == overview)
103 return;
104 is_overview_ = overview;
105
106 ui::Transform transform;
107 if (is_overview_) {
108 // TODO(oshima|sky): We limit the how small windows can be shrinked
109 // in overview mode, thus part of the contents_view may not be visible.
110 // We need to add capability to scroll/move contents_view in overview mode.
111 float scale = std::min(
112 kMaxOverviewScale,
113 workspace_size_.width() /
114 static_cast<float>(contents_view_->bounds().width()));
115 scale = std::max(kMinOverviewScale, scale);
116
117 transform.SetScale(scale, scale);
118
119 int overview_width = contents_view_->bounds().width() * scale;
120 int dx = 0;
121 if (overview_width < workspace_size_.width()) {
122 dx = (workspace_size_.width() - overview_width) / 2;
123 } else if (active_workspace_) {
124 // Center the active workspace.
125 int active_workspace_mid_x = (active_workspace_->bounds().x() +
126 active_workspace_->bounds().width() / 2) * scale;
127 dx = workspace_size_.width() / 2 - active_workspace_mid_x;
128 dx = std::min(0, std::max(dx, workspace_size_.width() - overview_width));
129 }
130
131 transform.SetTranslateX(dx);
132 transform.SetTranslateY(workspace_size_.height() * (1.0f - scale) / 2);
133 } else if (active_workspace_) {
134 transform.SetTranslateX(-active_workspace_->bounds().x());
135 }
136
137 ui::LayerAnimator::ScopedSettings settings(
138 contents_view_->layer()->GetAnimator());
139 contents_view_->layer()->SetTransform(transform);
140 }
141
142 void WorkspaceManager::RotateWindows(aura::Window* source,
143 aura::Window* target) {
144 DCHECK(source);
145 DCHECK(target);
146 int source_ws_index = GetWorkspaceIndexContaining(source);
147 int target_ws_index = GetWorkspaceIndexContaining(target);
148 DCHECK(source_ws_index >= 0);
149 DCHECK(target_ws_index >= 0);
150 if (source_ws_index == target_ws_index) {
151 workspaces_[source_ws_index]->RotateWindows(source, target);
152 } else {
153 aura::Window* insert = source;
154 aura::Window* target_to_insert = target;
155 if (source_ws_index < target_ws_index) {
156 for (int i = target_ws_index; i >= source_ws_index; --i) {
157 insert = workspaces_[i]->ShiftWindows(
158 insert, source, target_to_insert, Workspace::SHIFT_TO_LEFT);
159 // |target| can only be in the 1st workspace.
160 target_to_insert = NULL;
161 }
162 } else {
163 for (int i = target_ws_index; i <= source_ws_index; ++i) {
164 insert = workspaces_[i]->ShiftWindows(
165 insert, source, target_to_insert, Workspace::SHIFT_TO_RIGHT);
166 // |target| can only be in the 1st workspace.
167 target_to_insert = NULL;
168 }
169 }
170 }
171 FOR_EACH_OBSERVER(WorkspaceObserver, observers_,
172 WindowMoved(this, source, target));
173 workspaces_[target_ws_index]->Activate();
174 }
175
176 void WorkspaceManager::SetWorkspaceSize(const gfx::Size& workspace_size) {
177 if (workspace_size == workspace_size_)
178 return;
179 workspace_size_ = workspace_size;
180 LayoutWorkspaces();
181 }
182
183 void WorkspaceManager::AddObserver(WorkspaceObserver* observer) {
184 observers_.AddObserver(observer);
185 }
186
187 void WorkspaceManager::RemoveObserver(WorkspaceObserver* observer) {
188 observers_.RemoveObserver(observer);
189 }
190
191 ////////////////////////////////////////////////////////////////////////////////
192 // WorkspaceManager, private:
193
194 void WorkspaceManager::AddWorkspace(Workspace* workspace) {
195 Workspaces::iterator i = std::find(workspaces_.begin(),
196 workspaces_.end(),
197 workspace);
198 DCHECK(i == workspaces_.end());
199 workspaces_.push_back(workspace);
200 }
201
202 void WorkspaceManager::RemoveWorkspace(Workspace* workspace) {
203 Workspaces::iterator i = std::find(workspaces_.begin(),
204 workspaces_.end(),
205 workspace);
206 DCHECK(i != workspaces_.end());
207 Workspace* old = NULL;
208
209 if (workspace == active_workspace_) {
210 old = active_workspace_;
211 active_workspace_ = NULL;
212 }
213 workspaces_.erase(i);
214 LayoutWorkspaces();
215
216 if (old) {
217 FOR_EACH_OBSERVER(WorkspaceObserver, observers_,
218 ActiveWorkspaceChanged(this, old));
219 }
220 }
221
222 void WorkspaceManager::SetActiveWorkspace(Workspace* workspace) {
223 if (active_workspace_ == workspace)
224 return;
225 DCHECK(std::find(workspaces_.begin(), workspaces_.end(),
226 workspace) != workspaces_.end());
227 Workspace* old = active_workspace_;
228 active_workspace_ = workspace;
229
230 is_overview_ = false;
231 UpdateContentsView();
232
233 FOR_EACH_OBSERVER(WorkspaceObserver, observers_,
234 ActiveWorkspaceChanged(this, old));
235 }
236
237 gfx::Rect WorkspaceManager::GetWorkAreaBounds(
238 const gfx::Rect& workspace_bounds) {
239 gfx::Rect bounds = workspace_bounds;
240 bounds.Inset(
241 aura::RootWindow::GetInstance()->screen()->work_area_insets());
242 return bounds;
243 }
244
245 // Returns the index of the workspace that contains the |window|.
246 int WorkspaceManager::GetWorkspaceIndexContaining(aura::Window* window) const {
247 for (Workspaces::const_iterator i = workspaces_.begin();
248 i != workspaces_.end();
249 ++i) {
250 if ((*i)->Contains(window))
251 return i - workspaces_.begin();
252 }
253 return -1;
254 }
255
256 void WorkspaceManager::UpdateContentsView() {
257 int num_workspaces = std::max(1, static_cast<int>(workspaces_.size()));
258 int total_width = workspace_size_.width() * num_workspaces +
259 kWorkspaceHorizontalMargin * (num_workspaces - 1);
260 gfx::Rect bounds(0, 0, total_width, workspace_size_.height());
261
262 if (contents_view_->GetTargetBounds() != bounds)
263 contents_view_->SetBounds(bounds);
264
265 // Move to active workspace.
266 if (active_workspace_) {
267 ui::Transform transform;
268 transform.SetTranslateX(-active_workspace_->bounds().x());
269 ui::LayerAnimator::ScopedSettings settings(
270 contents_view_->layer()->GetAnimator());
271 contents_view_->SetTransform(transform);
272 }
273 }
274
275 } // namespace internal
276 } // namespace aura_shell
OLDNEW
« no previous file with comments | « ui/aura_shell/workspace/workspace_manager.h ('k') | ui/aura_shell/workspace/workspace_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698