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

Unified Diff: athena/wm/bezel_controller.cc

Issue 394833004: Split View Mode: Support for the 2-finger bezel scroll. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing scroll update. Created 6 years, 5 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/bezel_controller.cc
diff --git a/athena/wm/bezel_controller.cc b/athena/wm/bezel_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ef7577225821a1b82deda73accb81f355e44b268
--- /dev/null
+++ b/athena/wm/bezel_controller.cc
@@ -0,0 +1,167 @@
+// 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 {
+
+// static
+// Using bezel swipes on Nexus 10, the first touch that is registered is
oshima 2014/07/22 17:56:11 please remove the reference to specific hw
mfomitchev 2014/07/22 19:20:22 Done.
+// usually within 5-10 pixels from the edge, but sometimes as far as 29
+// pixels away. So setting this width fairly high.
+const float BezelController::kBezelWidth = 20.0f;
+
+// static
+const gfx::PointF& BezelController::kScrollPositionNone =
+ gfx::PointF(-100, -100);
oshima 2014/07/22 17:56:11 won't this create static initializer?
mfomitchev 2014/07/22 19:20:22 Done. Just constructing gfx::Point when I need it
+
+BezelController::BezelController(aura::Window* container)
+ : container_(container),
+ num_fingers_down_(0),
+ state_(NO_FINGERS_DOWN),
+ scroll_bezel_(BEZEL_NONE),
+ 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_) {
+ if (state != state_) {
+ 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_ == IGNORE || state == NO_FINGERS_DOWN) {
+ scroll_bezel_ = BEZEL_NONE;
+ }
oshima 2014/07/22 17:56:12 nuke {}
mfomitchev 2014/07/22 19:20:22 Done.
+}
+
+// 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;
+ }
+}
+
+bool BezelController::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;
+}
+
+void BezelController::OnTouchEvent(ui::TouchEvent* event) {
+ if (!left_right_delegate_)
+ return;
+
+ // 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.
+
+ ui::EventType type = event->type();
+ if (type == ui::ET_TOUCH_PRESSED) {
+ num_fingers_down_++;
+ BezelController::Bezel event_bezel =
+ GetBezel(gfx::PointF(event->x(), event->y()));
+
+ if (num_fingers_down_ > 2 ||
+ (event_bezel != BEZEL_LEFT && event_bezel != BEZEL_RIGHT)) {
+ SetState(IGNORE, kScrollPositionNone);
+ return;
+ }
+
+ switch (state_) {
+ case NO_FINGERS_DOWN:
+ SetState(BEZEL_GESTURE_STARTED, kScrollPositionNone);
+ scroll_bezel_ = event_bezel;
+ return;
+ case IGNORE:
+ case BEZEL_GESTURE_STARTED:
+ return;
+ case BEZEL_SCROLLING_ONE_FINGER:
+ if (event_bezel != scroll_bezel_)
+ SetState(IGNORE, kScrollPositionNone);
+ return;
+ case BEZEL_SCROLLING_TWO_FINGERS:
+ // Should've exited above
+ NOTREACHED();
+ return;
+ };
+ } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
+ num_fingers_down_--;
+ DCHECK_NE(state_, NO_FINGERS_DOWN);
+ // The finger beeing lifted gets counted for touch_points.
+ if (num_fingers_down_ == 0) {
+ SetState(NO_FINGERS_DOWN, kScrollPositionNone);
+ } else {
+ // Lifting fingers means the user is doing a gesture other than 2-finger
+ // scrolling.
+ SetState(IGNORE, kScrollPositionNone);
+ }
+ }
+}
+
+void BezelController::OnGestureEvent(ui::GestureEvent* event) {
+ if (!left_right_delegate_)
+ return;
+
+ ui::EventType type = event->type();
+ if (!ShouldProcessGesture(type))
+ return;
+
+ gfx::PointF event_location = event->location_f();
+ const ui::GestureEventDetails& event_details = event->details();
+
+ if (type == ui::ET_GESTURE_BEGIN && event_details.touch_points() == 2 &&
+ state_ == BEZEL_SCROLLING_ONE_FINGER) {
+ SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location);
+ } else if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
+ DCHECK(state_ == IGNORE || state_ == BEZEL_GESTURE_STARTED);
+ if (state_ == BEZEL_GESTURE_STARTED) {
+ if (num_fingers_down_ == 1) {
+ SetState(BEZEL_SCROLLING_ONE_FINGER, event_location);
+ } else {
+ DCHECK_EQ(num_fingers_down_, 2);
+ SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location);
+ if (left_right_delegate_->CanScroll()) {
+ event->SetHandled();
+ event->StopPropagation();
+ }
+ }
+ }
+ } else if (type == ui::ET_GESTURE_SCROLL_UPDATE) {
+ if (state_ == BEZEL_SCROLLING_TWO_FINGERS) {
+ float scroll_delta = GetDistance(event_location, scroll_bezel_);
+ left_right_delegate_->ScrollUpdate(scroll_delta);
+ if (left_right_delegate_->CanScroll()) {
+ event->SetHandled();
+ event->StopPropagation();
+ }
+ }
+ }
+}
+
+} // namespace athena

Powered by Google App Engine
This is Rietveld 408576698