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 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 | 838 |
839 if (layer()) { | 839 if (layer()) { |
840 layer()->SchedulePaint(rect); | 840 layer()->SchedulePaint(rect); |
841 } else if (parent_) { | 841 } else if (parent_) { |
842 // Translate the requested paint rect to the parent's coordinate system | 842 // Translate the requested paint rect to the parent's coordinate system |
843 // then pass this notification up to the parent. | 843 // then pass this notification up to the parent. |
844 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); | 844 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); |
845 } | 845 } |
846 } | 846 } |
847 | 847 |
848 void View::Paint(const ui::PaintContext& parent_context) { | 848 void View::Paint(const PaintInfo& parent_paint_info) { |
849 if (!ShouldPaint()) | 849 if (!ShouldPaint()) |
850 return; | 850 return; |
851 | 851 |
852 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 852 const gfx::Rect& parent_bounds = !parent() |
| 853 ? GetPaintRecordingBounds() |
| 854 : parent()->GetPaintRecordingBounds(); |
853 | 855 |
| 856 PaintInfo paint_info = PaintInfo::CreateChildPaintInfo( |
| 857 parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(), |
| 858 GetPaintScaleType()); |
| 859 |
| 860 const ui::PaintContext& context = paint_info.context(); |
854 bool is_invalidated = true; | 861 bool is_invalidated = true; |
855 if (context.CanCheckInvalid()) { | 862 if (paint_info.context().CanCheckInvalid()) { |
856 #if DCHECK_IS_ON() | 863 #if DCHECK_IS_ON() |
857 gfx::Vector2d offset; | 864 if (!context.is_pixel_canvas()) { |
858 context.Visited(this); | 865 gfx::Vector2d offset; |
859 View* view = this; | 866 context.Visited(this); |
860 while (view->parent() && !view->layer()) { | 867 View* view = this; |
861 DCHECK(view->GetTransform().IsIdentity()); | 868 while (view->parent() && !view->layer()) { |
862 offset += view->GetMirroredPosition().OffsetFromOrigin(); | 869 DCHECK(view->GetTransform().IsIdentity()); |
863 view = view->parent(); | 870 offset += view->GetMirroredPosition().OffsetFromOrigin(); |
| 871 view = view->parent(); |
| 872 } |
| 873 // The offset in the PaintContext should be the offset up to the paint |
| 874 // root, which we compute and verify here. |
| 875 DCHECK_EQ(context.PaintOffset().x(), offset.x()); |
| 876 DCHECK_EQ(context.PaintOffset().y(), offset.y()); |
| 877 // The above loop will stop when |view| is the paint root, which should be |
| 878 // the root of the current paint walk, as verified by storing the root in |
| 879 // the PaintContext. |
| 880 DCHECK_EQ(context.RootVisited(), view); |
864 } | 881 } |
865 // The offset in the PaintContext should be the offset up to the paint root, | |
866 // which we compute and verify here. | |
867 DCHECK_EQ(context.PaintOffset().x(), offset.x()); | |
868 DCHECK_EQ(context.PaintOffset().y(), offset.y()); | |
869 // The above loop will stop when |view| is the paint root, which should be | |
870 // the root of the current paint walk, as verified by storing the root in | |
871 // the PaintContext. | |
872 DCHECK_EQ(context.RootVisited(), view); | |
873 #endif | 882 #endif |
874 | 883 |
875 // If the View wasn't invalidated, don't waste time painting it, the output | 884 // If the View wasn't invalidated, don't waste time painting it, the output |
876 // would be culled. | 885 // would be culled. |
877 is_invalidated = context.IsRectInvalid(GetLocalBounds()); | 886 is_invalidated = |
| 887 context.IsRectInvalid(gfx::Rect(paint_info.paint_recording_size())); |
878 } | 888 } |
879 | 889 |
880 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); | 890 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
881 | 891 |
882 // If the view is backed by a layer, it should paint with itself as the origin | 892 // If the view is backed by a layer, it should paint with itself as the origin |
883 // rather than relative to its parent. | 893 // rather than relative to its parent. |
884 // TODO(danakj): Rework clip and transform recorder usage here to use | 894 // TODO(danakj): Rework clip and transform recorder usage here to use |
885 // std::optional once we can do so. | 895 // std::optional once we can do so. |
886 ui::ClipRecorder clip_recorder(parent_context); | 896 ui::ClipRecorder clip_recorder(parent_paint_info.context()); |
887 if (!layer()) { | 897 if (!layer()) { |
888 // Set the clip rect to the bounds of this View, or |clip_path_| if it's | 898 // Set the clip rect to the bounds of this View, or |clip_path_| if it's |
889 // been set. Note that the X (or left) position we pass to ClipRect takes | 899 // been set. Note that the X (or left) position we pass to ClipRect takes |
890 // into consideration whether or not the View uses a right-to-left layout so | 900 // into consideration whether or not the View uses a right-to-left layout so |
891 // that we paint the View in its mirrored position if need be. | 901 // that we paint the View in its mirrored position if need be. |
892 if (clip_path_.isEmpty()) { | 902 if (clip_path_.isEmpty()) { |
893 clip_recorder.ClipRect(GetMirroredBounds()); | 903 clip_recorder.ClipRect(gfx::Rect(paint_info.paint_recording_size()) + |
| 904 paint_info.offset_from_parent()); |
894 } else { | 905 } else { |
895 gfx::Path clip_path_in_parent = clip_path_; | 906 gfx::Path clip_path_in_parent = clip_path_; |
896 clip_path_in_parent.offset(GetMirroredX(), y()); | 907 |
| 908 // Transform |clip_path_| from local space to parent recording space. |
| 909 gfx::Transform to_parent_recording_space; |
| 910 |
| 911 to_parent_recording_space.Scale( |
| 912 SkFloatToScalar(paint_info.paint_recording_scale_x()), |
| 913 SkFloatToScalar(paint_info.paint_recording_scale_y())); |
| 914 to_parent_recording_space.Translate(paint_info.offset_from_parent()); |
| 915 |
| 916 clip_path_in_parent.transform(to_parent_recording_space.matrix()); |
897 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); | 917 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
898 } | 918 } |
899 } | 919 } |
900 | 920 |
901 ui::TransformRecorder transform_recorder(context); | 921 ui::TransformRecorder transform_recorder(context); |
902 SetupTransformRecorderForPainting(&transform_recorder); | 922 SetupTransformRecorderForPainting(paint_info.offset_from_parent(), |
| 923 &transform_recorder); |
903 | 924 |
904 // Note that the cache is not aware of the offset of the view | 925 // Note that the cache is not aware of the offset of the view |
905 // relative to the parent since painting is always done relative to | 926 // relative to the parent since painting is always done relative to |
906 // the top left of the individual view. | 927 // the top left of the individual view. |
907 if (is_invalidated || !paint_cache_.UseCache(context, size())) { | 928 if (is_invalidated || |
908 ui::PaintRecorder recorder(context, size(), &paint_cache_); | 929 !paint_cache_.UseCache(context, paint_info.paint_recording_size())) { |
| 930 ui::PaintRecorder recorder(context, paint_info.paint_recording_size(), |
| 931 paint_info.paint_recording_scale_x(), |
| 932 paint_info.paint_recording_scale_y(), |
| 933 &paint_cache_); |
909 gfx::Canvas* canvas = recorder.canvas(); | 934 gfx::Canvas* canvas = recorder.canvas(); |
910 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), | 935 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
911 flip_canvas_on_paint_for_rtl_ui_); | 936 flip_canvas_on_paint_for_rtl_ui_); |
912 | 937 |
913 // Delegate painting the contents of the View to the virtual OnPaint method. | 938 // Delegate painting the contents of the View to the virtual OnPaint method. |
914 OnPaint(canvas); | 939 OnPaint(canvas); |
915 } | 940 } |
916 | 941 |
917 // View::Paint() recursion over the subtree. | 942 // View::Paint() recursion over the subtree. |
918 PaintChildren(context); | 943 PaintChildren(paint_info); |
919 } | 944 } |
920 | 945 |
921 void View::SetBackground(std::unique_ptr<Background> b) { | 946 void View::SetBackground(std::unique_ptr<Background> b) { |
922 background_ = std::move(b); | 947 background_ = std::move(b); |
923 } | 948 } |
924 | 949 |
925 void View::SetBorder(std::unique_ptr<Border> b) { | 950 void View::SetBorder(std::unique_ptr<Border> b) { |
926 border_ = std::move(b); | 951 border_ = std::move(b); |
927 } | 952 } |
928 | 953 |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 RegisterPendingAccelerators(); | 1561 RegisterPendingAccelerators(); |
1537 } | 1562 } |
1538 } | 1563 } |
1539 | 1564 |
1540 void View::AddedToWidget() {} | 1565 void View::AddedToWidget() {} |
1541 | 1566 |
1542 void View::RemovedFromWidget() {} | 1567 void View::RemovedFromWidget() {} |
1543 | 1568 |
1544 // Painting -------------------------------------------------------------------- | 1569 // Painting -------------------------------------------------------------------- |
1545 | 1570 |
1546 void View::PaintChildren(const ui::PaintContext& context) { | 1571 void View::PaintChildren(const PaintInfo& paint_info) { |
1547 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); | 1572 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); |
1548 RecursivePaintHelper(&View::Paint, context); | 1573 RecursivePaintHelper(&View::Paint, paint_info); |
1549 } | 1574 } |
1550 | 1575 |
1551 void View::OnPaint(gfx::Canvas* canvas) { | 1576 void View::OnPaint(gfx::Canvas* canvas) { |
1552 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); | 1577 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); |
1553 OnPaintBackground(canvas); | 1578 OnPaintBackground(canvas); |
1554 OnPaintBorder(canvas); | 1579 OnPaintBorder(canvas); |
1555 } | 1580 } |
1556 | 1581 |
1557 void View::OnPaintBackground(gfx::Canvas* canvas) { | 1582 void View::OnPaintBackground(gfx::Canvas* canvas) { |
1558 if (background_) { | 1583 if (background_) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 // and for different display density. | 1835 // and for different display density. |
1811 return kDefaultHorizontalDragThreshold; | 1836 return kDefaultHorizontalDragThreshold; |
1812 } | 1837 } |
1813 | 1838 |
1814 int View::GetVerticalDragThreshold() { | 1839 int View::GetVerticalDragThreshold() { |
1815 // TODO(jennyz): This value may need to be adjusted for different platforms | 1840 // TODO(jennyz): This value may need to be adjusted for different platforms |
1816 // and for different display density. | 1841 // and for different display density. |
1817 return kDefaultVerticalDragThreshold; | 1842 return kDefaultVerticalDragThreshold; |
1818 } | 1843 } |
1819 | 1844 |
| 1845 PaintInfo::ScaleType View::GetPaintScaleType() const { |
| 1846 return PaintInfo::ScaleType::kScaleToFit; |
| 1847 } |
| 1848 |
1820 // Debugging ------------------------------------------------------------------- | 1849 // Debugging ------------------------------------------------------------------- |
1821 | 1850 |
1822 #if !defined(NDEBUG) | 1851 #if !defined(NDEBUG) |
1823 | 1852 |
1824 std::string View::PrintViewGraph(bool first) { | 1853 std::string View::PrintViewGraph(bool first) { |
1825 return DoPrintViewGraph(first, this); | 1854 return DoPrintViewGraph(first, this); |
1826 } | 1855 } |
1827 | 1856 |
1828 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { | 1857 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { |
1829 // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19. | 1858 // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19. |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 // Translate the requested paint rect to the parent's coordinate system | 1991 // Translate the requested paint rect to the parent's coordinate system |
1963 // then pass this notification up to the parent. | 1992 // then pass this notification up to the parent. |
1964 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); | 1993 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); |
1965 } | 1994 } |
1966 } | 1995 } |
1967 | 1996 |
1968 bool View::ShouldPaint() const { | 1997 bool View::ShouldPaint() const { |
1969 return visible_ && !size().IsEmpty(); | 1998 return visible_ && !size().IsEmpty(); |
1970 } | 1999 } |
1971 | 2000 |
1972 gfx::Vector2d View::GetPaintContextOffset() const { | 2001 gfx::Rect View::GetPaintRecordingBounds() const { |
1973 // If the View has a layer() then it is a paint root. Otherwise, we need to | 2002 // If the View has a layer() then it is a paint root and no offset information |
1974 // add the offset from the parent into the total offset from the paint root. | 2003 // is needed. Otherwise, we need bounds that includes an offset from the |
| 2004 // parent to add to the total offset from the paint root. |
1975 DCHECK(layer() || parent() || origin() == gfx::Point()); | 2005 DCHECK(layer() || parent() || origin() == gfx::Point()); |
1976 return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); | 2006 return layer() ? GetLocalBounds() : GetMirroredBounds(); |
1977 } | 2007 } |
1978 | 2008 |
1979 void View::SetupTransformRecorderForPainting( | 2009 void View::SetupTransformRecorderForPainting( |
| 2010 const gfx::Vector2d& offset_from_parent, |
1980 ui::TransformRecorder* recorder) const { | 2011 ui::TransformRecorder* recorder) const { |
1981 // If the view is backed by a layer, it should paint with itself as the origin | 2012 // If the view is backed by a layer, it should paint with itself as the origin |
1982 // rather than relative to its parent. | 2013 // rather than relative to its parent. |
1983 if (layer()) | 2014 if (layer()) |
1984 return; | 2015 return; |
1985 | 2016 |
1986 // Translate the graphics such that 0,0 corresponds to where this View is | 2017 // Translate the graphics such that 0,0 corresponds to where this View is |
1987 // located relative to its parent. | 2018 // located relative to its parent. |
1988 gfx::Transform transform_from_parent; | 2019 gfx::Transform transform_from_parent; |
1989 gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); | |
1990 transform_from_parent.Translate(offset_from_parent.x(), | 2020 transform_from_parent.Translate(offset_from_parent.x(), |
1991 offset_from_parent.y()); | 2021 offset_from_parent.y()); |
1992 transform_from_parent.PreconcatTransform(GetTransform()); | |
1993 recorder->Transform(transform_from_parent); | 2022 recorder->Transform(transform_from_parent); |
1994 } | 2023 } |
1995 | 2024 |
1996 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), | 2025 void View::RecursivePaintHelper(void (View::*func)(const PaintInfo&), |
1997 const ui::PaintContext& context) { | 2026 const PaintInfo& info) { |
1998 View::Views children = GetChildrenInZOrder(); | 2027 View::Views children = GetChildrenInZOrder(); |
1999 DCHECK_EQ(child_count(), static_cast<int>(children.size())); | 2028 DCHECK_EQ(child_count(), static_cast<int>(children.size())); |
2000 for (auto* child : children) { | 2029 for (auto* child : children) { |
2001 if (!child->layer()) | 2030 if (!child->layer()) |
2002 (child->*func)(context); | 2031 (child->*func)(info); |
2003 } | 2032 } |
2004 } | 2033 } |
2005 | 2034 |
2006 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { | 2035 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { |
2007 Paint(parent_context); | 2036 PaintInfo paint_info = PaintInfo::CreateRootPaintInfo( |
| 2037 parent_context, layer() ? layer()->size() : size()); |
| 2038 Paint(paint_info); |
2008 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 2039 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
2009 switches::kDrawViewBoundsRects)) | 2040 switches::kDrawViewBoundsRects)) |
2010 PaintDebugRects(parent_context); | 2041 PaintDebugRects(paint_info); |
2011 } | 2042 } |
2012 | 2043 |
2013 void View::PaintDebugRects(const ui::PaintContext& parent_context) { | 2044 void View::PaintDebugRects(const PaintInfo& parent_paint_info) { |
2014 if (!ShouldPaint()) | 2045 if (!ShouldPaint()) |
2015 return; | 2046 return; |
2016 | 2047 |
2017 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 2048 const gfx::Rect& parent_bounds = (layer() || !parent()) |
| 2049 ? GetPaintRecordingBounds() |
| 2050 : parent()->GetPaintRecordingBounds(); |
| 2051 PaintInfo paint_info = PaintInfo::CreateChildPaintInfo( |
| 2052 parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(), |
| 2053 GetPaintScaleType()); |
| 2054 |
| 2055 const ui::PaintContext& context = paint_info.context(); |
| 2056 |
2018 ui::TransformRecorder transform_recorder(context); | 2057 ui::TransformRecorder transform_recorder(context); |
2019 SetupTransformRecorderForPainting(&transform_recorder); | 2058 SetupTransformRecorderForPainting(paint_info.offset_from_parent(), |
| 2059 &transform_recorder); |
2020 | 2060 |
2021 RecursivePaintHelper(&View::PaintDebugRects, context); | 2061 RecursivePaintHelper(&View::PaintDebugRects, paint_info); |
2022 | 2062 |
2023 // Draw outline rects for debugging. | 2063 // Draw outline rects for debugging. |
2024 ui::PaintRecorder recorder(context, size()); | 2064 ui::PaintRecorder recorder(context, paint_info.paint_recording_size(), |
| 2065 paint_info.paint_recording_scale_x(), |
| 2066 paint_info.paint_recording_scale_y(), |
| 2067 &paint_cache_); |
2025 gfx::Canvas* canvas = recorder.canvas(); | 2068 gfx::Canvas* canvas = recorder.canvas(); |
2026 const float scale = canvas->UndoDeviceScaleFactor(); | 2069 const float scale = canvas->UndoDeviceScaleFactor(); |
2027 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); | 2070 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |
2028 outline_rect.Inset(0.5f, 0.5f); | 2071 outline_rect.Inset(0.5f, 0.5f); |
2029 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); | 2072 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); |
2030 canvas->DrawRect(outline_rect, color); | 2073 canvas->DrawRect(outline_rect, color); |
2031 } | 2074 } |
2032 | 2075 |
2033 // Tree operations ------------------------------------------------------------- | 2076 // Tree operations ------------------------------------------------------------- |
2034 | 2077 |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2669 // Message the RootView to do the drag and drop. That way if we're removed | 2712 // Message the RootView to do the drag and drop. That way if we're removed |
2670 // the RootView can detect it and avoid calling us back. | 2713 // the RootView can detect it and avoid calling us back. |
2671 gfx::Point widget_location(event.location()); | 2714 gfx::Point widget_location(event.location()); |
2672 ConvertPointToWidget(this, &widget_location); | 2715 ConvertPointToWidget(this, &widget_location); |
2673 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2716 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
2674 // WARNING: we may have been deleted. | 2717 // WARNING: we may have been deleted. |
2675 return true; | 2718 return true; |
2676 } | 2719 } |
2677 | 2720 |
2678 } // namespace views | 2721 } // namespace views |
OLD | NEW |