| 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 #include "ui/views/view.h" | 5 #include "ui/views/view.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 21 #include "ui/gfx/canvas.h" | 21 #include "ui/gfx/canvas.h" | 
| 22 #include "ui/gfx/interpolated_transform.h" | 22 #include "ui/gfx/interpolated_transform.h" | 
| 23 #include "ui/gfx/path.h" | 23 #include "ui/gfx/path.h" | 
| 24 #include "ui/gfx/point3.h" | 24 #include "ui/gfx/point3.h" | 
| 25 #include "ui/gfx/skia_util.h" | 25 #include "ui/gfx/skia_util.h" | 
| 26 #include "ui/gfx/transform.h" | 26 #include "ui/gfx/transform.h" | 
| 27 #include "ui/views/background.h" | 27 #include "ui/views/background.h" | 
| 28 #include "ui/views/context_menu_controller.h" | 28 #include "ui/views/context_menu_controller.h" | 
| 29 #include "ui/views/drag_controller.h" | 29 #include "ui/views/drag_controller.h" | 
| 30 #include "ui/views/layout/layout_manager.h" | 30 #include "ui/views/layout/layout_manager.h" | 
|  | 31 #include "ui/views/view_constants.h" | 
| 31 #include "ui/views/views_delegate.h" | 32 #include "ui/views/views_delegate.h" | 
| 32 #include "ui/views/widget/native_widget_private.h" | 33 #include "ui/views/widget/native_widget_private.h" | 
| 33 #include "ui/views/widget/root_view.h" | 34 #include "ui/views/widget/root_view.h" | 
| 34 #include "ui/views/widget/tooltip_manager.h" | 35 #include "ui/views/widget/tooltip_manager.h" | 
| 35 #include "ui/views/widget/widget.h" | 36 #include "ui/views/widget/widget.h" | 
| 36 | 37 | 
| 37 #if defined(OS_WIN) | 38 #if defined(OS_WIN) | 
| 38 #include "base/win/scoped_gdi_object.h" | 39 #include "base/win/scoped_gdi_object.h" | 
| 39 #include "ui/views/accessibility/native_view_accessibility_win.h" | 40 #include "ui/views/accessibility/native_view_accessibility_win.h" | 
| 40 #endif | 41 #endif | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 74 }; | 75 }; | 
| 75 | 76 | 
| 76 // Returns the top view in |view|'s hierarchy. | 77 // Returns the top view in |view|'s hierarchy. | 
| 77 const views::View* GetHierarchyRoot(const views::View* view) { | 78 const views::View* GetHierarchyRoot(const views::View* view) { | 
| 78   const views::View* root = view; | 79   const views::View* root = view; | 
| 79   while (root && root->parent()) | 80   while (root && root->parent()) | 
| 80     root = root->parent(); | 81     root = root->parent(); | 
| 81   return root; | 82   return root; | 
| 82 } | 83 } | 
| 83 | 84 | 
|  | 85 // Returns a ratio of the area of intersection compared to the smaller of | 
|  | 86 // the two rectangles. | 
|  | 87 double OverlapProportion(const gfx::Rect& rect_one, | 
|  | 88                           const gfx::Rect& rect_two) { | 
|  | 89   gfx::Rect intersection = rect_one.Intersect(rect_two); | 
|  | 90   double rect_one_area = rect_one.size().GetArea();; | 
|  | 91   double rect_two_area = rect_two.size().GetArea();; | 
|  | 92   double intersection_area = intersection.size().GetArea();; | 
|  | 93   if ((rect_one_area <= 0) || (rect_two_area <= 0)) | 
|  | 94     return 0.0; | 
|  | 95   if (rect_one_area > rect_two_area) | 
|  | 96     return intersection_area / rect_two_area; | 
|  | 97   else | 
|  | 98     return intersection_area / rect_one_area; | 
|  | 99 } | 
|  | 100 | 
|  | 101 // The positive distance from |pos| to the nearest endpoint of the interval | 
|  | 102 // [start, end] is returned if |pos| lies within the interval, otherwise | 
|  | 103 // 0 is returned. | 
|  | 104 int DistanceToInterval(int pos, int start, int end) { | 
|  | 105   if (pos < start) | 
|  | 106     return start - pos; | 
|  | 107   if (pos > end) | 
|  | 108     return pos - end; | 
|  | 109   return 0; | 
|  | 110 } | 
|  | 111 | 
|  | 112 // Returns the square of the distance from |point| to the center line of | 
|  | 113 // |target_rect|. The center line of a rectangle is obtained by repeatedly | 
|  | 114 // stripping away 1px borders around the rectangle until a line remains. | 
|  | 115 int DistanceSquaredFromCenterLineToPoint(const gfx::Point& point, | 
|  | 116                                          const gfx::Rect& target_rect) { | 
|  | 117   gfx::Point center_point = target_rect.CenterPoint(); | 
|  | 118   int dx = center_point.x() - point.x(); | 
|  | 119   int dy = center_point.y() - point.y(); | 
|  | 120 | 
|  | 121   if (target_rect.width() > target_rect.height()) { | 
|  | 122     dx = DistanceToInterval(point.x(), | 
|  | 123                             target_rect.x() + (target_rect.height() / 2), | 
|  | 124                             target_rect.right() - (target_rect.height() / 2)); | 
|  | 125   } else { | 
|  | 126     dy = DistanceToInterval(point.y(), | 
|  | 127                             target_rect.y() + (target_rect.width() / 2), | 
|  | 128                             target_rect.bottom() - (target_rect.width() / 2)); | 
|  | 129   } | 
|  | 130   return (dx * dx) + (dy * dy); | 
|  | 131 } | 
|  | 132 | 
| 84 }  // namespace | 133 }  // namespace | 
| 85 | 134 | 
| 86 namespace views { | 135 namespace views { | 
| 87 | 136 | 
| 88 // static | 137 // static | 
| 89 ViewsDelegate* ViewsDelegate::views_delegate = NULL; | 138 ViewsDelegate* ViewsDelegate::views_delegate = NULL; | 
| 90 | 139 | 
| 91 // static | 140 // static | 
| 92 const char View::kViewClassName[] = "views/View"; | 141 const char View::kViewClassName[] = "views/View"; | 
| 93 | 142 | 
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 620     target->ConvertPointFromAncestor(root, point); | 669     target->ConvertPointFromAncestor(root, point); | 
| 621 | 670 | 
| 622   // API defines NULL |source| as returning the point in screen coordinates. | 671   // API defines NULL |source| as returning the point in screen coordinates. | 
| 623   if (!source) { | 672   if (!source) { | 
| 624     *point = point->Subtract( | 673     *point = point->Subtract( | 
| 625         root->GetWidget()->GetClientAreaBoundsInScreen().origin()); | 674         root->GetWidget()->GetClientAreaBoundsInScreen().origin()); | 
| 626   } | 675   } | 
| 627 } | 676 } | 
| 628 | 677 | 
| 629 // static | 678 // static | 
|  | 679 void View::ConvertRectToTarget(const View* source, | 
|  | 680                                const View* target, | 
|  | 681                                gfx::Rect* rect) { | 
|  | 682   gfx::Point rect_location(rect->x(), rect->y()); | 
|  | 683   View::ConvertPointToTarget(source, target, &rect_location); | 
|  | 684   rect->set_origin(rect_location); | 
|  | 685 } | 
|  | 686 | 
|  | 687 // static | 
| 630 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { | 688 void View::ConvertPointToWidget(const View* src, gfx::Point* p) { | 
| 631   DCHECK(src); | 689   DCHECK(src); | 
| 632   DCHECK(p); | 690   DCHECK(p); | 
| 633 | 691 | 
| 634   src->ConvertPointForAncestor(NULL, p); | 692   src->ConvertPointForAncestor(NULL, p); | 
| 635 } | 693 } | 
| 636 | 694 | 
| 637 // static | 695 // static | 
| 638 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { | 696 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) { | 
| 639   DCHECK(dest); | 697   DCHECK(dest); | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 742 } | 800 } | 
| 743 | 801 | 
| 744 // static | 802 // static | 
| 745 bool View::get_use_acceleration_when_possible() { | 803 bool View::get_use_acceleration_when_possible() { | 
| 746   return use_acceleration_when_possible; | 804   return use_acceleration_when_possible; | 
| 747 } | 805 } | 
| 748 | 806 | 
| 749 // Input ----------------------------------------------------------------------- | 807 // Input ----------------------------------------------------------------------- | 
| 750 | 808 | 
| 751 View* View::GetEventHandlerForPoint(const gfx::Point& point) { | 809 View* View::GetEventHandlerForPoint(const gfx::Point& point) { | 
| 752   // Walk the child Views recursively looking for the View that most | 810   return GetEventHandler(gfx::Rect(point, gfx::Size(1, 1)), | 
| 753   // tightly encloses the specified point. | 811       EVENT_HANDLER_TYPE_MOUSE); | 
|  | 812 } | 
|  | 813 | 
|  | 814 View* View::GetEventHandlerForRect(const gfx::Rect& rect) { | 
|  | 815   // TODO: Consider expanding small (single point) rectangles. | 
|  | 816   return GetEventHandler(rect, EVENT_HANDLER_TYPE_TOUCH); | 
|  | 817 } | 
|  | 818 | 
|  | 819 View* View::GetEventHandler(const gfx::Rect& rect, EventType type) { | 
|  | 820   View* closest_view = NULL; | 
|  | 821   View* closest_untouched_view = NULL; | 
|  | 822   double max_proportion = 0; | 
|  | 823   int closest_distance = INT_MAX; | 
| 754   for (int i = child_count() - 1; i >= 0; --i) { | 824   for (int i = child_count() - 1; i >= 0; --i) { | 
| 755     View* child = child_at(i); | 825     View* child = child_at(i); | 
| 756     if (!child->visible()) | 826     if (!child->visible()) | 
| 757       continue; | 827       continue; | 
| 758 | 828 | 
| 759     gfx::Point point_in_child_coords(point); | 829     gfx::Rect child_rect(child->bounds()); | 
| 760     ConvertPointToTarget(this, child, &point_in_child_coords); | 830 | 
| 761     if (child->HitTestPoint(point_in_child_coords)) | 831     if (!child_rect.Intersects(rect)) | 
| 762       return child->GetEventHandlerForPoint(point_in_child_coords); | 832       continue; | 
|  | 833 | 
|  | 834     gfx::Rect rect_in_child_coords(rect); | 
|  | 835     View::ConvertRectToTarget(this, child, &rect_in_child_coords); | 
|  | 836     View* cur_view = child->GetEventHandler(rect_in_child_coords, type); | 
|  | 837     if (!cur_view) | 
|  | 838       continue; | 
|  | 839 | 
|  | 840     if (type == EVENT_HANDLER_TYPE_MOUSE) | 
|  | 841       return cur_view; | 
|  | 842 | 
|  | 843     gfx::Point touch_center(rect.CenterPoint()); | 
|  | 844     gfx::Rect cur_rect(cur_view->GetLocalBounds()); | 
|  | 845     View::ConvertRectToTarget(cur_view, this, &cur_rect); | 
|  | 846     int distance = DistanceSquaredFromCenterLineToPoint(touch_center, | 
|  | 847                                                         cur_rect); | 
|  | 848     double proportion = OverlapProportion(cur_rect, rect); | 
|  | 849     if (proportion == 0) { | 
|  | 850       if (distance < closest_distance) { | 
|  | 851         closest_untouched_view = cur_view; | 
|  | 852         closest_distance = distance; | 
|  | 853       } | 
|  | 854     } else if (!closest_view || proportion > max_proportion) { | 
|  | 855       closest_view = cur_view; | 
|  | 856       max_proportion = proportion; | 
|  | 857     } | 
| 763   } | 858   } | 
| 764   return this; | 859 | 
|  | 860   if (closest_view) | 
|  | 861     return closest_view; | 
|  | 862 | 
|  | 863   gfx::Rect view_rect(GetLocalBounds()); | 
|  | 864   double proportion = OverlapProportion(view_rect, rect); | 
|  | 865   if (proportion > max_proportion) | 
|  | 866     return this; | 
|  | 867   if (closest_untouched_view) | 
|  | 868     return closest_untouched_view; | 
|  | 869   return type == EVENT_HANDLER_TYPE_MOUSE ? this : NULL; | 
| 765 } | 870 } | 
| 766 | 871 | 
| 767 gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) { | 872 gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) { | 
| 768 #if defined(OS_WIN) | 873 #if defined(OS_WIN) | 
| 769 #if defined(USE_AURA) | 874 #if defined(USE_AURA) | 
| 770   static ui::Cursor arrow; | 875   static ui::Cursor arrow; | 
| 771   if (!arrow.platform()) | 876   if (!arrow.platform()) | 
| 772     arrow.SetPlatformCursor(LoadCursor(NULL, IDC_ARROW)); | 877     arrow.SetPlatformCursor(LoadCursor(NULL, IDC_ARROW)); | 
| 773   return arrow; | 878   return arrow; | 
| 774 #else | 879 #else | 
| (...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2120   gfx::Point widget_location(event.location()); | 2225   gfx::Point widget_location(event.location()); | 
| 2121   ConvertPointToWidget(this, &widget_location); | 2226   ConvertPointToWidget(this, &widget_location); | 
| 2122   GetWidget()->RunShellDrag(this, data, widget_location, drag_operations); | 2227   GetWidget()->RunShellDrag(this, data, widget_location, drag_operations); | 
| 2123   return true; | 2228   return true; | 
| 2124 #else | 2229 #else | 
| 2125   return false; | 2230   return false; | 
| 2126 #endif  // !defined(OS_MACOSX) | 2231 #endif  // !defined(OS_MACOSX) | 
| 2127 } | 2232 } | 
| 2128 | 2233 | 
| 2129 }  // namespace views | 2234 }  // namespace views | 
| OLD | NEW | 
|---|