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

Unified Diff: ui/aura_shell/workspace/workspace.cc

Issue 8391035: Drag and rotate windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix a bug Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/aura_shell/workspace/workspace.h ('k') | ui/aura_shell/workspace/workspace_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « ui/aura_shell/workspace/workspace.h ('k') | ui/aura_shell/workspace/workspace_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698