OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 gfx::Image* GetCenterHandleImage() { | |
30 static gfx::Image* handle_image = nullptr; | |
31 if (!handle_image) { | |
32 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
jdduke (slow)
2015/01/28 16:35:32
How expensive are these calls? If they're relative
mohsen
2015/02/22 23:23:09
Yeah, apparently ResourceBundle has its own cachin
| |
33 IDR_TEXT_SELECTION_HANDLE_CENTER); | |
34 } | |
35 return handle_image; | |
36 } | |
37 | |
38 gfx::Image* GetLeftHandleImage() { | |
39 static gfx::Image* handle_image = nullptr; | |
40 if (!handle_image) { | |
41 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
42 IDR_TEXT_SELECTION_HANDLE_LEFT); | |
43 } | |
44 return handle_image; | |
45 } | |
46 | |
47 gfx::Image* GetRightHandleImage() { | |
48 static gfx::Image* handle_image = nullptr; | |
49 if (!handle_image) { | |
50 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
51 IDR_TEXT_SELECTION_HANDLE_RIGHT); | |
52 } | |
53 return handle_image; | |
54 } | |
55 | |
56 // Return the appropriate handle image based on the bound's type | |
57 gfx::Image* GetHandleImage(ui::TouchHandleOrientation orientation) { | |
58 switch(orientation) { | |
59 case ui::TOUCH_HANDLE_LEFT: | |
60 return GetLeftHandleImage(); | |
61 case ui::TOUCH_HANDLE_CENTER: | |
62 return GetCenterHandleImage(); | |
63 case ui::TOUCH_HANDLE_RIGHT: | |
64 return GetRightHandleImage(); | |
65 default: | |
66 NOTREACHED() << "Invalid touch handle bound type."; | |
67 return nullptr; | |
68 }; | |
69 } | |
70 | |
71 class TouchHandleDrawableAuraTargeter : public aura::WindowTargeter { | |
72 protected: | |
73 bool EventLocationInsideBounds(ui::EventTarget* target, | |
74 const LocatedEvent& event) const override; | |
75 }; | |
76 | |
77 bool TouchHandleDrawableAuraTargeter::EventLocationInsideBounds( | |
78 EventTarget* target, | |
79 const LocatedEvent& event) const { | |
80 return false; | |
81 } | |
82 | |
83 } | |
84 | |
85 // static | |
86 gfx::Size TouchHandleDrawableAura::GetMaxHandleImageSize() { | |
87 gfx::Rect center_rect = gfx::Rect(GetCenterHandleImage()->Size()); | |
88 gfx::Rect left_rect = gfx::Rect(GetLeftHandleImage()->Size()); | |
89 gfx::Rect right_rect = gfx::Rect(GetRightHandleImage()->Size()); | |
90 gfx::Rect union_rect = center_rect; | |
91 union_rect.Union(left_rect); | |
92 union_rect.Union(right_rect); | |
93 return union_rect.size(); | |
94 } | |
95 | |
96 TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent) | |
97 : window_(new aura::Window(this)), | |
98 enabled_(false), | |
99 alpha_(0), | |
100 orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED) { | |
101 SetSelfDestroy(false); | |
102 SetImageOffset(gfx::Vector2d(kSelectionHandlePadding, | |
103 kSelectionHandlePadding)); | |
104 SetBackgroundColor(SK_ColorTRANSPARENT); | |
105 window_->SetTransparent(true); | |
106 window_->Init(aura::WINDOW_LAYER_TEXTURED); | |
107 window_->set_owned_by_parent(false); | |
108 window_->SetEventTargeter( | |
109 scoped_ptr<EventTargeter>(new TouchHandleDrawableAuraTargeter)); | |
110 parent->AddChild(window_.get()); | |
111 } | |
112 | |
113 TouchHandleDrawableAura::~TouchHandleDrawableAura() { | |
114 } | |
115 | |
116 void TouchHandleDrawableAura::UpdateBounds() { | |
117 gfx::RectF new_bounds = relative_bounds_; | |
118 new_bounds.Offset(focal_position_.x(), focal_position_.y()); | |
119 window_->SetBounds(gfx::ToNearestRect(new_bounds)); | |
120 } | |
121 | |
122 void TouchHandleDrawableAura::SetEnabled(bool enabled) { | |
123 if (enabled == enabled_) | |
124 return; | |
125 | |
126 enabled_ = enabled; | |
127 bool visible = alpha_ > 0; // XXX: float comparison | |
128 if (enabled_ && visible) | |
129 window_->Show(); | |
130 else | |
131 window_->Hide(); | |
132 } | |
133 | |
134 void TouchHandleDrawableAura::SetOrientation( | |
135 TouchHandleOrientation orientation) { | |
136 if (orientation_ == orientation) | |
137 return; | |
138 orientation_ = orientation; | |
139 gfx::Image* image = GetHandleImage(orientation); | |
140 SetImage(*image); | |
141 | |
142 // Calculate the relative bounds. | |
143 gfx::Size image_size = image->Size(); | |
144 int window_width = image_size.width() + 2 * kSelectionHandlePadding; | |
145 int window_height = image_size.height() + 2 * kSelectionHandlePadding; | |
146 // Due to the shape of the handle images, the window is aligned differently to | |
147 // the selection bound depending on the orientation. | |
148 int window_left = 0; | |
149 switch (orientation) { | |
150 case ui::TOUCH_HANDLE_LEFT: | |
151 window_left = -image_size.width() - kSelectionHandlePadding; | |
152 break; | |
153 case ui::TOUCH_HANDLE_RIGHT: | |
154 window_left = -kSelectionHandlePadding; | |
155 break; | |
156 case ui::TOUCH_HANDLE_CENTER: | |
157 window_left = -window_width / 2; | |
158 break; | |
159 default: | |
160 NOTREACHED() << "Undefined handle orientation."; | |
161 break; | |
162 }; | |
163 relative_bounds_ = gfx::RectF( | |
164 window_left, | |
165 kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding, | |
166 window_width, | |
167 window_height); | |
168 UpdateBounds(); | |
169 } | |
170 | |
171 void TouchHandleDrawableAura::SetAlpha(float alpha) { | |
172 if (alpha == alpha_) // XXX: float comparison | |
173 return; | |
174 | |
175 alpha_ = alpha; | |
176 window_->layer()->SetOpacity(alpha_); | |
177 bool visible = alpha_ > 0; // XXX: float comparison | |
178 if (enabled_ && visible) | |
179 window_->Show(); | |
180 else | |
181 window_->Hide(); | |
182 } | |
183 | |
184 void TouchHandleDrawableAura::SetFocus(const gfx::PointF& position) { | |
185 focal_position_ = position; | |
186 UpdateBounds(); | |
187 } | |
188 | |
189 gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const { | |
190 gfx::RectF r(window_->bounds()); | |
191 r.Inset(kSelectionHandlePadding, | |
192 kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset, | |
193 kSelectionHandlePadding, | |
194 kSelectionHandlePadding); | |
195 return r; | |
196 } | |
197 | |
198 } // namespace ui | |
OLD | NEW |