Chromium Code Reviews| Index: ui/views/view_targeter.cc |
| diff --git a/ui/views/view_targeter.cc b/ui/views/view_targeter.cc |
| index 99c28fe78755440bd24d4d3b046198fab9a6d212..0c5de634d0ec2ba92c9cb7ffdff66b05eef6f657 100644 |
| --- a/ui/views/view_targeter.cc |
| +++ b/ui/views/view_targeter.cc |
| @@ -8,6 +8,9 @@ |
| #include "ui/views/focus/focus_manager.h" |
| #include "ui/views/view.h" |
| #include "ui/views/view_targeter_delegate.h" |
| +#include "ui/views/views_switches.h" |
| +#include "ui/views/widget/root_view.h" |
| +#include "ui/views/widget/widget.h" |
| namespace views { |
| @@ -39,6 +42,9 @@ ui::EventTarget* ViewTargeter::FindTargetForEvent(ui::EventTarget* root, |
| *static_cast<ui::ScrollEvent*>(event)); |
| } |
| + if (event->IsGestureEvent()) |
| + return FindTargetForGestureEvent(view, *(event->AsGestureEvent())); |
| + |
| NOTREACHED() << "ViewTargeter does not yet support this event type."; |
| return NULL; |
| } |
| @@ -46,6 +52,30 @@ ui::EventTarget* ViewTargeter::FindTargetForEvent(ui::EventTarget* root, |
| ui::EventTarget* ViewTargeter::FindNextBestTarget( |
| ui::EventTarget* previous_target, |
| ui::Event* event) { |
| + if (!previous_target) |
| + return NULL; |
| + |
| + if (event->IsGestureEvent()) { |
| + View* root = |
| + static_cast<View*>(previous_target)->GetWidget()->GetRootView(); |
| + internal::RootView* root_view = static_cast<internal::RootView*>(root); |
| + |
| + // If the default gesture handler was already established prior to |event|, |
| + // only GESTURE_SCROLL_BEGIN events may be re-targeted. |
| + if (root_view->dispatch_to_gesture_handler_ && |
| + event->type() != ui::ET_GESTURE_SCROLL_BEGIN) { |
| + return NULL; |
| + } |
| + |
| + // If |gesture_handler_| is NULL, it is either because the view was removed |
| + // from the tree by the previous dispatch of |event| or because |event| is |
| + // the GESTURE_END event corresponding to the removal of the last touch |
| + // point. In either case, no further re-targeting of |event| should be |
| + // permitted. |
| + if (!root_view->gesture_handler_) |
| + return NULL; |
| + } |
| + |
| return previous_target->GetParentTarget(); |
| } |
| @@ -75,4 +105,31 @@ View* ViewTargeter::FindTargetForScrollEvent(View* root, |
| return root->GetEffectiveViewTargeter()->TargetForRect(root, rect); |
| } |
| +View* ViewTargeter::FindTargetForGestureEvent(View* root, |
| + const ui::GestureEvent& gesture) { |
| + CHECK(!root->parent()); |
| + internal::RootView* root_view = static_cast<internal::RootView*>(root); |
|
sadrul
2014/08/26 16:21:44
This is pretty ugly.
How about have a RootViewTar
tdanderson
2014/08/26 20:21:14
Done.
|
| + |
| + // Return the default gesture handler if one is already set. |
| + if (root_view->gesture_handler_) { |
| + CHECK(root_view->dispatch_to_gesture_handler_); |
| + return root_view->gesture_handler_; |
| + } |
| + |
| + // If rect-based targeting is enabled, use the gesture's bounding box to |
| + // determine the target. Otherwise use the center point of the gesture's |
| + // bounding box to determine the target. |
| + gfx::Rect rect(gesture.location(), gfx::Size(1, 1)); |
| + if (views::switches::IsRectBasedTargetingEnabled() && |
| + !gesture.details().bounding_box().IsEmpty()) { |
| + // TODO(tdanderson): Pass in the bounding box to GetEventHandlerForRect() |
| + // once crbug.com/313392 is resolved. |
| + rect = gfx::Rect(gesture.details().bounding_box()); |
| + rect.set_origin(gesture.location()); |
| + rect.Offset(-rect.width() / 2, -rect.height() / 2); |
| + } |
| + |
| + return root->GetEffectiveViewTargeter()->TargetForRect(root, rect); |
| +} |
| + |
| } // namespace views |