| 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 |