Commit d8315d22 authored by sky@chromium.org's avatar sky@chromium.org

Wires up painting of layerless children

BUG=none
TEST=covered by tests.
R=ben@chromium.org

Review URL: https://codereview.chromium.org/102313002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238453 0039d316-1c4b-4281-b951-d872f2087c98
parent 95e0955c
......@@ -32,6 +32,7 @@
#include "ui/gfx/animation/multi_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/path.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/gfx/screen.h"
namespace aura {
......@@ -829,7 +830,8 @@ void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
}
void Window::SetVisible(bool visible) {
if (visible == layer_->GetTargetVisibility())
if ((layer_ && visible == layer_->GetTargetVisibility()) ||
(!layer_ && visible == visible_))
return; // No change.
FOR_EACH_OBSERVER(WindowObserver, observers_,
......@@ -843,7 +845,7 @@ void Window::SetVisible(bool visible) {
client::GetVisibilityClient(this);
if (visibility_client)
visibility_client->UpdateLayerVisibility(this, visible);
else
else if (layer_)
layer_->SetVisible(visible);
visible_ = visible;
SchedulePaint();
......@@ -863,6 +865,25 @@ void Window::SchedulePaint() {
SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
}
void Window::Paint(gfx::Canvas* canvas) {
if (delegate_)
delegate_->OnPaint(canvas);
PaintLayerlessChildren(canvas);
}
void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
for (size_t i = 0, count = children_.size(); i < count; ++i) {
Window* child = children_[i];
if (!child->layer_ && child->visible_) {
gfx::ScopedCanvas scoped_canvas(canvas);
if (canvas->ClipRect(child->bounds())) {
canvas->Translate(child->bounds().OffsetFromOrigin());
child->Paint(canvas);
}
}
}
}
Window* Window::GetWindowForPoint(const gfx::Point& local_point,
bool return_tightest,
bool for_event_handling) {
......@@ -1293,8 +1314,7 @@ void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds,
}
void Window::OnPaintLayer(gfx::Canvas* canvas) {
if (delegate_)
delegate_->OnPaint(canvas);
Paint(canvas);
}
base::Closure Window::PrepareForLayerBoundsChange() {
......
......@@ -402,6 +402,13 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Schedules a paint for the Window's entire bounds.
void SchedulePaint();
// Asks the delegate to paint the window and invokes PaintLayerlessChildren()
// to paint any children with no layers.
void Paint(gfx::Canvas* canvas);
// Paints any layerless children to |canvas|.
void PaintLayerlessChildren(gfx::Canvas* canvas);
// Gets a Window (either this one or a subwindow) containing |local_point|.
// If |return_tightest| is true, returns the tightest-containing (i.e.
// furthest down the hierarchy) Window containing the point; otherwise,
......
......@@ -41,6 +41,7 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vector2d.h"
DECLARE_WINDOW_PROPERTY_TYPE(const char*)
DECLARE_WINDOW_PROPERTY_TYPE(int)
......@@ -3366,5 +3367,105 @@ TEST_F(WindowTest, NestedLayerlessWindowsBoundsOnSetBounds) {
delete w1ll;
}
namespace {
// Tracks the number of times paint is invoked along with what the clip and
// translate was.
class PaintWindowDelegate : public TestWindowDelegate {
public:
PaintWindowDelegate() : paint_count_(0) {}
virtual ~PaintWindowDelegate() {}
const gfx::Rect& most_recent_paint_clip_bounds() const {
return most_recent_paint_clip_bounds_;
}
const gfx::Vector2d& most_recent_paint_matrix_offset() const {
return most_recent_paint_matrix_offset_;
}
void clear_paint_count() { paint_count_ = 0; }
int paint_count() const { return paint_count_; }
// TestWindowDelegate::
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
paint_count_++;
canvas->GetClipBounds(&most_recent_paint_clip_bounds_);
const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
most_recent_paint_matrix_offset_ = gfx::Vector2d(
SkScalarFloorToInt(matrix.getTranslateX()),
SkScalarFloorToInt(matrix.getTranslateY()));
}
private:
int paint_count_;
gfx::Rect most_recent_paint_clip_bounds_;
gfx::Vector2d most_recent_paint_matrix_offset_;
DISALLOW_COPY_AND_ASSIGN(PaintWindowDelegate);
};
} // namespace
// Assertions around layerless children being painted when non-layerless window
// is painted.
TEST_F(WindowTest, PaintLayerless) {
// Creates the following structure (all children owned by root):
// root
// w1ll 1,2 40x50
// w11ll 3,4 11x12
// w111 5,6
//
// ll: layer less, eg no layer
PaintWindowDelegate w1ll_delegate;
PaintWindowDelegate w11ll_delegate;
PaintWindowDelegate w111_delegate;
Window root(NULL);
root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
root.SetBounds(gfx::Rect(0, 0, 100, 100));
Window* w1ll = new Window(&w1ll_delegate);
w1ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
w1ll->SetBounds(gfx::Rect(1, 2, 40, 50));
w1ll->Show();
root.AddChild(w1ll);
Window* w11ll = new Window(&w11ll_delegate);
w11ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
w11ll->SetBounds(gfx::Rect(3, 4, 11, 12));
w11ll->Show();
w1ll->AddChild(w11ll);
Window* w111 = new Window(&w111_delegate);
w111->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
w111->SetBounds(gfx::Rect(5, 6, 100, 100));
w111->Show();
w11ll->AddChild(w111);
EXPECT_EQ(0, w1ll_delegate.paint_count());
EXPECT_EQ(0, w11ll_delegate.paint_count());
EXPECT_EQ(0, w111_delegate.paint_count());
// Paint the root, this should trigger painting of the two layerless
// descendants but not the layered descendant.
gfx::Canvas canvas(gfx::Size(200, 200), 1.0f, true);
static_cast<ui::LayerDelegate&>(root).OnPaintLayer(&canvas);
// NOTE: SkCanvas::getClipBounds() extends the clip 1 pixel to the left and up
// and 2 pixels down and to the right.
EXPECT_EQ(1, w1ll_delegate.paint_count());
EXPECT_EQ("-1,-1 42x52",
w1ll_delegate.most_recent_paint_clip_bounds().ToString());
EXPECT_EQ("[1 2]",
w1ll_delegate.most_recent_paint_matrix_offset().ToString());
EXPECT_EQ(1, w11ll_delegate.paint_count());
EXPECT_EQ("-1,-1 13x14",
w11ll_delegate.most_recent_paint_clip_bounds().ToString());
EXPECT_EQ("[4 6]",
w11ll_delegate.most_recent_paint_matrix_offset().ToString());
EXPECT_EQ(0, w111_delegate.paint_count());
}
} // namespace test
} // namespace aura
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment