touch_handle_drawable_aura.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. #include "ui/touch_selection/touch_handle_drawable_aura.h"
  5. #include "ui/aura/window.h"
  6. #include "ui/aura/window_targeter.h"
  7. #include "ui/aura_extra/image_window_delegate.h"
  8. #include "ui/base/cursor/cursor.h"
  9. #include "ui/base/hit_test.h"
  10. #include "ui/base/resource/resource_bundle.h"
  11. #include "ui/compositor/layer.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. namespace ui {
  17. namespace {
  18. // The distance by which a handle image is offset from the focal point (i.e.
  19. // text baseline) downwards.
  20. const int kSelectionHandleVerticalVisualOffset = 2;
  21. // The padding around the selection handle image can be used to extend the
  22. // handle window so that touch events near the selection handle image are
  23. // targeted to the selection handle window.
  24. const int kSelectionHandlePadding = 0;
  25. // Epsilon value used to compare float values to zero.
  26. const float kEpsilon = 1e-8f;
  27. // Returns the appropriate handle image based on the handle orientation.
  28. gfx::Image* GetHandleImage(TouchHandleOrientation orientation) {
  29. int resource_id = 0;
  30. switch (orientation) {
  31. case TouchHandleOrientation::LEFT:
  32. resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
  33. break;
  34. case TouchHandleOrientation::CENTER:
  35. resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
  36. break;
  37. case TouchHandleOrientation::RIGHT:
  38. resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
  39. break;
  40. case TouchHandleOrientation::UNDEFINED:
  41. NOTREACHED() << "Invalid touch handle bound type.";
  42. return nullptr;
  43. };
  44. return &ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
  45. }
  46. bool IsNearlyZero(float value) {
  47. return std::abs(value) < kEpsilon;
  48. }
  49. } // namespace
  50. TouchHandleDrawableAura::TouchHandleDrawableAura(aura::Window* parent)
  51. : window_delegate_(new aura_extra::ImageWindowDelegate),
  52. window_(new aura::Window(window_delegate_)),
  53. enabled_(false),
  54. alpha_(0),
  55. orientation_(TouchHandleOrientation::UNDEFINED) {
  56. window_delegate_->set_image_offset(gfx::Vector2d(kSelectionHandlePadding,
  57. kSelectionHandlePadding));
  58. window_->SetTransparent(true);
  59. window_->Init(LAYER_TEXTURED);
  60. window_->set_owned_by_parent(false);
  61. window_->SetEventTargetingPolicy(aura::EventTargetingPolicy::kNone);
  62. parent->AddChild(window_.get());
  63. }
  64. TouchHandleDrawableAura::~TouchHandleDrawableAura() {
  65. }
  66. void TouchHandleDrawableAura::UpdateBounds() {
  67. gfx::RectF new_bounds = relative_bounds_;
  68. new_bounds.Offset(origin_position_.x(), origin_position_.y());
  69. window_->SetBounds(gfx::ToEnclosingRect(new_bounds));
  70. }
  71. bool TouchHandleDrawableAura::IsVisible() const {
  72. return enabled_ && !IsNearlyZero(alpha_);
  73. }
  74. void TouchHandleDrawableAura::SetEnabled(bool enabled) {
  75. if (enabled == enabled_)
  76. return;
  77. enabled_ = enabled;
  78. if (IsVisible())
  79. window_->Show();
  80. else
  81. window_->Hide();
  82. }
  83. void TouchHandleDrawableAura::SetOrientation(TouchHandleOrientation orientation,
  84. bool mirror_vertical,
  85. bool mirror_horizontal) {
  86. // TODO(AviD): Implement adaptive handle orientation logic for Aura
  87. DCHECK(!mirror_vertical);
  88. DCHECK(!mirror_horizontal);
  89. if (orientation_ == orientation)
  90. return;
  91. orientation_ = orientation;
  92. gfx::Image* image = GetHandleImage(orientation);
  93. window_delegate_->SetImage(*image);
  94. // Calculate the relative bounds.
  95. gfx::Size image_size = image->Size();
  96. int window_width = image_size.width() + 2 * kSelectionHandlePadding;
  97. int window_height = image_size.height() + 2 * kSelectionHandlePadding;
  98. relative_bounds_ =
  99. gfx::RectF(-kSelectionHandlePadding,
  100. kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding,
  101. window_width, window_height);
  102. gfx::Rect paint_bounds(relative_bounds_.x(), relative_bounds_.y(),
  103. relative_bounds_.width(), relative_bounds_.height());
  104. window_->SchedulePaintInRect(paint_bounds);
  105. UpdateBounds();
  106. }
  107. void TouchHandleDrawableAura::SetOrigin(const gfx::PointF& position) {
  108. origin_position_ = position;
  109. UpdateBounds();
  110. }
  111. void TouchHandleDrawableAura::SetAlpha(float alpha) {
  112. if (alpha == alpha_)
  113. return;
  114. alpha_ = alpha;
  115. window_->layer()->SetOpacity(alpha_);
  116. if (IsVisible())
  117. window_->Show();
  118. else
  119. window_->Hide();
  120. }
  121. gfx::RectF TouchHandleDrawableAura::GetVisibleBounds() const {
  122. gfx::RectF bounds(window_->bounds());
  123. bounds.Inset(gfx::InsetsF::TLBR(
  124. kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
  125. kSelectionHandlePadding, kSelectionHandlePadding,
  126. kSelectionHandlePadding));
  127. return bounds;
  128. }
  129. float TouchHandleDrawableAura::GetDrawableHorizontalPaddingRatio() const {
  130. // Aura does not have any transparent padding for its handle drawable.
  131. return 0.0f;
  132. }
  133. } // namespace ui