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

Unified Diff: ash/touch/touch_exploration_controller.cc

Issue 240333007: wip: Second crack at implementing the touch exploration mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't extend DisplayController::Observer - TouchExplorationController is owned by the root window (… Created 6 years, 8 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: ash/touch/touch_exploration_controller.cc
diff --git a/ash/touch/touch_exploration_controller.cc b/ash/touch/touch_exploration_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9eb0f3237358d9889f02776c6497849e450b6e6b
--- /dev/null
+++ b/ash/touch/touch_exploration_controller.cc
@@ -0,0 +1,184 @@
+// 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 "ash/touch/touch_exploration_controller.h"
+
+#include "ash/root_window_settings.h"
+#include "ash/shell.h"
+#include "ash/wm/coordinate_conversion.h"
+#include "base/logging.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/events/event.h"
+#include "ui/gfx/point.h"
+
+namespace ash {
+
+TouchExplorationController::TouchExplorationController(
+ aura::Window* root_window) :
Daniel Erat 2014/04/18 00:44:08 see the style guide: http://google-styleguide.goog
mfomitchev 2014/04/23 18:27:37 Done.
+ display_id_(GetRootWindowSettings(root_window)->display_id),
+ root_window_(root_window) {
+ Shell::GetInstance()->display_controller()->AddObserver(this);
+ ui::EventSource* event_source = root_window->GetHost()->GetEventSource();
+ event_source->AddEventRewriter(this);
Daniel Erat 2014/04/18 00:44:08 nit: combine this line with the previous one as in
mfomitchev 2014/04/23 18:27:37 Done.
+}
+
+TouchExplorationController::~TouchExplorationController() {
+ Shell::GetInstance()->display_controller()->RemoveObserver(this);
+ if (root_window_)
Daniel Erat 2014/04/18 00:44:08 why does the c'tor assume that root_window is non-
mfomitchev 2014/04/23 18:27:37 Done.
+ root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
+}
+
+ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
+ const ui::Event& event,
+ scoped_ptr<ui::Event>* rewritten_event) {
+ if (!event.IsTouchEvent()) {
Daniel Erat 2014/04/18 00:44:08 nit: leave out these curly brackets since the stat
mfomitchev 2014/04/23 18:27:37 Done.
+ return ui::EVENT_REWRITE_CONTINUE;
+ }
+ ui::EventRewriteStatus result;
+ const ui::TouchEvent& touch_event =
+ static_cast<const ui::TouchEvent&> (event);
Daniel Erat 2014/04/18 00:44:08 get rid of space before '('
mfomitchev 2014/04/23 18:27:37 Done.
+ ui::EventType type = touch_event.type();
+ gfx::Point location = touch_event.location();
+ int touch_id = touch_event.touch_id();
+ int flags = touch_event.flags();
Daniel Erat 2014/04/18 00:44:08 nit: make all of the above types be const
mfomitchev 2014/04/23 18:27:37 Done.
+
+ if (type == ui::ET_TOUCH_PRESSED) {
+ LOG(ERROR) << "ET_TOUCH_PRESSED";
Daniel Erat 2014/04/18 00:44:08 remove debug messages here and below (i.e. switch
mfomitchev 2014/04/23 18:27:37 I am going to leave the logging for now, since thi
+ // If this is the first and only finger touching rewrite the touch as a
+ // mouse move.
+ if (touch_ids_.size() == 0) {
Daniel Erat 2014/04/18 00:44:08 touch_ids_.empty()
+ result = ui::EVENT_REWRITE_REWRITTEN;
+ rewritten_event->reset(CreateMouseMoveEvent(location, flags));
+ EnterMouseMoveMode();
+
+ // Otherwise let the touch go through.
+ } else {
+ result = ui::EVENT_REWRITE_CONTINUE;
+ }
+ touch_ids_.push_back(touch_id);
+ touch_locations_.insert(std::pair<int, gfx::Point>(touch_id, location));
Daniel Erat 2014/04/18 00:44:08 please make this method return early whenever it c
mfomitchev 2014/04/23 18:27:37 Done.. kind of
+ } else if ((type == ui::ET_TOUCH_RELEASED ||
+ type == ui::ET_TOUCH_CANCELLED)) {
Daniel Erat 2014/04/18 00:44:08 fix indenting and get rid of extra parentheses
mfomitchev 2014/04/23 18:27:37 Done.
+ LOG(ERROR) << (type == ui::ET_TOUCH_RELEASED ?
+ "ET_TOUCH_RELEASED" : "ET_TOUCH_CANCELLED");
+ std::vector<int>::iterator it =
+ std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
+ if (it != touch_ids_.end()) {
+ if (it != touch_ids_.begin()) {
+ // If it wasn't the first finger that was lifted, dispatch the event as
+ // is. If there were exactly two fingers on the screen - enter the mouse
+ // move mode and generate a mouse move corresponding to the location of
+ // the first finger.
+ if (touch_ids_.size() != 2) {
+ result = ui::EVENT_REWRITE_CONTINUE;
+ } else {
+ LOG(ERROR) << "Dispatching release, entering mouse move mode.";
+ result = ui::EVENT_REWRITE_DISPATCH_ANOTHER;
+ // Dispatch the release event as is.
+ rewritten_event->reset(new ui::TouchEvent(touch_event));
+ int first_touch_id = touch_ids_.at(0);
+ gfx::Point first_touch_location = touch_locations_[first_touch_id];
+ next_dispatch_event_.reset(
+ CreateMouseMoveEvent(first_touch_location, flags));
+ EnterMouseMoveMode();
+ }
+ } else {
+ // If it was the first finger that was lifted, we need to do a few
+ // things depending on how many fingers were on the screen:
+ // 1. If only one finger was on the screen, this is simply equivalent to
+ // the end of the mouse move.
+ // 2. If there were multiple fingers on the screen, this is equivalent
+ // to lifting the _second_ finger. Also, if there were exactly two
+ // fingers touching, we are only left with one, so we are entering
+ // the mouse move mode, and so we should also generate a mouse move.
+ if (touch_ids_.size() == 1) {
+ result = ui::EVENT_REWRITE_REWRITTEN;
+ rewritten_event->reset(CreateMouseMoveEvent(location, flags));
+ } else {
+ LOG(ERROR) << "Rewriting as a touch release event";
+ // Rewrite the release of the first finger as a release of the
+ // second finger.
+ int second_touch_id = touch_ids_.at(1);
+ gfx::Point second_touch_location = touch_locations_[second_touch_id];
+ ui::TouchEvent* touch_release_event = new ui::TouchEvent(
+ ui::ET_TOUCH_RELEASED,
+ second_touch_location,
+ second_touch_id,
+ event.time_stamp());
+ rewritten_event->reset(touch_release_event);
+ if (touch_ids_.size() == 2) {
+ // If there were exactly two fingers touching - enter the mouse move
+ // mode and dispatch a mouse move corresponding to the location of
+ // the second finger.
+ result = ui::EVENT_REWRITE_DISPATCH_ANOTHER;
+ next_dispatch_event_.reset(
+ CreateMouseMoveEvent(second_touch_location, flags));
+ EnterMouseMoveMode();
+ } else {
+ result = ui::EVENT_REWRITE_REWRITTEN;
+ }
+ }
+ }
+ touch_ids_.erase(it);
+ touch_locations_.erase(touch_id);
+ } else {
+ NOTREACHED();
+ result = ui::EVENT_REWRITE_CONTINUE;
+ }
+ } else if (type == ui::ET_TOUCH_MOVED) {
+ LOG(ERROR) << "ET_TOUCH_MOVED";
+ // Consume if it is the first finger.
+ // If it is the the first and only finger - generate a mouse move event.
+ std::vector<int>::iterator it =
+ std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
+ if (it != touch_ids_.end()) {
+ if (it != touch_ids_.begin()) {
sadrul 2014/04/22 16:46:12 You can just do 'touch_ids_.front() != touch_id' i
mfomitchev 2014/04/23 18:27:37 Done.
+ result = ui::EVENT_REWRITE_CONTINUE;
+ } else {
+ if (touch_ids_.size() == 1) {
+ result = ui::EVENT_REWRITE_REWRITTEN;
+ rewritten_event->reset(CreateMouseMoveEvent(location, flags));
+ } else {
+ result = ui::EVENT_REWRITE_DISCARD;
+ }
+ }
+ touch_locations_[*it] = location;
+ } else {
+ NOTREACHED();
+ result = ui::EVENT_REWRITE_CONTINUE;
+ }
+ } else {
+ result = ui::EVENT_REWRITE_CONTINUE;
+ }
sadrul 2014/04/22 16:46:12 The nested ifs and incorrect indentation in some p
mfomitchev 2014/04/23 18:27:37 I've tried to make the code more readable. I also
+ return result;
+}
+
+ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
+ const ui::Event& last_event,
+ scoped_ptr<ui::Event>* new_event) {
+ new_event->reset(next_dispatch_event_.release());
sadrul 2014/04/22 16:46:12 I think you can do *new_event = next_dispatch_even
mfomitchev 2014/04/23 18:27:37 Done.
+ return ui::EVENT_REWRITE_REWRITTEN;
+}
+
+ui::Event* TouchExplorationController::CreateMouseMoveEvent(
+ gfx::Point location, int flags) {
Daniel Erat 2014/04/18 00:44:08 nit: one parameter per line in function sigs if th
+ LOG(ERROR) << "Creating mouse move event";
+ return new ui::MouseEvent(ui::ET_MOUSE_MOVED,
+ location,
+ location,
+ ui::EF_IS_SYNTHESIZED | flags,
sadrul 2014/04/22 16:49:22 Should this also set EF_FROM_TOUCH?
mfomitchev 2014/04/23 18:27:37 Done.
+ 0);
+}
+
+void TouchExplorationController::EnterMouseMoveMode() {
+ aura::client::CursorClient* cursor_client =
+ root_window_ ? aura::client::GetCursorClient(root_window_) : NULL;
+ if (cursor_client) {
+ cursor_client->EnableMouseEvents();
+ cursor_client->HideCursor();
+ }
+}
+
+} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698