summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-29 20:33:53 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-29 20:33:53 +0000
commitad72589169dcb25134e1aafef502680f8feab8e4 (patch)
tree083104f7f6d4d60363b54df434a9d0dffb342ab6 /ui
parentfa70c11b670acb36641bec22c8834b06d0b9c8dc (diff)
downloadchromium_src-ad72589169dcb25134e1aafef502680f8feab8e4.zip
chromium_src-ad72589169dcb25134e1aafef502680f8feab8e4.tar.gz
chromium_src-ad72589169dcb25134e1aafef502680f8feab8e4.tar.bz2
Adds support for point conversions to ui::Layer.
Also adds a skeleton for testing compositor API changes. BUG=none TEST=see unittest Review URL: http://codereview.chromium.org/7769001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98689 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/compositor/compositor.gyp27
-rw-r--r--ui/gfx/compositor/layer.cc60
-rw-r--r--ui/gfx/compositor/layer.h16
-rw-r--r--ui/gfx/compositor/layer_unittest.cc162
-rw-r--r--ui/gfx/compositor/run_all_unittests.cc9
-rw-r--r--ui/gfx/compositor/test_compositor_host.h36
-rw-r--r--ui/gfx/compositor/test_compositor_host_win.cc64
-rw-r--r--ui/gfx/compositor/test_suite.cc32
-rw-r--r--ui/gfx/compositor/test_suite.h22
-rw-r--r--ui/ui.gyp2
10 files changed, 430 insertions, 0 deletions
diff --git a/ui/gfx/compositor/compositor.gyp b/ui/gfx/compositor/compositor.gyp
index 5a76bce..7614e15 100644
--- a/ui/gfx/compositor/compositor.gyp
+++ b/ui/gfx/compositor/compositor.gyp
@@ -76,5 +76,32 @@
}],
],
},
+
+ {
+ 'target_name': 'compositor_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:base',
+ '<(DEPTH)/base/base.gyp:test_support_base',
+ '<(DEPTH)/skia/skia.gyp:skia',
+ '<(DEPTH)/testing/gtest.gyp:gtest',
+ '<(DEPTH)/ui/gfx/gl/gl.gyp:gl',
+ '<(DEPTH)/ui/ui.gyp:gfx_resources',
+ '<(DEPTH)/ui/ui.gyp:ui',
+ '<(DEPTH)/ui/ui.gyp:ui_resources',
+ 'compositor',
+ ],
+ 'sources': [
+ 'layer_unittest.cc',
+ 'run_all_unittests.cc',
+ 'test_compositor_host.h',
+ 'test_compositor_host_win.cc',
+ 'test_suite.cc',
+ 'test_suite.h',
+ '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc',
+ '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc',
+ ],
+ },
+
],
}
diff --git a/ui/gfx/compositor/layer.cc b/ui/gfx/compositor/layer.cc
index 8061294..4f1ed241 100644
--- a/ui/gfx/compositor/layer.cc
+++ b/ui/gfx/compositor/layer.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/logging.h"
+#include "ui/gfx/point3.h"
namespace ui {
@@ -45,6 +46,14 @@ void Layer::Remove(Layer* child) {
RecomputeHole();
}
+bool Layer::Contains(const Layer* other) const {
+ for (const Layer* parent = other; parent; parent = parent->parent()) {
+ if (parent == this)
+ return true;
+ }
+ return false;
+}
+
void Layer::SetTransform(const ui::Transform& transform) {
transform_ = transform;
@@ -59,6 +68,25 @@ void Layer::SetBounds(const gfx::Rect& bounds) {
parent()->RecomputeHole();
}
+// static
+void Layer::ConvertPointToLayer(const Layer* source,
+ const Layer* target,
+ gfx::Point* point) {
+ const Layer* inner = NULL;
+ const Layer* outer = NULL;
+ if (source->Contains(target)) {
+ inner = target;
+ outer = source;
+ inner->ConvertPointFromAncestor(outer, point);
+ } else if (target->Contains(source)) {
+ inner = source;
+ outer = target;
+ inner->ConvertPointForAncestor(outer, point);
+ } else {
+ NOTREACHED(); // |source| and |target| are in unrelated hierarchies.
+ }
+}
+
void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
if (fills_bounds_opaquely_ == fills_bounds_opaquely)
return;
@@ -144,4 +172,36 @@ void Layer::RecomputeHole() {
hole_rect_ = gfx::Rect();
}
+bool Layer::ConvertPointForAncestor(const Layer* ancestor,
+ gfx::Point* point) const {
+ ui::Transform transform;
+ bool result = GetTransformRelativeTo(ancestor, &transform);
+ gfx::Point3f p(*point);
+ transform.TransformPoint(p);
+ *point = p.AsPoint();
+ return result;
+}
+
+bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
+ gfx::Point* point) const {
+ ui::Transform transform;
+ bool result = GetTransformRelativeTo(ancestor, &transform);
+ gfx::Point3f p(*point);
+ transform.TransformPointReverse(p);
+ *point = p.AsPoint();
+ return result;
+}
+
+bool Layer::GetTransformRelativeTo(const Layer* ancestor,
+ ui::Transform* transform) const {
+ const Layer* p = this;
+ for (; p && p != ancestor; p = p->parent()) {
+ if (p->transform().HasChange())
+ transform->ConcatTransform(p->transform());
+ transform->ConcatTranslate(static_cast<float>(p->bounds().x()),
+ static_cast<float>(p->bounds().y()));
+ }
+ return p == ancestor;
+}
+
} // namespace ui
diff --git a/ui/gfx/compositor/layer.h b/ui/gfx/compositor/layer.h
index 7bbc890..d523c9c 100644
--- a/ui/gfx/compositor/layer.h
+++ b/ui/gfx/compositor/layer.h
@@ -44,6 +44,9 @@ class COMPOSITOR_EXPORT Layer {
const Layer* parent() const { return parent_; }
Layer* parent() { return parent_; }
+ // Returns true if this Layer contains |other| somewhere in its children.
+ bool Contains(const Layer* other) const;
+
// The transform, relative to the parent.
void SetTransform(const ui::Transform& transform);
const ui::Transform& transform() const { return transform_; }
@@ -52,6 +55,13 @@ class COMPOSITOR_EXPORT Layer {
void SetBounds(const gfx::Rect& bounds);
const gfx::Rect& bounds() const { return bounds_; }
+ // Converts a point from the coordinates of |source| to the coordinates of
+ // |target|. Necessarily, |source| and |target| must inhabit the same Layer
+ // tree.
+ static void ConvertPointToLayer(const Layer* source,
+ const Layer* target,
+ gfx::Point* point);
+
// See description in View for details
void SetFillsBoundsOpaquely(bool fills_bounds_opaquely);
bool fills_bounds_opaquely() const { return fills_bounds_opaquely_; }
@@ -102,6 +112,12 @@ class COMPOSITOR_EXPORT Layer {
// view has no transfrom with respect to its parent.
void RecomputeHole();
+ bool ConvertPointForAncestor(const Layer* ancestor, gfx::Point* point) const;
+ bool ConvertPointFromAncestor(const Layer* ancestor, gfx::Point* point) const;
+
+ bool GetTransformRelativeTo(const Layer* ancestor,
+ Transform* transform) const;
+
Compositor* compositor_;
scoped_refptr<ui::Texture> texture_;
diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc
new file mode 100644
index 0000000..3a82d2a
--- /dev/null
+++ b/ui/gfx/compositor/layer_unittest.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/compositor/test_compositor_host.h"
+
+namespace ui {
+
+namespace {
+
+class LayerTest : public testing::Test {
+ public:
+ LayerTest() {}
+ virtual ~LayerTest() {}
+
+ // Overridden from testing::Test:
+ virtual void SetUp() OVERRIDE {
+ const gfx::Rect host_bounds(10, 10, 500, 500);
+ window_.reset(TestCompositorHost::Create(host_bounds));
+ window_->Show();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ }
+
+ Compositor* GetCompositor() {
+ return window_->GetCompositor();
+ }
+
+ Layer* CreateLayer() {
+ return new Layer(GetCompositor());
+ }
+
+ Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
+ Layer* layer = CreateLayer();
+ layer->SetBounds(bounds);
+ PaintColorToLayer(layer, color);
+ return layer;
+ }
+
+ gfx::Canvas* CreateCanvasForLayer(const Layer* layer) {
+ return gfx::Canvas::CreateCanvas(layer->bounds().width(),
+ layer->bounds().height(),
+ false);
+ }
+
+ void PaintColorToLayer(Layer* layer, SkColor color) {
+ scoped_ptr<gfx::Canvas> canvas(CreateCanvasForLayer(layer));
+ canvas->FillRectInt(color, 0, 0, layer->bounds().width(),
+ layer->bounds().height());
+ layer->SetCanvas(*canvas->AsCanvasSkia(), layer->bounds().origin());
+ }
+
+ void DrawTree(Layer* root) {
+ window_->GetCompositor()->NotifyStart();
+ DrawLayerChildren(root);
+ window_->GetCompositor()->NotifyEnd();
+ }
+
+ void DrawLayerChildren(Layer* layer) {
+ layer->Draw();
+ std::vector<Layer*>::const_iterator it = layer->children().begin();
+ while (it != layer->children().end()) {
+ DrawLayerChildren(*it);
+ ++it;
+ }
+ }
+
+ void RunPendingMessages() {
+ MessageLoop main_message_loop(MessageLoop::TYPE_UI);
+ MessageLoopForUI::current()->Run(NULL);
+ }
+
+ private:
+ scoped_ptr<TestCompositorHost> window_;
+
+ DISALLOW_COPY_AND_ASSIGN(LayerTest);
+};
+
+}
+
+TEST_F(LayerTest, Draw) {
+ scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
+ gfx::Rect(20, 20, 50, 50)));
+ DrawTree(layer.get());
+}
+
+// Create this hierarchy:
+// L1 - red
+// +-- L2 - blue
+// | +-- L3 - yellow
+// +-- L4 - magenta
+//
+TEST_F(LayerTest, Hierarchy) {
+ scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
+ gfx::Rect(20, 20, 400, 400)));
+ scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
+ gfx::Rect(10, 10, 350, 350)));
+ scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
+ gfx::Rect(5, 5, 25, 25)));
+ scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
+ gfx::Rect(300, 300, 100, 100)));
+
+ l1->Add(l2.get());
+ l1->Add(l4.get());
+ l2->Add(l3.get());
+
+ DrawTree(l1.get());
+}
+
+// L1
+// +-- L2
+TEST_F(LayerTest, ConvertPointToLayer_Simple) {
+ scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
+ gfx::Rect(20, 20, 400, 400)));
+ scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
+ gfx::Rect(10, 10, 350, 350)));
+ l1->Add(l2.get());
+ DrawTree(l1.get());
+
+ gfx::Point point1_in_l2_coords(5, 5);
+ Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
+ gfx::Point point1_in_l1_coords(15, 15);
+ EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
+
+ gfx::Point point2_in_l1_coords(5, 5);
+ Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
+ gfx::Point point2_in_l2_coords(-5, -5);
+ EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
+}
+
+// L1
+// +-- L2
+// +-- L3
+TEST_F(LayerTest, ConvertPointToLayer_Medium) {
+ scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
+ gfx::Rect(20, 20, 400, 400)));
+ scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
+ gfx::Rect(10, 10, 350, 350)));
+ scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
+ gfx::Rect(10, 10, 100, 100)));
+ l1->Add(l2.get());
+ l2->Add(l3.get());
+ DrawTree(l1.get());
+
+ gfx::Point point1_in_l3_coords(5, 5);
+ Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
+ gfx::Point point1_in_l1_coords(25, 25);
+ EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
+
+ gfx::Point point2_in_l1_coords(5, 5);
+ Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
+ gfx::Point point2_in_l3_coords(-15, -15);
+ EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
+}
+
+} // namespace ui
+
diff --git a/ui/gfx/compositor/run_all_unittests.cc b/ui/gfx/compositor/run_all_unittests.cc
new file mode 100644
index 0000000..5419134
--- /dev/null
+++ b/ui/gfx/compositor/run_all_unittests.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/compositor/test_suite.h"
+
+int main(int argc, char** argv) {
+ return CompositorTestSuite(argc, argv).Run();
+}
diff --git a/ui/gfx/compositor/test_compositor_host.h b/ui/gfx/compositor/test_compositor_host.h
new file mode 100644
index 0000000..f0bdbaa
--- /dev/null
+++ b/ui/gfx/compositor/test_compositor_host.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_COMPOSITOR_TEST_COMPOSITOR_HOST_H_
+#define UI_GFX_COMPOSITOR_TEST_COMPOSITOR_HOST_H_
+#pragma once
+
+#include "base/message_loop.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace gfx {
+class Rect;
+class Size;
+}
+
+namespace ui {
+
+class Compositor;
+
+class TestCompositorHost : public MessageLoop::Dispatcher {
+ public:
+ virtual ~TestCompositorHost() {}
+
+ // Creates a new TestCompositorHost. The caller owns the returned value.
+ static TestCompositorHost* Create(const gfx::Rect& bounds);
+
+ // Shows the TestCompositorHost.
+ virtual void Show() = 0;
+
+ virtual ui::Compositor* GetCompositor() = 0;
+};
+
+} // namespace ui
+
+#endif // UI_GFX_COMPOSITOR_TEST_COMPOSITOR_HOST_H_
diff --git a/ui/gfx/compositor/test_compositor_host_win.cc b/ui/gfx/compositor/test_compositor_host_win.cc
new file mode 100644
index 0000000..f126b08
--- /dev/null
+++ b/ui/gfx/compositor/test_compositor_host_win.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/compositor/test_compositor_host.h"
+
+#include "ui/base/win/window_impl.h"
+#include "ui/gfx/compositor/compositor.h"
+
+namespace ui {
+
+class TestCompositorHostWin : public TestCompositorHost,
+ public ui::WindowImpl {
+ public:
+ explicit TestCompositorHostWin(const gfx::Rect& bounds) {
+ Init(NULL, bounds);
+ compositor_ = ui::Compositor::Create(hwnd(), GetSize());
+ }
+
+ virtual ~TestCompositorHostWin() {
+ DestroyWindow(hwnd());
+ }
+
+ // Overridden from MessageLoop::Dispatcher:
+ virtual bool Dispatch(const MSG& msg) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ return true;
+ }
+
+ // Overridden from TestCompositorHost:
+ virtual void Show() OVERRIDE {
+ ShowWindow(hwnd(), SW_SHOWNORMAL);
+ }
+ virtual ui::Compositor* GetCompositor() OVERRIDE {
+ return compositor_;
+ }
+
+ private:
+ BEGIN_MSG_MAP_EX(TestCompositorHostWin)
+ MSG_WM_PAINT(OnPaint)
+ END_MSG_MAP()
+
+ void OnPaint(HDC dc) {
+ ValidateRect(hwnd(), NULL);
+ }
+
+ gfx::Size GetSize() {
+ RECT r;
+ GetClientRect(hwnd(), &r);
+ return gfx::Rect(r).size();
+ }
+
+ scoped_refptr<ui::Compositor> compositor_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCompositorHostWin);
+};
+
+TestCompositorHost* TestCompositorHost::Create(const gfx::Rect& bounds) {
+ return new TestCompositorHostWin(bounds);
+}
+
+} // namespace ui
+
diff --git a/ui/gfx/compositor/test_suite.cc b/ui/gfx/compositor/test_suite.cc
new file mode 100644
index 0000000..bcba004
--- /dev/null
+++ b/ui/gfx/compositor/test_suite.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/compositor/test_suite.h"
+
+#include "base/file_path.h"
+#include "base/path_service.h"
+#include "build/build_config.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_paths.h"
+#include "ui/gfx/gfx_paths.h"
+
+CompositorTestSuite::CompositorTestSuite(int argc, char** argv)
+ : TestSuite(argc, argv) {}
+
+void CompositorTestSuite::Initialize() {
+ base::TestSuite::Initialize();
+
+ gfx::RegisterPathProvider();
+ ui::RegisterPathProvider();
+
+ // Force unittests to run using en-US so if we test against string
+ // output, it'll pass regardless of the system language.
+ ui::ResourceBundle::InitSharedInstance("en-US");
+}
+
+void CompositorTestSuite::Shutdown() {
+ ui::ResourceBundle::CleanupSharedInstance();
+
+ base::TestSuite::Shutdown();
+}
diff --git a/ui/gfx/compositor/test_suite.h b/ui/gfx/compositor/test_suite.h
new file mode 100644
index 0000000..0472a24
--- /dev/null
+++ b/ui/gfx/compositor/test_suite.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_COMPOSITOR_TEST_SUITE_H_
+#define UI_GFX_COMPOSITOR_TEST_SUITE_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "base/test/test_suite.h"
+
+class CompositorTestSuite : public base::TestSuite {
+ public:
+ CompositorTestSuite(int argc, char** argv);
+
+ protected:
+ // base::TestSuite:
+ virtual void Initialize() OVERRIDE;
+ virtual void Shutdown() OVERRIDE;
+};
+
+#endif // UI_GFX_COMPOSITOR_TEST_SUITE_H_
diff --git a/ui/ui.gyp b/ui/ui.gyp
index 273d63c..a340465 100644
--- a/ui/ui.gyp
+++ b/ui/ui.gyp
@@ -293,6 +293,8 @@
['use_aura==1', {
'sources/': [
['exclude', 'gfx/screen_win.cc'],
+ ['exclude', 'base/win/mouse_wheel_util.cc'],
+ ['exclude', 'base/win/mouse_wheel_util.h'],
],
}],
['toolkit_uses_gtk == 1', {