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/aura_extra/image_window_delegate.h" |
| 10 #include "ui/base/cursor/cursor.h" |
| 11 #include "ui/base/hit_test.h" |
| 12 #include "ui/base/resource/resource_bundle.h" |
| 13 #include "ui/events/event.h" |
| 14 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/geometry/rect_conversions.h" |
| 16 #include "ui/resources/grit/ui_resources.h" |
| 17 |
| 18 namespace ui { |
| 19 namespace { |
| 20 |
| 21 // The distance by which a handle image is offset from the focal point (i.e. |
| 22 // text baseline) downwards. |
| 23 const int kSelectionHandleVerticalVisualOffset = 2; |
| 24 |
| 25 // The padding around the selection handle image can be used to extend the |
| 26 // handle window so that touch events near the selection handle image are |
| 27 // targeted to the selection handle window. |
| 28 const int kSelectionHandlePadding = 0; |
| 29 |
| 30 // Epsilon value used to compare float values to zero. |
| 31 const float kEpsilon = 1e-8f; |
| 32 |
| 33 // Returns the appropriate handle image based on the handle orientation. |
| 34 gfx::Image* GetHandleImage(TouchHandleOrientation orientation) { |
| 35 int resource_id = 0; |
| 36 switch (orientation) { |
| 37 case TouchHandleOrientation::LEFT: |
| 38 resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT; |
| 39 break; |
| 40 case TouchHandleOrientation::CENTER: |
| 41 resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER; |
| 42 break; |
| 43 case TouchHandleOrientation::RIGHT: |
| 44 resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT; |
| 45 break; |
| 46 case TouchHandleOrientation::UNDEFINED: |
| 47 NOTREACHED() << "Invalid touch handle bound type."; |
| 48 return nullptr; |
| 49 }; |
| 50 return &ResourceBundle::GetSharedInstance().GetImageNamed(resource_id); |
| 51 } |
| 52 |
| 53 bool IsNearlyZero(float value) { |
| 54 return std::abs(value) < kEpsilon; |
| 55 } |
| 56 |
| 57 } // namespace |
| 58 |
| 59 TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent) |
| 60 : window_delegate_(new aura_extra::ImageWindowDelegate), |
| 61 window_(new aura::Window(window_delegate_)), |
| 62 enabled_(false), |
| 63 alpha_(0), |
| 64 orientation_(TouchHandleOrientation::UNDEFINED) { |
| 65 window_delegate_->set_image_offset(gfx::Vector2d(kSelectionHandlePadding, |
| 66 kSelectionHandlePadding)); |
| 67 window_delegate_->set_background_color(SK_ColorTRANSPARENT); |
| 68 window_->SetTransparent(true); |
| 69 window_->Init(LAYER_TEXTURED); |
| 70 window_->set_owned_by_parent(false); |
| 71 window_->set_ignore_events(true); |
| 72 parent->AddChild(window_.get()); |
| 73 } |
| 74 |
| 75 TouchHandleDrawableAura::~TouchHandleDrawableAura() { |
| 76 } |
| 77 |
| 78 void TouchHandleDrawableAura::UpdateBounds() { |
| 79 gfx::RectF new_bounds = relative_bounds_; |
| 80 new_bounds.Offset(focal_position_.x(), focal_position_.y()); |
| 81 window_->SetBounds(gfx::ToEnclosingRect(new_bounds)); |
| 82 } |
| 83 |
| 84 void TouchHandleDrawableAura::SetEnabled(bool enabled) { |
| 85 if (enabled == enabled_) |
| 86 return; |
| 87 |
| 88 enabled_ = enabled; |
| 89 bool visible = !IsNearlyZero(alpha_); |
| 90 if (enabled_ && visible) |
| 91 window_->Show(); |
| 92 else |
| 93 window_->Hide(); |
| 94 } |
| 95 |
| 96 void TouchHandleDrawableAura::SetOrientation( |
| 97 TouchHandleOrientation orientation) { |
| 98 if (orientation_ == orientation) |
| 99 return; |
| 100 orientation_ = orientation; |
| 101 gfx::Image* image = GetHandleImage(orientation); |
| 102 window_delegate_->SetImage(*image); |
| 103 |
| 104 // Calculate the relative bounds. |
| 105 gfx::Size image_size = image->Size(); |
| 106 int window_width = image_size.width() + 2 * kSelectionHandlePadding; |
| 107 int window_height = image_size.height() + 2 * kSelectionHandlePadding; |
| 108 // Due to the shape of the handle images, the window is aligned differently to |
| 109 // the selection bound depending on the orientation. |
| 110 int window_left = 0; |
| 111 switch (orientation) { |
| 112 case TouchHandleOrientation::LEFT: |
| 113 window_left = -image_size.width() - kSelectionHandlePadding; |
| 114 break; |
| 115 case TouchHandleOrientation::RIGHT: |
| 116 window_left = -kSelectionHandlePadding; |
| 117 break; |
| 118 case TouchHandleOrientation::CENTER: |
| 119 window_left = -window_width / 2; |
| 120 break; |
| 121 case TouchHandleOrientation::UNDEFINED: |
| 122 NOTREACHED() << "Undefined handle orientation."; |
| 123 break; |
| 124 }; |
| 125 relative_bounds_ = gfx::RectF( |
| 126 window_left, |
| 127 kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding, |
| 128 window_width, |
| 129 window_height); |
| 130 UpdateBounds(); |
| 131 } |
| 132 |
| 133 void TouchHandleDrawableAura::SetAlpha(float alpha) { |
| 134 if (alpha == alpha_) |
| 135 return; |
| 136 |
| 137 alpha_ = alpha; |
| 138 window_->layer()->SetOpacity(alpha_); |
| 139 bool visible = !IsNearlyZero(alpha_); |
| 140 if (enabled_ && visible) |
| 141 window_->Show(); |
| 142 else |
| 143 window_->Hide(); |
| 144 } |
| 145 |
| 146 void TouchHandleDrawableAura::SetFocus(const gfx::PointF& position) { |
| 147 focal_position_ = position; |
| 148 UpdateBounds(); |
| 149 } |
| 150 |
| 151 gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const { |
| 152 gfx::RectF bounds(window_->bounds()); |
| 153 bounds.Inset(kSelectionHandlePadding, |
| 154 kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset, |
| 155 kSelectionHandlePadding, |
| 156 kSelectionHandlePadding); |
| 157 return bounds; |
| 158 } |
| 159 |
| 160 } // namespace ui |
OLD | NEW |