| 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> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/command_line.h" |
| 14 #include "base/containers/adapters.h" | 15 #include "base/containers/adapters.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "base/macros.h" | 17 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 18 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
| 19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 20 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 21 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/trace_event/trace_event.h" | 23 #include "base/trace_event/trace_event.h" |
| 23 #include "build/build_config.h" | 24 #include "build/build_config.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 47 #include "ui/native_theme/native_theme.h" | 48 #include "ui/native_theme/native_theme.h" |
| 48 #include "ui/views/accessibility/native_view_accessibility.h" | 49 #include "ui/views/accessibility/native_view_accessibility.h" |
| 49 #include "ui/views/background.h" | 50 #include "ui/views/background.h" |
| 50 #include "ui/views/border.h" | 51 #include "ui/views/border.h" |
| 51 #include "ui/views/context_menu_controller.h" | 52 #include "ui/views/context_menu_controller.h" |
| 52 #include "ui/views/drag_controller.h" | 53 #include "ui/views/drag_controller.h" |
| 53 #include "ui/views/focus/view_storage.h" | 54 #include "ui/views/focus/view_storage.h" |
| 54 #include "ui/views/layout/layout_manager.h" | 55 #include "ui/views/layout/layout_manager.h" |
| 55 #include "ui/views/view_observer.h" | 56 #include "ui/views/view_observer.h" |
| 56 #include "ui/views/views_delegate.h" | 57 #include "ui/views/views_delegate.h" |
| 58 #include "ui/views/views_switches.h" |
| 57 #include "ui/views/widget/native_widget_private.h" | 59 #include "ui/views/widget/native_widget_private.h" |
| 58 #include "ui/views/widget/root_view.h" | 60 #include "ui/views/widget/root_view.h" |
| 59 #include "ui/views/widget/tooltip_manager.h" | 61 #include "ui/views/widget/tooltip_manager.h" |
| 60 #include "ui/views/widget/widget.h" | 62 #include "ui/views/widget/widget.h" |
| 61 | 63 |
| 62 #if defined(OS_WIN) | 64 #if defined(OS_WIN) |
| 63 #include "base/win/scoped_gdi_object.h" | 65 #include "base/win/scoped_gdi_object.h" |
| 64 #include "ui/native_theme/native_theme_win.h" | 66 #include "ui/native_theme/native_theme_win.h" |
| 65 #endif | 67 #endif |
| 66 | 68 |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 if (layer()) { | 837 if (layer()) { |
| 836 layer()->SchedulePaint(rect); | 838 layer()->SchedulePaint(rect); |
| 837 } else if (parent_) { | 839 } else if (parent_) { |
| 838 // Translate the requested paint rect to the parent's coordinate system | 840 // Translate the requested paint rect to the parent's coordinate system |
| 839 // then pass this notification up to the parent. | 841 // then pass this notification up to the parent. |
| 840 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); | 842 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); |
| 841 } | 843 } |
| 842 } | 844 } |
| 843 | 845 |
| 844 void View::Paint(const ui::PaintContext& parent_context) { | 846 void View::Paint(const ui::PaintContext& parent_context) { |
| 845 if (!visible_) | 847 if (!ShouldPaint()) |
| 846 return; | |
| 847 if (size().IsEmpty()) | |
| 848 return; | 848 return; |
| 849 | 849 |
| 850 gfx::Vector2d offset_to_parent; | 850 ui::PaintContext context(parent_context, GetPaintContextOffset()); |
| 851 if (!layer()) { | |
| 852 // If the View has a layer() then it is a paint root. Otherwise, we need to | |
| 853 // add the offset from the parent into the total offset from the paint root. | |
| 854 DCHECK(parent() || origin() == gfx::Point()); | |
| 855 offset_to_parent = GetMirroredPosition().OffsetFromOrigin(); | |
| 856 } | |
| 857 ui::PaintContext context(parent_context, offset_to_parent); | |
| 858 | 851 |
| 859 bool is_invalidated = true; | 852 bool is_invalidated = true; |
| 860 if (context.CanCheckInvalid()) { | 853 if (context.CanCheckInvalid()) { |
| 861 #if DCHECK_IS_ON() | 854 #if DCHECK_IS_ON() |
| 862 gfx::Vector2d offset; | 855 gfx::Vector2d offset; |
| 863 context.Visited(this); | 856 context.Visited(this); |
| 864 View* view = this; | 857 View* view = this; |
| 865 while (view->parent() && !view->layer()) { | 858 while (view->parent() && !view->layer()) { |
| 866 DCHECK(view->GetTransform().IsIdentity()); | 859 DCHECK(view->GetTransform().IsIdentity()); |
| 867 offset += view->GetMirroredPosition().OffsetFromOrigin(); | 860 offset += view->GetMirroredPosition().OffsetFromOrigin(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 879 | 872 |
| 880 // If the View wasn't invalidated, don't waste time painting it, the output | 873 // If the View wasn't invalidated, don't waste time painting it, the output |
| 881 // would be culled. | 874 // would be culled. |
| 882 is_invalidated = context.IsRectInvalid(GetLocalBounds()); | 875 is_invalidated = context.IsRectInvalid(GetLocalBounds()); |
| 883 } | 876 } |
| 884 | 877 |
| 885 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); | 878 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
| 886 | 879 |
| 887 // If the view is backed by a layer, it should paint with itself as the origin | 880 // If the view is backed by a layer, it should paint with itself as the origin |
| 888 // rather than relative to its parent. | 881 // rather than relative to its parent. |
| 889 bool paint_relative_to_parent = !layer(); | |
| 890 | |
| 891 // TODO(danakj): Rework clip and transform recorder usage here to use | 882 // TODO(danakj): Rework clip and transform recorder usage here to use |
| 892 // std::optional once we can do so. | 883 // std::optional once we can do so. |
| 893 ui::ClipRecorder clip_recorder(parent_context); | 884 ui::ClipRecorder clip_recorder(parent_context); |
| 894 if (paint_relative_to_parent) { | 885 if (!layer()) { |
| 895 // Set the clip rect to the bounds of this View, or |clip_path_| if it's | 886 // Set the clip rect to the bounds of this View, or |clip_path_| if it's |
| 896 // been set. Note that the X (or left) position we pass to ClipRect takes | 887 // been set. Note that the X (or left) position we pass to ClipRect takes |
| 897 // into consideration whether or not the View uses a right-to-left layout so | 888 // into consideration whether or not the View uses a right-to-left layout so |
| 898 // that we paint the View in its mirrored position if need be. | 889 // that we paint the View in its mirrored position if need be. |
| 899 if (clip_path_.isEmpty()) { | 890 if (clip_path_.isEmpty()) { |
| 900 clip_recorder.ClipRect(GetMirroredBounds()); | 891 clip_recorder.ClipRect(GetMirroredBounds()); |
| 901 } else { | 892 } else { |
| 902 gfx::Path clip_path_in_parent = clip_path_; | 893 gfx::Path clip_path_in_parent = clip_path_; |
| 903 clip_path_in_parent.offset(GetMirroredX(), y()); | 894 clip_path_in_parent.offset(GetMirroredX(), y()); |
| 904 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); | 895 clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
| 905 } | 896 } |
| 906 } | 897 } |
| 907 | 898 |
| 908 ui::TransformRecorder transform_recorder(context); | 899 ui::TransformRecorder transform_recorder(context); |
| 909 if (paint_relative_to_parent) { | 900 SetupTransformRecorderForPainting(&transform_recorder); |
| 910 // Translate the graphics such that 0,0 corresponds to where | |
| 911 // this View is located relative to its parent. | |
| 912 gfx::Transform transform_from_parent; | |
| 913 gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); | |
| 914 transform_from_parent.Translate(offset_from_parent.x(), | |
| 915 offset_from_parent.y()); | |
| 916 transform_from_parent.PreconcatTransform(GetTransform()); | |
| 917 transform_recorder.Transform(transform_from_parent); | |
| 918 } | |
| 919 | 901 |
| 920 // Note that the cache is not aware of the offset of the view | 902 // Note that the cache is not aware of the offset of the view |
| 921 // relative to the parent since painting is always done relative to | 903 // relative to the parent since painting is always done relative to |
| 922 // the top left of the individual view. | 904 // the top left of the individual view. |
| 923 if (is_invalidated || !paint_cache_.UseCache(context, size())) { | 905 if (is_invalidated || !paint_cache_.UseCache(context, size())) { |
| 924 ui::PaintRecorder recorder(context, size(), &paint_cache_); | 906 ui::PaintRecorder recorder(context, size(), &paint_cache_); |
| 925 gfx::Canvas* canvas = recorder.canvas(); | 907 gfx::Canvas* canvas = recorder.canvas(); |
| 926 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), | 908 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
| 927 flip_canvas_on_paint_for_rtl_ui_); | 909 flip_canvas_on_paint_for_rtl_ui_); |
| 928 | 910 |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 } | 1495 } |
| 1514 | 1496 |
| 1515 void View::AddedToWidget() {} | 1497 void View::AddedToWidget() {} |
| 1516 | 1498 |
| 1517 void View::RemovedFromWidget() {} | 1499 void View::RemovedFromWidget() {} |
| 1518 | 1500 |
| 1519 // Painting -------------------------------------------------------------------- | 1501 // Painting -------------------------------------------------------------------- |
| 1520 | 1502 |
| 1521 void View::PaintChildren(const ui::PaintContext& context) { | 1503 void View::PaintChildren(const ui::PaintContext& context) { |
| 1522 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); | 1504 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); |
| 1523 View::Views children = GetChildrenInZOrder(); | 1505 RecursivePaintHelper(&View::Paint, context); |
| 1524 DCHECK_EQ(child_count(), static_cast<int>(children.size())); | |
| 1525 for (auto* child : children) { | |
| 1526 if (!child->layer()) | |
| 1527 child->Paint(context); | |
| 1528 } | |
| 1529 } | 1506 } |
| 1530 | 1507 |
| 1531 void View::OnPaint(gfx::Canvas* canvas) { | 1508 void View::OnPaint(gfx::Canvas* canvas) { |
| 1532 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); | 1509 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); |
| 1533 OnPaintBackground(canvas); | 1510 OnPaintBackground(canvas); |
| 1534 OnPaintBorder(canvas); | 1511 OnPaintBorder(canvas); |
| 1535 } | 1512 } |
| 1536 | 1513 |
| 1537 void View::OnPaintBackground(gfx::Canvas* canvas) { | 1514 void View::OnPaintBackground(gfx::Canvas* canvas) { |
| 1538 if (background_.get()) { | 1515 if (background_.get()) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1621 } else { | 1598 } else { |
| 1622 internal::ScopedChildrenLock lock(this); | 1599 internal::ScopedChildrenLock lock(this); |
| 1623 for (auto* child : children_) { | 1600 for (auto* child : children_) { |
| 1624 child->UpdateChildLayerBounds( | 1601 child->UpdateChildLayerBounds( |
| 1625 offset + gfx::Vector2d(child->GetMirroredX(), child->y())); | 1602 offset + gfx::Vector2d(child->GetMirroredX(), child->y())); |
| 1626 } | 1603 } |
| 1627 } | 1604 } |
| 1628 } | 1605 } |
| 1629 | 1606 |
| 1630 void View::OnPaintLayer(const ui::PaintContext& context) { | 1607 void View::OnPaintLayer(const ui::PaintContext& context) { |
| 1631 Paint(context); | 1608 PaintFromPaintRoot(context); |
| 1632 } | 1609 } |
| 1633 | 1610 |
| 1634 void View::OnDelegatedFrameDamage( | 1611 void View::OnDelegatedFrameDamage( |
| 1635 const gfx::Rect& damage_rect_in_dip) { | 1612 const gfx::Rect& damage_rect_in_dip) { |
| 1636 } | 1613 } |
| 1637 | 1614 |
| 1638 void View::OnDeviceScaleFactorChanged(float device_scale_factor) { | 1615 void View::OnDeviceScaleFactorChanged(float device_scale_factor) { |
| 1639 snap_layer_to_pixel_boundary_ = | 1616 snap_layer_to_pixel_boundary_ = |
| 1640 (device_scale_factor - std::floor(device_scale_factor)) != 0.0f; | 1617 (device_scale_factor - std::floor(device_scale_factor)) != 0.0f; |
| 1641 SnapLayerToPixelBoundary(); | 1618 SnapLayerToPixelBoundary(); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 } | 1875 } |
| 1899 | 1876 |
| 1900 void View::SchedulePaintOnParent() { | 1877 void View::SchedulePaintOnParent() { |
| 1901 if (parent_) { | 1878 if (parent_) { |
| 1902 // Translate the requested paint rect to the parent's coordinate system | 1879 // Translate the requested paint rect to the parent's coordinate system |
| 1903 // then pass this notification up to the parent. | 1880 // then pass this notification up to the parent. |
| 1904 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); | 1881 parent_->SchedulePaintInRect(ConvertRectToParent(GetLocalBounds())); |
| 1905 } | 1882 } |
| 1906 } | 1883 } |
| 1907 | 1884 |
| 1885 bool View::ShouldPaint() const { |
| 1886 return visible_ && !size().IsEmpty(); |
| 1887 } |
| 1888 |
| 1889 gfx::Vector2d View::GetPaintContextOffset() const { |
| 1890 // If the View has a layer() then it is a paint root. Otherwise, we need to |
| 1891 // add the offset from the parent into the total offset from the paint root. |
| 1892 DCHECK(layer() || parent() || origin() == gfx::Point()); |
| 1893 return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); |
| 1894 } |
| 1895 |
| 1896 void View::SetupTransformRecorderForPainting( |
| 1897 ui::TransformRecorder* recorder) const { |
| 1898 // If the view is backed by a layer, it should paint with itself as the origin |
| 1899 // rather than relative to its parent. |
| 1900 if (layer()) |
| 1901 return; |
| 1902 |
| 1903 // Translate the graphics such that 0,0 corresponds to where this View is |
| 1904 // located relative to its parent. |
| 1905 gfx::Transform transform_from_parent; |
| 1906 gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); |
| 1907 transform_from_parent.Translate(offset_from_parent.x(), |
| 1908 offset_from_parent.y()); |
| 1909 transform_from_parent.PreconcatTransform(GetTransform()); |
| 1910 recorder->Transform(transform_from_parent); |
| 1911 } |
| 1912 |
| 1913 void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), |
| 1914 const ui::PaintContext& context) { |
| 1915 View::Views children = GetChildrenInZOrder(); |
| 1916 DCHECK_EQ(child_count(), static_cast<int>(children.size())); |
| 1917 for (auto* child : children) { |
| 1918 if (!child->layer()) |
| 1919 (child->*func)(context); |
| 1920 } |
| 1921 } |
| 1922 |
| 1923 void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { |
| 1924 Paint(parent_context); |
| 1925 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1926 switches::kDrawViewBoundsRects)) |
| 1927 PaintDebugRects(parent_context); |
| 1928 } |
| 1929 |
| 1930 void View::PaintDebugRects(const ui::PaintContext& parent_context) { |
| 1931 if (!ShouldPaint()) |
| 1932 return; |
| 1933 |
| 1934 ui::PaintContext context(parent_context, GetPaintContextOffset()); |
| 1935 ui::TransformRecorder transform_recorder(context); |
| 1936 SetupTransformRecorderForPainting(&transform_recorder); |
| 1937 |
| 1938 RecursivePaintHelper(&View::PaintDebugRects, context); |
| 1939 |
| 1940 // Draw outline rects for debugging. |
| 1941 ui::PaintRecorder recorder(context, size()); |
| 1942 gfx::Canvas* canvas = recorder.canvas(); |
| 1943 const float scale = canvas->UndoDeviceScaleFactor(); |
| 1944 gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |
| 1945 outline_rect.Inset(0.5f, 0.5f); |
| 1946 const SkColor color = SkColorSetARGB(0x30, 0xff, 0, 0); |
| 1947 canvas->DrawRect(outline_rect, color); |
| 1948 } |
| 1949 |
| 1908 // Tree operations ------------------------------------------------------------- | 1950 // Tree operations ------------------------------------------------------------- |
| 1909 | 1951 |
| 1910 void View::DoRemoveChildView(View* view, | 1952 void View::DoRemoveChildView(View* view, |
| 1911 bool update_focus_cycle, | 1953 bool update_focus_cycle, |
| 1912 bool update_tool_tip, | 1954 bool update_tool_tip, |
| 1913 bool delete_removed_view, | 1955 bool delete_removed_view, |
| 1914 View* new_parent) { | 1956 View* new_parent) { |
| 1915 DCHECK(view); | 1957 DCHECK(view); |
| 1916 | 1958 |
| 1917 const Views::iterator i(std::find(children_.begin(), children_.end(), view)); | 1959 const Views::iterator i(std::find(children_.begin(), children_.end(), view)); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2562 // Message the RootView to do the drag and drop. That way if we're removed | 2604 // Message the RootView to do the drag and drop. That way if we're removed |
| 2563 // the RootView can detect it and avoid calling us back. | 2605 // the RootView can detect it and avoid calling us back. |
| 2564 gfx::Point widget_location(event.location()); | 2606 gfx::Point widget_location(event.location()); |
| 2565 ConvertPointToWidget(this, &widget_location); | 2607 ConvertPointToWidget(this, &widget_location); |
| 2566 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2608 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
| 2567 // WARNING: we may have been deleted. | 2609 // WARNING: we may have been deleted. |
| 2568 return true; | 2610 return true; |
| 2569 } | 2611 } |
| 2570 | 2612 |
| 2571 } // namespace views | 2613 } // namespace views |
| OLD | NEW |