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 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 | 775 |
776 // Non-empty clip, translate the graphics such that 0,0 corresponds to where | 776 // Non-empty clip, translate the graphics such that 0,0 corresponds to where |
777 // this view is located (related to its parent). | 777 // this view is located (related to its parent). |
778 canvas->Translate(GetMirroredPosition().OffsetFromOrigin()); | 778 canvas->Translate(GetMirroredPosition().OffsetFromOrigin()); |
779 canvas->Transform(GetTransform()); | 779 canvas->Transform(GetTransform()); |
780 | 780 |
781 // If we are a paint root, we need to construct our own CullSet object for | 781 // If we are a paint root, we need to construct our own CullSet object for |
782 // propagation to our children. | 782 // propagation to our children. |
783 if (IsPaintRoot()) { | 783 if (IsPaintRoot()) { |
784 if (!bounds_tree_) | 784 if (!bounds_tree_) |
785 bounds_tree_.reset(new gfx::RTree(2, 5)); | 785 bounds_tree_.reset(new BoundsTree(2, 5)); |
786 | 786 |
787 // Recompute our bounds tree as needed. | 787 // Recompute our bounds tree as needed. |
788 UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d()); | 788 UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d()); |
789 | 789 |
790 // Grab the clip rect from the supplied canvas to use as the query rect. | 790 // Grab the clip rect from the supplied canvas to use as the query rect. |
791 gfx::Rect canvas_bounds; | 791 gfx::Rect canvas_bounds; |
792 if (!canvas->GetClipBounds(&canvas_bounds)) { | 792 if (!canvas->GetClipBounds(&canvas_bounds)) { |
793 NOTREACHED() << "Failed to get clip bounds from the canvas!"; | 793 NOTREACHED() << "Failed to get clip bounds from the canvas!"; |
794 return; | 794 return; |
795 } | 795 } |
796 | 796 |
797 // Now query our bounds_tree_ for a set of damaged views that intersect | 797 // Now query our bounds_tree_ for a set of damaged views that intersect |
798 // our canvas bounds. | 798 // our canvas bounds. |
799 scoped_ptr<base::hash_set<intptr_t> > damaged_views( | 799 scoped_ptr<base::hash_set<intptr_t> > damaged_views( |
800 new base::hash_set<intptr_t>()); | 800 new base::hash_set<intptr_t>()); |
801 bounds_tree_->Query(canvas_bounds, damaged_views.get()); | 801 bounds_tree_->AppendIntersectingRecords( |
| 802 canvas_bounds, damaged_views.get()); |
802 // Construct a CullSet to wrap the damaged views set, it will delete it | 803 // Construct a CullSet to wrap the damaged views set, it will delete it |
803 // for us on scope exit. | 804 // for us on scope exit. |
804 CullSet paint_root_cull_set(damaged_views.Pass()); | 805 CullSet paint_root_cull_set(damaged_views.Pass()); |
805 // Paint all descendents using our new cull set. | 806 // Paint all descendents using our new cull set. |
806 PaintCommon(canvas, paint_root_cull_set); | 807 PaintCommon(canvas, paint_root_cull_set); |
807 } else { | 808 } else { |
808 // Not a paint root, so we can proceed as normal. | 809 // Not a paint root, so we can proceed as normal. |
809 PaintCommon(canvas, cull_set); | 810 PaintCommon(canvas, cull_set); |
810 } | 811 } |
811 } | 812 } |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 | 1861 |
1861 if (GetWidget()) { | 1862 if (GetWidget()) { |
1862 UnregisterChildrenForVisibleBoundsNotification(view); | 1863 UnregisterChildrenForVisibleBoundsNotification(view); |
1863 if (view->visible()) | 1864 if (view->visible()) |
1864 view->SchedulePaint(); | 1865 view->SchedulePaint(); |
1865 GetWidget()->NotifyWillRemoveView(view); | 1866 GetWidget()->NotifyWillRemoveView(view); |
1866 } | 1867 } |
1867 | 1868 |
1868 // Remove the bounds of this child and any of its descendants from our | 1869 // Remove the bounds of this child and any of its descendants from our |
1869 // paint root bounds tree. | 1870 // paint root bounds tree. |
1870 gfx::RTree* bounds_tree = GetBoundsTreeFromPaintRoot(); | 1871 BoundsTree* bounds_tree = GetBoundsTreeFromPaintRoot(); |
1871 if (bounds_tree) | 1872 if (bounds_tree) |
1872 view->RemoveRootBounds(bounds_tree); | 1873 view->RemoveRootBounds(bounds_tree); |
1873 | 1874 |
1874 view->PropagateRemoveNotifications(this, new_parent); | 1875 view->PropagateRemoveNotifications(this, new_parent); |
1875 view->parent_ = NULL; | 1876 view->parent_ = NULL; |
1876 view->UpdateLayerVisibility(); | 1877 view->UpdateLayerVisibility(); |
1877 | 1878 |
1878 if (delete_removed_view && !view->owned_by_client_) | 1879 if (delete_removed_view && !view->owned_by_client_) |
1879 view_to_be_deleted.reset(view); | 1880 view_to_be_deleted.reset(view); |
1880 | 1881 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2071 // Inform our children that their root bounds are dirty, as their relative | 2072 // Inform our children that their root bounds are dirty, as their relative |
2072 // coordinates in paint root space have changed since ours have changed. | 2073 // coordinates in paint root space have changed since ours have changed. |
2073 for (Views::const_iterator i(children_.begin()); i != children_.end(); | 2074 for (Views::const_iterator i(children_.begin()); i != children_.end(); |
2074 ++i) { | 2075 ++i) { |
2075 if (!(*i)->IsPaintRoot()) | 2076 if (!(*i)->IsPaintRoot()) |
2076 (*i)->SetRootBoundsDirty(origin_changed); | 2077 (*i)->SetRootBoundsDirty(origin_changed); |
2077 } | 2078 } |
2078 } | 2079 } |
2079 } | 2080 } |
2080 | 2081 |
2081 void View::UpdateRootBounds(gfx::RTree* tree, const gfx::Vector2d& offset) { | 2082 void View::UpdateRootBounds(BoundsTree* tree, const gfx::Vector2d& offset) { |
2082 // No need to recompute bounds if we haven't flagged ours as dirty. | 2083 // No need to recompute bounds if we haven't flagged ours as dirty. |
2083 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); | 2084 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); |
2084 | 2085 |
2085 // Add our own offset to the provided offset, for our own bounds update and | 2086 // Add our own offset to the provided offset, for our own bounds update and |
2086 // for propagation to our children if needed. | 2087 // for propagation to our children if needed. |
2087 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin(); | 2088 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin(); |
2088 | 2089 |
2089 // If our bounds have changed we must re-insert our new bounds to the tree. | 2090 // If our bounds have changed we must re-insert our new bounds to the tree. |
2090 if (root_bounds_dirty_) { | 2091 if (root_bounds_dirty_) { |
2091 root_bounds_dirty_ = false; | 2092 root_bounds_dirty_ = false; |
2092 gfx::Rect bounds( | 2093 gfx::Rect bounds( |
2093 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); | 2094 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); |
2094 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); | 2095 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); |
2095 } | 2096 } |
2096 | 2097 |
2097 // Update our children's bounds if needed. | 2098 // Update our children's bounds if needed. |
2098 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { | 2099 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
2099 // We don't descend in to layer views for bounds recomputation, as they | 2100 // We don't descend in to layer views for bounds recomputation, as they |
2100 // manage their own RTree as paint roots. | 2101 // manage their own RTree as paint roots. |
2101 if (!(*i)->IsPaintRoot()) | 2102 if (!(*i)->IsPaintRoot()) |
2102 (*i)->UpdateRootBounds(tree, view_offset); | 2103 (*i)->UpdateRootBounds(tree, view_offset); |
2103 } | 2104 } |
2104 } | 2105 } |
2105 | 2106 |
2106 void View::RemoveRootBounds(gfx::RTree* tree) { | 2107 void View::RemoveRootBounds(BoundsTree* tree) { |
2107 tree->Remove(reinterpret_cast<intptr_t>(this)); | 2108 tree->Remove(reinterpret_cast<intptr_t>(this)); |
2108 | 2109 |
2109 root_bounds_dirty_ = true; | 2110 root_bounds_dirty_ = true; |
2110 | 2111 |
2111 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { | 2112 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
2112 if (!(*i)->IsPaintRoot()) | 2113 if (!(*i)->IsPaintRoot()) |
2113 (*i)->RemoveRootBounds(tree); | 2114 (*i)->RemoveRootBounds(tree); |
2114 } | 2115 } |
2115 } | 2116 } |
2116 | 2117 |
2117 gfx::RTree* View::GetBoundsTreeFromPaintRoot() { | 2118 View::BoundsTree* View::GetBoundsTreeFromPaintRoot() { |
2118 gfx::RTree* bounds_tree = bounds_tree_.get(); | 2119 BoundsTree* bounds_tree = bounds_tree_.get(); |
2119 View* paint_root = this; | 2120 View* paint_root = this; |
2120 while (!bounds_tree && !paint_root->IsPaintRoot()) { | 2121 while (!bounds_tree && !paint_root->IsPaintRoot()) { |
2121 // Assumption is that if IsPaintRoot() is false then parent_ is valid. | 2122 // Assumption is that if IsPaintRoot() is false then parent_ is valid. |
2122 DCHECK(paint_root); | 2123 DCHECK(paint_root); |
2123 paint_root = paint_root->parent_; | 2124 paint_root = paint_root->parent_; |
2124 bounds_tree = paint_root->bounds_tree_.get(); | 2125 bounds_tree = paint_root->bounds_tree_.get(); |
2125 } | 2126 } |
2126 | 2127 |
2127 return bounds_tree; | 2128 return bounds_tree; |
2128 } | 2129 } |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2497 // Message the RootView to do the drag and drop. That way if we're removed | 2498 // Message the RootView to do the drag and drop. That way if we're removed |
2498 // the RootView can detect it and avoid calling us back. | 2499 // the RootView can detect it and avoid calling us back. |
2499 gfx::Point widget_location(event.location()); | 2500 gfx::Point widget_location(event.location()); |
2500 ConvertPointToWidget(this, &widget_location); | 2501 ConvertPointToWidget(this, &widget_location); |
2501 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2502 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
2502 // WARNING: we may have been deleted. | 2503 // WARNING: we may have been deleted. |
2503 return true; | 2504 return true; |
2504 } | 2505 } |
2505 | 2506 |
2506 } // namespace views | 2507 } // namespace views |
OLD | NEW |