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 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 | 1864 |
1864 if (GetWidget()) { | 1865 if (GetWidget()) { |
1865 UnregisterChildrenForVisibleBoundsNotification(view); | 1866 UnregisterChildrenForVisibleBoundsNotification(view); |
1866 if (view->visible()) | 1867 if (view->visible()) |
1867 view->SchedulePaint(); | 1868 view->SchedulePaint(); |
1868 GetWidget()->NotifyWillRemoveView(view); | 1869 GetWidget()->NotifyWillRemoveView(view); |
1869 } | 1870 } |
1870 | 1871 |
1871 // Remove the bounds of this child and any of its descendants from our | 1872 // Remove the bounds of this child and any of its descendants from our |
1872 // paint root bounds tree. | 1873 // paint root bounds tree. |
1873 gfx::RTree* bounds_tree = GetBoundsTreeFromPaintRoot(); | 1874 BoundsTree* bounds_tree = GetBoundsTreeFromPaintRoot(); |
1874 if (bounds_tree) | 1875 if (bounds_tree) |
1875 view->RemoveRootBounds(bounds_tree); | 1876 view->RemoveRootBounds(bounds_tree); |
1876 | 1877 |
1877 view->PropagateRemoveNotifications(this, new_parent); | 1878 view->PropagateRemoveNotifications(this, new_parent); |
1878 view->parent_ = NULL; | 1879 view->parent_ = NULL; |
1879 view->UpdateLayerVisibility(); | 1880 view->UpdateLayerVisibility(); |
1880 | 1881 |
1881 if (delete_removed_view && !view->owned_by_client_) | 1882 if (delete_removed_view && !view->owned_by_client_) |
1882 view_to_be_deleted.reset(view); | 1883 view_to_be_deleted.reset(view); |
1883 | 1884 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 // Inform our children that their root bounds are dirty, as their relative | 2075 // Inform our children that their root bounds are dirty, as their relative |
2075 // coordinates in paint root space have changed since ours have changed. | 2076 // coordinates in paint root space have changed since ours have changed. |
2076 for (Views::const_iterator i(children_.begin()); i != children_.end(); | 2077 for (Views::const_iterator i(children_.begin()); i != children_.end(); |
2077 ++i) { | 2078 ++i) { |
2078 if (!(*i)->IsPaintRoot()) | 2079 if (!(*i)->IsPaintRoot()) |
2079 (*i)->SetRootBoundsDirty(origin_changed); | 2080 (*i)->SetRootBoundsDirty(origin_changed); |
2080 } | 2081 } |
2081 } | 2082 } |
2082 } | 2083 } |
2083 | 2084 |
2084 void View::UpdateRootBounds(gfx::RTree* tree, const gfx::Vector2d& offset) { | 2085 void View::UpdateRootBounds(BoundsTree* tree, const gfx::Vector2d& offset) { |
2085 // No need to recompute bounds if we haven't flagged ours as dirty. | 2086 // No need to recompute bounds if we haven't flagged ours as dirty. |
2086 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); | 2087 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); |
2087 | 2088 |
2088 // Add our own offset to the provided offset, for our own bounds update and | 2089 // Add our own offset to the provided offset, for our own bounds update and |
2089 // for propagation to our children if needed. | 2090 // for propagation to our children if needed. |
2090 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin(); | 2091 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin(); |
2091 | 2092 |
2092 // If our bounds have changed we must re-insert our new bounds to the tree. | 2093 // If our bounds have changed we must re-insert our new bounds to the tree. |
2093 if (root_bounds_dirty_) { | 2094 if (root_bounds_dirty_) { |
2094 root_bounds_dirty_ = false; | 2095 root_bounds_dirty_ = false; |
2095 gfx::Rect bounds( | 2096 gfx::Rect bounds( |
2096 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); | 2097 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); |
2097 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); | 2098 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); |
2098 } | 2099 } |
2099 | 2100 |
2100 // Update our children's bounds if needed. | 2101 // Update our children's bounds if needed. |
2101 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { | 2102 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
2102 // We don't descend in to layer views for bounds recomputation, as they | 2103 // We don't descend in to layer views for bounds recomputation, as they |
2103 // manage their own RTree as paint roots. | 2104 // manage their own RTree as paint roots. |
2104 if (!(*i)->IsPaintRoot()) | 2105 if (!(*i)->IsPaintRoot()) |
2105 (*i)->UpdateRootBounds(tree, view_offset); | 2106 (*i)->UpdateRootBounds(tree, view_offset); |
2106 } | 2107 } |
2107 } | 2108 } |
2108 | 2109 |
2109 void View::RemoveRootBounds(gfx::RTree* tree) { | 2110 void View::RemoveRootBounds(BoundsTree* tree) { |
2110 tree->Remove(reinterpret_cast<intptr_t>(this)); | 2111 tree->Remove(reinterpret_cast<intptr_t>(this)); |
2111 | 2112 |
2112 root_bounds_dirty_ = true; | 2113 root_bounds_dirty_ = true; |
2113 | 2114 |
2114 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { | 2115 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
2115 if (!(*i)->IsPaintRoot()) | 2116 if (!(*i)->IsPaintRoot()) |
2116 (*i)->RemoveRootBounds(tree); | 2117 (*i)->RemoveRootBounds(tree); |
2117 } | 2118 } |
2118 } | 2119 } |
2119 | 2120 |
2120 gfx::RTree* View::GetBoundsTreeFromPaintRoot() { | 2121 View::BoundsTree* View::GetBoundsTreeFromPaintRoot() { |
2121 gfx::RTree* bounds_tree = bounds_tree_.get(); | 2122 BoundsTree* bounds_tree = bounds_tree_.get(); |
2122 View* paint_root = this; | 2123 View* paint_root = this; |
2123 while (!bounds_tree && !paint_root->IsPaintRoot()) { | 2124 while (!bounds_tree && !paint_root->IsPaintRoot()) { |
2124 // Assumption is that if IsPaintRoot() is false then parent_ is valid. | 2125 // Assumption is that if IsPaintRoot() is false then parent_ is valid. |
2125 DCHECK(paint_root); | 2126 DCHECK(paint_root); |
2126 paint_root = paint_root->parent_; | 2127 paint_root = paint_root->parent_; |
2127 bounds_tree = paint_root->bounds_tree_.get(); | 2128 bounds_tree = paint_root->bounds_tree_.get(); |
2128 } | 2129 } |
2129 | 2130 |
2130 return bounds_tree; | 2131 return bounds_tree; |
2131 } | 2132 } |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 // Message the RootView to do the drag and drop. That way if we're removed | 2501 // Message the RootView to do the drag and drop. That way if we're removed |
2501 // the RootView can detect it and avoid calling us back. | 2502 // the RootView can detect it and avoid calling us back. |
2502 gfx::Point widget_location(event.location()); | 2503 gfx::Point widget_location(event.location()); |
2503 ConvertPointToWidget(this, &widget_location); | 2504 ConvertPointToWidget(this, &widget_location); |
2504 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2505 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
2505 // WARNING: we may have been deleted. | 2506 // WARNING: we may have been deleted. |
2506 return true; | 2507 return true; |
2507 } | 2508 } |
2508 | 2509 |
2509 } // namespace views | 2510 } // namespace views |
OLD | NEW |