Index: mojo/ui/associates/view_tree_hit_tester_client.cc |
diff --git a/mojo/ui/associates/view_tree_hit_tester_client.cc b/mojo/ui/associates/view_tree_hit_tester_client.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c98d059a22b1e6835167dd7a6603f15751b8f674 |
--- /dev/null |
+++ b/mojo/ui/associates/view_tree_hit_tester_client.cc |
@@ -0,0 +1,92 @@ |
+// Copyright 2016 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 "mojo/ui/associates/view_tree_hit_tester_client.h" |
+ |
+#include "base/bind.h" |
+#include "base/logging.h" |
+ |
+namespace mojo { |
+namespace ui { |
+ |
+ViewTreeHitTesterClient::ViewTreeHitTesterClient( |
+ const scoped_refptr<ViewInspectorClient>& view_inspector_client, |
+ mojo::ui::ViewTreeTokenPtr view_tree_token) |
+ : view_inspector_client_(view_inspector_client), |
+ view_tree_token_(view_tree_token.Pass()), |
+ weak_factory_(this) { |
+ DCHECK(view_inspector_client_); |
+ DCHECK(view_tree_token_); |
+ |
+ UpdateHitTester(); |
+} |
+ |
+ViewTreeHitTesterClient::~ViewTreeHitTesterClient() {} |
+ |
+void ViewTreeHitTesterClient::HitTest(mojo::PointPtr point, |
+ const ResolvedHitsCallback& callback) { |
+ if (!hit_tester_) { |
+ callback.Run(nullptr); |
+ return; |
+ } |
+ |
+ // TODO(jeffbrown): Here we are assuming that the hit test callbacks will be |
+ // invoked in FIFO order. It might be a good idea to eliminate that |
+ // assumption. |
+ pending_callbacks_.push(callback); |
+ hit_tester_->HitTest(point.Pass(), |
+ base::Bind(&ViewTreeHitTesterClient::OnHitTestResult, |
+ base::Unretained(this))); |
+} |
+ |
+void ViewTreeHitTesterClient::OnHitTestResult( |
+ mojo::gfx::composition::HitTestResultPtr result) { |
+ DCHECK(result); |
+ DCHECK(!pending_callbacks_.empty()); |
+ |
+ view_inspector_client_->ResolveHits(result.Pass(), |
+ pending_callbacks_.front()); |
+ pending_callbacks_.pop(); |
+} |
+ |
+void ViewTreeHitTesterClient::UpdateHitTester() { |
+ DCHECK(!hit_tester_); |
+ |
+ view_inspector_client_->view_inspector()->GetHitTester( |
+ view_tree_token_.Clone(), mojo::GetProxy(&hit_tester_), |
+ base::Bind(&ViewTreeHitTesterClient::OnHitTesterInvalidated, |
+ weak_factory_.GetWeakPtr())); |
+ |
+ hit_tester_.set_connection_error_handler(base::Bind( |
+ &ViewTreeHitTesterClient::OnHitTesterDied, base::Unretained(this))); |
+} |
+ |
+void ViewTreeHitTesterClient::ReleaseHitTester() { |
+ hit_tester_.reset(); |
+ |
+ while (!pending_callbacks_.empty()) { |
+ pending_callbacks_.front().Run(nullptr); |
+ pending_callbacks_.pop(); |
+ } |
+} |
+ |
+void ViewTreeHitTesterClient::OnHitTesterInvalidated(bool renderer_changed) { |
+ ReleaseHitTester(); |
+ |
+ if (renderer_changed) |
+ UpdateHitTester(); |
+ |
+ if (!hit_tester_changed_callback_.is_null()) |
+ hit_tester_changed_callback_.Run(); |
+} |
+ |
+void ViewTreeHitTesterClient::OnHitTesterDied() { |
+ ReleaseHitTester(); |
+ |
+ if (!hit_tester_changed_callback_.is_null()) |
+ hit_tester_changed_callback_.Run(); |
+} |
+ |
+} // namespace ui |
+} // namespace mojo |