summaryrefslogtreecommitdiffstats
path: root/athena
diff options
context:
space:
mode:
authormfomitchev@chromium.org <mfomitchev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-24 10:26:10 +0000
committermfomitchev@chromium.org <mfomitchev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-24 10:26:10 +0000
commit3ee09b5f26ebb41c39bae812b455f665dc0967da (patch)
tree636b4c04d8332efc8a766358e41811431c617477 /athena
parent39cd5ec541bf9faca9ddb12c8c49f58c3b60602d (diff)
downloadchromium_src-3ee09b5f26ebb41c39bae812b455f665dc0967da.zip
chromium_src-3ee09b5f26ebb41c39bae812b455f665dc0967da.tar.gz
chromium_src-3ee09b5f26ebb41c39bae812b455f665dc0967da.tar.bz2
Split View Mode: Support for the 2-finger bezel scroll.
Implementing the BezelController class responsible for detecting bezel gestures. Adding the bare skeleton of the SplitViewController class which is going to be responsible for the split view mode. BUG=383421 Review URL: https://codereview.chromium.org/394833004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285166 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'athena')
-rw-r--r--athena/athena.gyp4
-rw-r--r--athena/wm/bezel_controller.cc171
-rw-r--r--athena/wm/bezel_controller.h103
-rw-r--r--athena/wm/split_view_controller.cc32
-rw-r--r--athena/wm/split_view_controller.h32
-rw-r--r--athena/wm/window_manager_impl.cc12
-rw-r--r--athena/wm/window_overview_mode.cc5
7 files changed, 356 insertions, 3 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp
index 383eadb..3f1dc9f 100644
--- a/athena/athena.gyp
+++ b/athena/athena.gyp
@@ -64,6 +64,10 @@
'screen/screen_manager_impl.cc',
'wm/public/window_manager.h',
'wm/public/window_manager_observer.h',
+ 'wm/bezel_controller.cc',
+ 'wm/bezel_controller.h',
+ 'wm/split_view_controller.cc',
+ 'wm/split_view_controller.h',
'wm/window_manager_impl.cc',
'wm/window_overview_mode.cc',
'wm/window_overview_mode.h',
diff --git a/athena/wm/bezel_controller.cc b/athena/wm/bezel_controller.cc
new file mode 100644
index 0000000..fb62155
--- /dev/null
+++ b/athena/wm/bezel_controller.cc
@@ -0,0 +1,171 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "athena/wm/bezel_controller.h"
+
+#include "ui/aura/window.h"
+#include "ui/events/event_handler.h"
+
+namespace athena {
+namespace {
+
+// Using bezel swipes, the first touch that is registered is usually within
+// 5-10 pixels from the edge, but sometimes as far as 29 pixels away.
+// So setting this width fairly high for now.
+const float kBezelWidth = 20.0f;
+
+const float kScrollPositionNone = -100;
+
+bool ShouldProcessGesture(ui::EventType event_type) {
+ return event_type == ui::ET_GESTURE_SCROLL_UPDATE ||
+ event_type == ui::ET_GESTURE_SCROLL_BEGIN ||
+ event_type == ui::ET_GESTURE_BEGIN ||
+ event_type == ui::ET_GESTURE_END;
+}
+
+} // namespace
+
+BezelController::BezelController(aura::Window* container)
+ : container_(container),
+ state_(NONE),
+ scroll_bezel_(BEZEL_NONE),
+ scroll_target_(NULL),
+ left_right_delegate_(NULL) {
+}
+
+float BezelController::GetDistance(const gfx::PointF& position,
+ BezelController::Bezel bezel) {
+ DCHECK(bezel == BEZEL_LEFT || bezel == BEZEL_RIGHT);
+ return bezel == BEZEL_LEFT
+ ? position.x()
+ : position.x() - container_->GetBoundsInScreen().width();
+}
+
+void BezelController::SetState(BezelController::State state,
+ const gfx::PointF& scroll_position) {
+ if (!left_right_delegate_ || state == state_)
+ return;
+
+ if (state == BEZEL_SCROLLING_TWO_FINGERS) {
+ float delta = GetDistance(scroll_position, scroll_bezel_);
+ left_right_delegate_->ScrollBegin(scroll_bezel_, delta);
+ } else if (state_ == BEZEL_SCROLLING_TWO_FINGERS) {
+ left_right_delegate_->ScrollEnd();
+ }
+ state_ = state;
+ if (state == NONE) {
+ scroll_bezel_ = BEZEL_NONE;
+ scroll_target_ = NULL;
+ }
+}
+
+// Only implemented for LEFT and RIGHT bezels ATM.
+BezelController::Bezel BezelController::GetBezel(const gfx::PointF& location) {
+ if (location.x() < kBezelWidth) {
+ return BEZEL_LEFT;
+ } else if (location.x() >
+ container_->GetBoundsInScreen().width() - kBezelWidth) {
+ return BEZEL_RIGHT;
+ } else {
+ return BEZEL_NONE;
+ }
+}
+
+void BezelController::OnGestureEvent(ui::GestureEvent* event) {
+ // TODO (mfomitchev): Currently we aren't retargetting or consuming any of the
+ // touch events. This means that content can prevent the generation of gesture
+ // events and two-finger scroll won't work. Possible solution to this problem
+ // is hosting our own gesture recognizer or retargetting touch events at the
+ // bezel.
+
+ if (!left_right_delegate_)
+ return;
+
+ ui::EventType type = event->type();
+ if (!ShouldProcessGesture(type))
+ return;
+
+ if (scroll_target_ && event->target() != scroll_target_)
+ return;
+
+ const gfx::PointF& event_location = event->location_f();
+ const ui::GestureEventDetails& event_details = event->details();
+ int num_touch_points = event_details.touch_points();
+
+ if (type == ui::ET_GESTURE_BEGIN) {
+ if (num_touch_points > 2) {
+ SetState(IGNORE_CURRENT_SCROLL,
+ gfx::Point(kScrollPositionNone, kScrollPositionNone));
+ return;
+ }
+ BezelController::Bezel event_bezel = GetBezel(event->location_f());
+ switch (state_) {
+ case NONE:
+ scroll_bezel_ = event_bezel;
+ scroll_target_ = event->target();
+ if (event_bezel != BEZEL_LEFT && event_bezel != BEZEL_RIGHT) {
+ SetState(IGNORE_CURRENT_SCROLL,
+ gfx::Point(kScrollPositionNone, kScrollPositionNone));
+ } else {
+ SetState(BEZEL_GESTURE_STARTED, event_location);
+ }
+ break;
+ case IGNORE_CURRENT_SCROLL:
+ break;
+ case BEZEL_GESTURE_STARTED:
+ case BEZEL_SCROLLING_ONE_FINGER:
+ DCHECK_EQ(num_touch_points, 2);
+ DCHECK(scroll_target_);
+ DCHECK_NE(scroll_bezel_, BEZEL_NONE);
+
+ if (event_bezel != scroll_bezel_) {
+ SetState(IGNORE_CURRENT_SCROLL,
+ gfx::Point(kScrollPositionNone, kScrollPositionNone));
+ return;
+ }
+ if (state_ == BEZEL_SCROLLING_ONE_FINGER)
+ SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location);
+ break;
+ case BEZEL_SCROLLING_TWO_FINGERS:
+ // Should've exited above
+ NOTREACHED();
+ break;
+ }
+ } else if (type == ui::ET_GESTURE_END) {
+ if (state_ == NONE)
+ return;
+
+ CHECK(scroll_target_);
+ if (num_touch_points == 1) {
+ SetState(NONE, gfx::Point(kScrollPositionNone, kScrollPositionNone));
+ } else {
+ SetState(IGNORE_CURRENT_SCROLL,
+ gfx::Point(kScrollPositionNone, kScrollPositionNone));
+ }
+ } else if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
+ DCHECK(state_ == IGNORE_CURRENT_SCROLL || state_ == BEZEL_GESTURE_STARTED);
+ if (state_ != BEZEL_GESTURE_STARTED)
+ return;
+
+ if (num_touch_points == 1) {
+ SetState(BEZEL_SCROLLING_ONE_FINGER, event_location);
+ return;
+ }
+
+ DCHECK_EQ(num_touch_points, 2);
+ SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location);
+ if (left_right_delegate_->CanScroll())
+ event->SetHandled();
+ } else if (type == ui::ET_GESTURE_SCROLL_UPDATE) {
+ if (state_ != BEZEL_SCROLLING_TWO_FINGERS)
+ return;
+
+ float scroll_delta = GetDistance(event_location, scroll_bezel_);
+ left_right_delegate_->ScrollUpdate(scroll_delta);
+ if (left_right_delegate_->CanScroll())
+ event->SetHandled();
+ }
+}
+
+} // namespace athena
diff --git a/athena/wm/bezel_controller.h b/athena/wm/bezel_controller.h
new file mode 100644
index 0000000..30fe974
--- /dev/null
+++ b/athena/wm/bezel_controller.h
@@ -0,0 +1,103 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ATHENA_WM_BEZEL_CONTROLLER_H_
+#define ATHENA_WM_BEZEL_CONTROLLER_H_
+
+#include "ui/events/event_handler.h"
+
+namespace aura {
+class Window;
+}
+
+namespace gfx {
+class PointF;
+}
+
+namespace ui {
+class EventTarget;
+}
+
+namespace athena {
+
+// Responsible for detecting bezel gestures and notifying the delegate(s)
+// subscribed to them.
+class BezelController : public ui::EventHandler {
+ public:
+ enum Bezel { BEZEL_NONE, BEZEL_LEFT, BEZEL_RIGHT, BEZEL_TOP, BEZEL_BOTTOM };
+
+ // Responsible for handling scroll gestures initiated from the bezel.
+ // Two touch points are need to perform the bezel scroll gesture from
+ // the left and right bezel.
+ class ScrollDelegate {
+ public:
+ virtual ~ScrollDelegate() {}
+
+ // Beginning of a bezel scroll gesture started from the |bezel|.
+ virtual void ScrollBegin(Bezel bezel, float delta) = 0;
+
+ // End of the current bezel scroll
+ virtual void ScrollEnd() = 0;
+
+ // Update of the scroll position for the currently active bezel scroll.
+ virtual void ScrollUpdate(float delta) = 0;
+
+ // Should return false if the delegate isn't going to react to the scroll
+ // events.
+ virtual bool CanScroll() = 0;
+ };
+
+ explicit BezelController(aura::Window* container);
+ virtual ~BezelController() {}
+
+ // Set the delegate to handle the gestures from left and right bezels.
+ // Two touch points are need to perform the bezel scroll gesture from
+ // the left and right bezel.
+ void set_left_right_delegate(ScrollDelegate* delegate) {
+ left_right_delegate_ = delegate;
+ }
+
+ private:
+ enum State {
+ NONE,
+ IGNORE_CURRENT_SCROLL,
+ BEZEL_GESTURE_STARTED,
+ BEZEL_SCROLLING_ONE_FINGER,
+ BEZEL_SCROLLING_TWO_FINGERS,
+ };
+
+ // Calculates the distance from |position| to the |bezel|.
+ float GetDistance(const gfx::PointF& position, Bezel bezel);
+
+ // |scroll_position| only needs to be passed in the scrolling state
+ void SetState(State state, const gfx::PointF& scroll_position);
+
+ // Returns the bezel corresponding to the |location| or BEZEL_NONE if the
+ // location is outside of the bezel area.
+ Bezel GetBezel(const gfx::PointF& location);
+
+ // ui::EventHandler overrides
+ virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+
+ aura::Window* container_;
+
+ State state_;
+
+ // The bezel where the currently active scroll was started.
+ Bezel scroll_bezel_;
+
+ // The target of the bezel scroll gesture. Used to filter out other gestures
+ // when the bezel scroll is in progress.
+ ui::EventTarget* scroll_target_;
+
+ // Responsible for handling gestures started from the left and right bezels.
+ // Not owned.
+ ScrollDelegate* left_right_delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(BezelController);
+};
+
+} // namespace athena
+
+#endif // ATHENA_WM_BEZEL_CONTROLLER_H_
diff --git a/athena/wm/split_view_controller.cc b/athena/wm/split_view_controller.cc
new file mode 100644
index 0000000..7da3675
--- /dev/null
+++ b/athena/wm/split_view_controller.cc
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "athena/wm/split_view_controller.h"
+
+#include "ui/aura/window.h"
+#include "ui/events/event_handler.h"
+
+namespace athena {
+
+SplitViewController::SplitViewController() {
+}
+
+SplitViewController::~SplitViewController() {
+}
+
+void SplitViewController::ScrollBegin(BezelController::Bezel bezel,
+ float delta) {
+}
+
+void SplitViewController::ScrollEnd() {
+}
+
+void SplitViewController::ScrollUpdate(float delta) {
+}
+
+bool SplitViewController::CanScroll() {
+ return false;
+}
+
+} // namespace athena
diff --git a/athena/wm/split_view_controller.h b/athena/wm/split_view_controller.h
new file mode 100644
index 0000000..e0652de
--- /dev/null
+++ b/athena/wm/split_view_controller.h
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
+#define ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
+
+#include "athena/wm/bezel_controller.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace athena {
+
+// Responsible for entering split view mode, exiting from split view mode, and
+// laying out the windows in split view mode.
+class SplitViewController : public BezelController::ScrollDelegate {
+ public:
+ SplitViewController();
+ virtual ~SplitViewController();
+
+ private:
+ // BezelController::ScrollDelegate overrides.
+ virtual void ScrollBegin(BezelController::Bezel bezel, float delta) OVERRIDE;
+ virtual void ScrollEnd() OVERRIDE;
+ virtual void ScrollUpdate(float delta) OVERRIDE;
+ virtual bool CanScroll() OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(SplitViewController);
+};
+
+} // namespace athena
+
+#endif // ATHENA_WM_SPLIT_VIEW_CONTROLLER_H_
diff --git a/athena/wm/window_manager_impl.cc b/athena/wm/window_manager_impl.cc
index 2c94686..d90f34c 100644
--- a/athena/wm/window_manager_impl.cc
+++ b/athena/wm/window_manager_impl.cc
@@ -6,7 +6,9 @@
#include "athena/input/public/accelerator_manager.h"
#include "athena/screen/public/screen_manager.h"
+#include "athena/wm/bezel_controller.h"
#include "athena/wm/public/window_manager_observer.h"
+#include "athena/wm/split_view_controller.h"
#include "athena/wm/window_overview_mode.h"
#include "base/logging.h"
#include "base/observer_list.h"
@@ -94,6 +96,8 @@ class WindowManagerImpl : public WindowManager,
scoped_ptr<aura::Window> container_;
scoped_ptr<WindowOverviewMode> overview_;
+ scoped_ptr<BezelController> bezel_controller_;
+ scoped_ptr<SplitViewController> split_view_controller_;
ObserverList<WindowManagerObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerImpl);
@@ -135,13 +139,19 @@ WindowManagerImpl::WindowManagerImpl() {
container_.reset(ScreenManager::Get()->CreateDefaultContainer(params));
container_->SetLayoutManager(new AthenaContainerLayoutManager);
container_->AddObserver(this);
+ bezel_controller_.reset(new BezelController(container_.get()));
+ split_view_controller_.reset(new SplitViewController());
+ bezel_controller_->set_left_right_delegate(split_view_controller_.get());
+ container_->AddPreTargetHandler(bezel_controller_.get());
instance = this;
InstallAccelerators();
}
WindowManagerImpl::~WindowManagerImpl() {
- if (container_)
+ if (container_) {
container_->RemoveObserver(this);
+ container_->RemovePreTargetHandler(bezel_controller_.get());
+ }
container_.reset();
instance = NULL;
}
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
index 16f889c..b37339e 100644
--- a/athena/wm/window_overview_mode.cc
+++ b/athena/wm/window_overview_mode.cc
@@ -302,11 +302,12 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
} // namespace
+// static
scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create(
- aura::Window* window,
+ aura::Window* container,
WindowOverviewModeDelegate* delegate) {
return scoped_ptr<WindowOverviewMode>(
- new WindowOverviewModeImpl(window, delegate));
+ new WindowOverviewModeImpl(container, delegate));
}
} // namespace athena