Chromium Code Reviews| Index: ui/aura_shell/workspace/workspace.cc |
| diff --git a/ui/aura_shell/workspace/workspace.cc b/ui/aura_shell/workspace/workspace.cc |
| index 8e9f2cda5d8401e96b8737527ccca47062402141..4d04014386e9a1c3dde3142108b203154eeb9a4d 100644 |
| --- a/ui/aura_shell/workspace/workspace.cc |
| +++ b/ui/aura_shell/workspace/workspace.cc |
| @@ -5,6 +5,7 @@ |
| #include "ui/aura_shell/workspace/workspace.h" |
| #include "base/logging.h" |
| +#include "ui/aura/desktop.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura_shell/workspace/workspace_manager.h" |
| #include "ui/gfx/compositor/layer.h" |
| @@ -12,6 +13,9 @@ |
| namespace { |
| // Horizontal margin between windows. |
| const int kWindowHorizontalMargin = 10; |
| + |
| +// Maximum number of windows a workspace can have. |
| +size_t g_max_windows_per_workspace = 2; |
| } |
| namespace aura_shell { |
| @@ -29,7 +33,7 @@ void Workspace::SetBounds(const gfx::Rect& bounds) { |
| bool bounds_changed = bounds_ != bounds; |
| bounds_ = bounds; |
| if (bounds_changed) |
| - Layout(NULL); |
| + Layout(NULL, NULL); |
| } |
| gfx::Rect Workspace::GetWorkAreaBounds() const { |
| @@ -49,7 +53,7 @@ bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) { |
| std::find(windows_.begin(), windows_.end(), after); |
| windows_.insert(++i, window); |
| } |
| - Layout(window); |
| + Layout(NULL, window); |
| return true; |
| } |
| @@ -57,45 +61,124 @@ bool Workspace::AddWindowAfter(aura::Window* window, aura::Window* after) { |
| void Workspace::RemoveWindow(aura::Window* window) { |
| DCHECK(Contains(window)); |
| windows_.erase(std::find(windows_.begin(), windows_.end(), window)); |
| - Layout(NULL); |
| + Layout(NULL, NULL); |
| } |
| bool Workspace::Contains(aura::Window* window) const { |
| return std::find(windows_.begin(), windows_.end(), window) != windows_.end(); |
| } |
| +aura::Window* Workspace::FindRotateWindowForLocation( |
| + const gfx::Point& position) { |
| + aura::Window* active = aura::Desktop::GetInstance()->active_window(); |
| + if (GetTotalWindowsWidth() < bounds_.width()) { |
| + // If all windows fit to the width of the workspace, it returns the |
| + // window which contains |position|'s x coordinate. |
| + for (aura::Window::Windows::const_iterator i = windows_.begin(); |
| + i != windows_.end(); |
| + ++i) { |
| + if (active == *i) |
| + continue; |
| + gfx::Rect bounds = (*i)->GetTargetBounds(); |
| + if (bounds.x() < position.x() && position.x() < bounds.right()) |
| + return *i; |
| + } |
| + } else if (bounds_.x() < position.x() && position.x() < bounds_.right()) { |
| + // If windows are overlapping, it divides the workspace into |
| + // regions with the same width, and returns the Nth window that |
| + // corresponds to the region that contains the |position|. |
| + int width = bounds_.width() / windows_.size(); |
| + size_t index = (position.x() - bounds_.x()) / width; |
| + DCHECK(index < windows_.size()); |
| + aura::Window* window = windows_[index]; |
| + if (window != active) |
| + return window; |
| + } |
| + return NULL; |
| +} |
| + |
| +void Workspace::RotateWindows(aura::Window* source, aura::Window* target) { |
| + DCHECK(Contains(source)); |
| + DCHECK(Contains(target)); |
| + aura::Window::Windows::iterator source_iter = |
| + std::find(windows_.begin(), windows_.end(), source); |
| + aura::Window::Windows::iterator target_iter = |
| + std::find(windows_.begin(), windows_.end(), target); |
| + DCHECK(source_iter != target_iter); |
| + if (source_iter < target_iter) |
| + std::rotate(source_iter, source_iter + 1, target_iter + 1); |
| + else |
| + std::rotate(target_iter, source_iter, source_iter + 1); |
| + Layout(source, NULL); |
| +} |
| + |
| +aura::Window* Workspace::ShiftWindows(aura::Window* insert, |
| + aura::Window* until, |
| + aura::Window* target, |
| + ShiftDirection direction) { |
| + DCHECK(until); |
| + DCHECK(!Contains(insert)); |
| + |
| + bool shift_reached_until = GetIndexOf(until) >= 0; |
| + if (shift_reached_until) |
| + RemoveWindow(until); |
| + aura::Window* pushed = NULL; |
| + if (direction == SHIFT_TO_RIGHT) { |
| + aura::Window::Windows::iterator iter = |
| + std::find(windows_.begin(), windows_.end(), target); |
| + // Insert at |target| position, or at the beginnin. |
| + if (iter == windows_.end()) |
| + iter = windows_.begin(); |
| + windows_.insert(iter, insert); |
| + if (!shift_reached_until) { |
| + pushed = windows_.back(); |
| + windows_.erase(--windows_.end()); |
| + } |
| + } else { |
| + aura::Window::Windows::iterator iter = |
| + std::find(windows_.begin(), windows_.end(), target); |
| + // Insert after |target|, or at the end. |
| + if (iter != windows_.end()) |
| + iter++; |
|
sky
2011/10/27 22:28:53
++iter.
|
| + windows_.insert(iter, insert); |
| + if (!shift_reached_until) { |
| + pushed = windows_.front(); |
| + windows_.erase(windows_.begin()); |
| + } |
| + } |
| + Layout(shift_reached_until ? until : NULL, NULL); |
| + return pushed; |
| +} |
| + |
| void Workspace::Activate() { |
| workspace_manager_->SetActiveWorkspace(this); |
| } |
| -void Workspace::Layout(aura::Window* no_animation) { |
| +void Workspace::Layout(aura::Window* ignore, aura::Window* no_animation) { |
| gfx::Rect work_area = workspace_manager_->GetWorkAreaBounds(bounds_); |
| - int total_width = 0; |
| - for (aura::Window::Windows::const_iterator i = windows_.begin(); |
| - i != windows_.end(); |
| - ++i) { |
| - if (total_width) |
| - total_width += kWindowHorizontalMargin; |
| - // TODO(oshima): use restored bounds. |
| - total_width += (*i)->bounds().width(); |
| - } |
| - |
| + int total_width = GetTotalWindowsWidth(); |
| if (total_width < work_area.width()) { |
| int dx = (work_area.width() - total_width) / 2; |
| for (aura::Window::Windows::iterator i = windows_.begin(); |
| i != windows_.end(); |
| ++i) { |
| - MoveWindowTo(*i, |
| - gfx::Point(work_area.x() + dx, work_area.y()), |
| - no_animation != *i); |
| + if (*i != ignore) { |
| + MoveWindowTo(*i, |
| + gfx::Point(work_area.x() + dx, work_area.y()), |
| + no_animation != *i); |
| + } |
| dx += (*i)->bounds().width() + kWindowHorizontalMargin; |
| } |
| } else { |
| DCHECK_LT(windows_.size(), 3U); |
| - // TODO(oshima): Figure out general algorithm to layout more than |
| - // 2 windows. |
| - MoveWindowTo(windows_[0], work_area.origin(), no_animation != windows_[0]); |
| - if (windows_.size() == 2) { |
| + // TODO(oshima): This is messy. Figure out general algorithm to |
| + // layout more than 2 windows. |
| + if (windows_[0] != ignore) { |
| + MoveWindowTo(windows_[0], |
| + work_area.origin(), |
| + no_animation != windows_[0]); |
| + } |
| + if (windows_.size() == 2 && windows_[1] != ignore) { |
| MoveWindowTo(windows_[1], |
| gfx::Point(work_area.right() - windows_[1]->bounds().width(), |
| work_area.y()), |
| @@ -114,7 +197,7 @@ bool Workspace::CanAdd(aura::Window* window) const { |
| // TODO(oshima): This should be based on available space and the |
| // size of the |window|. |
| NOTIMPLEMENTED(); |
| - return windows_.size() < 2; |
| + return windows_.size() < g_max_windows_per_workspace; |
| } |
| void Workspace::MoveWindowTo( |
| @@ -134,4 +217,24 @@ void Workspace::MoveWindowTo( |
| } |
| } |
| +int Workspace::GetTotalWindowsWidth() const { |
| + int total_width = 0; |
| + for (aura::Window::Windows::const_iterator i = windows_.begin(); |
| + i != windows_.end(); |
| + ++i) { |
| + if (total_width) |
| + total_width += kWindowHorizontalMargin; |
| + // TODO(oshima): use restored bounds. |
| + total_width += (*i)->bounds().width(); |
| + } |
| + return total_width; |
| +} |
| + |
| +// static |
| +size_t Workspace::SetMaxWindowsCount(size_t max) { |
| + int old = g_max_windows_per_workspace; |
| + g_max_windows_per_workspace = max; |
| + return old; |
| +} |
| + |
| } // namespace aura_shell |