Chromium Code Reviews| 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 |