Commit 1ac963a3 authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Draw a ring around screen in magnifier

Draws an orange ring around the screen while magnification is enabled,
as on Android.

Bug: internal b/112634030
Test: manual
Change-Id: Iac134759c7f6e931c7c4a4407d827fc7a75fedca
Reviewed-on: https://chromium-review.googlesource.com/c/1334197Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Reviewed-by: default avatarAlex Sakhartchouk <alexst@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607749}
parent 7d61bb26
......@@ -6,10 +6,15 @@
#include "base/numerics/ranges.h"
#include "chromecast/graphics/gestures/cast_gesture_handler.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"
......@@ -17,7 +22,7 @@ namespace chromecast {
namespace {
// Default ratio of magnifier scale.
const float kDefaultMagnificationScale = 2.f;
constexpr float kDefaultMagnificationScale = 2.f;
constexpr float kMaxMagnifiedScale = 20.0f;
constexpr float kMinMagnifiedScaleThreshold = 1.1f;
......@@ -26,6 +31,11 @@ constexpr float kNonMagnifiedScale = 1.0f;
constexpr float kZoomGestureLockThreshold = 0.1f;
constexpr float kScrollGestureLockThreshold = 20000.0f;
// The color of the highlight ring.
constexpr SkColor kHighlightRingColor = SkColorSetRGB(247, 152, 58);
constexpr int kHighlightShadowRadius = 10;
constexpr int kHighlightShadowAlpha = 90;
// Convert point locations to DIP by using the original transform, rather than
// the one currently installed on the window tree host (which might be our
// magnifier).
......@@ -100,7 +110,21 @@ void FullscreenMagnificationController::SetEnabled(bool enabled) {
original_transform_ = root_window_->transform();
}
is_enabled_ = enabled;
root_window_->SetTransform(GetMagnifierTransform());
auto magnifier_transform(GetMagnifierTransform());
root_window_->SetTransform(magnifier_transform);
if (enabled) {
// Add the highlight ring.
if (!highlight_ring_layer_) {
AddHighlightLayer();
}
UpdateHighlightLayerTransform(magnifier_transform);
} else {
// Remove the highlight ring.
if (highlight_ring_layer_) {
root_window_->layer()->Remove(highlight_ring_layer_.get());
highlight_ring_layer_.reset();
}
}
}
bool FullscreenMagnificationController::IsEnabled() const {
......@@ -277,7 +301,10 @@ bool FullscreenMagnificationController::RedrawDIP(
magnification_origin_.set_y(y);
magnification_scale_ = scale;
root_window_->SetTransform(GetMagnifierTransform());
auto magnifier_transform = GetMagnifierTransform();
root_window_->SetTransform(magnifier_transform);
UpdateHighlightLayerTransform(magnifier_transform);
return true;
}
......@@ -387,4 +414,64 @@ bool FullscreenMagnificationController::ProcessGestures() {
return cancel_pressed_touches;
}
void FullscreenMagnificationController::AddHighlightLayer() {
ui::Layer* root_layer = root_window_->layer();
highlight_ring_layer_ = std::make_unique<ui::Layer>(ui::LAYER_TEXTURED);
highlight_ring_layer_->set_name("MagnificationHighlightLayer");
root_layer->Add(highlight_ring_layer_.get());
highlight_ring_layer_->parent()->StackAtTop(highlight_ring_layer_.get());
gfx::Rect bounds(root_layer->bounds());
highlight_ring_layer_->SetBounds(bounds);
highlight_ring_layer_->set_delegate(this);
highlight_ring_layer_->SetFillsBoundsOpaquely(false);
}
void FullscreenMagnificationController::UpdateHighlightLayerTransform(
const gfx::Transform& magnifier_transform) {
// The highlight ring layer needs to be drawn unmagnified, so take the inverse
// of the magnification transform.
gfx::Transform inverse_transform;
if (!magnifier_transform.GetInverse(&inverse_transform)) {
LOG(ERROR) << "Unable to apply inverse transform to magnifier ring";
return;
}
gfx::Transform highlight_layer_transform(original_transform_);
highlight_layer_transform.ConcatTransform(inverse_transform);
highlight_ring_layer_->SetTransform(highlight_layer_transform);
// Make sure the highlight ring layer is on top.
highlight_ring_layer_->parent()->StackAtTop(highlight_ring_layer_.get());
// Repaint.
highlight_ring_layer_->SchedulePaint(root_window_->layer()->bounds());
}
void FullscreenMagnificationController::OnPaintLayer(
const ui::PaintContext& context) {
ui::PaintRecorder recorder(context, highlight_ring_layer_->size());
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setStyle(cc::PaintFlags::kStroke_Style);
flags.setStrokeWidth(2);
flags.setColor(kHighlightRingColor);
gfx::Rect bounds(highlight_ring_layer_->bounds());
for (int i = 0; i < 10; i++) {
// Fade out alpha quadratically.
flags.setAlpha(
(kHighlightShadowAlpha * std::pow(kHighlightShadowRadius - i, 2)) /
std::pow(kHighlightShadowRadius, 2));
gfx::Rect outsetRect = bounds;
outsetRect.Inset(i, i, i, i);
recorder.canvas()->DrawRect(outsetRect, flags);
}
}
void FullscreenMagnificationController::OnDeviceScaleFactorChanged(
float old_device_scale_factor,
float new_device_scale_factor) {}
} // namespace chromecast
......@@ -6,6 +6,7 @@
#define CHROMECAST_GRAPHICS_ACCESSIBILITY_FULLSCREEN_MAGNIFICATION_CONTROLLER_H_
#include "chromecast/graphics/accessibility/magnification_controller.h"
#include "ui/compositor/layer_delegate.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/gestures/gesture_provider_aura.h"
......@@ -19,6 +20,7 @@ class Window;
namespace ui {
class GestureProviderAura;
class Layer;
} // namespace ui
namespace chromecast {
......@@ -27,7 +29,8 @@ class CastGestureHandler;
class FullscreenMagnificationController : public MagnificationController,
public ui::EventRewriter,
public ui::GestureConsumer {
public ui::GestureConsumer,
public ui::LayerDelegate {
public:
explicit FullscreenMagnificationController(
aura::Window* root_window,
......@@ -61,6 +64,16 @@ class FullscreenMagnificationController : public MagnificationController,
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) override;
// Adds the layer for the highlight-ring which provides a visual indicator
// that magnification is enabled.
void UpdateHighlightLayerTransform(const gfx::Transform& magnifier_transform);
void AddHighlightLayer();
// ui::LayerDelegate overrides:
void OnPaintLayer(const ui::PaintContext& context) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override;
aura::Window* root_window_;
bool is_enabled_ = false;
......@@ -101,6 +114,8 @@ class FullscreenMagnificationController : public MagnificationController,
std::map<int32_t, std::unique_ptr<ui::TouchEvent>> press_event_map_;
CastGestureHandler* cast_gesture_handler_;
std::unique_ptr<ui::Layer> highlight_ring_layer_;
};
} // namespace chromecast
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment