| 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..a9574da9617949c80f1b9afee3048f9a8699b772 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 begining.
|
| + 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;
|
| + 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
|
|
|