| OLD | NEW |
| 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" | 7 #include "ash/display/display_controller.h" |
| 8 #include "ash/display/display_manager.h" | 8 #include "ash/display/display_manager.h" |
| 9 #include "ash/root_window_controller.h" | 9 #include "ash/root_window_controller.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" | 12 #include "base/json/json_string_value_serializer.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "third_party/skia/include/core/SkPath.h" | 16 #include "third_party/skia/include/core/SkPath.h" |
| 17 #include "third_party/skia/include/core/SkXfermode.h" | 17 #include "third_party/skia/include/core/SkXfermode.h" |
| 18 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 18 #include "ui/aura/root_window.h" | 19 #include "ui/aura/root_window.h" |
| 19 #include "ui/aura/window.h" | 20 #include "ui/aura/window.h" |
| 21 #include "ui/base/animation/animation_delegate.h" |
| 22 #include "ui/base/animation/linear_animation.h" |
| 20 #include "ui/base/events/event.h" | 23 #include "ui/base/events/event.h" |
| 21 #include "ui/gfx/canvas.h" | 24 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/display.h" | 25 #include "ui/gfx/display.h" |
| 23 #include "ui/gfx/rect.h" | 26 #include "ui/gfx/rect.h" |
| 24 #include "ui/gfx/screen.h" | 27 #include "ui/gfx/screen.h" |
| 25 #include "ui/gfx/size.h" | 28 #include "ui/gfx/size.h" |
| 26 #include "ui/gfx/transform.h" | 29 #include "ui/gfx/transform.h" |
| 27 #include "ui/views/background.h" | 30 #include "ui/views/background.h" |
| 28 #include "ui/views/controls/label.h" | 31 #include "ui/views/controls/label.h" |
| 29 #include "ui/views/layout/box_layout.h" | 32 #include "ui/views/layout/box_layout.h" |
| 30 #include "ui/views/widget/widget.h" | 33 #include "ui/views/widget/widget.h" |
| 31 | 34 |
| 32 #if defined(USE_X11) | 35 #if defined(USE_X11) |
| 33 #include <X11/extensions/XInput2.h> | 36 #include <X11/extensions/XInput2.h> |
| 34 #include <X11/Xlib.h> | 37 #include <X11/Xlib.h> |
| 35 | 38 |
| 36 #include "ui/base/x/valuators.h" | 39 #include "ui/base/x/valuators.h" |
| 37 #endif | 40 #endif |
| 38 | 41 |
| 39 namespace ash { | 42 namespace ash { |
| 40 namespace internal { | 43 namespace internal { |
| 41 | 44 |
| 42 const int kPointRadius = 20; | 45 const int kPointRadius = 20; |
| 43 const int kColors[] = { | 46 const SkColor kColors[] = { |
| 44 static_cast<int>(SK_ColorYELLOW), | 47 SK_ColorYELLOW, |
| 45 static_cast<int>(SK_ColorGREEN), | 48 SK_ColorGREEN, |
| 46 static_cast<int>(SK_ColorRED), | 49 SK_ColorRED, |
| 47 static_cast<int>(SK_ColorBLUE), | 50 SK_ColorBLUE, |
| 48 static_cast<int>(SK_ColorGRAY), | 51 SK_ColorGRAY, |
| 49 static_cast<int>(SK_ColorMAGENTA), | 52 SK_ColorMAGENTA, |
| 50 static_cast<int>(SK_ColorCYAN), | 53 SK_ColorCYAN, |
| 51 static_cast<int>(SK_ColorWHITE), | 54 SK_ColorWHITE, |
| 52 static_cast<int>(SK_ColorBLACK) | 55 SK_ColorBLACK, |
| 56 SkColorSetRGB(0xFF, 0x8C, 0x00), |
| 57 SkColorSetRGB(0x8B, 0x45, 0x13), |
| 58 SkColorSetRGB(0xFF, 0xDE, 0xAD), |
| 53 }; | 59 }; |
| 54 const int kAlpha = 0x60; | 60 const int kAlpha = 0x60; |
| 61 const SkColor kProjectionFillColor = SkColorSetRGB(0xF5, 0xF5, 0xDC); |
| 62 const SkColor kProjectionStrokeColor = SK_ColorGRAY; |
| 63 const int kProjectionAlpha = 0xB0; |
| 55 const int kMaxPaths = arraysize(kColors); | 64 const int kMaxPaths = arraysize(kColors); |
| 56 const int kReducedScale = 10; | 65 const int kReducedScale = 10; |
| 66 const int kFadeoutDurationInMs = 250; |
| 67 const int kFadeoutFrameRate = 60; |
| 57 | 68 |
| 58 const char* GetTouchEventLabel(ui::EventType type) { | 69 const char* GetTouchEventLabel(ui::EventType type) { |
| 59 switch (type) { | 70 switch (type) { |
| 60 case ui::ET_UNKNOWN: | 71 case ui::ET_UNKNOWN: |
| 61 return " "; | 72 return " "; |
| 62 case ui::ET_TOUCH_PRESSED: | 73 case ui::ET_TOUCH_PRESSED: |
| 63 return "P"; | 74 return "P"; |
| 64 case ui::ET_TOUCH_MOVED: | 75 case ui::ET_TOUCH_MOVED: |
| 65 return "M"; | 76 return "M"; |
| 66 case ui::ET_TOUCH_RELEASED: | 77 case ui::ET_TOUCH_RELEASED: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 float radius_y; | 150 float radius_y; |
| 140 float pressure; | 151 float pressure; |
| 141 int tracking_id; | 152 int tracking_id; |
| 142 int source_device; | 153 int source_device; |
| 143 }; | 154 }; |
| 144 | 155 |
| 145 // A TouchTrace keeps track of all the touch events of a single touch point | 156 // A TouchTrace keeps track of all the touch events of a single touch point |
| 146 // (starting from a touch-press and ending at touch-release). | 157 // (starting from a touch-press and ending at touch-release). |
| 147 class TouchTrace { | 158 class TouchTrace { |
| 148 public: | 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 |
| 149 TouchTrace() { | 166 TouchTrace() { |
| 150 } | 167 } |
| 151 | 168 |
| 152 void AddTouchPoint(const ui::TouchEvent& touch) { | 169 void AddTouchPoint(const ui::TouchEvent& touch) { |
| 153 log_.push_back(TouchPointLog(touch)); | 170 log_.push_back(TouchPointLog(touch)); |
| 154 } | 171 } |
| 155 | 172 |
| 156 bool empty() const { return log_.empty(); } | 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 } |
| 157 | 179 |
| 158 // Returns a list containing data from all events for the touch point. | 180 // Returns a list containing data from all events for the touch point. |
| 159 scoped_ptr<ListValue> GetAsList() const { | 181 scoped_ptr<ListValue> GetAsList() const { |
| 160 scoped_ptr<ListValue> list(new ListValue()); | 182 scoped_ptr<ListValue> list(new ListValue()); |
| 161 for (std::vector<TouchPointLog>::const_iterator i = log_.begin(); | 183 for (const_iterator i = log_.begin(); i != log_.end(); ++i) |
| 162 i != log_.end(); ++i) { | |
| 163 list->Append((*i).GetAsDictionary().release()); | 184 list->Append((*i).GetAsDictionary().release()); |
| 164 } | |
| 165 | |
| 166 return list.Pass(); | 185 return list.Pass(); |
| 167 } | 186 } |
| 168 | 187 |
| 169 void Reset() { | 188 void Reset() { |
| 170 log_.clear(); | 189 log_.clear(); |
| 171 } | 190 } |
| 172 | 191 |
| 173 private: | 192 private: |
| 174 std::vector<TouchPointLog> log_; | 193 std::vector<TouchPointLog> log_; |
| 175 | 194 |
| 176 DISALLOW_COPY_AND_ASSIGN(TouchTrace); | 195 DISALLOW_COPY_AND_ASSIGN(TouchTrace); |
| 177 }; | 196 }; |
| 178 | 197 |
| 179 class TouchHudCanvas : public views::View { | 198 // A TouchLog keeps track of all touch events of all touch points. |
| 199 class TouchLog { |
| 180 public: | 200 public: |
| 181 explicit TouchHudCanvas(TouchObserverHUD* owner) | 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 class TouchHudCanvas : public views::View, public ui::AnimationDelegate { |
| 264 public: |
| 265 TouchHudCanvas(TouchObserverHUD* owner, const TouchLog& touch_log) |
| 182 : owner_(owner), | 266 : owner_(owner), |
| 183 path_index_(0), | 267 touch_log_(touch_log), |
| 184 color_index_(0), | |
| 185 scale_(1) { | 268 scale_(1) { |
| 186 SetPaintToLayer(true); | 269 SetPaintToLayer(true); |
| 187 SetFillsBoundsOpaquely(false); | 270 SetFillsBoundsOpaquely(false); |
| 271 |
| 272 paint_.setStyle(SkPaint::kFill_Style); |
| 273 |
| 274 projection_stroke_paint_.setStyle(SkPaint::kStroke_Style); |
| 275 projection_stroke_paint_.setColor(kProjectionStrokeColor); |
| 276 |
| 277 projection_gradient_colors_[0] = kProjectionFillColor; |
| 278 projection_gradient_colors_[1] = kProjectionStrokeColor; |
| 279 |
| 280 projection_gradient_pos_[0] = SkFloatToScalar(0.9f); |
| 281 projection_gradient_pos_[1] = SkFloatToScalar(1.0f); |
| 188 } | 282 } |
| 189 | 283 |
| 190 virtual ~TouchHudCanvas() {} | 284 virtual ~TouchHudCanvas() {} |
| 191 | 285 |
| 192 void SetScale(int scale) { | 286 void SetScale(int scale) { |
| 193 if (scale_ == scale) | 287 if (scale_ == scale) |
| 194 return; | 288 return; |
| 195 scale_ = scale; | 289 scale_ = scale; |
| 196 gfx::Transform transform; | 290 gfx::Transform transform; |
| 197 transform.Scale(1. / scale_, 1. / scale_); | 291 transform.Scale(1. / scale_, 1. / scale_); |
| 198 layer()->SetTransform(transform); | 292 layer()->SetTransform(transform); |
| 199 } | 293 } |
| 200 | 294 |
| 201 int scale() const { return scale_; } | 295 int scale() const { return scale_; } |
| 202 | 296 |
| 203 void Start(const ui::TouchEvent& touch) { | 297 void TouchPointAdded(int touch_id) { |
| 204 int id = touch.touch_id(); | 298 int trace_index = touch_log_.GetTraceIndex(touch_id); |
| 205 paths_[path_index_].reset(); | 299 const TouchTrace& trace = touch_log_.traces()[trace_index]; |
| 206 traces_[path_index_].Reset(); | 300 const TouchPointLog& point = trace.log().back(); |
| 207 colors_[path_index_] = SkColorSetA(kColors[color_index_], kAlpha); | 301 if (point.type == ui::ET_TOUCH_PRESSED) |
| 208 color_index_ = (color_index_ + 1) % arraysize(kColors); | 302 StartedTrace(trace_index); |
| 209 touch_id_to_path_[id] = path_index_; | 303 if (point.type != ui::ET_TOUCH_CANCELLED) |
| 210 path_index_ = (path_index_ + 1) % kMaxPaths; | 304 AddedPointToTrace(trace_index); |
| 211 AddPoint(touch); | 305 if (owner_->mode() == TouchObserverHUD::PROJECTION && !trace.active()) |
| 212 SchedulePaint(); | 306 StartAnimation(trace_index); |
| 213 } | 307 } |
| 214 | 308 |
| 215 void AddPoint(const ui::TouchEvent& touch) { | 309 void StopAnimations() { |
| 216 int id = touch.touch_id(); | 310 for (int i = 0; i < kMaxPaths; ++i) |
| 217 const gfx::Point& point = touch.root_location(); | 311 fadeouts_[i].reset(NULL); |
| 218 int path_id = touch_id_to_path_[id]; | |
| 219 SkScalar x = SkIntToScalar(point.x()); | |
| 220 SkScalar y = SkIntToScalar(point.y()); | |
| 221 SkPoint last; | |
| 222 if (!paths_[path_id].getLastPt(&last) || x != last.x() || y != last.y()) { | |
| 223 paths_[path_id].addCircle(x, y, SkIntToScalar(kPointRadius)); | |
| 224 traces_[path_id].AddTouchPoint(touch); | |
| 225 } | |
| 226 SchedulePaint(); | |
| 227 } | 312 } |
| 228 | 313 |
| 229 void Clear() { | 314 void Clear() { |
| 230 path_index_ = 0; | 315 for (int i = 0; i < kMaxPaths; ++i) |
| 231 color_index_ = 0; | |
| 232 for (size_t i = 0; i < arraysize(paths_); ++i) { | |
| 233 paths_[i].reset(); | 316 paths_[i].reset(); |
| 234 traces_[i].Reset(); | 317 if (owner_->mode() == TouchObserverHUD::PROJECTION) |
| 235 } | 318 StopAnimations(); |
| 236 | 319 |
| 237 SchedulePaint(); | 320 SchedulePaint(); |
| 238 } | 321 } |
| 239 | 322 |
| 240 scoped_ptr<ListValue> GetAsList() const { | 323 private: |
| 241 scoped_ptr<ListValue> list(new ListValue()); | 324 void StartedTrace(int trace_index) { |
| 242 for (size_t i = 0; i < arraysize(traces_); ++i) { | 325 paths_[trace_index].reset(); |
| 243 if (!traces_[i].empty()) | 326 colors_[trace_index] = SkColorSetA(kColors[trace_index], kAlpha); |
| 244 list->Append(traces_[i].GetAsList().release()); | |
| 245 } | |
| 246 return list.Pass(); | |
| 247 } | 327 } |
| 248 | 328 |
| 249 private: | 329 void AddedPointToTrace(int trace_index) { |
| 250 // Overridden from views::View. | 330 const TouchTrace& trace = touch_log_.traces()[trace_index]; |
| 251 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { | 331 const TouchPointLog& point = trace.log().back(); |
| 252 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); | 332 const gfx::Point& location = point.location; |
| 253 canvas->DrawColor(SkColorSetARGB(0, 0, 0, 0)); | 333 SkScalar x = SkIntToScalar(location.x()); |
| 254 | 334 SkScalar y = SkIntToScalar(location.y()); |
| 255 SkPaint paint; | 335 SkPoint last; |
| 256 paint.setStyle(SkPaint::kFill_Style); | 336 if (!paths_[trace_index].getLastPt(&last) || x != last.x() || |
| 257 for (size_t i = 0; i < arraysize(paths_); ++i) { | 337 y != last.y()) { |
| 258 if (paths_[i].countPoints() == 0) | 338 paths_[trace_index].addCircle(x, y, SkIntToScalar(kPointRadius)); |
| 259 continue; | 339 SchedulePaint(); |
| 260 paint.setColor(colors_[i]); | |
| 261 canvas->DrawPath(paths_[i], paint); | |
| 262 } | 340 } |
| 263 } | 341 } |
| 264 | 342 |
| 265 TouchObserverHUD* owner_; | 343 void StartAnimation(int path_index) { |
| 344 DCHECK(!fadeouts_[path_index].get()); |
| 345 fadeouts_[path_index].reset(new ui::LinearAnimation(kFadeoutDurationInMs, |
| 346 kFadeoutFrameRate, |
| 347 this)); |
| 348 fadeouts_[path_index]->Start(); |
| 349 } |
| 350 |
| 351 // Overridden from views::View. |
| 352 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { |
| 353 if (owner_->mode() == TouchObserverHUD::PROJECTION) { |
| 354 for (int i = 0; i < kMaxPaths; ++i) { |
| 355 const TouchTrace& trace = touch_log_.traces()[i]; |
| 356 if (!trace.active() && !fadeouts_[i].get()) |
| 357 continue; |
| 358 TouchTrace::const_reverse_iterator point = trace.log().rbegin(); |
| 359 while (point != trace.log().rend() && |
| 360 point->type == ui::ET_TOUCH_CANCELLED) |
| 361 point++; |
| 362 DCHECK(point != trace.log().rend()); |
| 363 int alpha = kProjectionAlpha; |
| 364 if (fadeouts_[i].get()) |
| 365 alpha = static_cast<int>(fadeouts_[i]->CurrentValueBetween(alpha, 0)); |
| 366 projection_fill_paint_.setAlpha(alpha); |
| 367 projection_stroke_paint_.setAlpha(alpha); |
| 368 SkShader* shader = SkGradientShader::CreateRadial( |
| 369 SkPoint::Make(SkIntToScalar(point->location.x()), |
| 370 SkIntToScalar(point->location.y())), |
| 371 SkIntToScalar(kPointRadius), |
| 372 projection_gradient_colors_, |
| 373 projection_gradient_pos_, |
| 374 arraysize(projection_gradient_colors_), |
| 375 SkShader::kMirror_TileMode, |
| 376 NULL); |
| 377 projection_fill_paint_.setShader(shader); |
| 378 shader->unref(); |
| 379 canvas->DrawCircle(point->location, SkIntToScalar(kPointRadius), |
| 380 projection_fill_paint_); |
| 381 canvas->DrawCircle(point->location, SkIntToScalar(kPointRadius), |
| 382 projection_stroke_paint_); |
| 383 } |
| 384 } else { |
| 385 for (int i = 0; i < kMaxPaths; ++i) { |
| 386 if (paths_[i].countPoints() == 0) |
| 387 continue; |
| 388 paint_.setColor(colors_[i]); |
| 389 canvas->DrawPath(paths_[i], paint_); |
| 390 } |
| 391 } |
| 392 } |
| 393 |
| 394 // Overridden from ui::AnimationDelegate. |
| 395 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { |
| 396 for (int i = 0; i < kMaxPaths; ++i) |
| 397 if (fadeouts_[i].get() == animation) { |
| 398 fadeouts_[i].reset(NULL); |
| 399 break; |
| 400 } |
| 401 } |
| 402 |
| 403 // Overridden from ui::AnimationDelegate. |
| 404 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE { |
| 405 SchedulePaint(); |
| 406 } |
| 407 |
| 408 // Overridden from ui::AnimationDelegate. |
| 409 virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { |
| 410 AnimationEnded(animation); |
| 411 } |
| 412 |
| 413 const TouchObserverHUD* const owner_; |
| 414 const TouchLog& touch_log_; |
| 415 |
| 416 SkPaint paint_; |
| 417 SkPaint projection_fill_paint_; |
| 418 SkPaint projection_stroke_paint_; |
| 419 SkColor projection_gradient_colors_[2]; |
| 420 SkScalar projection_gradient_pos_[2]; |
| 421 |
| 266 SkPath paths_[kMaxPaths]; | 422 SkPath paths_[kMaxPaths]; |
| 423 scoped_ptr<ui::Animation> fadeouts_[kMaxPaths]; |
| 267 SkColor colors_[kMaxPaths]; | 424 SkColor colors_[kMaxPaths]; |
| 268 TouchTrace traces_[kMaxPaths]; | |
| 269 | 425 |
| 270 int path_index_; | |
| 271 int color_index_; | |
| 272 int scale_; | 426 int scale_; |
| 273 | 427 |
| 274 std::map<int, int> touch_id_to_path_; | |
| 275 | |
| 276 DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas); | 428 DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas); |
| 277 }; | 429 }; |
| 278 | 430 |
| 279 TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root) | 431 TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root) |
| 280 : display_id_(initial_root->GetProperty(kDisplayIdKey)), | 432 : display_id_(initial_root->GetProperty(kDisplayIdKey)), |
| 281 root_window_(initial_root) { | 433 root_window_(initial_root), |
| 434 mode_(FULLSCREEN), |
| 435 touch_log_(new TouchLog()) { |
| 282 const gfx::Display& display = | 436 const gfx::Display& display = |
| 283 Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_); | 437 Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_); |
| 284 | 438 |
| 285 views::View* content = new views::View; | 439 views::View* content = new views::View; |
| 286 | 440 |
| 287 canvas_ = new TouchHudCanvas(this); | 441 canvas_ = new TouchHudCanvas(this, *touch_log_); |
| 288 content->AddChildView(canvas_); | 442 content->AddChildView(canvas_); |
| 289 | 443 |
| 290 const gfx::Size& display_size = display.size(); | 444 const gfx::Size& display_size = display.size(); |
| 291 canvas_->SetSize(display_size); | 445 canvas_->SetSize(display_size); |
| 292 content->SetSize(display_size); | 446 content->SetSize(display_size); |
| 293 | 447 |
| 294 label_container_ = new views::View; | 448 label_container_ = new views::View; |
| 295 label_container_->SetLayoutManager(new views::BoxLayout( | 449 label_container_->SetLayoutManager(new views::BoxLayout( |
| 296 views::BoxLayout::kVertical, 0, 0, 0)); | 450 views::BoxLayout::kVertical, 0, 0, 0)); |
| 297 | 451 |
| 298 for (int i = 0; i < kMaxTouchPoints; ++i) { | 452 for (int i = 0; i < kMaxTouchPoints; ++i) { |
| 299 touch_status_[i] = ui::ET_UNKNOWN; | |
| 300 touch_labels_[i] = new views::Label; | 453 touch_labels_[i] = new views::Label; |
| 301 touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255)); | 454 touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255)); |
| 302 touch_labels_[i]->SetShadowColors(SK_ColorWHITE, | 455 touch_labels_[i]->SetShadowColors(SK_ColorWHITE, |
| 303 SK_ColorWHITE); | 456 SK_ColorWHITE); |
| 304 touch_labels_[i]->SetShadowOffset(1, 1); | 457 touch_labels_[i]->SetShadowOffset(1, 1); |
| 305 label_container_->AddChildView(touch_labels_[i]); | 458 label_container_->AddChildView(touch_labels_[i]); |
| 306 } | 459 } |
| 307 label_container_->SetX(0); | 460 label_container_->SetX(0); |
| 308 label_container_->SetY(display_size.height() / kReducedScale); | 461 label_container_->SetY(display_size.height() / kReducedScale); |
| 309 label_container_->SetSize(label_container_->GetPreferredSize()); | 462 label_container_->SetSize(label_container_->GetPreferredSize()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 scoped_ptr<ListValue> list = | 513 scoped_ptr<ListValue> list = |
| 361 controller->touch_observer_hud()->GetLogAsList(); | 514 controller->touch_observer_hud()->GetLogAsList(); |
| 362 if (!list->empty()) | 515 if (!list->empty()) |
| 363 value->Set(base::Int64ToString(display_id), list.release()); | 516 value->Set(base::Int64ToString(display_id), list.release()); |
| 364 } | 517 } |
| 365 } | 518 } |
| 366 return value.Pass(); | 519 return value.Pass(); |
| 367 } | 520 } |
| 368 | 521 |
| 369 void TouchObserverHUD::ChangeToNextMode() { | 522 void TouchObserverHUD::ChangeToNextMode() { |
| 370 if (widget_->IsVisible()) { | 523 switch (mode_) { |
| 371 if (canvas_->scale() == kReducedScale) { | 524 case FULLSCREEN: |
| 372 widget_->Hide(); | 525 SetMode(REDUCED_SCALE); |
| 373 } else { | 526 break; |
| 374 label_container_->SetVisible(true); | 527 case REDUCED_SCALE: |
| 375 canvas_->SetScale(kReducedScale); | 528 SetMode(PROJECTION); |
| 376 } | 529 break; |
| 377 } else { | 530 case PROJECTION: |
| 378 canvas_->SetScale(1); | 531 SetMode(INVISIBLE); |
| 379 label_container_->SetVisible(false); | 532 break; |
| 380 widget_->Show(); | 533 case INVISIBLE: |
| 534 SetMode(FULLSCREEN); |
| 535 break; |
| 381 } | 536 } |
| 382 } | 537 } |
| 383 | 538 |
| 384 void TouchObserverHUD::Clear() { | 539 void TouchObserverHUD::Clear() { |
| 385 if (widget_->IsVisible()) | 540 if (widget_->IsVisible()) |
| 386 canvas_->Clear(); | 541 canvas_->Clear(); |
| 542 for (int i = 0; i < kMaxTouchPoints; ++i) |
| 543 touch_labels_[i]->SetText(string16()); |
| 544 label_container_->SetSize(label_container_->GetPreferredSize()); |
| 387 } | 545 } |
| 388 | 546 |
| 389 scoped_ptr<ListValue> TouchObserverHUD::GetLogAsList() const { | 547 scoped_ptr<ListValue> TouchObserverHUD::GetLogAsList() const { |
| 390 return canvas_->GetAsList(); | 548 return touch_log_->GetAsList(); |
| 549 } |
| 550 |
| 551 void TouchObserverHUD::SetMode(Mode mode) { |
| 552 if (mode_ == mode) |
| 553 return; |
| 554 mode_ = mode; |
| 555 canvas_->StopAnimations(); |
| 556 switch (mode) { |
| 557 case FULLSCREEN: |
| 558 case PROJECTION: |
| 559 label_container_->SetVisible(false); |
| 560 canvas_->SetScale(1); |
| 561 canvas_->SchedulePaint(); |
| 562 widget_->Show(); |
| 563 break; |
| 564 case REDUCED_SCALE: |
| 565 label_container_->SetVisible(true); |
| 566 canvas_->SetScale(kReducedScale); |
| 567 canvas_->SchedulePaint(); |
| 568 widget_->Show(); |
| 569 break; |
| 570 case INVISIBLE: |
| 571 widget_->Hide(); |
| 572 break; |
| 573 } |
| 391 } | 574 } |
| 392 | 575 |
| 393 void TouchObserverHUD::UpdateTouchPointLabel(int index) { | 576 void TouchObserverHUD::UpdateTouchPointLabel(int index) { |
| 577 int trace_index = touch_log_->GetTraceIndex(index); |
| 578 const TouchTrace& trace = touch_log_->traces()[trace_index]; |
| 579 TouchTrace::const_reverse_iterator point = trace.log().rbegin(); |
| 580 ui::EventType touch_status = point->type; |
| 581 float touch_radius = std::max(point->radius_x, point->radius_y); |
| 582 while (point != trace.log().rend() && point->type == ui::ET_TOUCH_CANCELLED) |
| 583 point++; |
| 584 DCHECK(point != trace.log().rend()); |
| 585 gfx::Point touch_position = point->location; |
| 586 |
| 394 std::string string = base::StringPrintf("%2d: %s %s (%.4f)", | 587 std::string string = base::StringPrintf("%2d: %s %s (%.4f)", |
| 395 index, GetTouchEventLabel(touch_status_[index]), | 588 index, |
| 396 touch_positions_[index].ToString().c_str(), | 589 GetTouchEventLabel(touch_status), |
| 397 touch_radius_[index]); | 590 touch_position.ToString().c_str(), |
| 591 touch_radius); |
| 398 touch_labels_[index]->SetText(UTF8ToUTF16(string)); | 592 touch_labels_[index]->SetText(UTF8ToUTF16(string)); |
| 399 } | 593 } |
| 400 | 594 |
| 401 void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* event) { | 595 void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* event) { |
| 402 if (event->touch_id() >= kMaxTouchPoints) | 596 if (event->touch_id() >= kMaxTouchPoints) |
| 403 return; | 597 return; |
| 404 | 598 |
| 405 if (event->type() != ui::ET_TOUCH_CANCELLED) | 599 touch_log_->AddTouchPoint(*event); |
| 406 touch_positions_[event->touch_id()] = event->root_location(); | 600 canvas_->TouchPointAdded(event->touch_id()); |
| 407 | |
| 408 touch_radius_[event->touch_id()] = std::max(event->radius_x(), | |
| 409 event->radius_y()); | |
| 410 | |
| 411 if (event->type() == ui::ET_TOUCH_PRESSED) | |
| 412 canvas_->Start(*event); | |
| 413 else if (event->type() != ui::ET_TOUCH_CANCELLED) | |
| 414 canvas_->AddPoint(*event); | |
| 415 touch_status_[event->touch_id()] = event->type(); | |
| 416 | 601 |
| 417 UpdateTouchPointLabel(event->touch_id()); | 602 UpdateTouchPointLabel(event->touch_id()); |
| 418 label_container_->SetSize(label_container_->GetPreferredSize()); | 603 label_container_->SetSize(label_container_->GetPreferredSize()); |
| 419 } | 604 } |
| 420 | 605 |
| 421 void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) { | 606 void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) { |
| 422 DCHECK_EQ(widget, widget_); | 607 DCHECK_EQ(widget, widget_); |
| 423 delete this; | 608 delete this; |
| 424 } | 609 } |
| 425 | 610 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 internal::kShellWindowId_OverlayContainer)); | 663 internal::kShellWindowId_OverlayContainer)); |
| 479 | 664 |
| 480 RootWindowController* controller = GetRootWindowController(root_window_); | 665 RootWindowController* controller = GetRootWindowController(root_window_); |
| 481 controller->set_touch_observer_hud(this); | 666 controller->set_touch_observer_hud(this); |
| 482 | 667 |
| 483 root_window_->AddPreTargetHandler(this); | 668 root_window_->AddPreTargetHandler(this); |
| 484 } | 669 } |
| 485 | 670 |
| 486 } // namespace internal | 671 } // namespace internal |
| 487 } // namespace ash | 672 } // namespace ash |
| OLD | NEW |