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

Side by Side Diff: ash/touch/touch_observer_hud.cc

Issue 17063013: Separate projection mode from rest of touch HUD (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/touch/touch_observer_hud.h ('k') | ash/touch/touch_observer_hud_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/touch/touch_observer_hud.h" 5 #include "ash/touch/touch_observer_hud.h"
6 6
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h" 7 #include "ash/display/display_manager.h"
9 #include "ash/root_window_controller.h" 8 #include "ash/root_window_controller.h"
9 #include "ash/shell.h"
10 #include "ash/shell_window_ids.h" 10 #include "ash/shell_window_ids.h"
11 #include "ash/wm/property_util.h" 11 #include "ash/wm/property_util.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "third_party/skia/include/core/SkPath.h"
17 #include "third_party/skia/include/core/SkXfermode.h"
18 #include "third_party/skia/include/effects/SkGradientShader.h"
19 #include "ui/aura/root_window.h" 12 #include "ui/aura/root_window.h"
20 #include "ui/aura/window.h"
21 #include "ui/base/animation/animation_delegate.h"
22 #include "ui/base/animation/linear_animation.h"
23 #include "ui/base/events/event.h"
24 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/display.h" 13 #include "ui/gfx/display.h"
26 #include "ui/gfx/rect.h" 14 #include "ui/gfx/rect.h"
27 #include "ui/gfx/screen.h" 15 #include "ui/gfx/screen.h"
28 #include "ui/gfx/size.h" 16 #include "ui/gfx/size.h"
29 #include "ui/gfx/transform.h"
30 #include "ui/views/background.h"
31 #include "ui/views/controls/label.h"
32 #include "ui/views/layout/box_layout.h"
33 #include "ui/views/widget/widget.h" 17 #include "ui/views/widget/widget.h"
34 18
35 #if defined(USE_X11)
36 #include <X11/extensions/XInput2.h>
37 #include <X11/Xlib.h>
38
39 #include "ui/base/x/device_data_manager.h"
40 #endif
41
42 namespace ash { 19 namespace ash {
43 namespace internal { 20 namespace internal {
44 21
45 const int kPointRadius = 20;
46 const SkColor kColors[] = {
47 SK_ColorYELLOW,
48 SK_ColorGREEN,
49 SK_ColorRED,
50 SK_ColorBLUE,
51 SK_ColorGRAY,
52 SK_ColorMAGENTA,
53 SK_ColorCYAN,
54 SK_ColorWHITE,
55 SK_ColorBLACK,
56 SkColorSetRGB(0xFF, 0x8C, 0x00),
57 SkColorSetRGB(0x8B, 0x45, 0x13),
58 SkColorSetRGB(0xFF, 0xDE, 0xAD),
59 };
60 const int kAlpha = 0x60;
61 const SkColor kProjectionFillColor = SkColorSetRGB(0xF5, 0xF5, 0xDC);
62 const SkColor kProjectionStrokeColor = SK_ColorGRAY;
63 const int kProjectionAlpha = 0xB0;
64 const int kMaxPaths = arraysize(kColors);
65 const int kReducedScale = 10;
66 const int kFadeoutDurationInMs = 250;
67 const int kFadeoutFrameRate = 60;
68
69 const char* GetTouchEventLabel(ui::EventType type) {
70 switch (type) {
71 case ui::ET_UNKNOWN:
72 return " ";
73 case ui::ET_TOUCH_PRESSED:
74 return "P";
75 case ui::ET_TOUCH_MOVED:
76 return "M";
77 case ui::ET_TOUCH_RELEASED:
78 return "R";
79 case ui::ET_TOUCH_CANCELLED:
80 return "C";
81 default:
82 break;
83 }
84 return "?";
85 }
86
87 int GetTrackingId(const ui::TouchEvent& event) {
88 if (!event.HasNativeEvent())
89 return 0;
90 #if defined(USE_XI2_MT)
91 ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
92 double tracking_id;
93 if (manager->GetEventData(*event.native_event(),
94 ui::DeviceDataManager::DT_TOUCH_TRACKING_ID,
95 &tracking_id)) {
96 return static_cast<int>(tracking_id);
97 }
98 #endif
99 return 0;
100 }
101
102 int GetSourceDeviceId(const ui::TouchEvent& event) {
103 if (!event.HasNativeEvent())
104 return 0;
105 #if defined(USE_X11)
106 XEvent* xev = event.native_event();
107 return static_cast<XIDeviceEvent*>(xev->xcookie.data)->sourceid;
108 #endif
109 return 0;
110 }
111
112 // A TouchPointLog represents a single touch-event of a touch point.
113 struct TouchPointLog {
114 public:
115 explicit TouchPointLog(const ui::TouchEvent& touch)
116 : id(touch.touch_id()),
117 type(touch.type()),
118 location(touch.root_location()),
119 timestamp(touch.time_stamp().InMillisecondsF()),
120 radius_x(touch.radius_x()),
121 radius_y(touch.radius_y()),
122 pressure(touch.force()),
123 tracking_id(GetTrackingId(touch)),
124 source_device(GetSourceDeviceId(touch)) {
125 }
126
127 // Populates a dictionary value with all the information about the touch
128 // point.
129 scoped_ptr<DictionaryValue> GetAsDictionary() const {
130 scoped_ptr<DictionaryValue> value(new DictionaryValue());
131
132 value->SetInteger("id", id);
133 value->SetString("type", std::string(GetTouchEventLabel(type)));
134 value->SetString("location", location.ToString());
135 value->SetDouble("timestamp", timestamp);
136 value->SetDouble("radius_x", radius_x);
137 value->SetDouble("radius_y", radius_y);
138 value->SetDouble("pressure", pressure);
139 value->SetInteger("tracking_id", tracking_id);
140 value->SetInteger("source_device", source_device);
141
142 return value.Pass();
143 }
144
145 int id;
146 ui::EventType type;
147 gfx::Point location;
148 double timestamp;
149 float radius_x;
150 float radius_y;
151 float pressure;
152 int tracking_id;
153 int source_device;
154 };
155
156 // A TouchTrace keeps track of all the touch events of a single touch point
157 // (starting from a touch-press and ending at touch-release).
158 class TouchTrace {
159 public:
160 typedef std::vector<TouchPointLog>::iterator iterator;
161 typedef std::vector<TouchPointLog>::const_iterator const_iterator;
162 typedef std::vector<TouchPointLog>::reverse_iterator reverse_iterator;
163 typedef std::vector<TouchPointLog>::const_reverse_iterator
164 const_reverse_iterator;
165
166 TouchTrace() {
167 }
168
169 void AddTouchPoint(const ui::TouchEvent& touch) {
170 log_.push_back(TouchPointLog(touch));
171 }
172
173 const std::vector<TouchPointLog>& log() const { return log_; }
174
175 bool active() const {
176 return !log_.empty() && log_.back().type != ui::ET_TOUCH_RELEASED &&
177 log_.back().type != ui::ET_TOUCH_CANCELLED;
178 }
179
180 // Returns a list containing data from all events for the touch point.
181 scoped_ptr<ListValue> GetAsList() const {
182 scoped_ptr<ListValue> list(new ListValue());
183 for (const_iterator i = log_.begin(); i != log_.end(); ++i)
184 list->Append((*i).GetAsDictionary().release());
185 return list.Pass();
186 }
187
188 void Reset() {
189 log_.clear();
190 }
191
192 private:
193 std::vector<TouchPointLog> log_;
194
195 DISALLOW_COPY_AND_ASSIGN(TouchTrace);
196 };
197
198 // A TouchLog keeps track of all touch events of all touch points.
199 class TouchLog {
200 public:
201 TouchLog() : next_trace_index_(0) {
202 }
203
204 void AddTouchPoint(const ui::TouchEvent& touch) {
205 if (touch.type() == ui::ET_TOUCH_PRESSED)
206 StartTrace(touch);
207 AddToTrace(touch);
208 }
209
210 void Reset() {
211 next_trace_index_ = 0;
212 for (int i = 0; i < kMaxPaths; ++i)
213 traces_[i].Reset();
214 }
215
216 scoped_ptr<ListValue> GetAsList() const {
217 scoped_ptr<ListValue> list(new ListValue());
218 for (int i = 0; i < kMaxPaths; ++i) {
219 if (!traces_[i].log().empty())
220 list->Append(traces_[i].GetAsList().release());
221 }
222 return list.Pass();
223 }
224
225 int GetTraceIndex(int touch_id) const {
226 return touch_id_to_trace_index_.at(touch_id);
227 }
228
229 const TouchTrace* traces() const {
230 return traces_;
231 }
232
233 private:
234 void StartTrace(const ui::TouchEvent& touch) {
235 // Find the first inactive spot; otherwise, overwrite the one
236 // |next_trace_index_| is pointing to.
237 int old_trace_index = next_trace_index_;
238 do {
239 if (!traces_[next_trace_index_].active())
240 break;
241 next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
242 } while (next_trace_index_ != old_trace_index);
243 int touch_id = touch.touch_id();
244 traces_[next_trace_index_].Reset();
245 touch_id_to_trace_index_[touch_id] = next_trace_index_;
246 next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
247 }
248
249 void AddToTrace(const ui::TouchEvent& touch) {
250 int touch_id = touch.touch_id();
251 int trace_index = touch_id_to_trace_index_[touch_id];
252 traces_[trace_index].AddTouchPoint(touch);
253 }
254
255 TouchTrace traces_[kMaxPaths];
256 int next_trace_index_;
257
258 std::map<int, int> touch_id_to_trace_index_;
259
260 DISALLOW_COPY_AND_ASSIGN(TouchLog);
261 };
262
263 // TouchHudCanvas draws touch traces in |FULLSCREEN| and |REDUCED_SCALE| modes.
264 class TouchHudCanvas : public views::View {
265 public:
266 explicit TouchHudCanvas(const TouchLog& touch_log)
267 : touch_log_(touch_log),
268 scale_(1) {
269 SetPaintToLayer(true);
270 SetFillsBoundsOpaquely(false);
271
272 paint_.setStyle(SkPaint::kFill_Style);
273 }
274
275 virtual ~TouchHudCanvas() {}
276
277 void SetScale(int scale) {
278 if (scale_ == scale)
279 return;
280 scale_ = scale;
281 gfx::Transform transform;
282 transform.Scale(1. / scale_, 1. / scale_);
283 layer()->SetTransform(transform);
284 }
285
286 int scale() const { return scale_; }
287
288 void TouchPointAdded(int touch_id) {
289 int trace_index = touch_log_.GetTraceIndex(touch_id);
290 const TouchTrace& trace = touch_log_.traces()[trace_index];
291 const TouchPointLog& point = trace.log().back();
292 if (point.type == ui::ET_TOUCH_PRESSED)
293 StartedTrace(trace_index);
294 if (point.type != ui::ET_TOUCH_CANCELLED)
295 AddedPointToTrace(trace_index);
296 }
297
298 void Clear() {
299 for (int i = 0; i < kMaxPaths; ++i)
300 paths_[i].reset();
301
302 SchedulePaint();
303 }
304
305 private:
306 void StartedTrace(int trace_index) {
307 paths_[trace_index].reset();
308 colors_[trace_index] = SkColorSetA(kColors[trace_index], kAlpha);
309 }
310
311 void AddedPointToTrace(int trace_index) {
312 const TouchTrace& trace = touch_log_.traces()[trace_index];
313 const TouchPointLog& point = trace.log().back();
314 const gfx::Point& location = point.location;
315 SkScalar x = SkIntToScalar(location.x());
316 SkScalar y = SkIntToScalar(location.y());
317 SkPoint last;
318 if (!paths_[trace_index].getLastPt(&last) || x != last.x() ||
319 y != last.y()) {
320 paths_[trace_index].addCircle(x, y, SkIntToScalar(kPointRadius));
321 SchedulePaint();
322 }
323 }
324
325 // Overridden from views::View.
326 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
327 for (int i = 0; i < kMaxPaths; ++i) {
328 if (paths_[i].countPoints() == 0)
329 continue;
330 paint_.setColor(colors_[i]);
331 canvas->DrawPath(paths_[i], paint_);
332 }
333 }
334
335 SkPaint paint_;
336
337 const TouchLog& touch_log_;
338 SkPath paths_[kMaxPaths];
339 SkColor colors_[kMaxPaths];
340
341 int scale_;
342
343 DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas);
344 };
345
346 // TouchPointView draws a single touch point in |PROJECTION| mode. This object
347 // manages its own lifetime and deletes itself upon fade-out completion or
348 // whenever |Remove()| is explicitly called.
349 class TouchPointView : public views::View,
350 public ui::AnimationDelegate,
351 public views::WidgetObserver {
352 public:
353 explicit TouchPointView(views::Widget* parent_widget)
354 : circle_center_(kPointRadius + 1, kPointRadius + 1),
355 gradient_center_(SkPoint::Make(kPointRadius + 1,
356 kPointRadius + 1)) {
357 SetPaintToLayer(true);
358 SetFillsBoundsOpaquely(false);
359
360 SetSize(gfx::Size(2 * kPointRadius + 2, 2 * kPointRadius + 2));
361
362 stroke_paint_.setStyle(SkPaint::kStroke_Style);
363 stroke_paint_.setColor(kProjectionStrokeColor);
364
365 gradient_colors_[0] = kProjectionFillColor;
366 gradient_colors_[1] = kProjectionStrokeColor;
367
368 gradient_pos_[0] = SkFloatToScalar(0.9f);
369 gradient_pos_[1] = SkFloatToScalar(1.0f);
370
371 parent_widget->GetContentsView()->AddChildView(this);
372
373 parent_widget->AddObserver(this);
374 }
375
376 void UpdateTouch(const ui::TouchEvent& touch) {
377 if (touch.type() == ui::ET_TOUCH_RELEASED ||
378 touch.type() == ui::ET_TOUCH_CANCELLED) {
379 fadeout_.reset(new ui::LinearAnimation(kFadeoutDurationInMs,
380 kFadeoutFrameRate,
381 this));
382 fadeout_->Start();
383 } else {
384 SetX(touch.root_location().x() - kPointRadius - 1);
385 SetY(touch.root_location().y() - kPointRadius - 1);
386 }
387 }
388
389 void Remove() {
390 delete this;
391 }
392
393 private:
394 virtual ~TouchPointView() {
395 GetWidget()->RemoveObserver(this);
396 parent()->RemoveChildView(this);
397 }
398
399 // Overridden from views::View.
400 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
401 int alpha = kProjectionAlpha;
402 if (fadeout_)
403 alpha = static_cast<int>(fadeout_->CurrentValueBetween(alpha, 0));
404 fill_paint_.setAlpha(alpha);
405 stroke_paint_.setAlpha(alpha);
406 SkShader* shader = SkGradientShader::CreateRadial(
407 gradient_center_,
408 SkIntToScalar(kPointRadius),
409 gradient_colors_,
410 gradient_pos_,
411 arraysize(gradient_colors_),
412 SkShader::kMirror_TileMode,
413 NULL);
414 fill_paint_.setShader(shader);
415 shader->unref();
416 canvas->DrawCircle(circle_center_, SkIntToScalar(kPointRadius),
417 fill_paint_);
418 canvas->DrawCircle(circle_center_, SkIntToScalar(kPointRadius),
419 stroke_paint_);
420 }
421
422 // Overridden from ui::AnimationDelegate.
423 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
424 DCHECK_EQ(fadeout_.get(), animation);
425 delete this;
426 }
427
428 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE {
429 DCHECK_EQ(fadeout_.get(), animation);
430 SchedulePaint();
431 }
432
433 virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE {
434 AnimationEnded(animation);
435 }
436
437 // Overridden from views::WidgetObserver.
438 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
439 fadeout_->Stop();
440 }
441
442 const gfx::Point circle_center_;
443 const SkPoint gradient_center_;
444
445 SkPaint fill_paint_;
446 SkPaint stroke_paint_;
447 SkColor gradient_colors_[2];
448 SkScalar gradient_pos_[2];
449
450 scoped_ptr<ui::Animation> fadeout_;
451
452 DISALLOW_COPY_AND_ASSIGN(TouchPointView);
453 };
454
455 TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root) 22 TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root)
456 : display_id_(initial_root->GetProperty(kDisplayIdKey)), 23 : display_id_(initial_root->GetProperty(kDisplayIdKey)),
457 root_window_(initial_root), 24 root_window_(initial_root),
458 mode_(FULLSCREEN), 25 widget_(NULL) {
459 touch_log_(new TouchLog()) {
460 const gfx::Display& display = 26 const gfx::Display& display =
461 Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_); 27 Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_);
462 28
463 views::View* content = new views::View; 29 views::View* content = new views::View;
464 30
465 canvas_ = new TouchHudCanvas(*touch_log_);
466 content->AddChildView(canvas_);
467
468 const gfx::Size& display_size = display.size(); 31 const gfx::Size& display_size = display.size();
469 canvas_->SetSize(display_size);
470 content->SetSize(display_size); 32 content->SetSize(display_size);
471 33
472 label_container_ = new views::View;
473 label_container_->SetLayoutManager(new views::BoxLayout(
474 views::BoxLayout::kVertical, 0, 0, 0));
475
476 for (int i = 0; i < kMaxTouchPoints; ++i) {
477 touch_labels_[i] = new views::Label;
478 touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
479 touch_labels_[i]->SetShadowColors(SK_ColorWHITE,
480 SK_ColorWHITE);
481 touch_labels_[i]->SetShadowOffset(1, 1);
482 label_container_->AddChildView(touch_labels_[i]);
483 }
484 label_container_->SetX(0);
485 label_container_->SetY(display_size.height() / kReducedScale);
486 label_container_->SetSize(label_container_->GetPreferredSize());
487 label_container_->SetVisible(false);
488 content->AddChildView(label_container_);
489
490 widget_ = new views::Widget(); 34 widget_ = new views::Widget();
491 views::Widget::InitParams 35 views::Widget::InitParams
492 params(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 36 params(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
493 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 37 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
494 params.can_activate = false; 38 params.can_activate = false;
495 params.accept_events = false; 39 params.accept_events = false;
496 params.bounds = gfx::Rect(display_size); 40 params.bounds = display.bounds();
497 params.parent = Shell::GetContainer( 41 params.parent = Shell::GetContainer(
498 root_window_, 42 root_window_,
499 internal::kShellWindowId_OverlayContainer); 43 internal::kShellWindowId_OverlayContainer);
500 widget_->Init(params); 44 widget_->Init(params);
501 widget_->SetContentsView(content); 45 widget_->SetContentsView(content);
502 widget_->StackAtTop(); 46 widget_->StackAtTop();
503 widget_->Show(); 47 widget_->Show();
504 48
505 widget_->AddObserver(this); 49 widget_->AddObserver(this);
506 50
(...skipping 11 matching lines...) Expand all
518 Shell::GetInstance()->display_controller()->RemoveObserver(this); 62 Shell::GetInstance()->display_controller()->RemoveObserver(this);
519 63
520 #if defined(OS_CHROMEOS) 64 #if defined(OS_CHROMEOS)
521 Shell::GetInstance()->output_configurator()->RemoveObserver(this); 65 Shell::GetInstance()->output_configurator()->RemoveObserver(this);
522 #endif // defined(OS_CHROMEOS) 66 #endif // defined(OS_CHROMEOS)
523 Shell::GetScreen()->RemoveObserver(this); 67 Shell::GetScreen()->RemoveObserver(this);
524 68
525 widget_->RemoveObserver(this); 69 widget_->RemoveObserver(this);
526 } 70 }
527 71
528 // static 72 void TouchObserverHUD::Clear() {
529 scoped_ptr<DictionaryValue> TouchObserverHUD::GetAllAsDictionary() {
530 scoped_ptr<DictionaryValue> value(new DictionaryValue());
531 Shell::RootWindowList roots = Shell::GetInstance()->GetAllRootWindows();
532 for (Shell::RootWindowList::iterator iter = roots.begin();
533 iter != roots.end(); ++iter) {
534 internal::RootWindowController* controller = GetRootWindowController(*iter);
535 if (controller->touch_observer_hud()) {
536 int64 display_id = (*iter)->GetProperty(kDisplayIdKey);
537 scoped_ptr<ListValue> list =
538 controller->touch_observer_hud()->GetLogAsList();
539 if (!list->empty())
540 value->Set(base::Int64ToString(display_id), list.release());
541 }
542 }
543 return value.Pass();
544 } 73 }
545 74
546 void TouchObserverHUD::ChangeToNextMode() { 75 void TouchObserverHUD::Remove() {
547 switch (mode_) { 76 root_window_->RemovePreTargetHandler(this);
548 case FULLSCREEN: 77
549 SetMode(REDUCED_SCALE); 78 RootWindowController* controller = GetRootWindowController(root_window_);
550 break; 79 UnsetHudForRootWindowController(controller);
551 case REDUCED_SCALE: 80
552 SetMode(PROJECTION); 81 widget_->CloseNow();
553 break;
554 case PROJECTION:
555 SetMode(INVISIBLE);
556 break;
557 case INVISIBLE:
558 SetMode(FULLSCREEN);
559 break;
560 }
561 } 82 }
562 83
563 void TouchObserverHUD::Clear() { 84 void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* /*event*/) {
564 if (widget_->IsVisible())
565 canvas_->Clear();
566 for (int i = 0; i < kMaxTouchPoints; ++i)
567 touch_labels_[i]->SetText(string16());
568 label_container_->SetSize(label_container_->GetPreferredSize());
569 }
570
571 scoped_ptr<ListValue> TouchObserverHUD::GetLogAsList() const {
572 return touch_log_->GetAsList();
573 }
574
575 void TouchObserverHUD::SetMode(Mode mode) {
576 if (mode_ == mode)
577 return;
578 // When going out of projection mode, hide all active touch points.
579 if (mode_ == PROJECTION) {
580 for (std::map<int, TouchPointView*>::iterator iter = points_.begin();
581 iter != points_.end(); ++iter)
582 iter->second->Remove();
583 points_.clear();
584 }
585 mode_ = mode;
586 switch (mode) {
587 case FULLSCREEN:
588 label_container_->SetVisible(false);
589 canvas_->SetVisible(true);
590 canvas_->SetScale(1);
591 canvas_->SchedulePaint();
592 widget_->Show();
593 break;
594 case REDUCED_SCALE:
595 label_container_->SetVisible(true);
596 canvas_->SetVisible(true);
597 canvas_->SetScale(kReducedScale);
598 canvas_->SchedulePaint();
599 widget_->Show();
600 break;
601 case PROJECTION:
602 label_container_->SetVisible(false);
603 canvas_->SetVisible(false);
604 widget_->Show();
605 break;
606 case INVISIBLE:
607 widget_->Hide();
608 break;
609 }
610 }
611
612 void TouchObserverHUD::UpdateTouchPointLabel(int index) {
613 int trace_index = touch_log_->GetTraceIndex(index);
614 const TouchTrace& trace = touch_log_->traces()[trace_index];
615 TouchTrace::const_reverse_iterator point = trace.log().rbegin();
616 ui::EventType touch_status = point->type;
617 float touch_radius = std::max(point->radius_x, point->radius_y);
618 while (point != trace.log().rend() && point->type == ui::ET_TOUCH_CANCELLED)
619 point++;
620 DCHECK(point != trace.log().rend());
621 gfx::Point touch_position = point->location;
622
623 std::string string = base::StringPrintf("%2d: %s %s (%.4f)",
624 index,
625 GetTouchEventLabel(touch_status),
626 touch_position.ToString().c_str(),
627 touch_radius);
628 touch_labels_[index]->SetText(UTF8ToUTF16(string));
629 }
630
631 void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* event) {
632 if (event->touch_id() >= kMaxTouchPoints)
633 return;
634
635 touch_log_->AddTouchPoint(*event);
636 canvas_->TouchPointAdded(event->touch_id());
637
638 if (mode_ == PROJECTION) {
639 if (event->type() == ui::ET_TOUCH_PRESSED) {
640 TouchPointView* point = new TouchPointView(widget_);
641 point->UpdateTouch(*event);
642 std::pair<std::map<int, TouchPointView*>::iterator, bool> result =
643 points_.insert(std::make_pair(event->touch_id(), point));
644 // If a |TouchPointView| is already mapped to the touch id, remove it and
645 // replace it with the new one.
646 if (!result.second) {
647 result.first->second->Remove();
648 result.first->second = point;
649 }
650 } else {
651 std::map<int, TouchPointView*>::iterator iter =
652 points_.find(event->touch_id());
653 if (iter != points_.end()) {
654 iter->second->UpdateTouch(*event);
655 if (event->type() == ui::ET_TOUCH_RELEASED ||
656 event->type() == ui::ET_TOUCH_CANCELLED)
657 points_.erase(iter);
658 }
659 }
660 }
661
662 UpdateTouchPointLabel(event->touch_id());
663 label_container_->SetSize(label_container_->GetPreferredSize());
664 } 85 }
665 86
666 void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) { 87 void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) {
667 DCHECK_EQ(widget, widget_); 88 DCHECK_EQ(widget, widget_);
668 delete this; 89 delete this;
669 } 90 }
670 91
671 void TouchObserverHUD::OnDisplayBoundsChanged(const gfx::Display& display) { 92 void TouchObserverHUD::OnDisplayBoundsChanged(const gfx::Display& display) {
672 if (display.id() != display_id_) 93 if (display.id() != display_id_)
673 return; 94 return;
674 const gfx::Size& size = display.size(); 95 widget_->SetSize(display.size());
675 widget_->SetSize(size);
676 canvas_->SetSize(size);
677 label_container_->SetY(size.height() / kReducedScale);
678 } 96 }
679 97
680 void TouchObserverHUD::OnDisplayAdded(const gfx::Display& new_display) {} 98 void TouchObserverHUD::OnDisplayAdded(const gfx::Display& new_display) {}
681 99
682 void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) { 100 void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) {
683 if (old_display.id() != display_id_) 101 if (old_display.id() != display_id_)
684 return; 102 return;
685 widget_->CloseNow(); 103 widget_->CloseNow();
686 } 104 }
687 105
688 #if defined(OS_CHROMEOS) 106 #if defined(OS_CHROMEOS)
689 void TouchObserverHUD::OnDisplayModeChanged() { 107 void TouchObserverHUD::OnDisplayModeChanged() {
690 // Clear touch HUD for any change in display mode (single, dual extended, dual 108 // Clear touch HUD for any change in display mode (single, dual extended, dual
691 // mirrored, ...). 109 // mirrored, ...).
692 Clear(); 110 Clear();
693 } 111 }
694 #endif // defined(OS_CHROMEOS) 112 #endif // defined(OS_CHROMEOS)
695 113
696 void TouchObserverHUD::OnDisplayConfigurationChanging() { 114 void TouchObserverHUD::OnDisplayConfigurationChanging() {
697 if (!root_window_) 115 if (!root_window_)
698 return; 116 return;
699 117
700 root_window_->RemovePreTargetHandler(this); 118 root_window_->RemovePreTargetHandler(this);
701 119
702 RootWindowController* controller = GetRootWindowController(root_window_); 120 RootWindowController* controller = GetRootWindowController(root_window_);
703 controller->set_touch_observer_hud(NULL); 121 UnsetHudForRootWindowController(controller);
704 122
705 views::Widget::ReparentNativeView( 123 views::Widget::ReparentNativeView(
706 widget_->GetNativeView(), 124 widget_->GetNativeView(),
707 Shell::GetContainer(root_window_, 125 Shell::GetContainer(root_window_,
708 internal::kShellWindowId_UnparentedControlContainer)); 126 internal::kShellWindowId_UnparentedControlContainer));
709 127
710 root_window_ = NULL; 128 root_window_ = NULL;
711 } 129 }
712 130
713 void TouchObserverHUD::OnDisplayConfigurationChanged() { 131 void TouchObserverHUD::OnDisplayConfigurationChanged() {
714 if (root_window_) 132 if (root_window_)
715 return; 133 return;
716 134
717 root_window_ = Shell::GetInstance()->display_controller()-> 135 root_window_ = Shell::GetInstance()->display_controller()->
718 GetRootWindowForDisplayId(display_id_); 136 GetRootWindowForDisplayId(display_id_);
719 137
720 views::Widget::ReparentNativeView( 138 views::Widget::ReparentNativeView(
721 widget_->GetNativeView(), 139 widget_->GetNativeView(),
722 Shell::GetContainer(root_window_, 140 Shell::GetContainer(root_window_,
723 internal::kShellWindowId_OverlayContainer)); 141 internal::kShellWindowId_OverlayContainer));
724 142
725 RootWindowController* controller = GetRootWindowController(root_window_); 143 RootWindowController* controller = GetRootWindowController(root_window_);
726 controller->set_touch_observer_hud(this); 144 SetHudForRootWindowController(controller);
727 145
728 root_window_->AddPreTargetHandler(this); 146 root_window_->AddPreTargetHandler(this);
729 } 147 }
730 148
731 } // namespace internal 149 } // namespace internal
732 } // namespace ash 150 } // namespace ash
OLDNEW
« no previous file with comments | « ash/touch/touch_observer_hud.h ('k') | ash/touch/touch_observer_hud_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698