Skip to content

Commit

Permalink
[chromecast] Draw a ring around screen in magnifier
Browse files Browse the repository at this point in the history
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/1334197
Reviewed-by: Daniel Nicoara <dnicoara@chromium.org>
Reviewed-by: Alex Sakhartchouk <alexst@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607749}
  • Loading branch information
Ryan Daum authored and Commit Bot committed Nov 13, 2018
1 parent 7d61bb2 commit 1ac963a
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@

#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"

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;
Expand All @@ -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).
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -19,6 +20,7 @@ class Window;

namespace ui {
class GestureProviderAura;
class Layer;
} // namespace ui

namespace chromecast {
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1ac963a

Please sign in to comment.