Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: ui/views/view.cc

Issue 401933002: Move views event targeting into ViewTargeterDelegate::TargetForRect() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 11 matching lines...) Expand all
22 #include "ui/compositor/compositor.h" 22 #include "ui/compositor/compositor.h"
23 #include "ui/compositor/dip_util.h" 23 #include "ui/compositor/dip_util.h"
24 #include "ui/compositor/layer.h" 24 #include "ui/compositor/layer.h"
25 #include "ui/compositor/layer_animator.h" 25 #include "ui/compositor/layer_animator.h"
26 #include "ui/events/event_target_iterator.h" 26 #include "ui/events/event_target_iterator.h"
27 #include "ui/gfx/canvas.h" 27 #include "ui/gfx/canvas.h"
28 #include "ui/gfx/interpolated_transform.h" 28 #include "ui/gfx/interpolated_transform.h"
29 #include "ui/gfx/path.h" 29 #include "ui/gfx/path.h"
30 #include "ui/gfx/point3_f.h" 30 #include "ui/gfx/point3_f.h"
31 #include "ui/gfx/point_conversions.h" 31 #include "ui/gfx/point_conversions.h"
32 #include "ui/gfx/rect_conversions.h"
33 #include "ui/gfx/scoped_canvas.h" 32 #include "ui/gfx/scoped_canvas.h"
34 #include "ui/gfx/screen.h" 33 #include "ui/gfx/screen.h"
35 #include "ui/gfx/skia_util.h" 34 #include "ui/gfx/skia_util.h"
36 #include "ui/gfx/transform.h" 35 #include "ui/gfx/transform.h"
37 #include "ui/native_theme/native_theme.h" 36 #include "ui/native_theme/native_theme.h"
38 #include "ui/views/accessibility/native_view_accessibility.h" 37 #include "ui/views/accessibility/native_view_accessibility.h"
39 #include "ui/views/background.h" 38 #include "ui/views/background.h"
40 #include "ui/views/border.h" 39 #include "ui/views/border.h"
41 #include "ui/views/context_menu_controller.h" 40 #include "ui/views/context_menu_controller.h"
42 #include "ui/views/drag_controller.h" 41 #include "ui/views/drag_controller.h"
43 #include "ui/views/focus/view_storage.h" 42 #include "ui/views/focus/view_storage.h"
44 #include "ui/views/layout/layout_manager.h" 43 #include "ui/views/layout/layout_manager.h"
45 #include "ui/views/rect_based_targeting_utils.h"
46 #include "ui/views/views_delegate.h" 44 #include "ui/views/views_delegate.h"
47 #include "ui/views/widget/native_widget_private.h" 45 #include "ui/views/widget/native_widget_private.h"
48 #include "ui/views/widget/root_view.h" 46 #include "ui/views/widget/root_view.h"
49 #include "ui/views/widget/tooltip_manager.h" 47 #include "ui/views/widget/tooltip_manager.h"
50 #include "ui/views/widget/widget.h" 48 #include "ui/views/widget/widget.h"
51 49
52 #if defined(OS_WIN) 50 #if defined(OS_WIN)
53 #include "base/win/scoped_gdi_object.h" 51 #include "base/win/scoped_gdi_object.h"
54 #endif 52 #endif
55 53
56 namespace { 54 namespace {
57 55
58 #if defined(OS_WIN) 56 #if defined(OS_WIN)
59 const bool kContextMenuOnMousePress = false; 57 const bool kContextMenuOnMousePress = false;
60 #else 58 #else
61 const bool kContextMenuOnMousePress = true; 59 const bool kContextMenuOnMousePress = true;
62 #endif 60 #endif
63 61
64 // The minimum percentage of a view's area that needs to be covered by a rect
65 // representing a touch region in order for that view to be considered by the
66 // rect-based targeting algorithm.
67 static const float kRectTargetOverlap = 0.6f;
68
69 // Default horizontal drag threshold in pixels. 62 // Default horizontal drag threshold in pixels.
70 // Same as what gtk uses. 63 // Same as what gtk uses.
71 const int kDefaultHorizontalDragThreshold = 8; 64 const int kDefaultHorizontalDragThreshold = 8;
72 65
73 // Default vertical drag threshold in pixels. 66 // Default vertical drag threshold in pixels.
74 // Same as what gtk uses. 67 // Same as what gtk uses.
75 const int kDefaultVerticalDragThreshold = 8; 68 const int kDefaultVerticalDragThreshold = 8;
76 69
77 // Returns the top view in |view|'s hierarchy. 70 // Returns the top view in |view|'s hierarchy.
78 const views::View* GetHierarchyRoot(const views::View* view) { 71 const views::View* GetHierarchyRoot(const views::View* view) {
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 return widget ? widget->GetNativeTheme() : ui::NativeTheme::instance(); 836 return widget ? widget->GetNativeTheme() : ui::NativeTheme::instance();
844 } 837 }
845 838
846 // Input ----------------------------------------------------------------------- 839 // Input -----------------------------------------------------------------------
847 840
848 View* View::GetEventHandlerForPoint(const gfx::Point& point) { 841 View* View::GetEventHandlerForPoint(const gfx::Point& point) {
849 return GetEventHandlerForRect(gfx::Rect(point, gfx::Size(1, 1))); 842 return GetEventHandlerForRect(gfx::Rect(point, gfx::Size(1, 1)));
850 } 843 }
851 844
852 View* View::GetEventHandlerForRect(const gfx::Rect& rect) { 845 View* View::GetEventHandlerForRect(const gfx::Rect& rect) {
853 // |rect_view| represents the current best candidate to return 846 return GetEffectiveViewTargeter()->TargetForRect(this, rect);
854 // if rect-based targeting (i.e., fuzzing) is used.
855 // |rect_view_distance| is used to keep track of the distance
856 // between the center point of |rect_view| and the center
857 // point of |rect|.
858 View* rect_view = NULL;
859 int rect_view_distance = INT_MAX;
860
861 // |point_view| represents the view that would have been returned
862 // from this function call if point-based targeting were used.
863 View* point_view = NULL;
864
865 for (int i = child_count() - 1; i >= 0; --i) {
866 View* child = child_at(i);
867
868 if (!child->CanProcessEventsWithinSubtree())
869 continue;
870
871 // Ignore any children which are invisible or do not intersect |rect|.
872 if (!child->visible())
873 continue;
874 gfx::RectF rect_in_child_coords_f(rect);
875 ConvertRectToTarget(this, child, &rect_in_child_coords_f);
876 gfx::Rect rect_in_child_coords = gfx::ToEnclosingRect(
877 rect_in_child_coords_f);
878 if (!child->HitTestRect(rect_in_child_coords))
879 continue;
880
881 View* cur_view = child->GetEventHandlerForRect(rect_in_child_coords);
882
883 if (views::UsePointBasedTargeting(rect))
884 return cur_view;
885
886 gfx::RectF cur_view_bounds_f(cur_view->GetLocalBounds());
887 ConvertRectToTarget(cur_view, this, &cur_view_bounds_f);
888 gfx::Rect cur_view_bounds = gfx::ToEnclosingRect(
889 cur_view_bounds_f);
890 if (views::PercentCoveredBy(cur_view_bounds, rect) >= kRectTargetOverlap) {
891 // |cur_view| is a suitable candidate for rect-based targeting.
892 // Check to see if it is the closest suitable candidate so far.
893 gfx::Point touch_center(rect.CenterPoint());
894 int cur_dist = views::DistanceSquaredFromCenterToPoint(touch_center,
895 cur_view_bounds);
896 if (!rect_view || cur_dist < rect_view_distance) {
897 rect_view = cur_view;
898 rect_view_distance = cur_dist;
899 }
900 } else if (!rect_view && !point_view) {
901 // Rect-based targeting has not yielded any candidates so far. Check
902 // if point-based targeting would have selected |cur_view|.
903 gfx::Point point_in_child_coords(rect_in_child_coords.CenterPoint());
904 if (child->HitTestPoint(point_in_child_coords))
905 point_view = child->GetEventHandlerForPoint(point_in_child_coords);
906 }
907 }
908
909 if (views::UsePointBasedTargeting(rect) || (!rect_view && !point_view))
910 return this;
911
912 // If |this| is a suitable candidate for rect-based targeting, check to
913 // see if it is closer than the current best suitable candidate so far.
914 gfx::Rect local_bounds(GetLocalBounds());
915 if (views::PercentCoveredBy(local_bounds, rect) >= kRectTargetOverlap) {
916 gfx::Point touch_center(rect.CenterPoint());
917 int cur_dist = views::DistanceSquaredFromCenterToPoint(touch_center,
918 local_bounds);
919 if (!rect_view || cur_dist < rect_view_distance)
920 rect_view = this;
921 }
922
923 return rect_view ? rect_view : point_view;
924 } 847 }
925 848
926 bool View::CanProcessEventsWithinSubtree() const { 849 bool View::CanProcessEventsWithinSubtree() const {
927 return true; 850 return true;
928 } 851 }
929 852
930 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) { 853 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) {
854 // TODO(tdanderson): Move this implementation into ViewTargetDelegate.
931 if (!HitTestPoint(point) || !CanProcessEventsWithinSubtree()) 855 if (!HitTestPoint(point) || !CanProcessEventsWithinSubtree())
932 return NULL; 856 return NULL;
933 857
934 // Walk the child Views recursively looking for the View that most 858 // Walk the child Views recursively looking for the View that most
935 // tightly encloses the specified point. 859 // tightly encloses the specified point.
936 for (int i = child_count() - 1; i >= 0; --i) { 860 for (int i = child_count() - 1; i >= 0; --i) {
937 View* child = child_at(i); 861 View* child = child_at(i);
938 if (!child->visible()) 862 if (!child->visible())
939 continue; 863 continue;
940 864
(...skipping 15 matching lines...) Expand all
956 #else 880 #else
957 return gfx::kNullCursor; 881 return gfx::kNullCursor;
958 #endif 882 #endif
959 } 883 }
960 884
961 bool View::HitTestPoint(const gfx::Point& point) const { 885 bool View::HitTestPoint(const gfx::Point& point) const {
962 return HitTestRect(gfx::Rect(point, gfx::Size(1, 1))); 886 return HitTestRect(gfx::Rect(point, gfx::Size(1, 1)));
963 } 887 }
964 888
965 bool View::HitTestRect(const gfx::Rect& rect) const { 889 bool View::HitTestRect(const gfx::Rect& rect) const {
966 ViewTargeter* view_targeter = targeter(); 890 return GetEffectiveViewTargeter()->DoesIntersectRect(this, rect);
967 if (!view_targeter)
968 view_targeter = GetWidget()->GetRootView()->targeter();
969 CHECK(view_targeter);
970 return view_targeter->DoesIntersectRect(this, rect);
971 } 891 }
972 892
973 bool View::IsMouseHovered() { 893 bool View::IsMouseHovered() {
974 // If we haven't yet been placed in an onscreen view hierarchy, we can't be 894 // If we haven't yet been placed in an onscreen view hierarchy, we can't be
975 // hovered. 895 // hovered.
976 if (!GetWidget()) 896 if (!GetWidget())
977 return false; 897 return false;
978 898
979 // If mouse events are disabled, then the mouse cursor is invisible and 899 // If mouse events are disabled, then the mouse cursor is invisible and
980 // is therefore not hovering over this button. 900 // is therefore not hovering over this button.
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 if (HitTestPoint(location)) { 2263 if (HitTestPoint(location)) {
2344 ConvertPointToScreen(this, &location); 2264 ConvertPointToScreen(this, &location);
2345 ShowContextMenu(location, ui::MENU_SOURCE_MOUSE); 2265 ShowContextMenu(location, ui::MENU_SOURCE_MOUSE);
2346 } 2266 }
2347 } else { 2267 } else {
2348 OnMouseReleased(event); 2268 OnMouseReleased(event);
2349 } 2269 }
2350 // WARNING: we may have been deleted. 2270 // WARNING: we may have been deleted.
2351 } 2271 }
2352 2272
2273 ViewTargeter* View::GetEffectiveViewTargeter() const {
2274 ViewTargeter* view_targeter = targeter();
2275 if (!view_targeter)
2276 view_targeter = GetWidget()->GetRootView()->targeter();
2277 CHECK(view_targeter);
2278 return view_targeter;
2279 }
2280
2353 // Accelerators ---------------------------------------------------------------- 2281 // Accelerators ----------------------------------------------------------------
2354 2282
2355 void View::RegisterPendingAccelerators() { 2283 void View::RegisterPendingAccelerators() {
2356 if (!accelerators_.get() || 2284 if (!accelerators_.get() ||
2357 registered_accelerator_count_ == accelerators_->size()) { 2285 registered_accelerator_count_ == accelerators_->size()) {
2358 // No accelerators are waiting for registration. 2286 // No accelerators are waiting for registration.
2359 return; 2287 return;
2360 } 2288 }
2361 2289
2362 if (!GetWidget()) { 2290 if (!GetWidget()) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 // Message the RootView to do the drag and drop. That way if we're removed 2420 // Message the RootView to do the drag and drop. That way if we're removed
2493 // the RootView can detect it and avoid calling us back. 2421 // the RootView can detect it and avoid calling us back.
2494 gfx::Point widget_location(event.location()); 2422 gfx::Point widget_location(event.location());
2495 ConvertPointToWidget(this, &widget_location); 2423 ConvertPointToWidget(this, &widget_location);
2496 widget->RunShellDrag(this, data, widget_location, drag_operations, source); 2424 widget->RunShellDrag(this, data, widget_location, drag_operations, source);
2497 // WARNING: we may have been deleted. 2425 // WARNING: we may have been deleted.
2498 return true; 2426 return true;
2499 } 2427 }
2500 2428
2501 } // namespace views 2429 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698