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 15 matching lines...) Expand all Loading... | |
| 26 #include "ui/accessibility/ax_action_data.h" | 26 #include "ui/accessibility/ax_action_data.h" |
| 27 #include "ui/accessibility/ax_enums.h" | 27 #include "ui/accessibility/ax_enums.h" |
| 28 #include "ui/base/cursor/cursor.h" | 28 #include "ui/base/cursor/cursor.h" |
| 29 #include "ui/base/dragdrop/drag_drop_types.h" | 29 #include "ui/base/dragdrop/drag_drop_types.h" |
| 30 #include "ui/base/ime/input_method.h" | 30 #include "ui/base/ime/input_method.h" |
| 31 #include "ui/compositor/clip_recorder.h" | 31 #include "ui/compositor/clip_recorder.h" |
| 32 #include "ui/compositor/compositor.h" | 32 #include "ui/compositor/compositor.h" |
| 33 #include "ui/compositor/dip_util.h" | 33 #include "ui/compositor/dip_util.h" |
| 34 #include "ui/compositor/layer.h" | 34 #include "ui/compositor/layer.h" |
| 35 #include "ui/compositor/layer_animator.h" | 35 #include "ui/compositor/layer_animator.h" |
| 36 #include "ui/compositor/paint_context.h" | |
| 37 #include "ui/compositor/paint_recorder.h" | 36 #include "ui/compositor/paint_recorder.h" |
| 38 #include "ui/compositor/transform_recorder.h" | 37 #include "ui/compositor/transform_recorder.h" |
| 39 #include "ui/display/screen.h" | 38 #include "ui/display/screen.h" |
| 40 #include "ui/events/base_event_utils.h" | 39 #include "ui/events/base_event_utils.h" |
| 41 #include "ui/events/event_target_iterator.h" | 40 #include "ui/events/event_target_iterator.h" |
| 42 #include "ui/gfx/canvas.h" | 41 #include "ui/gfx/canvas.h" |
| 43 #include "ui/gfx/geometry/point3_f.h" | 42 #include "ui/gfx/geometry/point3_f.h" |
| 44 #include "ui/gfx/geometry/point_conversions.h" | 43 #include "ui/gfx/geometry/point_conversions.h" |
| 45 #include "ui/gfx/interpolated_transform.h" | 44 #include "ui/gfx/interpolated_transform.h" |
| 46 #include "ui/gfx/path.h" | 45 #include "ui/gfx/path.h" |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 } else if (parent_) { | 840 } else if (parent_) { |
| 842 // Translate the requested paint rect to the parent's coordinate system | 841 // Translate the requested paint rect to the parent's coordinate system |
| 843 // then pass this notification up to the parent. | 842 // then pass this notification up to the parent. |
| 844 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); | 843 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); |
| 845 } | 844 } |
| 846 } | 845 } |
| 847 | 846 |
| 848 void View::Paint(const ui::PaintContext& parent_context) { | 847 void View::Paint(const ui::PaintContext& parent_context) { |
| 849 if (!ShouldPaint()) | 848 if (!ShouldPaint()) |
| 850 return; | 849 return; |
| 850 const gfx::Rect& parent_bounds = | |
| 851 !parent() ? GetPaintContextBounds() : parent()->GetPaintContextBounds(); | |
| 852 ui::PaintContext context(parent_context, GetPaintContextBounds(), | |
| 853 parent_bounds, GetContextScaleType()); | |
| 851 | 854 |
| 852 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 855 gfx::Vector2d offset_from_parent = |
| 856 context.paint_recording_bounds().OffsetFromOrigin() - | |
| 857 parent_context.paint_recording_bounds().OffsetFromOrigin(); | |
| 853 | 858 |
| 854 bool is_invalidated = true; | 859 bool is_invalidated = true; |
| 855 if (context.CanCheckInvalid()) { | 860 if (context.CanCheckRepaint()) { |
| 856 #if DCHECK_IS_ON() | 861 #if DCHECK_IS_ON() |
| 857 gfx::Vector2d offset; | 862 if (!context.IsPixelCanvas()) { |
| 858 context.Visited(this); | 863 gfx::Vector2d offset; |
| 859 View* view = this; | 864 context.Visited(this); |
| 860 while (view->parent() && !view->layer()) { | 865 View* view = this; |
| 861 DCHECK(view->GetTransform().IsIdentity()); | 866 while (view->parent() && !view->layer()) { |
| 862 offset += view->GetMirroredPosition().OffsetFromOrigin(); | 867 DCHECK(view->GetTransform().IsIdentity()); |
| 863 view = view->parent(); | 868 offset += view->GetMirroredPosition().OffsetFromOrigin(); |
| 869 view = view->parent(); | |
| 870 } | |
| 871 // The offset in the PaintContext should be the offset up to the paint | |
| 872 // root, which we compute and verify here. | |
| 873 DCHECK_EQ(context.PaintOffset().x(), offset.x()); | |
| 874 DCHECK_EQ(context.PaintOffset().y(), offset.y()); | |
| 875 // The above loop will stop when |view| is the paint root, which should be | |
| 876 // the root of the current paint walk, as verified by storing the root in | |
| 877 // the PaintContext. | |
| 878 DCHECK_EQ(context.RootVisited(), view); | |
| 864 } | 879 } |
| 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 | 880 #endif |
| 874 | 881 |
| 875 // If the View wasn't invalidated, don't waste time painting it, the output | 882 // If the View wasn't invalidated, don't waste time painting it, the output |
| 876 // would be culled. | 883 // would be culled. |
| 877 is_invalidated = context.IsRectInvalid(GetLocalBounds()); | 884 is_invalidated = context.ShouldRepaint(); |
| 878 } | 885 } |
| 879 | 886 |
| 880 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); | 887 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
| 881 | 888 |
| 882 // If the view is backed by a layer, it should paint with itself as the origin | 889 // If the view is backed by a layer, it should paint with itself as the origin |
| 883 // rather than relative to its parent. | 890 // rather than relative to its parent. |
| 884 // TODO(danakj): Rework clip and transform recorder usage here to use | 891 // TODO(danakj): Rework clip and transform recorder usage here to use |
| 885 // std::optional once we can do so. | 892 // std::optional once we can do so. |
| 886 ui::ClipRecorder clip_recorder(parent_context); | 893 ui::ClipRecorder clip_recorder(parent_context); |
| 887 if (!layer()) { | 894 if (!layer()) { |
| 888 // Set the clip rect to the bounds of this View, or |clip_path_| if it's | 895 // 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 | 896 // 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 | 897 // 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. | 898 // that we paint the View in its mirrored position if need be. |
| 892 if (clip_path_.isEmpty()) { | 899 if (clip_path_.isEmpty()) { |
| 893 clip_recorder.ClipRect(GetMirroredBounds()); | 900 clip_recorder.ClipRect(gfx::Rect(context.paint_recording_size()) + |
| 901 offset_from_parent); | |
| 894 } else { | 902 } else { |
| 895 gfx::Path clip_path_in_parent = clip_path_; | 903 gfx::Path clip_path_in_parent = clip_path_; |
| 896 clip_path_in_parent.offset(GetMirroredX(), y()); | 904 clip_path_in_parent.transform( |
| 905 context.TransformToParentRecordingSpace(offset_from_parent).matrix()); | |
| 897 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); | 906 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
| 898 } | 907 } |
| 899 } | 908 } |
| 900 | 909 |
| 901 ui::TransformRecorder transform_recorder(context); | 910 ui::TransformRecorder transform_recorder(context); |
| 902 SetupTransformRecorderForPainting(&transform_recorder); | 911 SetupTransformRecorderForPainting(&transform_recorder, offset_from_parent); |
| 903 | 912 |
| 904 // Note that the cache is not aware of the offset of the view | 913 // 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 | 914 // relative to the parent since painting is always done relative to |
| 906 // the top left of the individual view. | 915 // the top left of the individual view. |
| 907 if (is_invalidated || !paint_cache_.UseCache(context, size())) { | 916 if (is_invalidated || |
| 908 ui::PaintRecorder recorder(context, size(), &paint_cache_); | 917 !paint_cache_.UseCache(context, context.paint_recording_size())) { |
| 918 ui::PaintRecorder recorder(context, context.paint_recording_size(), | |
| 919 &paint_cache_); | |
| 909 gfx::Canvas* canvas = recorder.canvas(); | 920 gfx::Canvas* canvas = recorder.canvas(); |
| 910 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), | 921 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
| 911 flip_canvas_on_paint_for_rtl_ui_); | 922 flip_canvas_on_paint_for_rtl_ui_); |
| 912 | 923 |
| 913 // Delegate painting the contents of the View to the virtual OnPaint method. | 924 // Delegate painting the contents of the View to the virtual OnPaint method. |
| 914 OnPaint(canvas); | 925 OnPaint(canvas); |
| 915 } | 926 } |
| 916 | 927 |
| 917 // View::Paint() recursion over the subtree. | 928 // View::Paint() recursion over the subtree. |
| 918 PaintChildren(context); | 929 PaintChildren(context); |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1810 // and for different display density. | 1821 // and for different display density. |
| 1811 return kDefaultHorizontalDragThreshold; | 1822 return kDefaultHorizontalDragThreshold; |
| 1812 } | 1823 } |
| 1813 | 1824 |
| 1814 int View::GetVerticalDragThreshold() { | 1825 int View::GetVerticalDragThreshold() { |
| 1815 // TODO(jennyz): This value may need to be adjusted for different platforms | 1826 // TODO(jennyz): This value may need to be adjusted for different platforms |
| 1816 // and for different display density. | 1827 // and for different display density. |
| 1817 return kDefaultVerticalDragThreshold; | 1828 return kDefaultVerticalDragThreshold; |
| 1818 } | 1829 } |
| 1819 | 1830 |
| 1831 ui::PaintContext::ScaleType View::GetContextScaleType() const { | |
| 1832 return ui::PaintContext::ScaleType::SCALE_TO_FIT; | |
| 1833 } | |
| 1834 | |
| 1820 // Debugging ------------------------------------------------------------------- | 1835 // Debugging ------------------------------------------------------------------- |
| 1821 | 1836 |
| 1822 #if !defined(NDEBUG) | 1837 #if !defined(NDEBUG) |
| 1823 | 1838 |
| 1824 std::string View::PrintViewGraph(bool first) { | 1839 std::string View::PrintViewGraph(bool first) { |
| 1825 return DoPrintViewGraph(first, this); | 1840 return DoPrintViewGraph(first, this); |
| 1826 } | 1841 } |
| 1827 | 1842 |
| 1828 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { | 1843 std::string View::DoPrintViewGraph(bool first, View* view_with_children) { |
| 1829 // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19. | 1844 // 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 | 1977 // Translate the requested paint rect to the parent's coordinate system |
| 1963 // then pass this notification up to the parent. | 1978 // then pass this notification up to the parent. |
| 1964 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); | 1979 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); |
| 1965 } | 1980 } |
| 1966 } | 1981 } |
| 1967 | 1982 |
| 1968 bool View::ShouldPaint() const { | 1983 bool View::ShouldPaint() const { |
| 1969 return visible_ && !size().IsEmpty(); | 1984 return visible_ && !size().IsEmpty(); |
| 1970 } | 1985 } |
| 1971 | 1986 |
| 1972 gfx::Vector2d View::GetPaintContextOffset() const { | 1987 gfx::Rect View::GetPaintContextBounds() const { |
| 1973 // If the View has a layer() then it is a paint root. Otherwise, we need to | 1988 // If the View has a layer() then it is a paint root. Otherwise, we need to |
|
vmpstr
2017/07/11 17:37:22
Can you update the comment?
malaykeshav
2017/07/12 00:55:36
Done
| |
| 1974 // add the offset from the parent into the total offset from the paint root. | 1989 // add the offset from the parent into the total offset from the paint root. |
| 1975 DCHECK(layer() || parent() || origin() == gfx::Point()); | 1990 DCHECK(layer() || parent() || origin() == gfx::Point()); |
| 1976 return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); | 1991 return layer() ? GetLocalBounds() : GetMirroredBounds(); |
| 1977 } | 1992 } |
| 1978 | 1993 |
| 1979 void View::SetupTransformRecorderForPainting( | 1994 void View::SetupTransformRecorderForPainting( |
| 1980 ui::TransformRecorder* recorder) const { | 1995 ui::TransformRecorder* recorder, |
| 1996 const gfx::Vector2d& offset_from_parent) const { | |
| 1981 // If the view is backed by a layer, it should paint with itself as the origin | 1997 // If the view is backed by a layer, it should paint with itself as the origin |
| 1982 // rather than relative to its parent. | 1998 // rather than relative to its parent. |
| 1983 if (layer()) | 1999 if (layer()) |
| 1984 return; | 2000 return; |
| 1985 | 2001 |
| 1986 // Translate the graphics such that 0,0 corresponds to where this View is | 2002 // Translate the graphics such that 0,0 corresponds to where this View is |
| 1987 // located relative to its parent. | 2003 // located relative to its parent. |
| 1988 gfx::Transform transform_from_parent; | 2004 gfx::Transform transform_from_parent; |
| 1989 gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); | |
| 1990 transform_from_parent.Translate(offset_from_parent.x(), | 2005 transform_from_parent.Translate(offset_from_parent.x(), |
| 1991 offset_from_parent.y()); | 2006 offset_from_parent.y()); |
| 1992 transform_from_parent.PreconcatTransform(GetTransform()); | |
| 1993 recorder->Transform(transform_from_parent); | 2007 recorder->Transform(transform_from_parent); |
| 1994 } | 2008 } |
| 1995 | 2009 |
| 1996 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), | 2010 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), |
| 1997 const ui::PaintContext& context) { | 2011 const ui::PaintContext& context) { |
| 1998 View::Views children = GetChildrenInZOrder(); | 2012 View::Views children = GetChildrenInZOrder(); |
| 1999 DCHECK_EQ(child_count(), static_cast<int>(children.size())); | 2013 DCHECK_EQ(child_count(), static_cast<int>(children.size())); |
| 2000 for (auto* child : children) { | 2014 for (auto* child : children) { |
| 2001 if (!child->layer()) | 2015 if (!child->layer()) |
| 2002 (child->*func)(context); | 2016 (child->*func)(context); |
| 2003 } | 2017 } |
| 2004 } | 2018 } |
| 2005 | 2019 |
| 2006 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { | 2020 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { |
| 2007 Paint(parent_context); | 2021 Paint(parent_context); |
| 2008 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 2022 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 2009 switches::kDrawViewBoundsRects)) | 2023 switches::kDrawViewBoundsRects)) |
| 2010 PaintDebugRects(parent_context); | 2024 PaintDebugRects(parent_context); |
| 2011 } | 2025 } |
| 2012 | 2026 |
| 2013 void View::PaintDebugRects(const ui::PaintContext& parent_context) { | 2027 void View::PaintDebugRects(const ui::PaintContext& parent_context) { |
| 2014 if (!ShouldPaint()) | 2028 if (!ShouldPaint()) |
| 2015 return; | 2029 return; |
| 2016 | 2030 |
| 2017 ui::PaintContext context(parent_context, GetPaintContextOffset()); | 2031 const gfx::Rect& parent_bounds = (layer() || !parent()) |
| 2032 ? GetPaintContextBounds() | |
| 2033 : parent()->GetPaintContextBounds(); | |
| 2034 ui::PaintContext context(parent_context, GetPaintContextBounds(), | |
| 2035 parent_bounds, GetContextScaleType()); | |
| 2036 gfx::Vector2d offset_from_parent = | |
| 2037 context.paint_recording_bounds().OffsetFromOrigin() - | |
| 2038 parent_context.paint_recording_bounds().OffsetFromOrigin(); | |
| 2039 | |
| 2018 ui::TransformRecorder transform_recorder(context); | 2040 ui::TransformRecorder transform_recorder(context); |
| 2019 SetupTransformRecorderForPainting(&transform_recorder); | 2041 SetupTransformRecorderForPainting(&transform_recorder, offset_from_parent); |
| 2020 | 2042 |
| 2021 RecursivePaintHelper(&View::PaintDebugRects, context); | 2043 RecursivePaintHelper(&View::PaintDebugRects, context); |
| 2022 | 2044 |
| 2023 // Draw outline rects for debugging. | 2045 // Draw outline rects for debugging. |
| 2024 ui::PaintRecorder recorder(context, size()); | 2046 ui::PaintRecorder recorder(context, context.paint_recording_size(), |
| 2047 &paint_cache_); | |
| 2025 gfx::Canvas* canvas = recorder.canvas(); | 2048 gfx::Canvas* canvas = recorder.canvas(); |
| 2026 const float scale = canvas->UndoDeviceScaleFactor(); | 2049 const float scale = canvas->UndoDeviceScaleFactor(); |
| 2027 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); | 2050 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |
| 2028 outline_rect.Inset(0.5f, 0.5f); | 2051 outline_rect.Inset(0.5f, 0.5f); |
| 2029 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); | 2052 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); |
| 2030 canvas->DrawRect(outline_rect, color); | 2053 canvas->DrawRect(outline_rect, color); |
| 2031 } | 2054 } |
| 2032 | 2055 |
| 2033 // Tree operations ------------------------------------------------------------- | 2056 // Tree operations ------------------------------------------------------------- |
| 2034 | 2057 |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2678 // Message the RootView to do the drag and drop. That way if we're removed | 2701 // Message the RootView to do the drag and drop. That way if we're removed |
| 2679 // the RootView can detect it and avoid calling us back. | 2702 // the RootView can detect it and avoid calling us back. |
| 2680 gfx::Point widget_location(event.location()); | 2703 gfx::Point widget_location(event.location()); |
| 2681 ConvertPointToWidget(this, &widget_location); | 2704 ConvertPointToWidget(this, &widget_location); |
| 2682 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2705 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
| 2683 // WARNING: we may have been deleted. | 2706 // WARNING: we may have been deleted. |
| 2684 return true; | 2707 return true; |
| 2685 } | 2708 } |
| 2686 | 2709 |
| 2687 } // namespace views | 2710 } // namespace views |
| OLD | NEW |