15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/renderer_host/input/touch_handle.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <cmath> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content { 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Maximum duration of a fade sequence. 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const double kFadeDurationMs = 200; 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Maximum amount of travel for a fade sequence. This avoids handle "ghosting" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// when the handle is moving rapidly while the fade is active. 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const double kFadeDistanceSquared = 20.f * 20.f; 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Avoid using an empty touch rect, as it may fail the intersection test event 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// if it lies within the other rect's bounds. 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const float kMinTouchMajorForHitTesting = 1.f; 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The maximum touch size to use when computing whether a touch point is 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// targetting a touch handle. This is necessary for devices that misreport 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// touch radii, preventing inappropriately largely touch sizes from completely 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// breaking handle dragging behavior. 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const float kMaxTouchMajorForHitTesting = 36.f; 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Responsible for rendering a selection or insertion handle for text editing. 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TouchHandle::TouchHandle(TouchHandleClient* client, 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TouchHandleOrientation orientation) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : drawable_(client->CreateDrawable()), 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_(client), 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) orientation_(orientation), 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deferred_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED), 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) alpha_(0.f), 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) animate_deferred_fade_(false), 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enabled_(true), 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_visible_(false), 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_dragging_(false), 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_drag_within_tap_region_(false) { 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED); 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetEnabled(enabled_); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetOrientation(orientation_); 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetAlpha(alpha_); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetVisible(is_visible_); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetFocus(position_); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TouchHandle::~TouchHandle() { 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::SetEnabled(bool enabled) { 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (enabled_ == enabled) 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!enabled) { 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndDrag(); 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enabled_ = enabled; 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetEnabled(enabled); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::SetVisible(bool visible, AnimationStyle animation_style) { 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_visible_ == visible) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_visible_ = visible; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Handle repositioning may have been deferred while previously invisible. 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (visible) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetFocus(position_); 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool animate = animation_style != ANIMATION_NONE; 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_dragging_) { 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) animate_deferred_fade_ = animate; 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (animate) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BeginFade(); 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::SetPosition(const gfx::PointF& position) { 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (position_ == position) 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) position_ = position; 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Suppress repositioning a handle while invisible or fading out to prevent it 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // from "ghosting" outside the visible bounds. The position will be pushed to 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the drawable when the handle regains visibility (see |SetVisible()|). 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_visible_) 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetFocus(position_); 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::SetOrientation(TouchHandleOrientation orientation) { 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_dragging_) { 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deferred_orientation_ = orientation; 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(deferred_orientation_, TOUCH_HANDLE_ORIENTATION_UNDEFINED); 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (orientation_ == orientation) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) orientation_ = orientation; 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetOrientation(orientation); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) { 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!enabled_) 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (event.GetAction()) { 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ui::MotionEvent::ACTION_DOWN: { 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!is_visible_) 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const float touch_size = std::max( 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) kMinTouchMajorForHitTesting, 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor())); 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::RectF touch_rect(event.GetX() - touch_size * .5f, 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event.GetY() - touch_size * .5f, 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) touch_size, 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) touch_size); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!drawable_->IntersectsWith(touch_rect)) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) touch_down_position_ = gfx::PointF(event.GetX(), event.GetY()); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) touch_to_focus_offset_ = position_ - touch_down_position_; 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) touch_down_time_ = event.GetEventTime(); 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BeginDrag(); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } break; 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ui::MotionEvent::ACTION_MOVE: { 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::PointF touch_move_position(event.GetX(), event.GetY()); 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_drag_within_tap_region_) { 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const float tap_slop = client_->GetTapSlop(); 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_drag_within_tap_region_ = 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (touch_move_position - touch_down_position_).LengthSquared() < 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tap_slop * tap_slop; 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Note that we signal drag update even if we're inside the tap region, 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // as there are cases where characters are narrower than the slop length. 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->OnHandleDragUpdate(*this, 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci touch_move_position + touch_to_focus_offset_); 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } break; 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ui::MotionEvent::ACTION_UP: { 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_drag_within_tap_region_ && 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (event.GetEventTime() - touch_down_time_) < 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->GetTapTimeout()) { 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->OnHandleTapped(*this); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndDrag(); 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } break; 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ui::MotionEvent::ACTION_CANCEL: 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndDrag(); 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool TouchHandle::Animate(base::TimeTicks frame_time) { 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (fade_end_time_ == base::TimeTicks()) 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) float time_u = 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs; 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) float position_u = 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared; 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) float u = std::max(time_u, position_u); 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetAlpha(is_visible_ ? u : 1.f - u); 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (u >= 1.f) { 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::BeginDrag() { 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_dragging_) 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_dragging_ = true; 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_drag_within_tap_region_ = true; 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->OnHandleDragBegin(*this); 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::EndDrag() { 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!is_dragging_) 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_dragging_ = false; 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_drag_within_tap_region_ = false; 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->OnHandleDragEnd(*this); 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED) { 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TouchHandleOrientation deferred_orientation = deferred_orientation_; 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED; 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetOrientation(deferred_orientation); 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (animate_deferred_fade_) { 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BeginFade(); 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // As drawable visibility assignment is deferred while dragging, push the 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // change by forcing fade completion. 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::BeginFade() { 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!is_dragging_); 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) animate_deferred_fade_ = false; 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const float target_alpha = is_visible_ ? 1.f : 0.f; 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (target_alpha == alpha_) { 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EndFade(); 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetVisible(true); 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fade_end_time_ = base::TimeTicks::Now() + 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta::FromMillisecondsD( 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kFadeDurationMs * std::abs(target_alpha - alpha_)); 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fade_start_position_ = position_; 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->SetNeedsAnimate(); 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::EndFade() { 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(enabled_); 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) animate_deferred_fade_ = false; 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fade_end_time_ = base::TimeTicks(); 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetAlpha(is_visible_ ? 1.f : 0.f); 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetVisible(is_visible_); 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TouchHandle::SetAlpha(float alpha) { 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) alpha = std::max(0.f, std::min(1.f, alpha)); 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (alpha_ == alpha) 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) alpha_ = alpha; 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drawable_->SetAlpha(alpha); 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace content 268