Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. | 5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. |
| 6 | 6 |
| 7 #include "ui/views/view.h" | 7 #include "ui/views/view.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 #else | 61 #else |
| 62 bool use_acceleration_when_possible = false; | 62 bool use_acceleration_when_possible = false; |
| 63 #endif | 63 #endif |
| 64 | 64 |
| 65 #if defined(OS_WIN) | 65 #if defined(OS_WIN) |
| 66 const bool kContextMenuOnMousePress = false; | 66 const bool kContextMenuOnMousePress = false; |
| 67 #else | 67 #else |
| 68 const bool kContextMenuOnMousePress = true; | 68 const bool kContextMenuOnMousePress = true; |
| 69 #endif | 69 #endif |
| 70 | 70 |
| 71 // The minimum percentage of a view's area that needs to be covered by a rect | |
| 72 // representing a touch region in order for that view to be considered by the | |
| 73 // views fuzzing algorithm. | |
| 74 static const float kViewsFuzzingOverlap = 0.6; | |
| 75 | |
| 71 // Returns the top view in |view|'s hierarchy. | 76 // Returns the top view in |view|'s hierarchy. |
| 72 const views::View* GetHierarchyRoot(const views::View* view) { | 77 const views::View* GetHierarchyRoot(const views::View* view) { |
| 73 const views::View* root = view; | 78 const views::View* root = view; |
| 74 while (root && root->parent()) | 79 while (root && root->parent()) |
| 75 root = root->parent(); | 80 root = root->parent(); |
| 76 return root; | 81 return root; |
| 77 } | 82 } |
| 78 | 83 |
| 79 } // namespace | 84 } // namespace |
| 80 | 85 |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 target->ConvertPointFromAncestor(root, point); | 679 target->ConvertPointFromAncestor(root, point); |
| 675 | 680 |
| 676 // API defines NULL |source| as returning the point in screen coordinates. | 681 // API defines NULL |source| as returning the point in screen coordinates. |
| 677 if (!source) { | 682 if (!source) { |
| 678 *point -= | 683 *point -= |
| 679 root->GetWidget()->GetClientAreaBoundsInScreen().OffsetFromOrigin(); | 684 root->GetWidget()->GetClientAreaBoundsInScreen().OffsetFromOrigin(); |
| 680 } | 685 } |
| 681 } | 686 } |
| 682 | 687 |
| 683 // static | 688 // static |
| 689 void View::ConvertRectToTarget(const View* source, | |
| 690 const View* target, | |
| 691 gfx::Rect* rect) { | |
| 692 if (source == target) | |
| 693 return; | |
| 694 | |
| 695 // |source| can be NULL. | |
| 696 const View* root = GetHierarchyRoot(target); | |
| 697 if (source) { | |
| 698 CHECK_EQ(GetHierarchyRoot(source), root); | |
| 699 | |
| 700 if (source != root) | |
| 701 source->ConvertRectForAncestor(root, rect); | |
| 702 } | |
| 703 | |
| 704 if (target != root) | |
| 705 target->ConvertRectFromAncestor(root, rect); | |
| 706 | |
| 707 // API defines NULL |source| as returning the point in screen coordinates. | |
| 708 if (!source) { | |
| 709 rect->set_origin(rect->origin() - | |
| 710 root->GetWidget()->GetClientAreaBoundsInScreen().OffsetFromOrigin()); | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 // static | |
| 684 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { | 715 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { |
| 685 DCHECK(src); | 716 DCHECK(src); |
| 686 DCHECK(p); | 717 DCHECK(p); |
| 687 | 718 |
| 688 src->ConvertPointForAncestor(NULL, p); | 719 src->ConvertPointForAncestor(NULL, p); |
| 689 } | 720 } |
| 690 | 721 |
| 691 // static | 722 // static |
| 692 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { | 723 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { |
| 693 DCHECK(dest); | 724 DCHECK(dest); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 } | 831 } |
| 801 | 832 |
| 802 // static | 833 // static |
| 803 bool View::get_use_acceleration_when_possible() { | 834 bool View::get_use_acceleration_when_possible() { |
| 804 return use_acceleration_when_possible; | 835 return use_acceleration_when_possible; |
| 805 } | 836 } |
| 806 | 837 |
| 807 // Input ----------------------------------------------------------------------- | 838 // Input ----------------------------------------------------------------------- |
| 808 | 839 |
| 809 View* View::GetEventHandlerForPoint(const gfx::Point& point) { | 840 View* View::GetEventHandlerForPoint(const gfx::Point& point) { |
| 810 // Walk the child Views recursively looking for the View that most | 841 return GetEventHandlerForRect(gfx::Rect(point, gfx::Size(1, 1))); |
| 811 // tightly encloses the specified point. | 842 } |
| 843 | |
| 844 View* View::GetEventHandlerForRect(const gfx::Rect& rect) { | |
| 845 // |rect_view| represents the current best candidate to return | |
| 846 // if rect-based targeting (i.e., fuzzing) is used. | |
| 847 // |rect_view_distance| is used to keep track of the distance | |
| 848 // between the center point of |rect_view| and the center | |
| 849 // point of |rect|. | |
| 850 View* rect_view = NULL; | |
| 851 int rect_view_distance = INT_MAX; | |
| 852 | |
| 853 // |point_view| represents the view that would have been returned | |
| 854 // from this function call if point-based targeting were used. | |
| 855 View* point_view = NULL; | |
| 856 | |
| 812 for (int i = child_count() - 1; i >= 0; --i) { | 857 for (int i = child_count() - 1; i >= 0; --i) { |
| 813 View* child = child_at(i); | 858 View* child = child_at(i); |
| 859 | |
| 860 // Ignore any children which are invisible or do not intersect |rect|. | |
| 814 if (!child->visible()) | 861 if (!child->visible()) |
| 815 continue; | 862 continue; |
| 863 gfx::Rect rect_in_child_coords(rect); | |
| 864 ConvertRectToTarget(this, child, &rect_in_child_coords); | |
| 865 if (!child->HitTestRect(rect_in_child_coords)) | |
| 866 continue; | |
| 816 | 867 |
| 817 gfx::Point point_in_child_coords(point); | 868 View* cur_view = child->GetEventHandlerForRect(rect_in_child_coords); |
| 818 ConvertPointToTarget(this, child, &point_in_child_coords); | 869 |
| 819 if (child->HitTestPoint(point_in_child_coords)) | 870 if (UsePointBasedTargeting(rect)) |
| 820 return child->GetEventHandlerForPoint(point_in_child_coords); | 871 return cur_view; |
| 872 | |
| 873 gfx::Rect cur_rect(cur_view->GetLocalBounds()); | |
|
sky
2013/10/04 17:03:49
cur_rect -> cur_view_bounds
tdanderson
2013/10/07 21:35:21
Done.
| |
| 874 ConvertRectToTarget(cur_view, this, &cur_rect); | |
| 875 if (PercentCoveredBy(cur_rect, rect) >= kViewsFuzzingOverlap) { | |
| 876 // |cur_view| is a suitable candidate for rect-based targeting. | |
| 877 // Check to see if it is the closest suitable candidate so far. | |
| 878 gfx::Point touch_center(rect.CenterPoint()); | |
| 879 // Terry: change this to just use distance between center points. | |
|
sky
2013/10/04 17:03:49
TODO(tdanderson):
tdanderson
2013/10/07 21:35:21
On second thought, I'm going to leave this as is s
| |
| 880 int cur_dist = DistanceSquaredFromCenterLineToPoint(touch_center, | |
| 881 cur_rect); | |
| 882 if (!rect_view || cur_dist < rect_view_distance) { | |
| 883 rect_view = cur_view; | |
| 884 rect_view_distance = cur_dist; | |
| 885 } | |
| 886 } else if (!rect_view && !point_view) { | |
| 887 // Rect-based targeting has not yielded any candidates so far. Check | |
| 888 // if point-based targeting would have selected |cur_view|. | |
| 889 gfx::Point point_in_child_coords(rect.CenterPoint()); | |
|
sky
2013/10/04 17:03:49
Can you use the center point of rect_in_child_coor
tdanderson
2013/10/07 21:35:21
Done.
| |
| 890 ConvertPointToTarget(this, child, &point_in_child_coords); | |
| 891 if (child->HitTestPoint(point_in_child_coords)) | |
| 892 point_view = child->GetEventHandlerForPoint(point_in_child_coords); | |
| 893 } | |
| 821 } | 894 } |
| 822 return this; | 895 |
| 896 if (UsePointBasedTargeting(rect) || (!rect_view && !point_view)) | |
| 897 return this; | |
| 898 | |
| 899 return rect_view ? rect_view : point_view; | |
| 823 } | 900 } |
| 824 | 901 |
| 825 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) { | 902 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) { |
| 826 if (!HitTestPoint(point)) | 903 if (!HitTestPoint(point)) |
| 827 return NULL; | 904 return NULL; |
| 828 | 905 |
| 829 // Walk the child Views recursively looking for the View that most | 906 // Walk the child Views recursively looking for the View that most |
| 830 // tightly encloses the specified point. | 907 // tightly encloses the specified point. |
| 831 for (int i = child_count() - 1; i >= 0; --i) { | 908 for (int i = child_count() - 1; i >= 0; --i) { |
| 832 View* child = child_at(i); | 909 View* child = child_at(i); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1243 int View::GetPageScrollIncrement(ScrollView* scroll_view, | 1320 int View::GetPageScrollIncrement(ScrollView* scroll_view, |
| 1244 bool is_horizontal, bool is_positive) { | 1321 bool is_horizontal, bool is_positive) { |
| 1245 return 0; | 1322 return 0; |
| 1246 } | 1323 } |
| 1247 | 1324 |
| 1248 int View::GetLineScrollIncrement(ScrollView* scroll_view, | 1325 int View::GetLineScrollIncrement(ScrollView* scroll_view, |
| 1249 bool is_horizontal, bool is_positive) { | 1326 bool is_horizontal, bool is_positive) { |
| 1250 return 0; | 1327 return 0; |
| 1251 } | 1328 } |
| 1252 | 1329 |
| 1330 // Views fuzzing --------------------------------------------------------------- | |
| 1331 | |
| 1332 // static | |
| 1333 bool View::UsePointBasedTargeting(const gfx::Rect& rect) { | |
| 1334 return rect.width() == 1 && rect.height() == 1; | |
| 1335 } | |
| 1336 | |
| 1337 // static | |
| 1338 float View::PercentCoveredBy(const gfx::Rect& rect_1, const gfx::Rect& rect_2) { | |
| 1339 gfx::Rect intersection(rect_1); | |
| 1340 intersection.Intersect(rect_2); | |
| 1341 float intersection_area = intersection.size().GetArea(); | |
|
sky
2013/10/04 17:03:49
Should this and 1342 be kept as ints and then case
tdanderson
2013/10/07 21:35:21
Done.
| |
| 1342 float rect_1_area = rect_1.size().GetArea(); | |
| 1343 return rect_1_area ? intersection_area / rect_1_area : 0; | |
| 1344 } | |
| 1345 | |
| 1346 // The positive distance from |pos| to the nearest endpoint of the interval | |
| 1347 // [start, end] is returned if |pos| lies within the interval, otherwise | |
| 1348 // 0 is returned. | |
| 1349 int DistanceToInterval(int pos, int start, int end) { | |
| 1350 if (pos < start) | |
| 1351 return start - pos; | |
| 1352 if (pos > end) | |
| 1353 return pos - end; | |
| 1354 return 0; | |
| 1355 } | |
| 1356 | |
| 1357 // static | |
| 1358 int View::DistanceSquaredFromCenterLineToPoint(const gfx::Point& point, | |
| 1359 const gfx::Rect& target_rect) { | |
| 1360 gfx::Point center_point = target_rect.CenterPoint(); | |
| 1361 int dx = center_point.x() - point.x(); | |
| 1362 int dy = center_point.y() - point.y(); | |
| 1363 | |
| 1364 if (target_rect.width() > target_rect.height()) { | |
| 1365 dx = DistanceToInterval(point.x(), | |
| 1366 target_rect.x() + (target_rect.height() / 2), | |
| 1367 target_rect.right() - (target_rect.height() / 2)); | |
| 1368 } else { | |
| 1369 dy = DistanceToInterval(point.y(), | |
| 1370 target_rect.y() + (target_rect.width() / 2), | |
| 1371 target_rect.bottom() - (target_rect.width() / 2)); | |
| 1372 } | |
| 1373 return (dx * dx) + (dy * dy); | |
| 1374 } | |
| 1375 | |
| 1253 //////////////////////////////////////////////////////////////////////////////// | 1376 //////////////////////////////////////////////////////////////////////////////// |
| 1254 // View, protected: | 1377 // View, protected: |
| 1255 | 1378 |
| 1256 // Size and disposition -------------------------------------------------------- | 1379 // Size and disposition -------------------------------------------------------- |
| 1257 | 1380 |
| 1258 void View::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 1381 void View::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 1259 } | 1382 } |
| 1260 | 1383 |
| 1261 void View::PreferredSizeChanged() { | 1384 void View::PreferredSizeChanged() { |
| 1262 InvalidateLayout(); | 1385 InvalidateLayout(); |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1971 bool View::ConvertPointFromAncestor(const View* ancestor, | 2094 bool View::ConvertPointFromAncestor(const View* ancestor, |
| 1972 gfx::Point* point) const { | 2095 gfx::Point* point) const { |
| 1973 gfx::Transform trans; | 2096 gfx::Transform trans; |
| 1974 bool result = GetTransformRelativeTo(ancestor, &trans); | 2097 bool result = GetTransformRelativeTo(ancestor, &trans); |
| 1975 gfx::Point3F p(*point); | 2098 gfx::Point3F p(*point); |
| 1976 trans.TransformPointReverse(&p); | 2099 trans.TransformPointReverse(&p); |
| 1977 *point = gfx::ToFlooredPoint(p.AsPointF()); | 2100 *point = gfx::ToFlooredPoint(p.AsPointF()); |
| 1978 return result; | 2101 return result; |
| 1979 } | 2102 } |
| 1980 | 2103 |
| 2104 bool View::ConvertRectForAncestor(const View* ancestor, | |
| 2105 gfx::Rect* rect) const { | |
| 2106 gfx::Transform trans; | |
| 2107 // TODO(sad): Have some way of caching the transformation results. | |
| 2108 bool result = GetTransformRelativeTo(ancestor, &trans); | |
| 2109 gfx::RectF r(*rect); | |
| 2110 trans.TransformRect(&r); | |
| 2111 *rect = gfx::ToEnclosingRect(r); | |
| 2112 return result; | |
| 2113 } | |
| 2114 | |
| 2115 bool View::ConvertRectFromAncestor(const View* ancestor, | |
| 2116 gfx::Rect* rect) const { | |
| 2117 gfx::Transform trans; | |
| 2118 bool result = GetTransformRelativeTo(ancestor, &trans); | |
| 2119 gfx::RectF r(*rect); | |
| 2120 trans.TransformRectReverse(&r); | |
| 2121 *rect = gfx::ToEnclosingRect(r); | |
| 2122 return result; | |
| 2123 } | |
| 2124 | |
| 1981 // Accelerated painting -------------------------------------------------------- | 2125 // Accelerated painting -------------------------------------------------------- |
| 1982 | 2126 |
| 1983 void View::CreateLayer() { | 2127 void View::CreateLayer() { |
| 1984 // A new layer is being created for the view. So all the layers of the | 2128 // A new layer is being created for the view. So all the layers of the |
| 1985 // sub-tree can inherit the visibility of the corresponding view. | 2129 // sub-tree can inherit the visibility of the corresponding view. |
| 1986 for (int i = 0, count = child_count(); i < count; ++i) | 2130 for (int i = 0, count = child_count(); i < count; ++i) |
| 1987 child_at(i)->UpdateChildLayerVisibility(true); | 2131 child_at(i)->UpdateChildLayerVisibility(true); |
| 1988 | 2132 |
| 1989 layer_ = new ui::Layer(); | 2133 layer_ = new ui::Layer(); |
| 1990 layer_owner_.reset(layer_); | 2134 layer_owner_.reset(layer_); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2280 // Message the RootView to do the drag and drop. That way if we're removed | 2424 // Message the RootView to do the drag and drop. That way if we're removed |
| 2281 // the RootView can detect it and avoid calling us back. | 2425 // the RootView can detect it and avoid calling us back. |
| 2282 gfx::Point widget_location(event.location()); | 2426 gfx::Point widget_location(event.location()); |
| 2283 ConvertPointToWidget(this, &widget_location); | 2427 ConvertPointToWidget(this, &widget_location); |
| 2284 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2428 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
| 2285 // WARNING: we may have been deleted. | 2429 // WARNING: we may have been deleted. |
| 2286 return true; | 2430 return true; |
| 2287 } | 2431 } |
| 2288 | 2432 |
| 2289 } // namespace views | 2433 } // namespace views |
| OLD | NEW |