Index: athena/wm/window_overview_mode.cc |
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc |
index b34991cf82d7a7341ac17c77d016f1cda20e0dc9..92c1929426a4f9eb4f03998b970c76d76c76c488 100644 |
--- a/athena/wm/window_overview_mode.cc |
+++ b/athena/wm/window_overview_mode.cc |
@@ -98,6 +98,32 @@ void RestoreWindowState(aura::Window* window, |
wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
} |
+gfx::RectF GetTransformedBounds(aura::Window* window) { |
+ gfx::Transform transform; |
+ gfx::RectF bounds = window->bounds(); |
+ transform.Translate(bounds.x(), bounds.y()); |
+ transform.PreconcatTransform(window->layer()->transform()); |
+ transform.Translate(-bounds.x(), -bounds.y()); |
+ transform.TransformRect(&bounds); |
+ return bounds; |
+} |
+ |
+gfx::Transform GetTransformForSplitWindow(aura::Window* window, float scale) { |
+ int x_translate = window->bounds().width() * (1 - scale) / 2; |
+ gfx::Transform transform; |
+ transform.Translate(x_translate, window->bounds().height() * 0.65); |
+ transform.Scale(scale, scale); |
+ return transform; |
+} |
+ |
+void TransformSplitWindowScale(aura::Window* window, float scale) { |
+ gfx::Transform transform = window->layer()->GetTargetTransform(); |
+ if (transform.Scale2d() == gfx::Vector2dF(scale, scale)) |
+ return; |
+ ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
+ window->SetTransform(GetTransformForSplitWindow(window, scale)); |
+} |
+ |
// Always returns the same target. |
class StaticWindowTargeter : public aura::WindowTargeter { |
public: |
@@ -178,9 +204,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
(window == split_view_controller_->left_window() || |
window == split_view_controller_->right_window())) { |
// Do not let the left/right windows be scrolled. |
- int x_translate = window->bounds().width() * (1 - kMaxScale) / 2; |
- state->top.Translate(x_translate, window->bounds().height() * 0.65); |
- state->top.Scale(kMaxScale, kMaxScale); |
+ state->top = GetTransformForSplitWindow(window, kMaxScale); |
state->bottom = state->top; |
--index; |
continue; |
@@ -343,6 +367,21 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
compositor->RemoveAnimationObserver(this); |
} |
+ aura::Window* GetSplitWindowDropTarget(const ui::GestureEvent& event) const { |
+ if (!split_view_controller_->IsSplitViewModeActive()) |
+ return NULL; |
+ CHECK(dragged_window_); |
+ CHECK_NE(split_view_controller_->left_window(), dragged_window_); |
+ CHECK_NE(split_view_controller_->right_window(), dragged_window_); |
+ aura::Window* window = split_view_controller_->left_window(); |
+ if (GetTransformedBounds(window).Contains(event.location())) |
+ return window; |
+ window = split_view_controller_->right_window(); |
+ if (GetTransformedBounds(window).Contains(event.location())) |
+ return window; |
+ return NULL; |
+ } |
+ |
void DragWindow(const ui::GestureEvent& event) { |
CHECK(dragged_window_); |
CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type()); |
@@ -380,6 +419,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
overview_toolbar_->current_action(); |
overview_toolbar_->SetHighlightAction(new_action); |
+ aura::Window* split_drop = GetSplitWindowDropTarget(event); |
+ |
// If the user has selected to get into split-view mode, then show the |
// window with full opacity. Otherwise, fade it out as it closes. Animate |
// the opacity if transitioning to/from the split-view button. |
@@ -390,7 +431,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
float ratio = std::min( |
1.f, std::abs(dragged_distance.x()) / kMinDistanceForDismissal); |
float opacity = |
- (new_action == OverviewToolbar::ACTION_TYPE_SPLIT) |
+ (new_action == OverviewToolbar::ACTION_TYPE_SPLIT || split_drop) |
? 1 |
: gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity); |
if (animate_opacity) { |
@@ -400,6 +441,18 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
} else { |
dragged_window_->layer()->SetOpacity(opacity); |
} |
+ |
+ if (split_view_controller_->IsSplitViewModeActive()) { |
+ float scale = kMaxScale; |
+ if (split_drop == split_view_controller_->left_window()) |
+ scale = kMaxScaleForSplitTarget; |
+ TransformSplitWindowScale(split_view_controller_->left_window(), scale); |
+ |
+ scale = kMaxScale; |
+ if (split_drop == split_view_controller_->right_window()) |
+ scale = kMaxScaleForSplitTarget; |
+ TransformSplitWindowScale(split_view_controller_->right_window(), scale); |
+ } |
} |
bool ShouldCloseDragWindow(const ui::GestureEvent& event) const { |
@@ -482,9 +535,26 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
CHECK(overview_toolbar_); |
OverviewToolbar::ActionType action = overview_toolbar_->current_action(); |
overview_toolbar_.reset(); |
- if (action == OverviewToolbar::ACTION_TYPE_SPLIT) |
+ if (action == OverviewToolbar::ACTION_TYPE_SPLIT) { |
delegate_->OnSplitViewMode(NULL, dragged_window_); |
- else if (ShouldCloseDragWindow(gesture)) |
+ return; |
+ } |
+ |
+ // If the window is dropped on one of the left/right windows in split-mode, |
+ // then switch that window. |
+ aura::Window* split_drop = GetSplitWindowDropTarget(gesture); |
+ if (split_drop) { |
+ aura::Window* left = split_view_controller_->left_window(); |
+ aura::Window* right = split_view_controller_->right_window(); |
+ if (left == split_drop) |
+ left = dragged_window_; |
+ else |
+ right = dragged_window_; |
+ delegate_->OnSplitViewMode(left, right); |
+ return; |
+ } |
+ |
+ if (ShouldCloseDragWindow(gesture)) |
CloseDragWindow(gesture); |
else |
RestoreDragWindow(); |
@@ -536,8 +606,26 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
std::abs(gesture->details().scroll_y_hint()) * 2) { |
dragged_start_location_ = gesture->location(); |
dragged_window_ = SelectWindowAt(gesture); |
- if (dragged_window_) |
+ if (split_view_controller_->IsSplitViewModeActive() && |
+ (dragged_window_ == split_view_controller_->left_window() || |
+ dragged_window_ == split_view_controller_->right_window())) { |
+ // TODO(sad): Allow closing the left/right window. Closing one of |
+ // these windows will terminate the split-view mode. Until then, do |
+ // not allow closing these (since otherwise it gets into an undefined |
+ // state). |
+ dragged_window_ = NULL; |
+ } |
+ |
+ if (dragged_window_) { |
+ // Show the toolbar (for closing a window, or going into split-view |
+ // mode). If already in split-view mode, then do not show the 'Split' |
+ // option. |
overview_toolbar_.reset(new OverviewToolbar(container_)); |
+ if (split_view_controller_->IsSplitViewModeActive()) { |
+ overview_toolbar_->DisableAction( |
+ OverviewToolbar::ACTION_TYPE_SPLIT); |
+ } |
+ } |
} |
} else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
if (dragged_window_) |
@@ -586,6 +674,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, |
const float kMaxScale = 0.75f; |
const float kMaxOpacity = 1.0f; |
const float kMinOpacity = 0.2f; |
+ const float kMaxScaleForSplitTarget = 0.9f; |
aura::Window* container_; |
// Provider of the stack of windows to show in the overview mode. Not owned. |