Move pending tile priorities to active on tree activation
[chromium-blink-merge.git] / ash / touch / touch_observer_hud.cc
blob176e52f95d1d506f7844061e8bfdf56b9e4414e7
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
3 // found in the LICENSE file.
5 #include "ash/touch/touch_observer_hud.h"
7 #include "ash/shell_window_ids.h"
8 #include "base/stringprintf.h"
9 #include "base/utf_string_conversions.h"
10 #include "third_party/skia/include/core/SkPath.h"
11 #include "third_party/skia/include/core/SkXfermode.h"
12 #include "ui/base/events/event.h"
13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/display.h"
15 #include "ui/gfx/rect.h"
16 #include "ui/gfx/screen.h"
17 #include "ui/gfx/size.h"
18 #include "ui/views/background.h"
19 #include "ui/views/controls/label.h"
20 #include "ui/views/layout/box_layout.h"
21 #include "ui/views/widget/widget.h"
23 namespace ash {
24 namespace internal {
26 const int kMaxPaths = 15;
27 const int kScale = 10;
28 const int kColors[] = {
29 static_cast<int>(SK_ColorYELLOW),
30 static_cast<int>(SK_ColorGREEN),
31 static_cast<int>(SK_ColorRED),
32 static_cast<int>(SK_ColorBLUE),
33 static_cast<int>(SK_ColorMAGENTA),
34 static_cast<int>(SK_ColorCYAN),
35 static_cast<int>(SK_ColorWHITE),
36 static_cast<int>(SK_ColorBLACK)
39 class TouchHudCanvas : public views::View {
40 public:
41 explicit TouchHudCanvas(TouchObserverHUD* owner)
42 : owner_(owner),
43 path_index_(0),
44 color_index_(0) {
45 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
46 gfx::Rect bounds = display.bounds();
47 size_.set_width(bounds.width() / kScale);
48 size_.set_height(bounds.height() / kScale);
51 virtual ~TouchHudCanvas() {}
53 void Start(int id, const gfx::Point& point) {
54 paths_[path_index_].reset();
55 paths_[path_index_].moveTo(SkIntToScalar(point.x() / kScale),
56 SkIntToScalar(point.y() / kScale));
57 colors_[path_index_] = kColors[color_index_];
58 color_index_ = (color_index_ + 1) % arraysize(kColors);
60 touch_id_to_path_[id] = path_index_;
61 path_index_ = (path_index_ + 1) % kMaxPaths;
62 SchedulePaint();
65 void Update(int id, gfx::Point& to) {
66 SkPoint last;
67 int path_id = touch_id_to_path_[id];
68 SkScalar x = SkIntToScalar(to.x() / kScale);
69 SkScalar y = SkIntToScalar(to.y() / kScale);
70 if (!paths_[path_id].getLastPt(&last) || x != last.x() || y != last.y())
71 paths_[path_id].lineTo(x, y);
72 SchedulePaint();
75 private:
76 // Overridden from views::View.
77 virtual gfx::Size GetPreferredSize() OVERRIDE {
78 return size_;
81 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
82 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
83 canvas->DrawColor(SkColorSetARGB(25, 0, 0, 0));
85 SkPaint paint;
86 paint.setStrokeWidth(SkIntToScalar(2));
87 paint.setStyle(SkPaint::kStroke_Style);
88 for (size_t i = 0; i < arraysize(paths_); ++i) {
89 if (paths_[i].countPoints() == 0)
90 continue;
91 paint.setColor(colors_[i]);
92 if (paths_[i].countPoints() == 1) {
93 SkPoint point = paths_[i].getPoint(0);
94 canvas->sk_canvas()->drawPoint(point.x(), point.y(), paint);
95 } else {
96 canvas->DrawPath(paths_[i], paint);
101 TouchObserverHUD* owner_;
102 SkPath paths_[kMaxPaths];
103 SkColor colors_[kMaxPaths];
105 int path_index_;
106 int color_index_;
108 std::map<int, int> touch_id_to_path_;
110 gfx::Size size_;
112 DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas);
115 TouchObserverHUD::TouchObserverHUD() {
116 views::View* content = new views::View;
117 content->SetLayoutManager(new views::BoxLayout(
118 views::BoxLayout::kVertical, 0, 0, 0));
120 canvas_ = new TouchHudCanvas(this);
121 content->AddChildView(canvas_);
122 for (int i = 0; i < kMaxTouchPoints; ++i) {
123 touch_status_[i] = ui::ET_UNKNOWN;
124 touch_labels_[i] = new views::Label;
125 touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
126 touch_labels_[i]->SetShadowColors(SK_ColorWHITE,
127 SK_ColorWHITE);
128 touch_labels_[i]->SetShadowOffset(1, 1);
129 touch_labels_[i]->SetVisible(false);
130 content->AddChildView(touch_labels_[i]);
133 widget_ = new views::Widget();
134 views::Widget::InitParams
135 params(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
136 params.transparent = true;
137 params.can_activate = false;
138 params.accept_events = false;
139 params.bounds = gfx::Rect(content->GetPreferredSize());
140 params.parent = Shell::GetContainer(
141 Shell::GetPrimaryRootWindow(),
142 internal::kShellWindowId_OverlayContainer);
143 widget_->Init(params);
144 widget_->SetContentsView(content);
145 widget_->StackAtTop();
146 widget_->Show();
148 // The TouchObserverHUD's lifetime is always more than |widget_|. The
149 // |widget_| is unset from the OnWidgetClosing callback.
150 widget_->AddObserver(this);
153 TouchObserverHUD::~TouchObserverHUD() {
154 // The widget should have already been destroyed.
155 DCHECK(!widget_);
158 void TouchObserverHUD::UpdateTouchPointLabel(int index) {
159 const char* status = NULL;
160 switch (touch_status_[index]) {
161 case ui::ET_UNKNOWN:
162 status = " ";
163 break;
164 case ui::ET_TOUCH_PRESSED:
165 status = "P";
166 break;
167 case ui::ET_TOUCH_MOVED:
168 status = "M";
169 break;
170 case ui::ET_TOUCH_RELEASED:
171 status = "R";
172 break;
173 case ui::ET_TOUCH_CANCELLED:
174 status = "C";
175 break;
176 default:
177 status = "?";
178 break;
180 std::string string = base::StringPrintf("%2d: %s %s",
181 index, status, touch_positions_[index].ToString().c_str());
182 touch_labels_[index]->SetText(UTF8ToUTF16(string));
185 void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* event) {
186 if (event->touch_id() >= kMaxTouchPoints)
187 return;
189 if (event->type() != ui::ET_TOUCH_CANCELLED)
190 touch_positions_[event->touch_id()] = event->root_location();
191 if (event->type() == ui::ET_TOUCH_PRESSED)
192 canvas_->Start(event->touch_id(), touch_positions_[event->touch_id()]);
193 else
194 canvas_->Update(event->touch_id(), touch_positions_[event->touch_id()]);
195 touch_status_[event->touch_id()] = event->type();
196 touch_labels_[event->touch_id()]->SetVisible(true);
197 UpdateTouchPointLabel(event->touch_id());
199 widget_->SetSize(widget_->GetContentsView()->GetPreferredSize());
202 void TouchObserverHUD::OnWidgetClosing(views::Widget* widget) {
203 DCHECK_EQ(widget, widget_);
204 widget_ = NULL;
207 } // namespace internal
208 } // namespace ash