blob: c48244b35996ef1d5b9b9470468a80bf34066d58 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/touch/touch_selection_magnifier_runner_ash.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
namespace ash {
namespace {
// Gets the bounds of the magnifier when showing the specified point of
// interest. `point_of_interest` and returned bounds are in root window
// coordinates.
gfx::Rect GetBounds(const gfx::Point& point_of_interest) {
const gfx::Size size = TouchSelectionMagnifierRunnerAsh::kMagnifierLayerSize;
const gfx::Point origin(
point_of_interest.x() - size.width() / 2,
point_of_interest.y() - size.height() / 2 +
TouchSelectionMagnifierRunnerAsh::kMagnifierVerticalOffset);
return gfx::Rect(origin, size);
}
// Returns the child container in `root` that should parent the magnifier layer.
aura::Window* GetMagnifierParentContainerForRoot(aura::Window* root) {
return root->GetChildById(kShellWindowId_ImeWindowParentContainer);
}
} // namespace
TouchSelectionMagnifierRunnerAsh::TouchSelectionMagnifierRunnerAsh() = default;
TouchSelectionMagnifierRunnerAsh::~TouchSelectionMagnifierRunnerAsh() = default;
void TouchSelectionMagnifierRunnerAsh::ShowMagnifier(
aura::Window* context,
const gfx::PointF& position) {
DCHECK(context);
DCHECK(!current_context_ || current_context_ == context);
if (!current_context_) {
current_context_ = context;
}
aura::Window* root_window = current_context_->GetRootWindow();
DCHECK(root_window);
gfx::PointF position_in_root(position);
aura::Window::ConvertPointToTarget(context, root_window, &position_in_root);
if (!magnifier_layer_) {
CreateMagnifierLayer(root_window, position_in_root);
} else {
magnifier_layer_->SetBounds(
GetBounds(gfx::ToRoundedPoint(position_in_root)));
}
}
void TouchSelectionMagnifierRunnerAsh::CloseMagnifier() {
current_context_ = nullptr;
magnifier_layer_ = nullptr;
}
bool TouchSelectionMagnifierRunnerAsh::IsRunning() const {
return current_context_ != nullptr;
}
const aura::Window*
TouchSelectionMagnifierRunnerAsh::GetCurrentContextForTesting() const {
return current_context_;
}
const ui::Layer* TouchSelectionMagnifierRunnerAsh::GetMagnifierLayerForTesting()
const {
return magnifier_layer_.get();
}
void TouchSelectionMagnifierRunnerAsh::CreateMagnifierLayer(
aura::Window* root_window,
const gfx::PointF& position_in_root) {
aura::Window* parent_container =
GetMagnifierParentContainerForRoot(root_window);
ui::Layer* parent_layer = parent_container->layer();
magnifier_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
magnifier_layer_->SetBounds(GetBounds(gfx::ToRoundedPoint(position_in_root)));
magnifier_layer_->SetBackgroundZoom(kMagnifierScale, 0);
magnifier_layer_->SetBackgroundOffset(
gfx::Point(0, kMagnifierVerticalOffset));
magnifier_layer_->SetFillsBoundsOpaquely(false);
magnifier_layer_->SetRoundedCornerRadius(kMagnifierRoundedCorners);
parent_layer->Add(magnifier_layer_.get());
}
} // namespace ash