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 |