Chromium Code Reviews| 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..0c6247b1826c2896de4bbc5704a3075ffb2f5f29 |
| --- /dev/null |
| +++ b/athena/wm/bezel_controller.cc |
| @@ -0,0 +1,168 @@ |
| +// 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 |
| +// 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); |
| + |
| +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(); |
| + |
|
Jun Mukai
2014/07/21 17:18:52
nit: remove this blank line
mfomitchev
2014/07/21 17:31:47
Done.
|
| +} |
| + |
| +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; |
| + } |
| +} |
| + |
| +// 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; |
| +} |
| + |
|
Jun Mukai
2014/07/21 17:18:52
nit: remove this blank line
mfomitchev
2014/07/21 17:31:47
Done.
|
| + |
| +void BezelController::OnTouchEvent(ui::TouchEvent* event) { |
| + if (!left_right_delegate_) |
| + return; |
| + |
| + // TODO: Currently we aren't retargetting or consuming any of the touch |
|
Jun Mukai
2014/07/21 17:18:52
TODO should have the owner name.
TODO(mfomitchev):
mfomitchev
2014/07/21 17:31:47
Done.
|
| + // 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 |
| + CHECK(false); |
| + //NOTREACHED(); |
|
Jun Mukai
2014/07/21 17:18:52
I think it's okay to be NOTREACHED(). Anyways, ple
mfomitchev
2014/07/21 17:31:47
Done. Also replaced all CHECKs with DCHECKs - mean
|
| + return; |
| + }; |
| + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| + num_fingers_down_--; |
| + CHECK_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); |
| + } |
| + return; |
|
Jun Mukai
2014/07/21 17:18:52
unnecessary to return; Anyways no further code exi
mfomitchev
2014/07/21 17:31:47
Done.
|
| + } |
| +} |
| + |
|
Jun Mukai
2014/07/21 17:18:52
nit: remove this blank line
mfomitchev
2014/07/21 17:31:47
Done.
|
| + |
| +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) { |
|
Jun Mukai
2014/07/21 17:18:52
space between _ and ==
mfomitchev
2014/07/21 17:31:47
Done.
|
| + SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location); |
| + } else if (type == ui::ET_GESTURE_SCROLL_BEGIN) { |
| + CHECK(state_ == IGNORE || state_ == BEZEL_GESTURE_STARTED); |
| + if (state_ == BEZEL_GESTURE_STARTED) { |
| + if (num_fingers_down_ == 1) { |
| + SetState(BEZEL_SCROLLING_ONE_FINGER, event_location); |
| + } else { |
| + CHECK_EQ(num_fingers_down_, 2); |
| + SetState(BEZEL_SCROLLING_TWO_FINGERS, event_location); |
| + if (left_right_delegate_->CanScroll()) { |
| + event->SetHandled(); |
| + event->StopPropagation(); |
| + } |
| + } |
| + } |
| + return; |
|
Jun Mukai
2014/07/21 17:18:52
you don't have to return here
mfomitchev
2014/07/21 17:31:47
Done.
|
| + } else if (type == ui::ET_GESTURE_SCROLL_UPDATE) { |
| + float scroll_delta = GetDistance(event_location, scroll_bezel_); |
| + left_right_delegate_->ScrollUpdate(scroll_delta); |
| + } |
| +} |
| + |
| +} // namespace athena |