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

Side by Side Diff: ui/chromeos/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: Adding a flag to disable the touch exploration mode. Created 6 years, 7 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 unified diff | Download patch
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/ui_chromeos.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/chromeos/touch_exploration_controller.h"
6
7 #include "ui/aura/client/cursor_client.h"
8 #include "ui/aura/window.h"
9 #include "ui/aura/window_tree_host.h"
10 #include "ui/events/event.h"
11
12 namespace ui {
13
14 TouchExplorationController::TouchExplorationController(
15 aura::Window* root_window)
16 : root_window_(root_window) {
17 CHECK(root_window);
18 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
19 }
20
21 TouchExplorationController::~TouchExplorationController() {
22 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
23 }
24
25 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
26 const ui::Event& event,
27 scoped_ptr<ui::Event>* rewritten_event) {
28 if (!event.IsTouchEvent())
29 return ui::EVENT_REWRITE_CONTINUE;
30
31 const ui::TouchEvent& touch_event =
32 static_cast<const ui::TouchEvent&>(event);
33 const ui::EventType type = touch_event.type();
34 const gfx::Point location = touch_event.location();
35 const int touch_id = touch_event.touch_id();
36 const int flags = touch_event.flags();
37
38 if (type == ui::ET_TOUCH_PRESSED) {
39 touch_ids_.push_back(touch_id);
40 touch_locations_.insert(std::pair<int, gfx::Point>(touch_id, location));
41 // If this is the first and only finger touching - rewrite the touch as a
42 // mouse move. Otherwise let the it go through as is.
43 if (touch_ids_.size() == 1) {
44 rewritten_event->reset(CreateMouseMoveEvent(location, flags));
45 EnterTouchToMouseMode();
46 return ui::EVENT_REWRITE_REWRITTEN;
47 } else {
48 return ui::EVENT_REWRITE_CONTINUE;
49 }
50 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
51 std::vector<int>::iterator it =
52 std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
53 // We may fail to find the finger if the exploration mode was turned on
54 // while the user had some fingers touching the screen. We simply ignore
55 // those fingers for the purposes of event transformation.
56 if (it == touch_ids_.end())
57 return ui::EVENT_REWRITE_CONTINUE;
58 const bool first_finger_released = it == touch_ids_.begin();
59 touch_ids_.erase(it);
60 touch_locations_.erase(touch_id);
61 const int num_fingers_remaining = touch_ids_.size();
62
63 if (num_fingers_remaining == 0) {
64 rewritten_event->reset(CreateMouseMoveEvent(location, flags));
65 return ui::EVENT_REWRITE_REWRITTEN;
66 }
67
68 // If we are left with one finger - enter the mouse move mode.
69 const bool enter_mouse_move_mode = num_fingers_remaining == 1;
70
71 if (!enter_mouse_move_mode && !first_finger_released) {
72 // No special handling needed.
73 return ui::EVENT_REWRITE_CONTINUE;
74 }
75
76 // If the finger which was released was the first one, - we need to rewrite
77 // the release event as a release of the was second / now first finger.
78 // This is the finger which will now be getting "substracted".
79 if (first_finger_released) {
80 int rewritten_release_id = touch_ids_[0];
81 gfx::Point rewritten_release_location =
82 touch_locations_[rewritten_release_id];
83 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent(
84 ui::ET_TOUCH_RELEASED,
85 rewritten_release_location,
86 rewritten_release_id,
87 event.time_stamp());
88 rewritten_event->reset(rewritten_release_event);
89 } else if (enter_mouse_move_mode) {
90 // Dispatch the release event as is.
91 // TODO(mfomitchev): We can get rid of this clause once we have
92 // EVENT_REWRITE_DISPATCH_ANOTHER working without having to set
93 // rewritten_event.
94 rewritten_event->reset(new ui::TouchEvent(touch_event));
95 }
96
97 if (enter_mouse_move_mode) {
98 // Since we are entering the mouse move mode - also dispatch a mouse move
99 // event at the location of the one remaining finger. (num_fingers == 1)
100 gfx::Point mouse_move_location = touch_locations_[touch_ids_[0]];
101 next_dispatch_event_.reset(
102 CreateMouseMoveEvent(mouse_move_location, flags));
103 }
104
105 if (enter_mouse_move_mode) {
106 return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
107 } else { // first_finger_released == true
108 return ui::EVENT_REWRITE_REWRITTEN;
109 }
110 } else if (type == ui::ET_TOUCH_MOVED) {
111 std::vector<int>::iterator it =
112 std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
113 // We may fail to find the finger if the exploration mode was turned on
114 // while the user had some fingers touching the screen. We simply ignore
115 // those fingers for the purposes of event transformation.
116 if (it == touch_ids_.end())
117 return ui::EVENT_REWRITE_CONTINUE;
118 touch_locations_[*it] = location;
119 if (touch_ids_.size() == 1) {
120 // Touch moves are rewritten as mouse moves when there's only one finger
121 // touching the screen.
122 rewritten_event->reset(CreateMouseMoveEvent(location, flags));
123 return ui::EVENT_REWRITE_REWRITTEN;
124 } else if (touch_id == touch_ids_.front()) {
125 // Touch moves of the first finger are discarded when there's more than
126 // one finger touching.
127 return ui::EVENT_REWRITE_DISCARD;
128 } else {
129 return ui::EVENT_REWRITE_CONTINUE;
130 }
131 } else if (type == ui::ET_TOUCH_STATIONARY) {
132 if (touch_id == touch_ids_.front())
133 return ui::EVENT_REWRITE_DISCARD;
134 else
135 return ui::EVENT_REWRITE_CONTINUE;
136 }
137 NOTREACHED();
138 return ui::EVENT_REWRITE_CONTINUE;
139 }
140
141 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
142 const ui::Event& last_event,
143 scoped_ptr<ui::Event>* new_event) {
144 CHECK(next_dispatch_event_);
145 *new_event = next_dispatch_event_.Pass();
146 // Enter the mouse move mode if needed
147 if ((*new_event)->IsMouseEvent())
148 EnterTouchToMouseMode();
149 return ui::EVENT_REWRITE_REWRITTEN;
150 }
151
152 ui::Event* TouchExplorationController::CreateMouseMoveEvent(gfx::Point location,
153 int flags) {
154 return new ui::MouseEvent(ui::ET_MOUSE_MOVED,
155 location,
156 location,
157 flags | ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH,
158 0);
159 }
160
161 void TouchExplorationController::EnterTouchToMouseMode() {
162 aura::client::CursorClient* cursor_client =
163 aura::client::GetCursorClient(root_window_);
164 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
165 cursor_client->EnableMouseEvents();
166 if (cursor_client && cursor_client->IsCursorVisible())
167 cursor_client->HideCursor();
168 }
169
170 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/ui_chromeos.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698