Index: ui/chromeos/touch_exploration_controller.cc |
diff --git a/ui/chromeos/touch_exploration_controller.cc b/ui/chromeos/touch_exploration_controller.cc |
index a952bd9893f496df2d1c982f2e3becd4ca847b9d..3670f1e948f213908d1884d9f844eacf35916a5c 100644 |
--- a/ui/chromeos/touch_exploration_controller.cc |
+++ b/ui/chromeos/touch_exploration_controller.cc |
@@ -6,7 +6,6 @@ |
#include "base/logging.h" |
#include "base/strings/string_number_conversions.h" |
-#include "base/time/default_tick_clock.h" |
#include "ui/aura/client/cursor_client.h" |
#include "ui/aura/window.h" |
#include "ui/aura/window_event_dispatcher.h" |
@@ -16,8 +15,7 @@ |
#include "ui/events/event_utils.h" |
#include "ui/gfx/geometry/rect.h" |
- |
-#define SET_STATE(state) SetState(state, __func__) |
+#define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) |
#define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) |
namespace ui { |
@@ -37,13 +35,12 @@ |
: root_window_(root_window), |
delegate_(delegate), |
state_(NO_FINGERS_DOWN), |
- gesture_provider_(new GestureProviderAura(this)), |
+ gesture_provider_(this), |
prev_state_(NO_FINGERS_DOWN), |
VLOG_on_(true), |
tick_clock_(NULL) { |
CHECK(root_window); |
root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
- InitializeSwipeGestureMaps(); |
} |
TouchExplorationController::~TouchExplorationController() { |
@@ -54,13 +51,6 @@ |
const ui::Event& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
if (!event.IsTouchEvent()) { |
- if (event.IsKeyEvent()) { |
- const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); |
- VLOG(0) << "\nKeyboard event: " << key_event.name() |
- << "\n Key code: " << key_event.key_code() |
- << ", Flags: " << key_event.flags() |
- << ", Is char: " << key_event.is_char(); |
- } |
return ui::EVENT_REWRITE_CONTINUE; |
} |
const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); |
@@ -88,6 +78,16 @@ |
current_touch_ids_.push_back(touch_id); |
touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); |
} else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
+ // In order to avoid accidentally double tapping when moving off the edge of |
+ // the screen, the state will be rewritten to NoFingersDown. |
+ TouchEvent touch_event = static_cast<const TouchEvent&>(event); |
+ if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != |
+ NO_EDGE) { |
+ if (current_touch_ids_.size() == 0) { |
+ ResetToNoFingersDown(); |
+ } |
+ } |
+ |
std::vector<int>::iterator it = std::find( |
current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); |
@@ -106,36 +106,11 @@ |
return ui::EVENT_REWRITE_CONTINUE; |
touch_locations_[*it] = location; |
- } else { |
- NOTREACHED() << "Unexpected event type received: " << event.name(); |
- return ui::EVENT_REWRITE_CONTINUE; |
- } |
+ } |
+ VLOG_STATE(); |
VLOG_EVENT(touch_event); |
- |
- // In order to avoid accidentally double tapping when moving off the edge |
- // of the screen, the state will be rewritten to NoFingersDown. |
- if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) && |
- FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != |
- NO_EDGE) { |
- if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
- return ui::EVENT_REWRITE_DISCARD; |
- } |
- } |
- |
- // If the user is in a gesture state, or if there is a possiblity that the |
- // user will enter it in the future, we send the event to the gesture |
- // provider so it can keep track of the state of the fingers. When the user |
- // leaves one of these states, SET_STATE will set the gesture provider to |
- // NULL. |
- if (gesture_provider_.get()) { |
- gesture_provider_->OnTouchEvent(touch_event); |
- gesture_provider_->OnTouchEventAck(false); |
- ProcessGestureEvents(); |
- } |
- |
// The rest of the processing depends on what state we're in. |
- switch (state_) { |
+ switch(state_) { |
case NO_FINGERS_DOWN: |
return InNoFingersDown(touch_event, rewritten_event); |
case SINGLE_TAP_PRESSED: |
@@ -157,8 +132,8 @@ |
return InSlideGesture(touch_event, rewritten_event); |
case ONE_FINGER_PASSTHROUGH: |
return InOneFingerPassthrough(touch_event, rewritten_event); |
- case WAIT_FOR_NO_FINGERS: |
- return InWaitForNoFingers(touch_event, rewritten_event); |
+ case WAIT_FOR_ONE_FINGER: |
+ return InWaitForOneFinger(touch_event, rewritten_event); |
} |
NOTREACHED(); |
return ui::EVENT_REWRITE_CONTINUE; |
@@ -177,7 +152,11 @@ |
initial_press_.reset(new TouchEvent(event)); |
last_unused_finger_event_.reset(new TouchEvent(event)); |
StartTapTimer(); |
- SET_STATE(SINGLE_TAP_PRESSED); |
+ gesture_provider_.OnTouchEvent(event); |
+ gesture_provider_.OnTouchEventAck(false); |
+ ProcessGestureEvents(); |
+ state_ = SINGLE_TAP_PRESSED; |
+ VLOG_STATE(); |
return ui::EVENT_REWRITE_DISCARD; |
} |
NOTREACHED() << "Unexpected event type received: " << event.name(); |
@@ -189,15 +168,17 @@ |
const ui::EventType type = event.type(); |
if (type == ui::ET_TOUCH_PRESSED) { |
- // This is the start of a multifinger gesture. |
- SET_STATE(GESTURE_IN_PROGRESS); |
- return InGestureInProgress(event, rewritten_event); |
+ // TODO (evy, lisayin) : add support for multifinger swipes. |
+ // For now, we wait for there to be only one finger down again. |
+ state_ = WAIT_FOR_ONE_FINGER; |
+ return EVENT_REWRITE_DISCARD; |
} else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
if (current_touch_ids_.size() == 0 && |
event.touch_id() == initial_press_->touch_id()) { |
- SET_STATE(SINGLE_TAP_RELEASED); |
+ state_ = SINGLE_TAP_RELEASED; |
+ VLOG_STATE(); |
} else if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
} |
return EVENT_REWRITE_DISCARD; |
} else if (type == ui::ET_TOUCH_MOVED) { |
@@ -220,21 +201,24 @@ |
// Change to slide gesture if the slide occurred at the right edge. |
int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); |
if (edge & RIGHT_EDGE) { |
- SET_STATE(SLIDE_GESTURE); |
+ state_ = SLIDE_GESTURE; |
+ VLOG_STATE(); |
return InSlideGesture(event, rewritten_event); |
} |
// If the user moves fast enough from the initial touch location, start |
// gesture detection. Otherwise, jump to the touch exploration mode early. |
if (velocity > gesture_detector_config_.minimum_swipe_velocity) { |
- SET_STATE(GESTURE_IN_PROGRESS); |
+ state_ = GESTURE_IN_PROGRESS; |
+ VLOG_STATE(); |
return InGestureInProgress(event, rewritten_event); |
} |
EnterTouchToMouseMode(); |
- SET_STATE(TOUCH_EXPLORATION); |
+ state_ = TOUCH_EXPLORATION; |
+ VLOG_STATE(); |
return InTouchExploration(event, rewritten_event); |
} |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
@@ -243,10 +227,10 @@ |
const ui::TouchEvent& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
const ui::EventType type = event.type(); |
- // If there is more than one finger down, then discard to wait until no |
- // fingers are down. |
+ // If there is more than one finger down, then discard to wait until only one |
+ // finger is or no fingers are down. |
if (current_touch_ids_.size() > 1) { |
- SET_STATE(WAIT_FOR_NO_FINGERS); |
+ state_ = WAIT_FOR_ONE_FINGER; |
return ui::EVENT_REWRITE_DISCARD; |
} |
if (type == ui::ET_TOUCH_PRESSED) { |
@@ -259,10 +243,8 @@ |
// We set the tap timer. If it fires before the user lifts their finger, |
// one-finger passthrough begins. Otherwise, there is a touch press and |
// release at the location of the last touch exploration. |
- SET_STATE(DOUBLE_TAP_PENDING); |
- // The old tap timer (from the initial click) is stopped if it is still |
- // going, and the new one is set. |
- tap_timer_.Stop(); |
+ state_ = DOUBLE_TAP_PENDING; |
+ VLOG_STATE(); |
StartTapTimer(); |
// This will update as the finger moves before a possible passthrough, and |
// will determine the offset. |
@@ -272,13 +254,13 @@ |
// If the previous press was discarded, we need to also handle its |
// release. |
if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
} |
return ui::EVENT_REWRITE_DISCARD; |
} else if (type == ui::ET_TOUCH_MOVED) { |
return ui::EVENT_REWRITE_DISCARD; |
} |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
@@ -314,10 +296,10 @@ |
initial_press_->touch_id(), |
event.time_stamp())); |
(*rewritten_event)->set_flags(event.flags()); |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
return ui::EVENT_REWRITE_REWRITTEN; |
} |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
@@ -337,10 +319,10 @@ |
initial_press_->touch_id(), |
event.time_stamp())); |
(*rewritten_event)->set_flags(event.flags()); |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
return ui::EVENT_REWRITE_REWRITTEN; |
} |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
@@ -351,21 +333,24 @@ |
if (type == ui::ET_TOUCH_PRESSED) { |
// Handle split-tap. |
initial_press_.reset(new TouchEvent(event)); |
- tap_timer_.Stop(); |
+ if (tap_timer_.IsRunning()) |
+ tap_timer_.Stop(); |
rewritten_event->reset( |
new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
last_touch_exploration_->location(), |
event.touch_id(), |
event.time_stamp())); |
(*rewritten_event)->set_flags(event.flags()); |
- SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); |
+ state_ = TOUCH_EXPLORE_SECOND_PRESS; |
+ VLOG_STATE(); |
return ui::EVENT_REWRITE_REWRITTEN; |
} else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
initial_press_.reset(new TouchEvent(event)); |
StartTapTimer(); |
- SET_STATE(TOUCH_EXPLORE_RELEASED); |
+ state_ = TOUCH_EXPLORE_RELEASED; |
+ VLOG_STATE(); |
} else if (type != ui::ET_TOUCH_MOVED) { |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
@@ -378,22 +363,49 @@ |
ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( |
const ui::TouchEvent& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
- // The events were sent to the gesture provider in RewriteEvent already. |
- // If no gesture is registered before the tap timer times out, the state |
- // will change to "wait for no fingers down" or "touch exploration" depending |
- // on the number of fingers down, and this function will stop being called. |
- if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
- } |
+ ui::EventType type = event.type(); |
+ // If additional fingers are added before a swipe gesture has been |
+ // registered, then the state will no longer be GESTURE_IN_PROGRESS. |
+ if (type == ui::ET_TOUCH_PRESSED || |
+ event.touch_id() != initial_press_->touch_id()) { |
+ if (tap_timer_.IsRunning()) |
+ tap_timer_.Stop(); |
+ // Discard any pending gestures. |
+ delete gesture_provider_.GetAndResetPendingGestures(); |
+ state_ = WAIT_FOR_ONE_FINGER; |
+ return EVENT_REWRITE_DISCARD; |
+ } |
+ |
+ // There should not be more than one finger down. |
+ DCHECK(current_touch_ids_.size() <= 1); |
+ if (type == ui::ET_TOUCH_MOVED) { |
+ gesture_provider_.OnTouchEvent(event); |
+ gesture_provider_.OnTouchEventAck(false); |
+ } |
+ if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
+ gesture_provider_.OnTouchEvent(event); |
+ gesture_provider_.OnTouchEventAck(false); |
+ if (current_touch_ids_.size() == 0) { |
+ ResetToNoFingersDown(); |
+ } |
+ } |
+ ProcessGestureEvents(); |
return ui::EVENT_REWRITE_DISCARD; |
} |
ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( |
const ui::TouchEvent& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
+ ui::EventType type = event.type(); |
+ |
+ if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || |
+ type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
+ return ui::EVENT_REWRITE_CONTINUE; |
+ } |
if (event.touch_id() != initial_press_->touch_id()) { |
if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
} |
return ui::EVENT_REWRITE_DISCARD; |
} |
@@ -405,8 +417,9 @@ |
(*rewritten_event)->set_flags(event.flags()); |
if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
- } |
+ ResetToNoFingersDown(); |
+ } |
+ |
return ui::EVENT_REWRITE_REWRITTEN; |
} |
@@ -426,7 +439,8 @@ |
// to touch explore anymore. The remaining finger acts as a pending |
// tap or long tap for the last touch explore location. |
if (event.touch_id() == last_touch_exploration_->touch_id()){ |
- SET_STATE(TOUCH_RELEASE_PENDING); |
+ state_ = TOUCH_RELEASE_PENDING; |
+ VLOG_STATE(); |
return EVENT_REWRITE_DISCARD; |
} |
@@ -442,19 +456,32 @@ |
initial_press_->touch_id(), |
event.time_stamp())); |
(*rewritten_event)->set_flags(event.flags()); |
- SET_STATE(TOUCH_EXPLORATION); |
+ state_ = TOUCH_EXPLORATION; |
EnterTouchToMouseMode(); |
+ VLOG_STATE(); |
return ui::EVENT_REWRITE_REWRITTEN; |
} |
- NOTREACHED(); |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
return ui::EVENT_REWRITE_CONTINUE; |
} |
-ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( |
+ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( |
const ui::TouchEvent& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
- if (current_touch_ids_.size() == 0) |
- SET_STATE(NO_FINGERS_DOWN); |
+ ui::EventType type = event.type(); |
+ if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || |
+ type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { |
+ NOTREACHED() << "Unexpected event type received: " << event.name(); |
+ return ui::EVENT_REWRITE_CONTINUE; |
+ } |
+ if (current_touch_ids_.size() == 1) { |
+ EnterTouchToMouseMode(); |
+ state_ = TOUCH_EXPLORATION; |
+ VLOG_STATE(); |
+ *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
+ last_touch_exploration_.reset(new TouchEvent(event)); |
+ return ui::EVENT_REWRITE_REWRITTEN; |
+ } |
return EVENT_REWRITE_DISCARD; |
} |
@@ -466,7 +493,8 @@ |
const ui::TouchEvent& event, |
scoped_ptr<ui::Event>* rewritten_event) { |
// The timer should not fire when sliding. |
- tap_timer_.Stop(); |
+ if (tap_timer_.IsRunning()) |
+ tap_timer_.Stop(); |
ui::EventType type = event.type(); |
// If additional fingers are added before a swipe gesture has been registered, |
@@ -475,13 +503,11 @@ |
event.touch_id() != initial_press_->touch_id()) { |
if (sound_timer_.IsRunning()) |
sound_timer_.Stop(); |
- SET_STATE(WAIT_FOR_NO_FINGERS); |
+ // Discard any pending gestures. |
+ delete gesture_provider_.GetAndResetPendingGestures(); |
+ state_ = WAIT_FOR_ONE_FINGER; |
return EVENT_REWRITE_DISCARD; |
} |
- |
- // There should not be more than one finger down. |
- DCHECK(current_touch_ids_.size() <= 1); |
- |
// Allows user to return to the edge to adjust the sound if they have left the |
// boundaries. |
@@ -503,10 +529,23 @@ |
delegate_->PlayVolumeAdjustSound(); |
} |
- if (current_touch_ids_.size() == 0) { |
- SET_STATE(NO_FINGERS_DOWN); |
- } |
- |
+ // There should not be more than one finger down. |
+ DCHECK(current_touch_ids_.size() <= 1); |
+ if (type == ui::ET_TOUCH_MOVED) { |
+ gesture_provider_.OnTouchEvent(event); |
+ gesture_provider_.OnTouchEventAck(false); |
+ } |
+ if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
+ gesture_provider_.OnTouchEvent(event); |
+ gesture_provider_.OnTouchEventAck(false); |
+ delete gesture_provider_.GetAndResetPendingGestures(); |
+ if (current_touch_ids_.size() == 0) { |
+ ResetToNoFingersDown(); |
+ } |
+ return ui::EVENT_REWRITE_DISCARD; |
+ } |
+ |
+ ProcessGestureEvents(); |
return ui::EVENT_REWRITE_DISCARD; |
} |
@@ -530,14 +569,15 @@ |
void TouchExplorationController::OnTapTimerFired() { |
switch (state_) { |
case SINGLE_TAP_RELEASED: |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
break; |
case TOUCH_EXPLORE_RELEASED: |
- SET_STATE(NO_FINGERS_DOWN); |
+ ResetToNoFingersDown(); |
last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
return; |
case DOUBLE_TAP_PENDING: { |
- SET_STATE(ONE_FINGER_PASSTHROUGH); |
+ state_ = ONE_FINGER_PASSTHROUGH; |
+ VLOG_STATE(); |
passthrough_offset_ = last_unused_finger_event_->location() - |
last_touch_exploration_->location(); |
scoped_ptr<ui::TouchEvent> passthrough_press( |
@@ -549,19 +589,12 @@ |
return; |
} |
case SINGLE_TAP_PRESSED: |
- EnterTouchToMouseMode(); |
- SET_STATE(TOUCH_EXPLORATION); |
+ case GESTURE_IN_PROGRESS: |
+ // Discard any pending gestures. |
+ delete gesture_provider_.GetAndResetPendingGestures(); |
+ state_ = TOUCH_EXPLORATION; |
+ VLOG_STATE(); |
break; |
- case GESTURE_IN_PROGRESS: |
- // If only one finger is down, go into touch exploration. |
- if (current_touch_ids_.size() == 1) { |
- EnterTouchToMouseMode(); |
- SET_STATE(TOUCH_EXPLORATION); |
- break; |
- } |
- // Otherwise wait for all fingers to be lifted. |
- SET_STATE(WAIT_FOR_NO_FINGERS); |
- return; |
default: |
return; |
} |
@@ -577,39 +610,40 @@ |
root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
} |
-// This is an override for a function that is only called for timer-based events |
-// like long press. Events that are created synchronously as a result of |
-// certain touch events are added to the vector accessible via |
-// GetAndResetPendingGestures(). We only care about swipes (which are created |
-// synchronously), so we ignore this callback. |
-void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { |
+void TouchExplorationController::OnGestureEvent( |
+ ui::GestureEvent* gesture) { |
+ CHECK(gesture->IsGestureEvent()); |
+ ui::EventType type = gesture->type(); |
+ if (VLOG_on_) |
+ VLOG(0) << " \n Gesture Triggered: " << gesture->name(); |
+ if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) { |
+ if (VLOG_on_) |
+ VLOG(0) << "Swipe!"; |
+ delete gesture_provider_.GetAndResetPendingGestures(); |
+ OnSwipeEvent(gesture); |
+ return; |
+ } |
} |
void TouchExplorationController::ProcessGestureEvents() { |
scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( |
- gesture_provider_->GetAndResetPendingGestures()); |
+ gesture_provider_.GetAndResetPendingGestures()); |
if (gestures) { |
for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); |
i != gestures->end(); |
++i) { |
- if ((*i)->type() == ui::ET_GESTURE_SWIPE && |
- state_ == GESTURE_IN_PROGRESS) { |
- OnSwipeEvent(*i); |
- // The tap timer to leave gesture state is ended, and we now wait for |
- // all fingers to be released. |
- tap_timer_.Stop(); |
- SET_STATE(WAIT_FOR_NO_FINGERS); |
- return; |
- } |
- if (state_ == SLIDE_GESTURE && (*i)->IsScrollGestureEvent()) { |
+ if (state_ == SLIDE_GESTURE) |
SideSlideControl(*i); |
- } |
+ else |
+ OnGestureEvent(*i); |
} |
} |
} |
void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { |
ui::EventType type = gesture->type(); |
+ if (!gesture->IsScrollGestureEvent()) |
+ return; |
if (type == ET_GESTURE_SCROLL_BEGIN) { |
delegate_->PlayVolumeAdjustSound(); |
@@ -654,31 +688,23 @@ |
delegate_->SetOutputLevel(int(volume)); |
} |
+ |
void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
// A swipe gesture contains details for the direction in which the swipe |
- // occurred. TODO(evy) : Research which swipe results users most want and |
- // remap these swipes to the best events. Hopefully in the near future |
- // there will also be a menu for users to pick custom mappings. |
+ // occurred. |
GestureEventDetails event_details = swipe_gesture->details(); |
- int num_fingers = event_details.touch_points(); |
- if(VLOG_on_) |
- VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; |
- |
- if (num_fingers > 4) |
- return; |
- |
- if (event_details.swipe_left() && |
- !left_swipe_gestures_[num_fingers].is_null()) { |
- left_swipe_gestures_[num_fingers].Run(); |
- } else if (event_details.swipe_right() && |
- !right_swipe_gestures_[num_fingers].is_null()) { |
- right_swipe_gestures_[num_fingers].Run(); |
- } else if (event_details.swipe_up() && |
- !up_swipe_gestures_[num_fingers].is_null()) { |
- up_swipe_gestures_[num_fingers].Run(); |
- } else if (event_details.swipe_down() && |
- !down_swipe_gestures_[num_fingers].is_null()) { |
- down_swipe_gestures_[num_fingers].Run(); |
+ if (event_details.swipe_left()) { |
+ DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); |
+ return; |
+ } else if (event_details.swipe_right()) { |
+ DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); |
+ return; |
+ } else if (event_details.swipe_up()) { |
+ DispatchShiftSearchKeyEvent(ui::VKEY_UP); |
+ return; |
+ } else if (event_details.swipe_down()) { |
+ DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); |
+ return; |
} |
} |
@@ -711,59 +737,30 @@ |
} |
void TouchExplorationController::DispatchShiftSearchKeyEvent( |
- const ui::KeyboardCode third_key) { |
+ const ui::KeyboardCode direction) { |
// In order to activate the shortcut shift+search+<arrow key> |
// three KeyPressed events must be dispatched in succession along |
// with three KeyReleased events. |
- |
- ui::KeyEvent shift_down( |
+ ui::KeyEvent shift_down = ui::KeyEvent( |
ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); |
- ui::KeyEvent search_down( |
+ ui::KeyEvent search_down = ui::KeyEvent( |
ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
- ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN); |
- |
- ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN); |
- ui::KeyEvent search_up( |
+ ui::KeyEvent direction_down = |
+ ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN); |
+ |
+ ui::KeyEvent direction_up = |
+ ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); |
+ ui::KeyEvent search_up = ui::KeyEvent( |
ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
- ui ::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); |
+ ui::KeyEvent shift_up = |
+ ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); |
DispatchEvent(&shift_down); |
DispatchEvent(&search_down); |
- DispatchEvent(&third_key_down); |
- DispatchEvent(&third_key_up); |
+ DispatchEvent(&direction_down); |
+ DispatchEvent(&direction_up); |
DispatchEvent(&search_up); |
DispatchEvent(&shift_up); |
-} |
- |
-base::Closure TouchExplorationController::BindShiftSearchKeyEvent( |
- const ui::KeyboardCode third_key) { |
- return base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, |
- base::Unretained(this), |
- third_key); |
-} |
- |
-void TouchExplorationController::DispatchKeyWithFlags( |
- const ui::KeyboardCode key, |
- int flags) { |
- ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); |
- ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); |
- DispatchEvent(&key_down); |
- DispatchEvent(&key_up); |
- if(VLOG_on_) { |
- VLOG(0) << "\nKey down: key code : " << key_down.key_code() |
- << ", flags: " << key_down.flags() |
- << "\nKey up: key code : " << key_up.key_code() |
- << ", flags: " << key_up.flags(); |
- } |
-} |
- |
-base::Closure TouchExplorationController::BindKeyEventWithFlags( |
- const ui::KeyboardCode key, |
- int flags) { |
- return base::Bind(&TouchExplorationController::DispatchKeyWithFlags, |
- base::Unretained(this), |
- key, |
- flags); |
} |
scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
@@ -801,37 +798,14 @@ |
cursor_client->HideCursor(); |
} |
-void TouchExplorationController::SetState(State new_state, |
- const char* function_name) { |
- state_ = new_state; |
- VlogState(function_name); |
- // These are the states the user can be in that will never result in a |
- // gesture before the user returns to NO_FINGERS_DOWN. Therefore, if the |
- // gesture provider still exists, it's reset to NULL until the user returns |
- // to NO_FINGERS_DOWN. |
- switch (new_state) { |
- case SINGLE_TAP_RELEASED: |
- case TOUCH_EXPLORE_RELEASED: |
- case DOUBLE_TAP_PENDING: |
- case TOUCH_RELEASE_PENDING: |
- case TOUCH_EXPLORATION: |
- case TOUCH_EXPLORE_SECOND_PRESS: |
- case ONE_FINGER_PASSTHROUGH: |
- case WAIT_FOR_NO_FINGERS: |
- if (gesture_provider_.get()) |
- gesture_provider_.reset(NULL); |
- break; |
- case NO_FINGERS_DOWN: |
- gesture_provider_.reset(new GestureProviderAura(this)); |
- if (sound_timer_.IsRunning()) |
- sound_timer_.Stop(); |
- tap_timer_.Stop(); |
- break; |
- case SINGLE_TAP_PRESSED: |
- case GESTURE_IN_PROGRESS: |
- case SLIDE_GESTURE: |
- break; |
- } |
+void TouchExplorationController::ResetToNoFingersDown() { |
+ ProcessGestureEvents(); |
+ if (sound_timer_.IsRunning()) |
+ sound_timer_.Stop(); |
+ state_ = NO_FINGERS_DOWN; |
+ VLOG_STATE(); |
+ if (tap_timer_.IsRunning()) |
+ tap_timer_.Stop(); |
} |
void TouchExplorationController::VlogState(const char* function_name) { |
@@ -850,6 +824,7 @@ |
if (!VLOG_on_) |
return; |
+ CHECK(touch_event.IsTouchEvent()); |
if (prev_event_ != NULL && |
prev_event_->type() == touch_event.type() && |
prev_event_->touch_id() == touch_event.touch_id()){ |
@@ -863,7 +838,6 @@ |
touch_event.type() == ET_TOUCH_MOVED){ |
return; |
} |
- |
const std::string& type = touch_event.name(); |
const gfx::PointF& location = touch_event.location_f(); |
const int touch_id = touch_event.touch_id(); |
@@ -899,53 +873,10 @@ |
return "SLIDE_GESTURE"; |
case ONE_FINGER_PASSTHROUGH: |
return "ONE_FINGER_PASSTHROUGH"; |
- case WAIT_FOR_NO_FINGERS: |
- return "WAIT_FOR_NO_FINGERS"; |
+ case WAIT_FOR_ONE_FINGER: |
+ return "WAIT_FOR_ONE_FINGER"; |
} |
return "Not a state"; |
} |
-// TODO(evy, lisayin) : Just call abstracted methods on the delegate (e.g. |
-// Swipe(Direction direction, int num_fingers)), and add the DispatchXYZ |
-// methods to the delegate. Avoid the middle step of dispatching keys at all, |
-// and simply have ChromeVox/ChromeOS complete the required action. |
- |
-void TouchExplorationController::InitializeSwipeGestureMaps() { |
- // Gestures with one finger are used for navigation. |
- left_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_LEFT); |
- right_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_RIGHT); |
- up_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_UP); |
- down_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_DOWN); |
- |
- // Gestures with two fingers. |
- left_swipe_gestures_[2] = |
- BindKeyEventWithFlags(ui::VKEY_BROWSER_BACK, ui::EF_NONE); |
- right_swipe_gestures_[2] = |
- BindKeyEventWithFlags(ui::VKEY_BROWSER_FORWARD, ui::EF_NONE); |
- // Jump to top. |
- up_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_A); |
- // Read from here. |
- down_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_R); |
- |
- // Gestures with three fingers switch tabs left/right and scroll up/down. |
- left_swipe_gestures_[3] = BindKeyEventWithFlags( |
- ui::VKEY_TAB, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); |
- right_swipe_gestures_[3] = |
- BindKeyEventWithFlags(ui::VKEY_TAB, ui::EF_CONTROL_DOWN); |
- up_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_NEXT, ui::EF_NONE); |
- down_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_PRIOR, ui::EF_NONE); |
- |
- // Gestures with four fingers should probably eventually be used for rare |
- // needs that are hard to access through menus. |
- // Note that brightness levels are here because they can be important for low |
- // vision users. However, none of these mappings are permanent. |
- left_swipe_gestures_[4] = |
- BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); |
- right_swipe_gestures_[4] = |
- BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE); |
- up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE); |
- down_swipe_gestures_[4] = |
- BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE); |
-} |
- |
} // namespace ui |