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 |