OLD | NEW |
---|---|
(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 | |
OLD | NEW |