Index: ui/views/view.cc |
diff --git a/ui/views/view.cc b/ui/views/view.cc |
index d200d03aeed93b2d6edcee1cc1873257d2eb3d84..fdd82d86f4c29809e15502f3d118e51fe26d202e 100644 |
--- a/ui/views/view.cc |
+++ b/ui/views/view.cc |
@@ -27,6 +27,7 @@ |
#include "ui/views/context_menu_controller.h" |
#include "ui/views/drag_controller.h" |
#include "ui/views/layout/layout_manager.h" |
+#include "ui/views/view_constants.h" |
#include "ui/views/views_delegate.h" |
#include "ui/views/widget/native_widget_private.h" |
#include "ui/views/widget/root_view.h" |
@@ -80,6 +81,40 @@ const views::View* GetHierarchyRoot(const views::View* view) { |
return root; |
} |
+// Returns the percentage of |rect1|'s area that is covered by |rect2|. |
+float PercentCoveredBy(const gfx::Rect& rect1, const gfx::Rect& rect2) { |
+ gfx::Rect intersection(rect1.Intersect(rect2)); |
+ float intersectionArea = intersection.width() * intersection.height(); |
+ float rect1Area = rect1.width() * rect1.height(); |
+ return intersectionArea / rect1Area; |
+} |
sadrul
2012/07/16 22:16:14
I think this is fine ... but perhaps you could use
tdanderson
2012/07/17 19:07:07
Done.
|
+ |
+int DistanceToInterval(int pos, int start, int end) { |
+ if (pos < start) |
+ return start - pos; |
+ if (pos > end) |
+ return end - pos; |
+ return 0; |
+} |
+ |
+int DistanceSquaredFromCenterLineToPoint(const gfx::Point& point, |
sadrul
2012/07/16 22:16:14
document
tdanderson
2012/07/17 19:07:07
Done.
|
+ const gfx::Rect& targetRect) { |
+ gfx::Point centerPoint = targetRect.CenterPoint(); |
+ int xdist = centerPoint.x() - point.x(); |
+ int ydist = centerPoint.y() - point.y(); |
+ |
+ if (targetRect.width() > targetRect.height()) |
sadrul
2012/07/16 22:16:14
braces
rjkroege
2012/07/16 23:35:48
Note how WebKit != Chrome. :-)
tdanderson
2012/07/17 19:07:07
Done.
tdanderson
2012/07/17 19:07:07
Done.
|
+ xdist = DistanceToInterval(point.x(), |
+ targetRect.x() + (targetRect.height() / 2), |
+ targetRect.right() - (targetRect.height() / 2)); |
+ else |
+ ydist = DistanceToInterval(point.y(), |
+ targetRect.y() + (targetRect.width() / 2), |
+ targetRect.bottom() - (targetRect.width() / 2)); |
+ |
+ return (xdist * xdist) + (ydist * ydist); |
+} |
+ |
} // namespace |
namespace views { |
@@ -1270,6 +1305,38 @@ void View::ReorderChildLayers(ui::Layer* parent_layer) { |
// Input ----------------------------------------------------------------------- |
+void View::FindClosestOverlappedRect(const gfx::Rect& touchRect, |
rjkroege
2012/07/16 23:35:48
This routine could conceivably explore many views.
tdanderson
2012/07/17 19:07:07
I tried to cut down the number of views explored a
|
+ gfx::Rect& closestOverlappedRect) { |
+ for (int i = child_count() - 1; i >= 0; --i) { |
+ View* child = child_at(i); |
+ |
+ if (!child->visible()) |
+ continue; |
+ |
+ gfx::Rect childRect(child->GetScreenBounds()); |
sadrul
2012/07/16 22:16:14
child_rect etc.
Why ScreenBounds?
tdanderson
2012/07/17 19:07:07
It seems easiest to have everything in a common co
sadrul
2012/07/17 19:26:45
This sounds reasonable. Make sure the doc for the
tdanderson
2012/07/18 22:35:42
Done.
|
+ if (!childRect.Intersects(touchRect)) |
+ continue; |
+ |
+ if (PercentCoveredBy(childRect, touchRect) >= kFuzzingOverlapPercentage) { |
+ if (closestOverlappedRect.IsEmpty()) { |
+ closestOverlappedRect = childRect; |
+ } else { |
+ gfx::Point touchCenter(touchRect.CenterPoint()); |
+ int bestDistSoFar = DistanceSquaredFromCenterLineToPoint( |
+ touchCenter, |
+ closestOverlappedRect); |
+ int curDist = DistanceSquaredFromCenterLineToPoint(touchCenter, |
+ childRect); |
+ |
+ if (curDist < bestDistSoFar) |
+ closestOverlappedRect = childRect; |
+ } |
+ } |
+ |
+ child->FindClosestOverlappedRect(touchRect, closestOverlappedRect); |
+ } |
sadrul
2012/07/16 22:16:14
indent is off.
tdanderson
2012/07/17 19:07:07
Done.
|
+} |
+ |
bool View::HasHitTestMask() const { |
return false; |
} |