Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: ui/touch_selection/touch_handle_drawable_aura.cc

Issue 698253004: Reland: Implement Aura side of unified touch text selection for contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased after addition of touch_handle_orientation file Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/touch_selection/touch_handle_drawable_aura.h"
6
7 #include "ui/aura/window.h"
8 #include "ui/aura/window_targeter.h"
9 #include "ui/base/cursor/cursor.h"
10 #include "ui/base/hit_test.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/events/event.h"
13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/geometry/rect_conversions.h"
15 #include "ui/resources/grit/ui_resources.h"
16
17 namespace ui {
18 namespace {
19
20 // The distance by which a handle image is offset from the focal point (i.e.
21 // text baseline) downwards.
22 const int kSelectionHandleVerticalVisualOffset = 2;
23
24 // The padding around the selection handle image can be used to extend the
25 // handle window so that touch events near the selection handle image are
26 // targeted to the selection handle window.
27 const int kSelectionHandlePadding = 0;
28
29 // Epsilon value used to compare float values to zero.
30 const float kEpsilon = 1e-8f;
31
32 // Returns the appropriate handle image based on the handle orientation.
33 gfx::Image* GetHandleImage(TouchHandleOrientation orientation) {
34 int resource_id;
35 switch(orientation) {
36 case TouchHandleOrientation::LEFT:
37 resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
38 break;
39 case TouchHandleOrientation::CENTER:
40 resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
41 break;
42 case TouchHandleOrientation::RIGHT:
43 resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
44 break;
45 default:
sadrul 2015/03/05 12:37:03 Remove default, explicitly list UNDEFINED
mohsen 2015/03/06 23:10:08 Done.
46 NOTREACHED() << "Invalid touch handle bound type.";
47 return nullptr;
48 };
49 return &ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
50 }
51
52 bool IsNearlyZero(float value) {
53 return std::abs(value) < kEpsilon;
54 }
55
56 // A window targeter for touch handles that will let every touch event pass
57 // through handles to the underlying window.
sadrul 2015/03/05 12:37:03 Can you set Window::set_ignore_events() instead?
mfomitchev 2015/03/05 16:07:54 So this is a bit awkward because at this point we
sadrul 2015/03/05 16:56:22 We shouldn't do this in a roundabout way to fit in
mfomitchev 2015/03/05 18:03:24 Yes, that's what I meant. Thus we'd have to switch
mohsen 2015/03/06 23:10:08 This is how ui::TouchSelectionController is implem
58 class TouchHandleDrawableAuraTargeter : public aura::WindowTargeter {
59 protected:
60 bool EventLocationInsideBounds(EventTarget* target,
61 const LocatedEvent& event) const override;
62 };
63
64 bool TouchHandleDrawableAuraTargeter::EventLocationInsideBounds(
65 EventTarget* target,
66 const LocatedEvent& event) const {
67 return false;
68 }
69
70 }
71
72 TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent)
73 : window_(new aura::Window(this)),
74 enabled_(false),
75 alpha_(0),
76 orientation_(TouchHandleOrientation::UNDEFINED) {
77 set_image_offset(gfx::Vector2d(kSelectionHandlePadding,
78 kSelectionHandlePadding));
79 set_background_color(SK_ColorTRANSPARENT);
80 window_->SetTransparent(true);
81 window_->Init(aura::WINDOW_LAYER_TEXTURED);
82 window_->set_owned_by_parent(false);
83 window_->SetEventTargeter(
84 scoped_ptr<EventTargeter>(new TouchHandleDrawableAuraTargeter));
85 parent->AddChild(window_.get());
86 }
87
88 TouchHandleDrawableAura::~TouchHandleDrawableAura() {
89 }
90
91 // static
92 gfx::Size TouchHandleDrawableAura::GetMaxHandleImageSize() {
93 gfx::Size max_size(GetHandleImage(TouchHandleOrientation::CENTER)->Size());
94 max_size.SetToMax(GetHandleImage(TouchHandleOrientation::LEFT)->Size());
95 max_size.SetToMax(GetHandleImage(TouchHandleOrientation::RIGHT)->Size());
96 return max_size;
97 }
98
99 void TouchHandleDrawableAura::OnWindowDestroyed(aura::Window* window) {
100 // Overriding ImageWindowDelegate's implementation, which calls |delete this|
101 // when the window is destroyed - in our case the delegate owns the window,
102 // and not vice versa.
103 }
104
105 void TouchHandleDrawableAura::UpdateBounds() {
106 gfx::RectF new_bounds = relative_bounds_;
107 new_bounds.Offset(focal_position_.x(), focal_position_.y());
108 window_->SetBounds(gfx::ToNearestRect(new_bounds));
109 }
110
111 void TouchHandleDrawableAura::SetEnabled(bool enabled) {
112 if (enabled == enabled_)
113 return;
114
115 enabled_ = enabled;
116 bool visible = !IsNearlyZero(alpha_);
117 if (enabled_ && visible)
118 window_->Show();
119 else
120 window_->Hide();
121 }
122
123 void TouchHandleDrawableAura::SetOrientation(
124 TouchHandleOrientation orientation) {
125 if (orientation_ == orientation)
126 return;
127 orientation_ = orientation;
128 gfx::Image* image = GetHandleImage(orientation);
129 SetImage(*image);
130
131 // Calculate the relative bounds.
132 gfx::Size image_size = image->Size();
133 int window_width = image_size.width() + 2 * kSelectionHandlePadding;
134 int window_height = image_size.height() + 2 * kSelectionHandlePadding;
135 // Due to the shape of the handle images, the window is aligned differently to
136 // the selection bound depending on the orientation.
137 int window_left = 0;
138 switch (orientation) {
139 case TouchHandleOrientation::LEFT:
140 window_left = -image_size.width() - kSelectionHandlePadding;
141 break;
142 case TouchHandleOrientation::RIGHT:
143 window_left = -kSelectionHandlePadding;
144 break;
145 case TouchHandleOrientation::CENTER:
146 window_left = -window_width / 2;
147 break;
148 default:
sadrul 2015/03/05 12:37:03 case UNDEFINED: instead of default:
mohsen 2015/03/06 23:10:08 Done.
149 NOTREACHED() << "Undefined handle orientation.";
150 break;
151 };
152 relative_bounds_ = gfx::RectF(
153 window_left,
154 kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding,
155 window_width,
156 window_height);
157 UpdateBounds();
158 }
159
160 void TouchHandleDrawableAura::SetAlpha(float alpha) {
161 if (alpha == alpha_)
162 return;
163
164 alpha_ = alpha;
165 window_->layer()->SetOpacity(alpha_);
166 bool visible = !IsNearlyZero(alpha_);
167 if (enabled_ && visible)
168 window_->Show();
169 else
170 window_->Hide();
171 }
172
173 void TouchHandleDrawableAura::SetFocus(const gfx::PointF& position) {
174 focal_position_ = position;
175 UpdateBounds();
176 }
177
178 gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const {
179 gfx::RectF bounds(window_->bounds());
180 bounds.Inset(kSelectionHandlePadding,
181 kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
182 kSelectionHandlePadding,
183 kSelectionHandlePadding);
184 return bounds;
185 }
186
187 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698