| Index: ui/touch_selection/touch_handle_drawable_aura.cc
|
| diff --git a/ui/touch_selection/touch_handle_drawable_aura.cc b/ui/touch_selection/touch_handle_drawable_aura.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a353c59a7fccd7f13457d4f73226ea3d4064445d
|
| --- /dev/null
|
| +++ b/ui/touch_selection/touch_handle_drawable_aura.cc
|
| @@ -0,0 +1,162 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/touch_selection/touch_handle_drawable_aura.h"
|
| +
|
| +#include "ui/aura/window.h"
|
| +#include "ui/aura/window_targeter.h"
|
| +#include "ui/aura_extra/image_window_delegate.h"
|
| +#include "ui/base/cursor/cursor.h"
|
| +#include "ui/base/hit_test.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| +#include "ui/events/event.h"
|
| +#include "ui/gfx/canvas.h"
|
| +#include "ui/gfx/geometry/rect_conversions.h"
|
| +#include "ui/resources/grit/ui_resources.h"
|
| +
|
| +namespace ui {
|
| +namespace {
|
| +
|
| +// The distance by which a handle image is offset from the focal point (i.e.
|
| +// text baseline) downwards.
|
| +const int kSelectionHandleVerticalVisualOffset = 2;
|
| +
|
| +// The padding around the selection handle image can be used to extend the
|
| +// handle window so that touch events near the selection handle image are
|
| +// targeted to the selection handle window.
|
| +const int kSelectionHandlePadding = 0;
|
| +
|
| +// Epsilon value used to compare float values to zero.
|
| +const float kEpsilon = 1e-8f;
|
| +
|
| +// Returns the appropriate handle image based on the handle orientation.
|
| +gfx::Image* GetHandleImage(TouchHandleOrientation orientation) {
|
| + int resource_id = 0;
|
| + switch (orientation) {
|
| + case TouchHandleOrientation::LEFT:
|
| + resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
|
| + break;
|
| + case TouchHandleOrientation::CENTER:
|
| + resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
|
| + break;
|
| + case TouchHandleOrientation::RIGHT:
|
| + resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
|
| + break;
|
| + case TouchHandleOrientation::UNDEFINED:
|
| + NOTREACHED() << "Invalid touch handle bound type.";
|
| + return nullptr;
|
| + };
|
| + return &ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
|
| +}
|
| +
|
| +bool IsNearlyZero(float value) {
|
| + return std::abs(value) < kEpsilon;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent)
|
| + : window_delegate_(new aura_extra::ImageWindowDelegate),
|
| + window_(new aura::Window(window_delegate_)),
|
| + enabled_(false),
|
| + alpha_(0),
|
| + orientation_(TouchHandleOrientation::UNDEFINED) {
|
| + window_delegate_->set_image_offset(gfx::Vector2d(kSelectionHandlePadding,
|
| + kSelectionHandlePadding));
|
| + window_delegate_->set_background_color(SK_ColorTRANSPARENT);
|
| + window_->SetTransparent(true);
|
| + window_->Init(LAYER_TEXTURED);
|
| + window_->set_owned_by_parent(false);
|
| + window_->set_ignore_events(true);
|
| + parent->AddChild(window_.get());
|
| +}
|
| +
|
| +TouchHandleDrawableAura::~TouchHandleDrawableAura() {
|
| +}
|
| +
|
| +void TouchHandleDrawableAura::UpdateBounds() {
|
| + gfx::RectF new_bounds = relative_bounds_;
|
| + new_bounds.Offset(focal_position_.x(), focal_position_.y());
|
| + window_->SetBounds(gfx::ToEnclosingRect(new_bounds));
|
| +}
|
| +
|
| +bool TouchHandleDrawableAura::IsVisible() const {
|
| + return enabled_ && !IsNearlyZero(alpha_);
|
| +}
|
| +
|
| +void TouchHandleDrawableAura::SetEnabled(bool enabled) {
|
| + if (enabled == enabled_)
|
| + return;
|
| +
|
| + enabled_ = enabled;
|
| + if (IsVisible())
|
| + window_->Show();
|
| + else
|
| + window_->Hide();
|
| +}
|
| +
|
| +void TouchHandleDrawableAura::SetOrientation(
|
| + TouchHandleOrientation orientation) {
|
| + if (orientation_ == orientation)
|
| + return;
|
| + orientation_ = orientation;
|
| + gfx::Image* image = GetHandleImage(orientation);
|
| + window_delegate_->SetImage(*image);
|
| +
|
| + // Calculate the relative bounds.
|
| + gfx::Size image_size = image->Size();
|
| + int window_width = image_size.width() + 2 * kSelectionHandlePadding;
|
| + int window_height = image_size.height() + 2 * kSelectionHandlePadding;
|
| + // Due to the shape of the handle images, the window is aligned differently to
|
| + // the selection bound depending on the orientation.
|
| + int window_left = 0;
|
| + switch (orientation) {
|
| + case TouchHandleOrientation::LEFT:
|
| + window_left = -image_size.width() - kSelectionHandlePadding;
|
| + break;
|
| + case TouchHandleOrientation::RIGHT:
|
| + window_left = -kSelectionHandlePadding;
|
| + break;
|
| + case TouchHandleOrientation::CENTER:
|
| + window_left = -window_width / 2;
|
| + break;
|
| + case TouchHandleOrientation::UNDEFINED:
|
| + NOTREACHED() << "Undefined handle orientation.";
|
| + break;
|
| + };
|
| + relative_bounds_ = gfx::RectF(
|
| + window_left,
|
| + kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding,
|
| + window_width,
|
| + window_height);
|
| + UpdateBounds();
|
| +}
|
| +
|
| +void TouchHandleDrawableAura::SetAlpha(float alpha) {
|
| + if (alpha == alpha_)
|
| + return;
|
| +
|
| + alpha_ = alpha;
|
| + window_->layer()->SetOpacity(alpha_);
|
| + if (IsVisible())
|
| + window_->Show();
|
| + else
|
| + window_->Hide();
|
| +}
|
| +
|
| +void TouchHandleDrawableAura::SetFocus(const gfx::PointF& position) {
|
| + focal_position_ = position;
|
| + UpdateBounds();
|
| +}
|
| +
|
| +gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const {
|
| + gfx::RectF bounds(window_->bounds());
|
| + bounds.Inset(kSelectionHandlePadding,
|
| + kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
|
| + kSelectionHandlePadding,
|
| + kSelectionHandlePadding);
|
| + return bounds;
|
| +}
|
| +
|
| +} // namespace ui
|
|
|