1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_TOUCH_SELECTION_TOUCH_HANDLE_H_
#define UI_TOUCH_SELECTION_TOUCH_HANDLE_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/velocity_tracker/motion_event.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/touch_selection/touch_handle_orientation.h"
#include "ui/touch_selection/touch_selection_draggable.h"
#include "ui/touch_selection/ui_touch_selection_export.h"
#if BUILDFLAG(IS_ANDROID)
namespace cc::slim {
class Layer;
}
#endif
namespace ui {
class TouchHandle;
// Interface through which |TouchHandle| delegates rendering-specific duties.
class UI_TOUCH_SELECTION_EXPORT TouchHandleDrawable {
public:
virtual ~TouchHandleDrawable() {}
// Sets whether the handle is active, allowing resource cleanup if necessary.
virtual void SetEnabled(bool enabled) = 0;
// Update the handle visuals to |orientation|.
// |mirror_vertical| and |mirror_horizontal| are used to invert the drawables
// if required for adaptive handle orientation.
virtual void SetOrientation(TouchHandleOrientation orientation,
bool mirror_vertical,
bool mirror_horizontal) = 0;
// Sets the origin position of the touch handle.
// |origin| takes care of positioning the handle drawable based on
// its visible bounds.
virtual void SetOrigin(const gfx::PointF& origin) = 0;
// Sets the transparency |alpha| for the handle drawable.
virtual void SetAlpha(float alpha) = 0;
// Returns the visible bounds of the handle drawable.
// The bounds includes the transparent horizontal padding.
virtual gfx::RectF GetVisibleBounds() const = 0;
// Returns the transparent horizontal padding ratio of the handle drawable.
virtual float GetDrawableHorizontalPaddingRatio() const = 0;
#if BUILDFLAG(IS_ANDROID)
virtual void OnUpdateNativeViewTree(gfx::NativeView parent_native_view,
cc::slim::Layer* parent_layer) {}
#endif
};
// Interface through which |TouchHandle| communicates handle manipulation and
// requests concrete drawable instances.
class UI_TOUCH_SELECTION_EXPORT TouchHandleClient
: public TouchSelectionDraggableClient {
public:
~TouchHandleClient() override {}
virtual void OnHandleTapped(const TouchHandle& handle) = 0;
virtual void SetNeedsAnimate() = 0;
virtual std::unique_ptr<TouchHandleDrawable> CreateDrawable() = 0;
virtual base::TimeDelta GetMaxTapDuration() const = 0;
virtual bool IsAdaptiveHandleOrientationEnabled() const = 0;
};
// Responsible for displaying a selection or insertion handle for text
// interaction.
class UI_TOUCH_SELECTION_EXPORT TouchHandle : public TouchSelectionDraggable {
public:
// The drawable will be enabled but invisible until otherwise specified.
TouchHandle(TouchHandleClient* client,
TouchHandleOrientation orientation,
const gfx::RectF& viewport_rect);
TouchHandle(const TouchHandle&) = delete;
TouchHandle& operator=(const TouchHandle&) = delete;
~TouchHandle() override;
// TouchSelectionDraggable implementation.
bool WillHandleTouchEvent(const MotionEvent& event) override;
bool IsActive() const override;
// Sets whether the handle is active, allowing resource cleanup if necessary.
// If false, active animations or touch drag sequences will be cancelled.
// While disabled, manipulation is *explicitly not supported*, and may lead to
// undesirable and/or unstable side-effects. The handle can be safely
// re-enabled to allow continued operation.
void SetEnabled(bool enabled);
enum AnimationStyle { ANIMATION_NONE, ANIMATION_SMOOTH };
// Update the handle visibility, fading in/out according to |animation_style|.
// If an animation is in-progress, it will be overriden appropriately.
void SetVisible(bool visible, AnimationStyle animation_style);
// Update the focus points for the handles. The handle will be positioned
// either |top| or |bottom| based on the mirror parameters.
// Note: If a fade out animation is active or the handle is invisible, the
// handle position will not be updated until the handle regains visibility.
void SetFocus(const gfx::PointF& top, const gfx::PointF& bottom);
// Update the viewport rect, based on which the handle decide its inversion.
void SetViewportRect(const gfx::RectF& viewport_rect);
// Update the handle visuals to |orientation|.
// Note: If the handle is being dragged, the orientation change will be
// deferred until the drag has ceased.
void SetOrientation(TouchHandleOrientation orientation);
// Ticks an active animation, as requested to the client by |SetNeedsAnimate|.
// Returns true if an animation is active and requires further ticking.
bool Animate(base::TimeTicks frame_time);
// Get the visible bounds of the handle, based on the current position and
// the drawable's size/orientation. If the handle is invisible or disabled,
// the bounds will be empty.
gfx::RectF GetVisibleBounds() const;
// Updates the handle layout if the is_handle_layout_update_required_ flag is
// set. Will be called once per frame update, avoids multiple updates for
// for the same frame update due to more than one parameter updates.
void UpdateHandleLayout();
// Set the handle to transparent. Handle will be set to opaque again in
// EndDrag() call.
void SetTransparent();
#if BUILDFLAG(IS_ANDROID)
void OnUpdateNativeViewTree(gfx::NativeView parent_native_view,
cc::slim::Layer* parent_layer);
#endif
const gfx::PointF& focus_bottom() const { return focus_bottom_; }
TouchHandleOrientation orientation() const { return orientation_; }
float alpha() const { return alpha_; }
private:
gfx::PointF ComputeHandleOrigin() const;
void BeginDrag();
void EndDrag();
void BeginFade();
void EndFade();
void SetAlpha(float alpha);
void SetUpdateLayoutRequired();
std::unique_ptr<TouchHandleDrawable> drawable_;
const raw_ptr<TouchHandleClient> client_;
gfx::PointF focus_bottom_;
gfx::PointF focus_top_;
gfx::RectF viewport_rect_;
TouchHandleOrientation orientation_;
TouchHandleOrientation deferred_orientation_;
gfx::PointF touch_down_position_;
gfx::Vector2dF touch_drag_offset_;
base::TimeTicks touch_down_time_;
// Note that when a fade animation is active, |is_visible_| and |position_|
// may not reflect the actual visibility and position of the drawable. This
// discrepancy is resolved either upon fade completion or cancellation.
base::TimeTicks fade_end_time_;
gfx::PointF fade_start_position_;
float alpha_;
bool animate_deferred_fade_;
bool enabled_;
bool is_visible_;
bool is_dragging_;
bool is_drag_within_tap_region_;
bool is_handle_layout_update_required_;
// Mirror variables determine if the handles should be inverted or not.
bool mirror_vertical_;
bool mirror_horizontal_;
float handle_horizontal_padding_;
};
} // namespace ui
#endif // UI_TOUCH_SELECTION_TOUCH_HANDLE_H_
|