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

Unified Diff: athena/wm/split_view_controller.cc

Issue 545393002: Adding split view divider widget. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format Created 6 years, 3 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
Index: athena/wm/split_view_controller.cc
diff --git a/athena/wm/split_view_controller.cc b/athena/wm/split_view_controller.cc
index 85db209536916f46ec72f8d59b586abf056f9e4e..1199c542db80582cdd4e2dd7680d77cfb974e052 100644
--- a/athena/wm/split_view_controller.cc
+++ b/athena/wm/split_view_controller.cc
@@ -12,7 +12,6 @@
#include "base/bind.h"
#include "ui/aura/window.h"
#include "ui/compositor/closure_animation_observer.h"
-#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/display.h"
@@ -23,10 +22,9 @@ namespace athena {
namespace {
-// Returns a target transform which is suitable for animating a windows's
-// bounds.
-gfx::Transform GetTargetTransformForBoundsAnimation(const gfx::Rect& from,
- const gfx::Rect& to) {
+// Returns a target transform required to transform |from| to |to|.
+gfx::Transform GetTransformForBounds(const gfx::Rect& from,
+ const gfx::Rect& to) {
gfx::Transform transform;
transform.Translate(to.x() - from.x(), to.y() - from.y());
transform.Scale(to.width() / static_cast<float>(from.width()),
@@ -49,7 +47,7 @@ SplitViewController::SplitViewController(
window_list_provider_(window_list_provider),
left_window_(NULL),
right_window_(NULL),
- separator_position_(0),
+ divider_position_(0),
weak_factory_(this) {
}
@@ -103,6 +101,11 @@ void SplitViewController::ActivateSplitMode(aura::Window* left,
left_window_ = left;
container_->StackChildAtTop(left_window_);
}
+ if (!divider_widget_) {
+ divider_widget_.reset(CreateDividerWidget());
+ divider_widget_->Show();
+ }
+
sadrul 2014/09/12 04:30:36 Show() should be outside of the if?
mfomitchev 2014/09/12 20:49:07 I changed the code so that Show/Hid is only done f
UpdateLayout(true);
}
@@ -133,20 +136,52 @@ void SplitViewController::DeactivateSplitMode() {
SetState(INACTIVE);
UpdateLayout(false);
left_window_ = right_window_ = NULL;
+ CHECK(divider_widget_);
+ divider_widget_.reset();
}
-gfx::Rect SplitViewController::GetLeftTargetBounds() {
+const int kDragHandleWidth = 4;
+const int kDragHandleHeight = 80;
+const int kDragHandleInnerMargin = 2;
+const int kDividerWidth = kDragHandleWidth + 2 * kDragHandleInnerMargin;
Jun Mukai 2014/09/08 19:32:00 These const values should be in the anonymous name
mfomitchev 2014/09/12 19:58:42 Done.
+
+views::Widget* SplitViewController::CreateDividerWidget() {
+ views::View* divider_view = CreateDragHandleView(DragHandle::HORIZONTAL,
+ this,
+ kDragHandleWidth,
+ kDragHandleHeight,
+ kDragHandleInnerMargin);
+ views::Widget* widget = new views::Widget();
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+ params.parent = container_;
+ params.accept_events = true;
+ params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
+ params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget->Init(params);
+ widget->SetContentsView(divider_view);
+ const gfx::Size& size =
+ gfx::Size(kDividerWidth, container_->bounds().height());
sadrul 2014/09/12 04:30:36 The minimized home-card allows swiping anywhere (i
mfomitchev 2014/09/12 20:49:07 I was trying to minimize the height of the widget,
+ widget->SetSize(size);
Jun Mukai 2014/09/08 19:32:00 why not simply SetSize(gfx::Size(...))? Also, use
mfomitchev 2014/09/12 19:58:42 Done. There's no intial_bounds, I just used bounds
+
+ return widget;
+}
+
+gfx::Rect SplitViewController::GetLeftAreaBounds() {
gfx::Rect work_area =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
- return gfx::Rect(0, 0, container_->bounds().width() / 2, work_area.height());
+ return gfx::Rect(
+ 0, 0, divider_position_ - kDividerWidth / 2, work_area.height());
}
-gfx::Rect SplitViewController::GetRightTargetBounds() {
+gfx::Rect SplitViewController::GetRightAreaBounds() {
gfx::Rect work_area =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
int container_width = container_->bounds().width();
- return gfx::Rect(
- container_width / 2, 0, container_width / 2, work_area.height());
+ return gfx::Rect(divider_position_ + kDividerWidth / 2,
+ 0,
+ container_width - divider_position_ - kDividerWidth / 2,
+ work_area.height());
}
void SplitViewController::SetState(SplitViewController::State state) {
@@ -160,40 +195,75 @@ void SplitViewController::SetState(SplitViewController::State state) {
void SplitViewController::UpdateLayout(bool animate) {
CHECK(left_window_);
CHECK(right_window_);
+ CHECK(divider_widget_);
// Splitview can be activated from SplitViewController::ActivateSplitMode or
// SplitViewController::ScrollEnd. Additionally we don't want to rotate the
// screen while engaging splitview (i.e. state_ == SCROLLING).
if (state_ == INACTIVE && !animate) {
- if (!wm::IsActiveWindow(left_window_))
+ aura::Window* active_window = window_list_provider_->GetWindowList().back();
+ if (active_window != left_window_) {
left_window_->Hide();
- if (!wm::IsActiveWindow(right_window_))
+ right_window_->SetBounds(gfx::Rect(container_->bounds()));
+ }
+ if (active_window != right_window_) {
+ left_window_->SetBounds(gfx::Rect(container_->bounds()));
right_window_->Hide();
- SetWindowTransforms(gfx::Transform(), gfx::Transform(), false);
+ }
+ SetWindowTransforms(
+ gfx::Transform(), gfx::Transform(), gfx::Transform(), false);
return;
}
left_window_->Show();
right_window_->Show();
+ // TODO(mfomitchev): This makes the widget become activated, which may be
+ // bad to do every time we layout? Keeping this for now for consistency, but
+ // should be revisited (if fine - pls remove the comment).
+ divider_widget_->Show();
sadrul 2014/09/12 04:30:36 Consider ShowInactive(), but perhaps the widget sh
mfomitchev 2014/09/12 20:49:07 ShowInactive() explicitly changes the state to ina
+ gfx::Transform divider_transform;
+ divider_transform.Translate(divider_position_ - kDividerWidth / 2, 0);
if (state_ == ACTIVE) {
+ int container_width = container_->GetBoundsInScreen().width();
+ divider_position_ = container_width / 2;
if (animate) {
- gfx::Transform left_transform = GetTargetTransformForBoundsAnimation(
- left_window_->bounds(), GetLeftTargetBounds());
- gfx::Transform right_transform = GetTargetTransformForBoundsAnimation(
- right_window_->bounds(), GetRightTargetBounds());
- SetWindowTransforms(left_transform, right_transform, true);
+ gfx::Transform left_transform =
+ GetTransformForBounds(left_window_->bounds(), GetLeftAreaBounds());
+ gfx::Transform right_transform =
+ GetTransformForBounds(right_window_->bounds(), GetRightAreaBounds());
+ SetWindowTransforms(
+ left_transform, right_transform, divider_transform, true);
} else {
- left_window_->SetBounds(GetLeftTargetBounds());
- right_window_->SetBounds(GetRightTargetBounds());
- SetWindowTransforms(gfx::Transform(), gfx::Transform(), false);
+ left_window_->SetBounds(GetLeftAreaBounds());
+ right_window_->SetBounds(GetRightAreaBounds());
+ SetWindowTransforms(
+ gfx::Transform(), gfx::Transform(), divider_transform, false);
}
} else {
gfx::Transform left_transform;
- left_transform.Translate(separator_position_ - container_->bounds().width(),
- 0);
gfx::Transform right_transform;
- right_transform.Translate(separator_position_, 0);
- SetWindowTransforms(left_transform, right_transform, animate);
+ gfx::Rect left_area_bounds = GetLeftAreaBounds();
+ gfx::Rect right_area_bounds = GetRightAreaBounds();
+ // If the width of the window is greater than the width of the area which it
+ // is supposed to occupy - translate the window. Otherwise scale the window
+ // up to fill the target area.
+ if (left_window_->bounds().width() >= left_area_bounds.width()) {
+ left_transform.Translate(divider_position_ - left_window_->bounds().x() -
+ left_window_->bounds().width(),
+ 0);
+ } else {
+ left_transform =
+ GetTransformForBounds(left_window_->bounds(), left_area_bounds);
+ }
+ if (right_window_->bounds().width() >= right_area_bounds.width()) {
+ right_transform.Translate(divider_position_ - right_window_->bounds().x(),
+ 0);
+ } else {
+ right_transform =
+ GetTransformForBounds(right_window_->bounds(), right_area_bounds);
+ }
+ SetWindowTransforms(
+ left_transform, right_transform, divider_transform, animate);
}
// Note: |left_window_| and |right_window_| may be NULL if calling
// SetWindowTransforms():
@@ -204,6 +274,7 @@ void SplitViewController::UpdateLayout(bool animate) {
void SplitViewController::SetWindowTransforms(
const gfx::Transform& left_transform,
const gfx::Transform& right_transform,
+ const gfx::Transform& divider_transform,
bool animate) {
if (animate) {
ui::ScopedLayerAnimationSettings left_settings(
@@ -212,6 +283,14 @@ void SplitViewController::SetWindowTransforms(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
left_window_->SetTransform(left_transform);
+ if (divider_widget_) {
sadrul 2014/09/12 04:30:36 There's a CHECK in DeactivateSplitMode()/UpdateLay
mfomitchev 2014/09/12 20:49:07 Done.
+ ui::ScopedLayerAnimationSettings divider_settings(
+ divider_widget_->GetNativeWindow()->layer()->GetAnimator());
+ divider_settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
+ }
+
ui::ScopedLayerAnimationSettings right_settings(
right_window_->layer()->GetAnimator());
right_settings.SetPreemptionStrategy(
@@ -223,6 +302,8 @@ void SplitViewController::SetWindowTransforms(
} else {
left_window_->SetTransform(left_transform);
right_window_->SetTransform(right_transform);
+ if (divider_widget_)
sadrul 2014/09/12 04:30:36 ditto
mfomitchev 2014/09/12 20:49:07 Done.
+ divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
}
}
@@ -235,6 +316,7 @@ void SplitViewController::OnAnimationCompleted() {
if (state_ == INACTIVE) {
left_window_ = NULL;
right_window_ = NULL;
+ divider_widget_.reset();
}
}
@@ -243,7 +325,7 @@ void SplitViewController::UpdateSeparatorPositionFromScrollDelta(float delta) {
const gfx::Rect& display_bounds =
screen->GetDisplayNearestWindow(container_).bounds();
gfx::Rect container_bounds = container_->GetBoundsInScreen();
- separator_position_ =
+ divider_position_ =
delta > 0 ? ((int)delta) + display_bounds.x() - container_bounds.x()
: display_bounds.right() - container_bounds.x() + delta;
}
@@ -274,6 +356,10 @@ void SplitViewController::ScrollBegin(BezelController::Bezel bezel,
CHECK(left_window_);
CHECK(right_window_);
+ CHECK(!divider_widget_);
+ divider_widget_.reset(CreateDividerWidget());
+ divider_widget_->Show();
+
UpdateSeparatorPositionFromScrollDelta(delta);
UpdateLayout(false);
}
@@ -286,16 +372,15 @@ void SplitViewController::ScrollEnd() {
// we would go into the split view mode.
const int kMaxDistanceFromMiddle = 120;
int container_width = container_->GetBoundsInScreen().width();
- if (std::abs(container_width / 2 - separator_position_) <=
+ if (std::abs(container_width / 2 - divider_position_) <=
kMaxDistanceFromMiddle) {
SetState(ACTIVE);
- separator_position_ = container_width / 2;
- } else if (separator_position_ < container_width / 2) {
- separator_position_ = 0;
+ } else if (divider_position_ < container_width / 2) {
+ divider_position_ = 0;
SetState(INACTIVE);
wm::ActivateWindow(right_window_);
} else {
- separator_position_ = container_width;
+ divider_position_ = container_width;
SetState(INACTIVE);
wm::ActivateWindow(left_window_);
}
@@ -318,4 +403,48 @@ bool SplitViewController::CanScroll() {
return result;
}
+///////////////////////////////////////////////////////////////////////////////
+// ScrollHandle::ScrollDelegate:
+
+void SplitViewController::HandleScrollBegin(float delta) {
+ CHECK(state_ == ACTIVE);
+ state_ = SCROLLING;
+ divider_position_ = delta + divider_position_;
+ UpdateLayout(false);
+}
+
+void SplitViewController::HandleScrollEnd() {
+ ScrollEnd();
+}
+
+void SplitViewController::HandleScrollUpdate(float delta) {
+ if (state_ != SCROLLING)
+ return;
+ divider_position_ = delta + container_->GetBoundsInScreen().width() / 2;
+ UpdateLayout(false);
+}
+
+bool SplitViewController::HandleCanScroll() {
+ CHECK(IsLandscapeOrientation(gfx::Screen::GetNativeScreen()
+ ->GetDisplayNearestWindow(container_)
+ .rotation()));
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// WindowManagerObserver:
+
+void SplitViewController::OnOverviewModeEnter() {
+ if (divider_widget_)
+ divider_widget_->Hide();
+}
+
+void SplitViewController::OnOverviewModeExit() {
+ if (divider_widget_)
+ divider_widget_->Show();
+}
+
+void SplitViewController::OnActivityOrderHasChanged() {
+}
+
} // namespace athena

Powered by Google App Engine
This is Rietveld 408576698