OLD | NEW |
---|---|
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; |
15 } | 16 } |
16 | 17 |
17 namespace aura_shell { | 18 namespace aura_shell { |
18 | 19 |
19 Workspace::Workspace(WorkspaceManager* manager) | 20 Workspace::Workspace(WorkspaceManager* manager) |
20 : workspace_manager_(manager) { | 21 : workspace_manager_(manager) { |
21 workspace_manager_->AddWorkspace(this); | 22 workspace_manager_->AddWorkspace(this); |
22 } | 23 } |
23 | 24 |
24 Workspace::~Workspace() { | 25 Workspace::~Workspace() { |
25 workspace_manager_->RemoveWorkspace(this); | 26 workspace_manager_->RemoveWorkspace(this); |
26 } | 27 } |
27 | 28 |
28 void Workspace::SetBounds(const gfx::Rect& bounds) { | 29 void Workspace::SetBounds(const gfx::Rect& bounds) { |
29 bool bounds_changed = bounds_ != bounds; | 30 bool bounds_changed = bounds_ != bounds; |
30 bounds_ = bounds; | 31 bounds_ = bounds; |
31 if (bounds_changed) | 32 if (bounds_changed) |
32 Layout(NULL); | 33 Layout(NULL, NULL); |
33 } | 34 } |
34 | 35 |
35 gfx::Rect Workspace::GetWorkAreaBounds() const { | 36 gfx::Rect Workspace::GetWorkAreaBounds() const { |
36 return workspace_manager_->GetWorkAreaBounds(bounds_); | 37 return workspace_manager_->GetWorkAreaBounds(bounds_); |
37 } | 38 } |
38 | 39 |
39 bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) { | 40 bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) { |
40 if (!CanAdd(window)) | 41 if (!CanAdd(window)) |
41 return false; | 42 return false; |
42 DCHECK(!Contains(window)); | 43 DCHECK(!Contains(window)); |
43 | 44 |
44 if (!after) { // insert at the end. | 45 if (!after) { // insert at the end. |
45 windows_.push_back(window); | 46 windows_.push_back(window); |
46 } else { | 47 } else { |
47 DCHECK(Contains(after)); | 48 DCHECK(Contains(after)); |
48 aura::Window::Windows::iterator i = | 49 aura::Window::Windows::iterator i = |
49 std::find(windows_.begin(), windows_.end(), after); | 50 std::find(windows_.begin(), windows_.end(), after); |
50 windows_.insert(++i, window); | 51 windows_.insert(++i, window); |
51 } | 52 } |
52 Layout(window); | 53 Layout(NULL, window); |
53 | 54 |
54 return true; | 55 return true; |
55 } | 56 } |
56 | 57 |
57 void Workspace::RemoveWindow(aura::Window* window) { | 58 void Workspace::RemoveWindow(aura::Window* window) { |
58 DCHECK(Contains(window)); | 59 DCHECK(Contains(window)); |
59 windows_.erase(std::find(windows_.begin(), windows_.end(), window)); | 60 windows_.erase(std::find(windows_.begin(), windows_.end(), window)); |
60 Layout(NULL); | 61 Layout(NULL, NULL); |
61 } | 62 } |
62 | 63 |
63 | 64 |
64 bool Workspace::Contains(aura::Window* window) const { | 65 bool Workspace::Contains(aura::Window* window) const { |
65 return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); | 66 return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); |
66 } | 67 } |
67 | 68 |
69 aura::Window* Workspace::FindSwapWindowForLocation(const gfx::Point& position) { | |
70 // If all windows fits to the width of workspace, it returns the | |
sky
2011/10/27 00:53:03
Split this comment up and move it into the appropr
oshima
2011/10/27 16:16:27
Done.
| |
71 // window which contains |position|'s x coordinate. If windows are | |
72 // overlapping, it divides the workspace into regions with the same width, | |
73 // and returns the Nth window that corresponds to this region that contains | |
74 // the |position|. | |
75 aura::Window* active = aura::Desktop::GetInstance()->active_window(); | |
76 int total_width = GetTotalWindowsWidth(); | |
77 if (total_width < bounds_.width()) { | |
sky
2011/10/27 00:53:03
nit: make this if (GetTotalWidth() < bounds_.width
oshima
2011/10/27 16:16:27
Done.
| |
78 for (aura::Window::Windows::const_iterator i = windows_.begin(); | |
79 i != windows_.end(); | |
80 ++i) { | |
81 if (active == *i) | |
82 continue; | |
83 gfx::Rect bounds = (*i)->GetTargetBounds(); | |
84 if (bounds.x() < position.x() && position.x() < bounds.right()) | |
85 return *i; | |
86 } | |
87 } else if (bounds_.x() < position.x() && position.x() < bounds_.right()) { | |
88 int width = bounds_.width() / windows_.size(); | |
89 size_t index = (position.x() - bounds_.x()) / width; | |
90 DCHECK(index < windows_.size()); | |
91 aura::Window* window = windows_[index]; | |
92 if (window != active) | |
93 return window; | |
94 } | |
95 return NULL; | |
96 } | |
97 | |
98 void Workspace::SwapWindow(aura::Window* drag, aura::Window* target) { | |
99 int drag_index = GetIndexOf(drag); | |
100 int target_index = GetIndexOf(target); | |
101 DCHECK(drag_index >= 0); | |
102 DCHECK(target_index >= 0); | |
103 std::swap(windows_[drag_index], windows_[target_index]); | |
oshima
2011/10/26 22:48:03
I feel there is better way but i somehow found fin
sky
2011/10/27 00:53:03
I can't think of a better way.
| |
104 Layout(drag, NULL); | |
105 } | |
106 | |
107 void Workspace::ReplaceWindow(aura::Window* orig, | |
108 aura::Window* with, | |
109 bool relayout) { | |
110 DCHECK(Contains(orig)); | |
111 DCHECK(!Contains(with)); | |
112 std::replace(windows_.begin(), windows_.end(), orig, with); | |
113 if (relayout) | |
114 Layout(NULL, NULL); | |
115 } | |
116 | |
68 void Workspace::Activate() { | 117 void Workspace::Activate() { |
69 workspace_manager_->SetActiveWorkspace(this); | 118 workspace_manager_->SetActiveWorkspace(this); |
70 } | 119 } |
71 | 120 |
72 void Workspace::Layout(aura::Window* no_animation) { | 121 void Workspace::Layout(aura::Window* ignore, aura::Window* no_animation) { |
73 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_); | 122 gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_); |
74 int total_width = 0; | 123 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 | 124 |
84 if (total_width < work_area.width()) { | 125 if (total_width < work_area.width()) { |
85 int dx = (work_area.width() - total_width) / 2; | 126 int dx = (work_area.width() - total_width) / 2; |
86 for (aura::Window::Windows::iterator i = windows_.begin(); | 127 for (aura::Window::Windows::iterator i = windows_.begin(); |
87 i != windows_.end(); | 128 i != windows_.end(); |
88 i++) { | 129 ++i) { |
89 MoveWindowTo(*i, | 130 if (*i != ignore) { |
90 gfx::Point(work_area.x() + dx, work_area.y()), | 131 MoveWindowTo(*i, |
91 no_animation != *i); | 132 gfx::Point(work_area.x() + dx, work_area.y()), |
133 no_animation != *i); | |
134 } | |
92 dx += (*i)->bounds().width() + kWindowHorizontalMargin; | 135 dx += (*i)->bounds().width() + kWindowHorizontalMargin; |
93 } | 136 } |
94 } else { | 137 } else { |
95 DCHECK_LT(windows_.size(), 3U); | 138 DCHECK_LT(windows_.size(), 3U); |
96 // TODO(oshima): Figure out general algorithm to layout more than | 139 // TODO(oshima): This is messy. Figure out general algorithm to |
97 // 2 windows. | 140 // layout more than 2 windows. |
98 MoveWindowTo(windows_[0], work_area.origin(), no_animation != windows_[0]); | 141 if (windows_[0] != ignore) { |
99 if (windows_.size() == 2) { | 142 MoveWindowTo(windows_[0], |
143 work_area.origin(), | |
144 no_animation != windows_[0]); | |
145 } | |
146 if (windows_.size() == 2 && windows_[1] != ignore) { | |
100 MoveWindowTo(windows_[1], | 147 MoveWindowTo(windows_[1], |
101 gfx::Point(work_area.right() - windows_[1]->bounds().width(), | 148 gfx::Point(work_area.right() - windows_[1]->bounds().width(), |
102 work_area.y()), | 149 work_area.y()), |
103 no_animation != windows_[1]); | 150 no_animation != windows_[1]); |
104 } | 151 } |
105 } | 152 } |
106 } | 153 } |
107 | 154 |
108 int Workspace::GetIndexOf(aura::Window* window) const { | 155 int Workspace::GetIndexOf(aura::Window* window) const { |
109 aura::Window::Windows::const_iterator i = | 156 aura::Window::Windows::const_iterator i = |
(...skipping 18 matching lines...) Expand all Loading... | |
128 window->Maximize(); | 175 window->Maximize(); |
129 else { | 176 else { |
130 gfx::Rect bounds = window->GetTargetBounds(); | 177 gfx::Rect bounds = window->GetTargetBounds(); |
131 bounds.set_origin(origin); | 178 bounds.set_origin(origin); |
132 if (animate) | 179 if (animate) |
133 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation()); | 180 window->layer()->SetAnimation(aura::Window::CreateDefaultAnimation()); |
134 window->SetBounds(bounds); | 181 window->SetBounds(bounds); |
135 } | 182 } |
136 } | 183 } |
137 | 184 |
185 int Workspace::GetTotalWindowsWidth() const { | |
186 int total_width = 0; | |
187 for (aura::Window::Windows::const_iterator i = windows_.begin(); | |
188 i != windows_.end(); | |
189 ++i) { | |
190 if (total_width) | |
191 total_width += kWindowHorizontalMargin; | |
192 // TODO(oshima): use restored bounds. | |
193 total_width += (*i)->bounds().width(); | |
194 } | |
195 return total_width; | |
196 } | |
197 | |
138 } // namespace aura_shell | 198 } // namespace aura_shell |
OLD | NEW |