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/magnifier/partial_magnification_controller.h" | 5 #include "ash/magnifier/partial_magnification_controller.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "third_party/skia/include/core/SkDrawLooper.h" | |
sammiequon
2016/09/22 00:51:46
Is this allowed?
jdufault
2016/09/22 19:59:12
Yes, third_party/skia is explicitly added in ash/D
sammiequon
2016/09/23 01:17:37
Oh right, forgot to check there. Thanks!
| |
8 #include "ui/aura/window_event_dispatcher.h" | 9 #include "ui/aura/window_event_dispatcher.h" |
9 #include "ui/aura/window_tree_host.h" | 10 #include "ui/aura/window_tree_host.h" |
10 #include "ui/compositor/layer.h" | 11 #include "ui/compositor/layer.h" |
11 #include "ui/compositor/paint_recorder.h" | 12 #include "ui/compositor/paint_recorder.h" |
12 #include "ui/events/event.h" | 13 #include "ui/events/event.h" |
13 #include "ui/events/event_constants.h" | 14 #include "ui/events/event_constants.h" |
14 #include "ui/views/widget/widget.h" | 15 #include "ui/views/widget/widget.h" |
15 #include "ui/wm/core/coordinate_conversion.h" | 16 #include "ui/wm/core/coordinate_conversion.h" |
16 | 17 |
17 #if defined(OS_CHROMEOS) | 18 #if defined(OS_CHROMEOS) |
18 #include "ash/common/system/chromeos/palette/palette_utils.h" | 19 #include "ash/common/system/chromeos/palette/palette_utils.h" |
19 #endif | 20 #endif |
20 | 21 |
21 namespace ash { | 22 namespace ash { |
22 namespace { | 23 namespace { |
23 | 24 |
24 // Ratio of magnifier scale. | 25 // Ratio of magnifier scale. |
25 const float kMagnificationScale = 2.f; | 26 const float kMagnificationScale = 2.f; |
26 // Radius of the magnifying glass in DIP. | 27 // Radius of the magnifying glass in DIP. This includes the thickness of the |
jdufault
2016/09/22 19:59:12
I think we should specify the radius of the magnif
sammiequon
2016/09/23 01:17:37
Makes sense, not sure why I didn't feel the need t
| |
27 const int kMagnifierRadius = 200; | 28 // magnifying glass shadow and border. |
29 const int kMagnifierRadius = 222; | |
28 // Size of the border around the magnifying glass in DIP. | 30 // Size of the border around the magnifying glass in DIP. |
29 const int kBorderSize = 10; | 31 const int kBorderSize = 10; |
30 // Thickness of the outline around magnifying glass border in DIP. | 32 // Thickness of the outline around magnifying glass border in DIP. |
31 const int kBorderOutlineThickness = 2; | 33 const int kBorderOutlineThickness = 1; |
32 // The color of the border and its outlines. The border has an outline on both | 34 // The color of the border and its outlines. The border has an outline on both |
33 // sides, producing a black/white/black ring. | 35 // sides, producing a black/white/black ring. |
34 const SkColor kBorderColor = SK_ColorWHITE; | 36 const SkColor kBorderColor = SkColorSetARGB(204, 255, 255, 255); |
35 const SkColor kBorderOutlineColor = SK_ColorBLACK; | 37 const SkColor kBorderOutlineColor = SkColorSetARGB(51, 0, 0, 0); |
jdufault
2016/09/22 19:59:12
Can we use SK_ColorTRANSPARENT for all of the colo
jdufault
2016/09/22 22:24:44
Sorry, ignore this comment. I was reading the colo
| |
38 // The colors of the two shadow around the magnifiying glass. | |
39 const SkColor kShadowOneColor = SkColorSetARGB(26, 0, 0, 0); | |
40 const SkColor kShadowTwoColor = SkColorSetARGB(61, 0, 0, 0); | |
41 // Thickness of the shadow around the magnifying glass in DIP. | |
42 const int kShadowThickness = 24; | |
36 // Inset on the zoom filter. | 43 // Inset on the zoom filter. |
37 const int kZoomInset = 0; | 44 const int kZoomInset = 0; |
38 // Vertical offset between the center of the magnifier and the tip of the | 45 // Vertical offset between the center of the magnifier and the tip of the |
39 // pointer. TODO(jdufault): The vertical offset should only apply to the window | 46 // pointer. TODO(jdufault): The vertical offset should only apply to the window |
40 // location, not the magnified contents. See crbug.com/637617. | 47 // location, not the magnified contents. See crbug.com/637617. |
41 const int kVerticalOffset = 0; | 48 const int kVerticalOffset = 0; |
42 | 49 |
43 // Name of the magnifier window. | 50 // Name of the magnifier window. |
44 const char kPartialMagniferWindowName[] = "PartialMagnifierWindow"; | 51 const char kPartialMagniferWindowName[] = "PartialMagnifierWindow"; |
45 | 52 |
(...skipping 27 matching lines...) Expand all Loading... | |
73 return false; | 80 return false; |
74 #endif | 81 #endif |
75 } | 82 } |
76 | 83 |
77 } // namespace | 84 } // namespace |
78 | 85 |
79 // The content mask provides a clipping layer for the magnification window so we | 86 // The content mask provides a clipping layer for the magnification window so we |
80 // can show a circular magnifier. | 87 // can show a circular magnifier. |
81 class PartialMagnificationController::ContentMask : public ui::LayerDelegate { | 88 class PartialMagnificationController::ContentMask : public ui::LayerDelegate { |
82 public: | 89 public: |
83 // If |stroke| is true, the circle will be a stroke. This is useful if we wish | 90 // If |is_border| is true, the circle will be a stroke. This is useful if we |
84 // to clip a border. | 91 // wish to clip a border. |
85 ContentMask(bool stroke, gfx::Size mask_bounds) | 92 ContentMask(bool is_border, gfx::Size mask_bounds) |
86 : layer_(ui::LAYER_TEXTURED), stroke_(stroke) { | 93 : layer_(ui::LAYER_TEXTURED), is_border_(is_border) { |
87 layer_.set_delegate(this); | 94 layer_.set_delegate(this); |
88 layer_.SetFillsBoundsOpaquely(false); | 95 layer_.SetFillsBoundsOpaquely(false); |
89 layer_.SetBounds(gfx::Rect(mask_bounds)); | 96 layer_.SetBounds(gfx::Rect(mask_bounds)); |
90 } | 97 } |
91 | 98 |
92 ~ContentMask() override { layer_.set_delegate(nullptr); } | 99 ~ContentMask() override { layer_.set_delegate(nullptr); } |
93 | 100 |
94 ui::Layer* layer() { return &layer_; } | 101 ui::Layer* layer() { return &layer_; } |
95 | 102 |
96 private: | 103 private: |
97 // ui::LayerDelegate: | 104 // ui::LayerDelegate: |
98 void OnPaintLayer(const ui::PaintContext& context) override { | 105 void OnPaintLayer(const ui::PaintContext& context) override { |
99 ui::PaintRecorder recorder(context, layer()->size()); | 106 ui::PaintRecorder recorder(context, layer()->size()); |
100 | 107 |
101 SkPaint paint; | 108 SkPaint paint; |
102 paint.setAlpha(255); | 109 paint.setAlpha(255); |
103 paint.setAntiAlias(true); | 110 paint.setAntiAlias(true); |
104 paint.setStrokeWidth(kBorderSize); | 111 paint.setStrokeWidth(kBorderSize + kShadowThickness); |
105 paint.setStyle(stroke_ ? SkPaint::kStroke_Style : SkPaint::kFill_Style); | 112 paint.setStyle(is_border_ ? SkPaint::kStroke_Style : SkPaint::kFill_Style); |
106 | 113 |
114 // If we want to clip the border, the radius of the circle is a little | |
115 // bigger. | |
107 gfx::Rect rect(layer()->bounds().size()); | 116 gfx::Rect rect(layer()->bounds().size()); |
108 recorder.canvas()->DrawCircle(rect.CenterPoint(), | 117 int clipping_radius = |
109 rect.width() / 2 - kBorderSize / 2, paint); | 118 rect.width() / 2 - (kShadowThickness + kBorderSize) / 2 - |
119 (is_border_ ? 0 : (kShadowThickness + kBorderSize) / 2); | |
120 recorder.canvas()->DrawCircle(rect.CenterPoint(), clipping_radius, paint); | |
110 } | 121 } |
111 | 122 |
112 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | 123 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
113 | 124 |
114 void OnDeviceScaleFactorChanged(float device_scale_factor) override { | 125 void OnDeviceScaleFactorChanged(float device_scale_factor) override { |
115 // Redrawing will take care of scale factor change. | 126 // Redrawing will take care of scale factor change. |
116 } | 127 } |
117 | 128 |
118 base::Closure PrepareForLayerBoundsChange() override { | 129 base::Closure PrepareForLayerBoundsChange() override { |
119 return base::Closure(); | 130 return base::Closure(); |
120 } | 131 } |
121 | 132 |
122 ui::Layer layer_; | 133 ui::Layer layer_; |
123 bool stroke_; | 134 bool is_border_; |
124 | |
125 DISALLOW_COPY_AND_ASSIGN(ContentMask); | 135 DISALLOW_COPY_AND_ASSIGN(ContentMask); |
126 }; | 136 }; |
127 | 137 |
128 // The border renderer draws the border as well as outline on both the outer and | 138 // The border renderer draws the border as well as outline on both the outer and |
129 // inner radius to increase visibility. | 139 // inner radius to increase visibility. The border renderer also handles drawing |
140 // the shadow. | |
130 class PartialMagnificationController::BorderRenderer | 141 class PartialMagnificationController::BorderRenderer |
131 : public ui::LayerDelegate { | 142 : public ui::LayerDelegate { |
132 public: | 143 public: |
133 explicit BorderRenderer(const gfx::Rect& magnifier_bounds) | 144 explicit BorderRenderer(const gfx::Rect& window_bounds) |
134 : magnifier_bounds_(magnifier_bounds) {} | 145 : magnifier_window_bounds_(window_bounds) { |
146 gfx::ShadowValue shadow1(gfx::Vector2d(0, -kShadowThickness), | |
147 kShadowThickness, kShadowOneColor); | |
148 gfx::ShadowValue shadow2(gfx::Vector2d(0, 0), kShadowThickness, | |
149 kShadowTwoColor); | |
150 magnifier_shadows_.push_back(shadow1); | |
jdufault
2016/09/22 19:59:12
Drop the temporaries and push_back the values dire
sammiequon
2016/09/23 01:17:37
Done.
| |
151 magnifier_shadows_.push_back(shadow2); | |
152 } | |
135 | 153 |
136 ~BorderRenderer() override {} | 154 ~BorderRenderer() override {} |
137 | 155 |
138 private: | 156 private: |
139 // ui::LayerDelegate: | 157 // ui::LayerDelegate: |
140 void OnPaintLayer(const ui::PaintContext& context) override { | 158 void OnPaintLayer(const ui::PaintContext& context) override { |
141 ui::PaintRecorder recorder(context, magnifier_bounds_.size()); | 159 ui::PaintRecorder recorder(context, magnifier_window_bounds_.size()); |
142 | 160 |
143 SkPaint paint; | 161 // Draw the shadow. |
144 paint.setAntiAlias(true); | 162 SkPaint shadow_paint; |
145 paint.setStyle(SkPaint::kStroke_Style); | 163 shadow_paint.setAntiAlias(true); |
164 shadow_paint.setColor(SK_ColorTRANSPARENT); | |
165 shadow_paint.setLooper(gfx::CreateShadowDrawLooper(magnifier_shadows_)); | |
166 gfx::Rect shadow_bounds(magnifier_window_bounds_.size()); | |
167 shadow_bounds.Inset(-gfx::ShadowValue::GetMargin(magnifier_shadows_)); | |
168 recorder.canvas()->DrawCircle( | |
169 shadow_bounds.CenterPoint(), | |
170 shadow_bounds.width() / 2 - kShadowThickness / 2, shadow_paint); | |
146 | 171 |
147 const int magnifier_radius = magnifier_bounds_.width() / 2; | 172 SkPaint border_paint; |
173 border_paint.setAntiAlias(true); | |
174 border_paint.setStyle(SkPaint::kStroke_Style); | |
175 | |
176 // The radius of the magnifier and its border. | |
177 const int magnifier_radius = | |
178 magnifier_window_bounds_.width() / 2 - kShadowThickness; | |
148 // Draw the inner border. | 179 // Draw the inner border. |
149 paint.setStrokeWidth(kBorderSize); | 180 border_paint.setStrokeWidth(kBorderSize); |
150 paint.setColor(kBorderColor); | 181 border_paint.setColor(kBorderColor); |
151 recorder.canvas()->DrawCircle(magnifier_bounds_.CenterPoint(), | 182 recorder.canvas()->DrawCircle(magnifier_window_bounds_.CenterPoint(), |
152 magnifier_radius - kBorderSize / 2, paint); | 183 magnifier_radius - kBorderSize / 2, |
184 border_paint); | |
153 | 185 |
154 // Draw border outer outline and then draw the border inner outline. | 186 // Draw border outer outline and then draw the border inner outline. |
155 paint.setStrokeWidth(kBorderOutlineThickness); | 187 border_paint.setStrokeWidth(kBorderOutlineThickness); |
156 paint.setColor(kBorderOutlineColor); | 188 border_paint.setColor(kBorderOutlineColor); |
157 recorder.canvas()->DrawCircle( | 189 recorder.canvas()->DrawCircle( |
158 magnifier_bounds_.CenterPoint(), | 190 magnifier_window_bounds_.CenterPoint(), |
159 magnifier_radius - kBorderOutlineThickness / 2, paint); | 191 magnifier_radius - kBorderOutlineThickness / 2, border_paint); |
160 recorder.canvas()->DrawCircle( | 192 recorder.canvas()->DrawCircle( |
161 magnifier_bounds_.CenterPoint(), | 193 magnifier_window_bounds_.CenterPoint(), |
162 magnifier_radius - kBorderSize + kBorderOutlineThickness / 2, paint); | 194 magnifier_radius - kBorderSize + kBorderOutlineThickness / 2, |
195 border_paint); | |
163 } | 196 } |
164 | 197 |
165 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | 198 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
166 | 199 |
167 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} | 200 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} |
168 | 201 |
169 base::Closure PrepareForLayerBoundsChange() override { | 202 base::Closure PrepareForLayerBoundsChange() override { |
170 return base::Closure(); | 203 return base::Closure(); |
171 } | 204 } |
172 | 205 |
173 gfx::Rect magnifier_bounds_; | 206 gfx::Rect magnifier_window_bounds_; |
207 std::vector<gfx::ShadowValue> magnifier_shadows_; | |
174 | 208 |
175 DISALLOW_COPY_AND_ASSIGN(BorderRenderer); | 209 DISALLOW_COPY_AND_ASSIGN(BorderRenderer); |
176 }; | 210 }; |
177 | 211 |
178 PartialMagnificationController::PartialMagnificationController() { | 212 PartialMagnificationController::PartialMagnificationController() { |
179 Shell::GetInstance()->AddPreTargetHandler(this); | 213 Shell::GetInstance()->AddPreTargetHandler(this); |
180 } | 214 } |
181 | 215 |
182 PartialMagnificationController::~PartialMagnificationController() { | 216 PartialMagnificationController::~PartialMagnificationController() { |
183 CloseMagnifierWindow(); | 217 CloseMagnifierWindow(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 CloseMagnifierWindow(); | 272 CloseMagnifierWindow(); |
239 } | 273 } |
240 } | 274 } |
241 | 275 |
242 void PartialMagnificationController::OnLocatedEvent( | 276 void PartialMagnificationController::OnLocatedEvent( |
243 ui::LocatedEvent* event, | 277 ui::LocatedEvent* event, |
244 const ui::PointerDetails& pointer_details) { | 278 const ui::PointerDetails& pointer_details) { |
245 if (!is_enabled_) | 279 if (!is_enabled_) |
246 return; | 280 return; |
247 | 281 |
248 if (pointer_details.pointer_type != ui::EventPointerType::POINTER_TYPE_PEN) | 282 if (pointer_details.pointer_type == ui::EventPointerType::POINTER_TYPE_PEN) |
sammiequon
2016/09/22 00:51:46
Missed this again.
| |
249 return; | 283 return; |
250 | 284 |
251 // Compute the event location in screen space. | 285 // Compute the event location in screen space. |
252 aura::Window* target = static_cast<aura::Window*>(event->target()); | 286 aura::Window* target = static_cast<aura::Window*>(event->target()); |
253 aura::Window* event_root = target->GetRootWindow(); | 287 aura::Window* event_root = target->GetRootWindow(); |
254 gfx::Point screen_point = event->root_location(); | 288 gfx::Point screen_point = event->root_location(); |
255 wm::ConvertPointToScreen(event_root, &screen_point); | 289 wm::ConvertPointToScreen(event_root, &screen_point); |
256 | 290 |
257 if (event->type() == ui::ET_MOUSE_PRESSED && | 291 if (event->type() == ui::ET_MOUSE_PRESSED && |
258 !ShouldSkipEventFiltering(screen_point)) { | 292 !ShouldSkipEventFiltering(screen_point)) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 | 349 |
316 zoom_layer_.reset(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); | 350 zoom_layer_.reset(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); |
317 zoom_layer_->SetBounds(gfx::Rect(GetWindowSize())); | 351 zoom_layer_->SetBounds(gfx::Rect(GetWindowSize())); |
318 zoom_layer_->SetBackgroundZoom(kMagnificationScale, kZoomInset); | 352 zoom_layer_->SetBackgroundZoom(kMagnificationScale, kZoomInset); |
319 root_layer->Add(zoom_layer_.get()); | 353 root_layer->Add(zoom_layer_.get()); |
320 | 354 |
321 border_layer_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); | 355 border_layer_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); |
322 border_layer_->SetBounds(gfx::Rect(GetWindowSize())); | 356 border_layer_->SetBounds(gfx::Rect(GetWindowSize())); |
323 border_renderer_.reset(new BorderRenderer(gfx::Rect(GetWindowSize()))); | 357 border_renderer_.reset(new BorderRenderer(gfx::Rect(GetWindowSize()))); |
324 border_layer_->set_delegate(border_renderer_.get()); | 358 border_layer_->set_delegate(border_renderer_.get()); |
359 border_layer_->SetFillsBoundsOpaquely(false); | |
325 root_layer->Add(border_layer_.get()); | 360 root_layer->Add(border_layer_.get()); |
326 | 361 |
327 border_mask_.reset(new ContentMask(true, GetWindowSize())); | 362 border_mask_.reset(new ContentMask(true, GetWindowSize())); |
328 border_layer_->SetMaskLayer(border_mask_->layer()); | 363 border_layer_->SetMaskLayer(border_mask_->layer()); |
329 | 364 |
330 zoom_mask_.reset(new ContentMask(false, GetWindowSize())); | 365 zoom_mask_.reset(new ContentMask(false, GetWindowSize())); |
331 zoom_layer_->SetMaskLayer(zoom_mask_->layer()); | 366 zoom_layer_->SetMaskLayer(zoom_mask_->layer()); |
332 | 367 |
333 host_widget_->AddObserver(this); | 368 host_widget_->AddObserver(this); |
334 } | 369 } |
335 | 370 |
336 void PartialMagnificationController::CloseMagnifierWindow() { | 371 void PartialMagnificationController::CloseMagnifierWindow() { |
337 if (host_widget_) { | 372 if (host_widget_) { |
338 RemoveZoomWidgetObservers(); | 373 RemoveZoomWidgetObservers(); |
339 host_widget_->Close(); | 374 host_widget_->Close(); |
340 host_widget_ = nullptr; | 375 host_widget_ = nullptr; |
341 } | 376 } |
342 } | 377 } |
343 | 378 |
344 void PartialMagnificationController::RemoveZoomWidgetObservers() { | 379 void PartialMagnificationController::RemoveZoomWidgetObservers() { |
345 DCHECK(host_widget_); | 380 DCHECK(host_widget_); |
346 host_widget_->RemoveObserver(this); | 381 host_widget_->RemoveObserver(this); |
347 aura::Window* root_window = host_widget_->GetNativeView()->GetRootWindow(); | 382 aura::Window* root_window = host_widget_->GetNativeView()->GetRootWindow(); |
348 DCHECK(root_window); | 383 DCHECK(root_window); |
349 root_window->RemoveObserver(this); | 384 root_window->RemoveObserver(this); |
350 } | 385 } |
351 | 386 |
352 } // namespace ash | 387 } // namespace ash |
OLD | NEW |