Chromium Code Reviews| 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 |