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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 | 151 |
152 View::View() | 152 View::View() |
153 : owned_by_client_(false), | 153 : owned_by_client_(false), |
154 id_(0), | 154 id_(0), |
155 group_(-1), | 155 group_(-1), |
156 parent_(NULL), | 156 parent_(NULL), |
157 visible_(true), | 157 visible_(true), |
158 enabled_(true), | 158 enabled_(true), |
159 notify_enter_exit_on_child_(false), | 159 notify_enter_exit_on_child_(false), |
160 registered_for_visible_bounds_notification_(false), | 160 registered_for_visible_bounds_notification_(false), |
| 161 root_bounds_dirty_(true), |
161 clip_insets_(0, 0, 0, 0), | 162 clip_insets_(0, 0, 0, 0), |
162 needs_layout_(true), | 163 needs_layout_(true), |
163 flip_canvas_on_paint_for_rtl_ui_(false), | 164 flip_canvas_on_paint_for_rtl_ui_(false), |
164 paint_to_layer_(false), | 165 paint_to_layer_(false), |
165 accelerator_focus_manager_(NULL), | 166 accelerator_focus_manager_(NULL), |
166 registered_accelerator_count_(0), | 167 registered_accelerator_count_(0), |
167 next_focusable_view_(NULL), | 168 next_focusable_view_(NULL), |
168 previous_focusable_view_(NULL), | 169 previous_focusable_view_(NULL), |
169 focusable_(false), | 170 focusable_(false), |
170 accessibility_focusable_(false), | 171 accessibility_focusable_(false), |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 parent->DoRemoveChildView(view, true, true, false, this); | 228 parent->DoRemoveChildView(view, true, true, false, this); |
228 } | 229 } |
229 | 230 |
230 // Sets the prev/next focus views. | 231 // Sets the prev/next focus views. |
231 InitFocusSiblings(view, index); | 232 InitFocusSiblings(view, index); |
232 | 233 |
233 // Let's insert the view. | 234 // Let's insert the view. |
234 view->parent_ = this; | 235 view->parent_ = this; |
235 children_.insert(children_.begin() + index, view); | 236 children_.insert(children_.begin() + index, view); |
236 | 237 |
| 238 // Instruct the view to recompute its root bounds on next Paint(). |
| 239 view->SetRootBoundsDirty(true); |
| 240 |
237 views::Widget* widget = GetWidget(); | 241 views::Widget* widget = GetWidget(); |
238 if (widget) { | 242 if (widget) { |
239 const ui::NativeTheme* new_theme = view->GetNativeTheme(); | 243 const ui::NativeTheme* new_theme = view->GetNativeTheme(); |
240 if (new_theme != old_theme) | 244 if (new_theme != old_theme) |
241 view->PropagateNativeThemeChanged(new_theme); | 245 view->PropagateNativeThemeChanged(new_theme); |
242 } | 246 } |
243 | 247 |
244 ViewHierarchyChangedDetails details(true, this, view, parent); | 248 ViewHierarchyChangedDetails details(true, this, view, parent); |
245 | 249 |
246 for (View* v = this; v; v = v->parent_) | 250 for (View* v = this; v; v = v->parent_) |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 } | 509 } |
506 } else { | 510 } else { |
507 if (!layer()) | 511 if (!layer()) |
508 CreateLayer(); | 512 CreateLayer(); |
509 layer()->SetTransform(transform); | 513 layer()->SetTransform(transform); |
510 layer()->ScheduleDraw(); | 514 layer()->ScheduleDraw(); |
511 } | 515 } |
512 } | 516 } |
513 | 517 |
514 void View::SetPaintToLayer(bool paint_to_layer) { | 518 void View::SetPaintToLayer(bool paint_to_layer) { |
| 519 if (paint_to_layer_ == paint_to_layer) |
| 520 return; |
| 521 |
| 522 // If this is a change in state we will also need to update bounds trees. |
| 523 if (paint_to_layer) { |
| 524 // Gaining a layer means becoming a paint root. We must remove ourselves |
| 525 // from our old paint root, if we had one. Traverse up view tree to find old |
| 526 // paint root. |
| 527 View* old_paint_root = parent_; |
| 528 while (old_paint_root && !old_paint_root->IsPaintRoot()) |
| 529 old_paint_root = old_paint_root->parent_; |
| 530 |
| 531 // Remove our and our children's bounds from the old tree. This will also |
| 532 // mark all of our bounds as dirty. |
| 533 if (old_paint_root && old_paint_root->bounds_tree_) |
| 534 RemoveRootBounds(old_paint_root->bounds_tree_.get()); |
| 535 |
| 536 } else { |
| 537 // Losing a layer means we are no longer a paint root, so delete our |
| 538 // bounds tree and mark ourselves as dirty for future insertion into our |
| 539 // new paint root's bounds tree. |
| 540 bounds_tree_.reset(); |
| 541 SetRootBoundsDirty(true); |
| 542 } |
| 543 |
515 paint_to_layer_ = paint_to_layer; | 544 paint_to_layer_ = paint_to_layer; |
516 if (paint_to_layer_ && !layer()) { | 545 if (paint_to_layer_ && !layer()) { |
517 CreateLayer(); | 546 CreateLayer(); |
518 } else if (!paint_to_layer_ && layer()) { | 547 } else if (!paint_to_layer_ && layer()) { |
519 DestroyLayer(); | 548 DestroyLayer(); |
520 } | 549 } |
521 } | 550 } |
522 | 551 |
523 // RTL positioning ------------------------------------------------------------- | 552 // RTL positioning ------------------------------------------------------------- |
524 | 553 |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 | 794 |
766 if (layer()) { | 795 if (layer()) { |
767 layer()->SchedulePaint(rect); | 796 layer()->SchedulePaint(rect); |
768 } else if (parent_) { | 797 } else if (parent_) { |
769 // Translate the requested paint rect to the parent's coordinate system | 798 // Translate the requested paint rect to the parent's coordinate system |
770 // then pass this notification up to the parent. | 799 // then pass this notification up to the parent. |
771 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); | 800 parent_->SchedulePaintInRect(ConvertRectToParent(rect)); |
772 } | 801 } |
773 } | 802 } |
774 | 803 |
775 void View::Paint(gfx::Canvas* canvas) { | 804 void View::Paint(gfx::Canvas* canvas, const CullSet& cull_set) { |
776 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); | 805 // The cull_set may allow us to skip painting without canvas construction or |
| 806 // even canvas rect intersection. |
| 807 if (cull_set.ShouldPaint(this)) { |
| 808 TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
777 | 809 |
778 gfx::ScopedCanvas scoped_canvas(canvas); | 810 gfx::ScopedCanvas scoped_canvas(canvas); |
779 | 811 |
780 // Paint this View and its children, setting the clip rect to the bounds | 812 // Paint this View and its children, setting the clip rect to the bounds |
781 // of this View and translating the origin to the local bounds' top left | 813 // of this View and translating the origin to the local bounds' top left |
782 // point. | 814 // point. |
783 // | 815 // |
784 // Note that the X (or left) position we pass to ClipRectInt takes into | 816 // Note that the X (or left) position we pass to ClipRectInt takes into |
785 // consideration whether or not the view uses a right-to-left layout so that | 817 // consideration whether or not the view uses a right-to-left layout so that |
786 // we paint our view in its mirrored position if need be. | 818 // we paint our view in its mirrored position if need be. |
787 gfx::Rect clip_rect = bounds(); | 819 gfx::Rect clip_rect = bounds(); |
788 clip_rect.Inset(clip_insets_); | 820 clip_rect.Inset(clip_insets_); |
789 if (parent_) | 821 if (parent_) |
790 clip_rect.set_x(parent_->GetMirroredXForRect(clip_rect)); | 822 clip_rect.set_x(parent_->GetMirroredXForRect(clip_rect)); |
791 canvas->ClipRect(clip_rect); | 823 canvas->ClipRect(clip_rect); |
792 if (canvas->IsClipEmpty()) | 824 if (canvas->IsClipEmpty()) |
793 return; | 825 return; |
794 | 826 |
795 // Non-empty clip, translate the graphics such that 0,0 corresponds to | 827 // Non-empty clip, translate the graphics such that 0,0 corresponds to where |
796 // where this view is located (related to its parent). | 828 // this view is located (related to its parent). |
797 canvas->Translate(GetMirroredPosition().OffsetFromOrigin()); | 829 canvas->Translate(GetMirroredPosition().OffsetFromOrigin()); |
798 canvas->Transform(GetTransform()); | 830 canvas->Transform(GetTransform()); |
799 | 831 |
800 PaintCommon(canvas); | 832 // If we are a paint root, we need to construct our own CullSet object for |
| 833 // propagation to our children. |
| 834 if (IsPaintRoot()) { |
| 835 if (!bounds_tree_) |
| 836 bounds_tree_.reset(new gfx::RTree(2, 5)); |
| 837 |
| 838 // Recompute our bounds tree as needed. |
| 839 UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d()); |
| 840 |
| 841 // Grab the clip rect from the supplied canvas to use as the query rect. |
| 842 gfx::Rect canvas_bounds; |
| 843 if (!canvas->GetClipBounds(&canvas_bounds)) { |
| 844 NOTREACHED() << "Failed to get clip bounds from the canvas!"; |
| 845 return; |
| 846 } |
| 847 |
| 848 // Now query our bounds_tree_ for a set of damaged views that intersect |
| 849 // our canvas bounds. |
| 850 scoped_ptr<base::hash_set<intptr_t> > damaged_views( |
| 851 new base::hash_set<intptr_t>()); |
| 852 bounds_tree_->Query(canvas_bounds, damaged_views.get()); |
| 853 // Construct a CullSet to wrap the damaged views set, it will delete it |
| 854 // for us on scope exit. |
| 855 CullSet paint_root_cull_set(damaged_views.Pass()); |
| 856 // Paint all descendents using our new cull set. |
| 857 PaintCommon(canvas, paint_root_cull_set); |
| 858 } else { |
| 859 // Not a paint root, so we can proceed as normal. |
| 860 PaintCommon(canvas, cull_set); |
| 861 } |
| 862 } |
801 } | 863 } |
802 | 864 |
803 void View::set_background(Background* b) { | 865 void View::set_background(Background* b) { |
804 background_.reset(b); | 866 background_.reset(b); |
805 } | 867 } |
806 | 868 |
807 void View::SetBorder(scoped_ptr<Border> b) { border_ = b.Pass(); } | 869 void View::SetBorder(scoped_ptr<Border> b) { border_ = b.Pass(); } |
808 | 870 |
809 ui::ThemeProvider* View::GetThemeProvider() const { | 871 ui::ThemeProvider* View::GetThemeProvider() const { |
810 const Widget* widget = GetWidget(); | 872 const Widget* widget = GetWidget(); |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 if (accelerator_focus_manager_ != focus_manager) { | 1444 if (accelerator_focus_manager_ != focus_manager) { |
1383 UnregisterAccelerators(true); | 1445 UnregisterAccelerators(true); |
1384 | 1446 |
1385 if (focus_manager) | 1447 if (focus_manager) |
1386 RegisterPendingAccelerators(); | 1448 RegisterPendingAccelerators(); |
1387 } | 1449 } |
1388 } | 1450 } |
1389 | 1451 |
1390 // Painting -------------------------------------------------------------------- | 1452 // Painting -------------------------------------------------------------------- |
1391 | 1453 |
1392 void View::PaintChildren(gfx::Canvas* canvas) { | 1454 void View::PaintChildren(gfx::Canvas* canvas, const CullSet& cull_set) { |
1393 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); | 1455 TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); |
1394 for (int i = 0, count = child_count(); i < count; ++i) | 1456 for (int i = 0, count = child_count(); i < count; ++i) |
1395 if (!child_at(i)->layer()) | 1457 if (!child_at(i)->layer()) |
1396 child_at(i)->Paint(canvas); | 1458 child_at(i)->Paint(canvas, cull_set); |
1397 } | 1459 } |
1398 | 1460 |
1399 void View::OnPaint(gfx::Canvas* canvas) { | 1461 void View::OnPaint(gfx::Canvas* canvas) { |
1400 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); | 1462 TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); |
1401 OnPaintBackground(canvas); | 1463 OnPaintBackground(canvas); |
1402 OnPaintBorder(canvas); | 1464 OnPaintBorder(canvas); |
1403 } | 1465 } |
1404 | 1466 |
1405 void View::OnPaintBackground(gfx::Canvas* canvas) { | 1467 void View::OnPaintBackground(gfx::Canvas* canvas) { |
1406 if (background_.get()) { | 1468 if (background_.get()) { |
1407 TRACE_EVENT2("views", "View::OnPaintBackground", | 1469 TRACE_EVENT2("views", "View::OnPaintBackground", |
1408 "width", canvas->sk_canvas()->getDevice()->width(), | 1470 "width", canvas->sk_canvas()->getDevice()->width(), |
1409 "height", canvas->sk_canvas()->getDevice()->height()); | 1471 "height", canvas->sk_canvas()->getDevice()->height()); |
1410 background_->Paint(canvas, this); | 1472 background_->Paint(canvas, this); |
1411 } | 1473 } |
1412 } | 1474 } |
1413 | 1475 |
1414 void View::OnPaintBorder(gfx::Canvas* canvas) { | 1476 void View::OnPaintBorder(gfx::Canvas* canvas) { |
1415 if (border_.get()) { | 1477 if (border_.get()) { |
1416 TRACE_EVENT2("views", "View::OnPaintBorder", | 1478 TRACE_EVENT2("views", "View::OnPaintBorder", |
1417 "width", canvas->sk_canvas()->getDevice()->width(), | 1479 "width", canvas->sk_canvas()->getDevice()->width(), |
1418 "height", canvas->sk_canvas()->getDevice()->height()); | 1480 "height", canvas->sk_canvas()->getDevice()->height()); |
1419 border_->Paint(*this, canvas); | 1481 border_->Paint(*this, canvas); |
1420 } | 1482 } |
1421 } | 1483 } |
1422 | 1484 |
| 1485 bool View::IsPaintRoot() { |
| 1486 return paint_to_layer_ || !parent_; |
| 1487 } |
| 1488 |
1423 // Accelerated Painting -------------------------------------------------------- | 1489 // Accelerated Painting -------------------------------------------------------- |
1424 | 1490 |
1425 void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { | 1491 void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { |
1426 // This method should not have the side-effect of creating the layer. | 1492 // This method should not have the side-effect of creating the layer. |
1427 if (layer()) | 1493 if (layer()) |
1428 layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely); | 1494 layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely); |
1429 } | 1495 } |
1430 | 1496 |
1431 gfx::Vector2d View::CalculateOffsetToAncestorWithLayer( | 1497 gfx::Vector2d View::CalculateOffsetToAncestorWithLayer( |
1432 ui::Layer** layer_parent) { | 1498 ui::Layer** layer_parent) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 View* child = child_at(i); | 1561 View* child = child_at(i); |
1496 child->UpdateChildLayerBounds( | 1562 child->UpdateChildLayerBounds( |
1497 offset + gfx::Vector2d(child->GetMirroredX(), child->y())); | 1563 offset + gfx::Vector2d(child->GetMirroredX(), child->y())); |
1498 } | 1564 } |
1499 } | 1565 } |
1500 } | 1566 } |
1501 | 1567 |
1502 void View::OnPaintLayer(gfx::Canvas* canvas) { | 1568 void View::OnPaintLayer(gfx::Canvas* canvas) { |
1503 if (!layer() || !layer()->fills_bounds_opaquely()) | 1569 if (!layer() || !layer()->fills_bounds_opaquely()) |
1504 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); | 1570 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); |
1505 PaintCommon(canvas); | 1571 PaintCommon(canvas, CullSet()); |
1506 } | 1572 } |
1507 | 1573 |
1508 void View::OnDeviceScaleFactorChanged(float device_scale_factor) { | 1574 void View::OnDeviceScaleFactorChanged(float device_scale_factor) { |
1509 // Repainting with new scale factor will paint the content at the right scale. | 1575 // Repainting with new scale factor will paint the content at the right scale. |
1510 } | 1576 } |
1511 | 1577 |
1512 base::Closure View::PrepareForLayerBoundsChange() { | 1578 base::Closure View::PrepareForLayerBoundsChange() { |
1513 return base::Closure(); | 1579 return base::Closure(); |
1514 } | 1580 } |
1515 | 1581 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 | 1809 |
1744 // Children. | 1810 // Children. |
1745 for (int i = 0, count = view_with_children->child_count(); i < count; ++i) | 1811 for (int i = 0, count = view_with_children->child_count(); i < count; ++i) |
1746 result.append(view_with_children->child_at(i)->PrintViewGraph(false)); | 1812 result.append(view_with_children->child_at(i)->PrintViewGraph(false)); |
1747 | 1813 |
1748 if (first) | 1814 if (first) |
1749 result.append("}\n"); | 1815 result.append("}\n"); |
1750 | 1816 |
1751 return result; | 1817 return result; |
1752 } | 1818 } |
1753 | |
1754 #endif | 1819 #endif |
1755 | 1820 |
1756 //////////////////////////////////////////////////////////////////////////////// | 1821 //////////////////////////////////////////////////////////////////////////////// |
1757 // View, private: | 1822 // View, private: |
1758 | 1823 |
1759 // DropInfo -------------------------------------------------------------------- | 1824 // DropInfo -------------------------------------------------------------------- |
1760 | 1825 |
1761 void View::DragInfo::Reset() { | 1826 void View::DragInfo::Reset() { |
1762 possible_drag = false; | 1827 possible_drag = false; |
1763 start_pt = gfx::Point(); | 1828 start_pt = gfx::Point(); |
(...skipping 16 matching lines...) Expand all Loading... |
1780 SchedulePaint(); | 1845 SchedulePaint(); |
1781 } else if (parent_ && type == SCHEDULE_PAINT_SIZE_SAME) { | 1846 } else if (parent_ && type == SCHEDULE_PAINT_SIZE_SAME) { |
1782 // The compositor doesn't Draw() until something on screen changes, so | 1847 // The compositor doesn't Draw() until something on screen changes, so |
1783 // if our position changes but nothing is being animated on screen, then | 1848 // if our position changes but nothing is being animated on screen, then |
1784 // tell the compositor to redraw the scene. We know layer() exists due to | 1849 // tell the compositor to redraw the scene. We know layer() exists due to |
1785 // the above if clause. | 1850 // the above if clause. |
1786 layer()->ScheduleDraw(); | 1851 layer()->ScheduleDraw(); |
1787 } | 1852 } |
1788 } | 1853 } |
1789 | 1854 |
1790 void View::PaintCommon(gfx::Canvas* canvas) { | 1855 void View::PaintCommon(gfx::Canvas* canvas, const CullSet& cull_set) { |
1791 if (!visible_) | 1856 if (!visible_) |
1792 return; | 1857 return; |
1793 | 1858 |
1794 { | 1859 { |
1795 // If the View we are about to paint requested the canvas to be flipped, we | 1860 // If the View we are about to paint requested the canvas to be flipped, we |
1796 // should change the transform appropriately. | 1861 // should change the transform appropriately. |
1797 // The canvas mirroring is undone once the View is done painting so that we | 1862 // The canvas mirroring is undone once the View is done painting so that we |
1798 // don't pass the canvas with the mirrored transform to Views that didn't | 1863 // don't pass the canvas with the mirrored transform to Views that didn't |
1799 // request the canvas to be flipped. | 1864 // request the canvas to be flipped. |
1800 gfx::ScopedCanvas scoped(canvas); | 1865 gfx::ScopedCanvas scoped(canvas); |
1801 if (FlipCanvasOnPaintForRTLUI()) { | 1866 if (FlipCanvasOnPaintForRTLUI()) { |
1802 canvas->Translate(gfx::Vector2d(width(), 0)); | 1867 canvas->Translate(gfx::Vector2d(width(), 0)); |
1803 canvas->Scale(-1, 1); | 1868 canvas->Scale(-1, 1); |
1804 } | 1869 } |
1805 | 1870 |
1806 OnPaint(canvas); | 1871 OnPaint(canvas); |
1807 } | 1872 } |
1808 | 1873 |
1809 PaintChildren(canvas); | 1874 PaintChildren(canvas, cull_set); |
1810 } | 1875 } |
1811 | 1876 |
1812 // Tree operations ------------------------------------------------------------- | 1877 // Tree operations ------------------------------------------------------------- |
1813 | 1878 |
1814 void View::DoRemoveChildView(View* view, | 1879 void View::DoRemoveChildView(View* view, |
1815 bool update_focus_cycle, | 1880 bool update_focus_cycle, |
1816 bool update_tool_tip, | 1881 bool update_tool_tip, |
1817 bool delete_removed_view, | 1882 bool delete_removed_view, |
1818 View* new_parent) { | 1883 View* new_parent) { |
1819 DCHECK(view); | 1884 DCHECK(view); |
(...skipping 10 matching lines...) Expand all Loading... |
1830 if (next_focusable) | 1895 if (next_focusable) |
1831 next_focusable->previous_focusable_view_ = prev_focusable; | 1896 next_focusable->previous_focusable_view_ = prev_focusable; |
1832 } | 1897 } |
1833 | 1898 |
1834 if (GetWidget()) { | 1899 if (GetWidget()) { |
1835 UnregisterChildrenForVisibleBoundsNotification(view); | 1900 UnregisterChildrenForVisibleBoundsNotification(view); |
1836 if (view->visible()) | 1901 if (view->visible()) |
1837 view->SchedulePaint(); | 1902 view->SchedulePaint(); |
1838 GetWidget()->NotifyWillRemoveView(view); | 1903 GetWidget()->NotifyWillRemoveView(view); |
1839 } | 1904 } |
| 1905 |
| 1906 // Remove the bounds of this child and any of its descendants from our |
| 1907 // paint root bounds tree. |
| 1908 gfx::RTree* bounds_tree = GetBoundsTreeFromPaintRoot(); |
| 1909 if (bounds_tree) |
| 1910 view->RemoveRootBounds(bounds_tree); |
| 1911 |
1840 view->PropagateRemoveNotifications(this, new_parent); | 1912 view->PropagateRemoveNotifications(this, new_parent); |
1841 view->parent_ = NULL; | 1913 view->parent_ = NULL; |
1842 view->UpdateLayerVisibility(); | 1914 view->UpdateLayerVisibility(); |
1843 | 1915 |
1844 if (delete_removed_view && !view->owned_by_client_) | 1916 if (delete_removed_view && !view->owned_by_client_) |
1845 view_to_be_deleted.reset(view); | 1917 view_to_be_deleted.reset(view); |
1846 | 1918 |
1847 children_.erase(i); | 1919 children_.erase(i); |
1848 } | 1920 } |
1849 | 1921 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 for (int i = 0, count = child_count(); i < count; ++i) | 1993 for (int i = 0, count = child_count(); i < count; ++i) |
1922 child_at(i)->PropagateVisibilityNotifications(start, is_visible); | 1994 child_at(i)->PropagateVisibilityNotifications(start, is_visible); |
1923 VisibilityChangedImpl(start, is_visible); | 1995 VisibilityChangedImpl(start, is_visible); |
1924 } | 1996 } |
1925 | 1997 |
1926 void View::VisibilityChangedImpl(View* starting_from, bool is_visible) { | 1998 void View::VisibilityChangedImpl(View* starting_from, bool is_visible) { |
1927 VisibilityChanged(starting_from, is_visible); | 1999 VisibilityChanged(starting_from, is_visible); |
1928 } | 2000 } |
1929 | 2001 |
1930 void View::BoundsChanged(const gfx::Rect& previous_bounds) { | 2002 void View::BoundsChanged(const gfx::Rect& previous_bounds) { |
| 2003 // Mark our bounds as dirty for the paint root, also see if we need to |
| 2004 // recompute our children's bounds due to origin change. |
| 2005 bool origin_changed = |
| 2006 previous_bounds.OffsetFromOrigin() != bounds_.OffsetFromOrigin(); |
| 2007 SetRootBoundsDirty(origin_changed); |
| 2008 |
1931 if (visible_) { | 2009 if (visible_) { |
1932 // Paint the new bounds. | 2010 // Paint the new bounds. |
1933 SchedulePaintBoundsChanged( | 2011 SchedulePaintBoundsChanged( |
1934 bounds_.size() == previous_bounds.size() ? SCHEDULE_PAINT_SIZE_SAME : | 2012 bounds_.size() == previous_bounds.size() ? SCHEDULE_PAINT_SIZE_SAME : |
1935 SCHEDULE_PAINT_SIZE_CHANGED); | 2013 SCHEDULE_PAINT_SIZE_CHANGED); |
1936 } | 2014 } |
1937 | 2015 |
1938 if (layer()) { | 2016 if (layer()) { |
1939 if (parent_) { | 2017 if (parent_) { |
1940 SetLayerBounds(GetLocalBounds() + | 2018 SetLayerBounds(GetLocalBounds() + |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 DCHECK(i != descendants_to_notify_->end()); | 2095 DCHECK(i != descendants_to_notify_->end()); |
2018 descendants_to_notify_->erase(i); | 2096 descendants_to_notify_->erase(i); |
2019 if (descendants_to_notify_->empty()) | 2097 if (descendants_to_notify_->empty()) |
2020 descendants_to_notify_.reset(); | 2098 descendants_to_notify_.reset(); |
2021 } | 2099 } |
2022 | 2100 |
2023 void View::SetLayerBounds(const gfx::Rect& bounds) { | 2101 void View::SetLayerBounds(const gfx::Rect& bounds) { |
2024 layer()->SetBounds(bounds); | 2102 layer()->SetBounds(bounds); |
2025 } | 2103 } |
2026 | 2104 |
| 2105 void View::SetRootBoundsDirty(bool origin_changed) { |
| 2106 root_bounds_dirty_ = true; |
| 2107 |
| 2108 if (origin_changed) { |
| 2109 // Inform our children that their root bounds are dirty, as their relative |
| 2110 // coordinates in paint root space have changed since ours have changed. |
| 2111 for (Views::const_iterator i(children_.begin()); i != children_.end(); |
| 2112 ++i) { |
| 2113 if (!(*i)->IsPaintRoot()) |
| 2114 (*i)->SetRootBoundsDirty(origin_changed); |
| 2115 } |
| 2116 } |
| 2117 } |
| 2118 |
| 2119 void View::UpdateRootBounds(gfx::RTree* tree, const gfx::Vector2d& offset) { |
| 2120 // No need to recompute bounds if we haven't flagged ours as dirty. |
| 2121 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); |
| 2122 |
| 2123 // Add our own offset to the provided offset, for our own bounds update and |
| 2124 // for propagation to our children if needed. |
| 2125 gfx::Vector2d view_offset = offset + bounds_.OffsetFromOrigin(); |
| 2126 |
| 2127 // If our bounds have changed we must re-insert our new bounds to the tree. |
| 2128 if (root_bounds_dirty_) { |
| 2129 root_bounds_dirty_ = false; |
| 2130 gfx::Rect bounds( |
| 2131 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); |
| 2132 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); |
| 2133 } |
| 2134 |
| 2135 // Update our children's bounds if needed. |
| 2136 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
| 2137 // We don't descend in to layer views for bounds recomputation, as they |
| 2138 // manage their own RTree as paint roots. |
| 2139 if (!(*i)->IsPaintRoot()) |
| 2140 (*i)->UpdateRootBounds(tree, view_offset); |
| 2141 } |
| 2142 } |
| 2143 |
| 2144 void View::RemoveRootBounds(gfx::RTree* tree) { |
| 2145 tree->Remove(reinterpret_cast<intptr_t>(this)); |
| 2146 |
| 2147 root_bounds_dirty_ = true; |
| 2148 |
| 2149 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
| 2150 if (!(*i)->IsPaintRoot()) |
| 2151 (*i)->RemoveRootBounds(tree); |
| 2152 } |
| 2153 } |
| 2154 |
| 2155 gfx::RTree* View::GetBoundsTreeFromPaintRoot() { |
| 2156 gfx::RTree* bounds_tree = bounds_tree_.get(); |
| 2157 View* paint_root = this; |
| 2158 while (!bounds_tree && !paint_root->IsPaintRoot()) { |
| 2159 // Assumption is that if IsPaintRoot() is false then parent_ is valid. |
| 2160 DCHECK(paint_root); |
| 2161 paint_root = paint_root->parent_; |
| 2162 bounds_tree = paint_root->bounds_tree_.get(); |
| 2163 } |
| 2164 |
| 2165 return bounds_tree; |
| 2166 } |
| 2167 |
2027 // Transformations ------------------------------------------------------------- | 2168 // Transformations ------------------------------------------------------------- |
2028 | 2169 |
2029 bool View::GetTransformRelativeTo(const View* ancestor, | 2170 bool View::GetTransformRelativeTo(const View* ancestor, |
2030 gfx::Transform* transform) const { | 2171 gfx::Transform* transform) const { |
2031 const View* p = this; | 2172 const View* p = this; |
2032 | 2173 |
2033 while (p && p != ancestor) { | 2174 while (p && p != ancestor) { |
2034 transform->ConcatTransform(p->GetTransform()); | 2175 transform->ConcatTransform(p->GetTransform()); |
2035 gfx::Transform translation; | 2176 gfx::Transform translation; |
2036 translation.Translate(static_cast<float>(p->GetMirroredX()), | 2177 translation.Translate(static_cast<float>(p->GetMirroredX()), |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 // Message the RootView to do the drag and drop. That way if we're removed | 2535 // Message the RootView to do the drag and drop. That way if we're removed |
2395 // the RootView can detect it and avoid calling us back. | 2536 // the RootView can detect it and avoid calling us back. |
2396 gfx::Point widget_location(event.location()); | 2537 gfx::Point widget_location(event.location()); |
2397 ConvertPointToWidget(this, &widget_location); | 2538 ConvertPointToWidget(this, &widget_location); |
2398 widget->RunShellDrag(this, data, widget_location, drag_operations, source); | 2539 widget->RunShellDrag(this, data, widget_location, drag_operations, source); |
2399 // WARNING: we may have been deleted. | 2540 // WARNING: we may have been deleted. |
2400 return true; | 2541 return true; |
2401 } | 2542 } |
2402 | 2543 |
2403 } // namespace views | 2544 } // namespace views |
OLD | NEW |