OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "views/view.h" | 5 #include "views/view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
| 9 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "third_party/skia/include/core/SkRect.h" | 14 #include "third_party/skia/include/core/SkRect.h" |
14 #include "ui/base/accessibility/accessibility_types.h" | 15 #include "ui/base/accessibility/accessibility_types.h" |
15 #include "ui/base/dragdrop/drag_drop_types.h" | 16 #include "ui/base/dragdrop/drag_drop_types.h" |
16 #include "ui/gfx/canvas_skia.h" | 17 #include "ui/gfx/canvas_skia.h" |
17 #include "ui/gfx/compositor/compositor.h" | 18 #include "ui/gfx/compositor/compositor.h" |
18 #include "ui/gfx/compositor/layer.h" | 19 #include "ui/gfx/compositor/layer.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 clip_y_(0.0), | 109 clip_y_(0.0), |
109 needs_layout_(true), | 110 needs_layout_(true), |
110 flip_canvas_on_paint_for_rtl_ui_(false), | 111 flip_canvas_on_paint_for_rtl_ui_(false), |
111 accelerator_registration_delayed_(false), | 112 accelerator_registration_delayed_(false), |
112 accelerator_focus_manager_(NULL), | 113 accelerator_focus_manager_(NULL), |
113 registered_accelerator_count_(0), | 114 registered_accelerator_count_(0), |
114 next_focusable_view_(NULL), | 115 next_focusable_view_(NULL), |
115 previous_focusable_view_(NULL), | 116 previous_focusable_view_(NULL), |
116 focusable_(false), | 117 focusable_(false), |
117 accessibility_focusable_(false), | 118 accessibility_focusable_(false), |
| 119 painting_enabled_(true), |
118 context_menu_controller_(NULL), | 120 context_menu_controller_(NULL), |
119 drag_controller_(NULL) { | 121 drag_controller_(NULL) { |
120 } | 122 } |
121 | 123 |
122 View::~View() { | 124 View::~View() { |
123 if (parent_) | 125 if (parent_) |
124 parent_->RemoveChildView(this); | 126 parent_->RemoveChildView(this); |
125 | 127 |
126 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { | 128 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { |
127 (*i)->parent_ = NULL; | 129 (*i)->parent_ = NULL; |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 } | 415 } |
414 | 416 |
415 bool View::IsEnabled() const { | 417 bool View::IsEnabled() const { |
416 return enabled_; | 418 return enabled_; |
417 } | 419 } |
418 | 420 |
419 void View::OnEnabledChanged() { | 421 void View::OnEnabledChanged() { |
420 SchedulePaint(); | 422 SchedulePaint(); |
421 } | 423 } |
422 | 424 |
| 425 void View::SetPaintingEnabled(bool enabled) { |
| 426 painting_enabled_ = enabled; |
| 427 } |
| 428 |
| 429 bool View::IsPaintingEnabled() const { |
| 430 return painting_enabled_; |
| 431 } |
| 432 |
423 // Transformations ------------------------------------------------------------- | 433 // Transformations ------------------------------------------------------------- |
424 | 434 |
425 const ui::Transform& View::GetTransform() const { | 435 const ui::Transform& View::GetTransform() const { |
426 static const ui::Transform* no_op = new ui::Transform; | 436 static const ui::Transform* no_op = new ui::Transform; |
427 return transform() ? *transform() : *no_op; | 437 return transform() ? *transform() : *no_op; |
428 } | 438 } |
429 | 439 |
430 void View::SetTransform(const ui::Transform& transform) { | 440 void View::SetTransform(const ui::Transform& transform) { |
431 if (!transform.HasChange()) { | 441 if (!transform.HasChange()) { |
432 if (!layer_helper_.get() || !this->transform()) | 442 if (!layer_helper_.get() || !this->transform()) |
433 return; | 443 return; |
434 layer_helper_->SetTransform(transform); | 444 layer_helper_->SetTransform(transform); |
435 | 445 |
436 if (!ShouldPaintToLayer()) | 446 if (!ShouldPaintToLayer()) |
437 DestroyLayerAndReparent(); | 447 DestroyLayerAndReparent(); |
438 else if (layer()) | 448 else if (layer()) |
439 layer_helper_->property_setter()->SetTransform(layer(), transform); | 449 layer_helper_->property_setter()->SetTransform(layer(), transform); |
440 | 450 |
441 SchedulePaint(); | 451 SchedulePaint(); |
442 } else { | 452 } else { |
443 // Make sure if the view didn't have its own texture and was painting onto | |
444 // something else, that gets refreshed too. | |
445 if (!ShouldPaintToLayer()) | |
446 MarkLayerDirty(); | |
447 | |
448 if (!layer_helper_.get()) | 453 if (!layer_helper_.get()) |
449 layer_helper_.reset(new internal::LayerHelper()); | 454 layer_helper_.reset(new internal::LayerHelper()); |
450 layer_helper_->SetTransform(transform); | 455 layer_helper_->SetTransform(transform); |
451 if (!layer()) { | 456 if (!layer()) { |
452 CreateLayer(); | 457 CreateLayer(); |
453 SchedulePaint(); | 458 SchedulePaint(); |
454 } else { | 459 } else { |
455 layer_helper_->property_setter()->SetTransform(layer(), transform); | 460 layer_helper_->property_setter()->SetTransform(layer(), transform); |
456 // We have a layer. When the transform changes and the layer is up to | 461 ScheduleComposite(); |
457 // date we don't want to SchedulePaint as it'll trigger painting to the | |
458 // layer. Instead we tell the Widget to paint, which makes the | |
459 // compositor draw using the existing layer. | |
460 // We schedule paint the complete bounds as compositor generally don't | |
461 // support partial painting. | |
462 Widget* widget = GetWidget(); | |
463 if (widget) | |
464 widget->SchedulePaintInRect(widget->GetRootView()->bounds()); | |
465 } | 462 } |
466 } | 463 } |
467 } | 464 } |
468 | 465 |
469 void View::SetPaintToLayer(bool value) { | 466 void View::SetPaintToLayer(bool value) { |
470 bool paint_to_layer = layer_helper_.get() && layer_helper_->paint_to_layer(); | 467 bool paint_to_layer = layer_helper_.get() && layer_helper_->paint_to_layer(); |
471 if (value == paint_to_layer) | 468 if (value == paint_to_layer) |
472 return; | 469 return; |
473 | 470 |
474 if (value) { | 471 if (value) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 return base::i18n::IsRTL() ? width() - x : x; | 517 return base::i18n::IsRTL() ? width() - x : x; |
521 } | 518 } |
522 | 519 |
523 int View::GetMirroredXWithWidthInView(int x, int w) const { | 520 int View::GetMirroredXWithWidthInView(int x, int w) const { |
524 return base::i18n::IsRTL() ? width() - x - w : x; | 521 return base::i18n::IsRTL() ? width() - x - w : x; |
525 } | 522 } |
526 | 523 |
527 // Layout ---------------------------------------------------------------------- | 524 // Layout ---------------------------------------------------------------------- |
528 | 525 |
529 void View::Layout() { | 526 void View::Layout() { |
| 527 TRACE_EVENT0("View", "Layout"); |
530 needs_layout_ = false; | 528 needs_layout_ = false; |
531 | 529 |
532 // If we have a layout manager, let it handle the layout for us. | 530 // If we have a layout manager, let it handle the layout for us. |
533 if (layout_manager_.get()) | 531 if (layout_manager_.get()) |
534 layout_manager_->Layout(this); | 532 layout_manager_->Layout(this); |
535 | 533 |
536 // Make sure to propagate the Layout() call to any children that haven't | 534 // Make sure to propagate the Layout() call to any children that haven't |
537 // received it yet through the layout manager and need to be laid out. This | 535 // received it yet through the layout manager and need to be laid out. This |
538 // is needed for the case when the child requires a layout but its bounds | 536 // is needed for the case when the child requires a layout but its bounds |
539 // weren't changed by the layout manager. If there is no layout manager, we | 537 // weren't changed by the layout manager. If there is no layout manager, we |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 } | 686 } |
689 | 687 |
690 void View::SchedulePaintInRect(const gfx::Rect& rect) { | 688 void View::SchedulePaintInRect(const gfx::Rect& rect) { |
691 if (!IsVisible()) | 689 if (!IsVisible()) |
692 return; | 690 return; |
693 | 691 |
694 MarkLayerDirty(); | 692 MarkLayerDirty(); |
695 SchedulePaintInternal(rect); | 693 SchedulePaintInternal(rect); |
696 } | 694 } |
697 | 695 |
| 696 void View::ScheduleComposite() { |
| 697 ScheduleCompositeInRect(GetLocalBounds()); |
| 698 } |
| 699 |
| 700 void View::ScheduleCompositeInRect(const gfx::Rect& rect) { |
| 701 if (!IsVisible()) |
| 702 return; |
| 703 |
| 704 SchedulePaintInternal(rect); |
| 705 } |
| 706 |
698 void View::Paint(gfx::Canvas* canvas) { | 707 void View::Paint(gfx::Canvas* canvas) { |
699 if (!IsVisible()) | 708 TRACE_EVENT0("View", "Paint"); |
| 709 if (!IsVisible() || !IsPaintingEnabled()) |
700 return; | 710 return; |
701 | 711 |
702 ScopedCanvas scoped_canvas(NULL); | 712 ScopedCanvas scoped_canvas(NULL); |
703 scoped_ptr<gfx::Canvas> layer_canvas; | 713 scoped_ptr<gfx::Canvas> layer_canvas; |
704 gfx::Rect layer_rect; | 714 gfx::Rect layer_rect; |
705 | 715 |
706 if (layer()) { | 716 if (layer()) { |
707 gfx::Rect dirty_rect; | 717 gfx::Rect dirty_rect; |
708 if (!layer_helper_->clip_rect().IsEmpty()) { | 718 if (!layer_helper_->clip_rect().IsEmpty()) { |
709 dirty_rect = layer_helper_->clip_rect(); | 719 dirty_rect = layer_helper_->clip_rect(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 } | 1174 } |
1165 | 1175 |
1166 void View::OnPaintFocusBorder(gfx::Canvas* canvas) { | 1176 void View::OnPaintFocusBorder(gfx::Canvas* canvas) { |
1167 if ((IsFocusable() || IsAccessibilityFocusableInRootView()) && HasFocus()) | 1177 if ((IsFocusable() || IsAccessibilityFocusableInRootView()) && HasFocus()) |
1168 canvas->DrawFocusRect(0, 0, width(), height()); | 1178 canvas->DrawFocusRect(0, 0, width(), height()); |
1169 } | 1179 } |
1170 | 1180 |
1171 // Accelerated Painting -------------------------------------------------------- | 1181 // Accelerated Painting -------------------------------------------------------- |
1172 | 1182 |
1173 void View::PaintComposite() { | 1183 void View::PaintComposite() { |
| 1184 TRACE_EVENT0("View", "PaintComposite"); |
1174 if (!IsVisible()) | 1185 if (!IsVisible()) |
1175 return; | 1186 return; |
1176 | 1187 |
1177 if (layer()) { | 1188 if (layer()) { |
1178 OnWillCompositeLayer(); | 1189 OnWillCompositeLayer(); |
1179 layer()->Draw(); | 1190 layer()->Draw(); |
1180 } | 1191 } |
1181 | 1192 |
1182 for (int i = 0, count = child_count(); i < count; ++i) | 1193 for (int i = 0, count = child_count(); i < count; ++i) |
1183 GetChildViewAt(i)->PaintComposite(); | 1194 GetChildViewAt(i)->PaintComposite(); |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 result.append(GetChildViewAt(i)->PrintViewGraph(false)); | 2056 result.append(GetChildViewAt(i)->PrintViewGraph(false)); |
2046 | 2057 |
2047 if (first) | 2058 if (first) |
2048 result.append("}\n"); | 2059 result.append("}\n"); |
2049 | 2060 |
2050 return result; | 2061 return result; |
2051 } | 2062 } |
2052 #endif | 2063 #endif |
2053 | 2064 |
2054 } // namespace views | 2065 } // namespace views |
OLD | NEW |