Chromium Code Reviews| 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..3fadeede44cfaf7ca906ab36cde20ca909d2e815 |
| --- /dev/null |
| +++ b/ui/touch_selection/touch_handle_drawable_aura.cc |
| @@ -0,0 +1,160 @@ |
| +// 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; |
|
jdduke (slow)
2015/05/07 20:38:15
Hmm, do we need this if it's always zero? Or you j
mohsen
2015/05/07 21:21:55
This is something that we might want to tune later
|
| + |
| +// 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)); |
| +} |
| + |
| +void TouchHandleDrawableAura::SetEnabled(bool enabled) { |
| + if (enabled == enabled_) |
| + return; |
| + |
| + enabled_ = enabled; |
| + bool visible = !IsNearlyZero(alpha_); |
| + if (enabled_ && visible) |
| + 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_); |
| + bool visible = !IsNearlyZero(alpha_); |
|
jdduke (slow)
2015/05/07 20:38:15
Would a |IsVisible()| method that returns |enabled
mohsen
2015/05/07 21:21:55
Definitely, Done.
|
| + if (enabled_ && visible) |
| + 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 |