Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: components/ui_devtools/views/ui_devtools_dom_agent.cc

Issue 2959263002: Show corresponding window/widget/view in UIElement tree when clicking on a UI element. (Closed)
Patch Set: set handled for cancelable event mouse click Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/ui_devtools/views/ui_devtools_dom_agent.h" 5 #include "components/ui_devtools/views/ui_devtools_dom_agent.h"
6 6
7 #include "components/ui_devtools/devtools_server.h" 7 #include "components/ui_devtools/devtools_server.h"
8 #include "components/ui_devtools/views/ui_devtools_overlay_agent.h"
8 #include "components/ui_devtools/views/ui_element.h" 9 #include "components/ui_devtools/views/ui_element.h"
9 #include "components/ui_devtools/views/view_element.h" 10 #include "components/ui_devtools/views/view_element.h"
10 #include "components/ui_devtools/views/widget_element.h" 11 #include "components/ui_devtools/views/widget_element.h"
11 #include "components/ui_devtools/views/window_element.h" 12 #include "components/ui_devtools/views/window_element.h"
12 #include "third_party/skia/include/core/SkColor.h" 13 #include "third_party/skia/include/core/SkColor.h"
13 #include "ui/aura/client/screen_position_client.h" 14 #include "ui/aura/client/screen_position_client.h"
14 #include "ui/aura/env.h" 15 #include "ui/aura/env.h"
15 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
16 #include "ui/aura/window_tree_host.h" 17 #include "ui/aura/window_tree_host.h"
17 #include "ui/display/display.h" 18 #include "ui/display/display.h"
18 #include "ui/display/screen.h" 19 #include "ui/display/screen.h"
19 #include "ui/views/background.h" 20 #include "ui/views/background.h"
20 #include "ui/views/border.h" 21 #include "ui/views/border.h"
22 #include "ui/views/pointer_watcher.h"
21 #include "ui/views/view.h" 23 #include "ui/views/view.h"
22 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
23 #include "ui/wm/core/window_util.h" 25 #include "ui/wm/core/window_util.h"
24 26
25 namespace ui_devtools { 27 namespace ui_devtools {
26 namespace { 28 namespace {
27 29
28 using namespace ui_devtools::protocol; 30 using namespace ui_devtools::protocol;
29 // TODO(mhashmi): Make ids reusable 31 // TODO(mhashmi): Make ids reusable
30 32
31 std::unique_ptr<DOM::Node> BuildNode( 33 std::unique_ptr<DOM::Node> BuildNode(
32 const std::string& name, 34 const std::string& name,
33 std::unique_ptr<Array<std::string>> attributes, 35 std::unique_ptr<Array<std::string>> attributes,
34 std::unique_ptr<Array<DOM::Node>> children, 36 std::unique_ptr<Array<DOM::Node>> children,
35 int node_ids) { 37 int node_ids) {
36 constexpr int kDomElementNodeType = 1; 38 constexpr int kDomElementNodeType = 1;
37 std::unique_ptr<DOM::Node> node = DOM::Node::create() 39 std::unique_ptr<DOM::Node> node = DOM::Node::create()
38 .setNodeId(node_ids) 40 .setNodeId(node_ids)
41 .setBackendNodeId(node_ids)
39 .setNodeName(name) 42 .setNodeName(name)
40 .setNodeType(kDomElementNodeType) 43 .setNodeType(kDomElementNodeType)
41 .setAttributes(std::move(attributes)) 44 .setAttributes(std::move(attributes))
42 .build(); 45 .build();
43 node->setChildNodeCount(static_cast<int>(children->length())); 46 node->setChildNodeCount(static_cast<int>(children->length()));
44 node->setChildren(std::move(children)); 47 node->setChildren(std::move(children));
45 return node; 48 return node;
46 } 49 }
47 50
48 // TODO(thanhph): Move this function to UIElement::GetAttributes(). 51 // TODO(thanhph): Move this function to UIElement::GetAttributes().
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 101 }
99 102
100 std::unique_ptr<DOM::Node> BuildDomNodeFromUIElement(UIElement* root) { 103 std::unique_ptr<DOM::Node> BuildDomNodeFromUIElement(UIElement* root) {
101 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 104 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
102 for (auto* it : root->children()) 105 for (auto* it : root->children())
103 children->addItem(BuildDomNodeFromUIElement(it)); 106 children->addItem(BuildDomNodeFromUIElement(it));
104 107
105 constexpr int kDomElementNodeType = 1; 108 constexpr int kDomElementNodeType = 1;
106 std::unique_ptr<DOM::Node> node = DOM::Node::create() 109 std::unique_ptr<DOM::Node> node = DOM::Node::create()
107 .setNodeId(root->node_id()) 110 .setNodeId(root->node_id())
111 .setBackendNodeId(root->node_id())
108 .setNodeName(root->GetTypeName()) 112 .setNodeName(root->GetTypeName())
109 .setNodeType(kDomElementNodeType) 113 .setNodeType(kDomElementNodeType)
110 .setAttributes(GetAttributes(root)) 114 .setAttributes(GetAttributes(root))
111 .build(); 115 .build();
112 node->setChildNodeCount(static_cast<int>(children->length())); 116 node->setChildNodeCount(static_cast<int>(children->length()));
113 node->setChildren(std::move(children)); 117 node->setChildren(std::move(children));
114 return node; 118 return node;
115 } 119 }
116 120
121 int FindUIElementIdForView(UIElement* root, views::View* element) {
122 if (root->type() == UIElementType::VIEW &&
123 UIElement::GetBackingElement<views::View, ViewElement>(root) == element)
124 return root->node_id();
125
126 for (auto* child : root->children()) {
127 int ui_element_id = FindUIElementIdForView(child, element);
128 if (ui_element_id)
129 return ui_element_id;
130 }
131 return 0;
132 }
133
134 int FindUIElementIdForWidget(UIElement* root, views::Widget* element) {
135 if (root->type() == UIElementType::WIDGET &&
136 UIElement::GetBackingElement<views::Widget, WidgetElement>(root) ==
137 element)
138 return root->node_id();
139
140 for (auto* child : root->children()) {
141 int ui_element_id = FindUIElementIdForWidget(child, element);
142 if (ui_element_id)
143 return ui_element_id;
144 }
145 return 0;
146 }
147
148 int FindUIElementIdForWindow(UIElement* root, aura::Window* element) {
149 if (root->type() == UIElementType::WINDOW &&
150 UIElement::GetBackingElement<aura::Window, WindowElement>(root) ==
151 element)
152 return root->node_id();
153
154 for (auto* child : root->children()) {
155 int ui_element_id = FindUIElementIdForWindow(child, element);
156 if (ui_element_id)
157 return ui_element_id;
158 }
159 return 0;
160 }
161
117 } // namespace 162 } // namespace
118 163
119 UIDevToolsDOMAgent::UIDevToolsDOMAgent() : is_building_tree_(false) { 164 UIDevToolsDOMAgent::UIDevToolsDOMAgent() : is_building_tree_(false) {
120 aura::Env::GetInstance()->AddObserver(this); 165 aura::Env::GetInstance()->AddObserver(this);
121 } 166 }
122 167
123 UIDevToolsDOMAgent::~UIDevToolsDOMAgent() { 168 UIDevToolsDOMAgent::~UIDevToolsDOMAgent() {
124 aura::Env::GetInstance()->RemoveObserver(this); 169 aura::Env::GetInstance()->RemoveObserver(this);
125 Reset(); 170 Reset();
126 } 171 }
127 172
128 ui_devtools::protocol::Response UIDevToolsDOMAgent::disable() { 173 ui_devtools::protocol::Response UIDevToolsDOMAgent::disable() {
129 Reset(); 174 Reset();
130 return ui_devtools::protocol::Response::OK(); 175 return ui_devtools::protocol::Response::OK();
131 } 176 }
132 177
133 ui_devtools::protocol::Response UIDevToolsDOMAgent::getDocument( 178 ui_devtools::protocol::Response UIDevToolsDOMAgent::getDocument(
134 std::unique_ptr<ui_devtools::protocol::DOM::Node>* out_root) { 179 std::unique_ptr<ui_devtools::protocol::DOM::Node>* out_root) {
135 *out_root = BuildInitialTree(); 180 *out_root = BuildInitialTree();
136 return ui_devtools::protocol::Response::OK(); 181 return ui_devtools::protocol::Response::OK();
137 } 182 }
138 183
139 ui_devtools::protocol::Response UIDevToolsDOMAgent::highlightNode(
140 std::unique_ptr<ui_devtools::protocol::DOM::HighlightConfig>
141 highlight_config,
142 ui_devtools::protocol::Maybe<int> node_id) {
143 return HighlightNode(std::move(highlight_config), node_id.fromJust());
144 }
145
146 ui_devtools::protocol::Response UIDevToolsDOMAgent::hideHighlight() { 184 ui_devtools::protocol::Response UIDevToolsDOMAgent::hideHighlight() {
147 if (layer_for_highlighting_ && layer_for_highlighting_->visible()) 185 if (layer_for_highlighting_ && layer_for_highlighting_->visible())
148 layer_for_highlighting_->SetVisible(false); 186 layer_for_highlighting_->SetVisible(false);
149 return ui_devtools::protocol::Response::OK(); 187 return ui_devtools::protocol::Response::OK();
150 } 188 }
151 189
190 ui_devtools::protocol::Response
191 UIDevToolsDOMAgent::pushNodesByBackendIdsToFrontend(
192 std::unique_ptr<protocol::Array<int>> backend_node_ids,
193 std::unique_ptr<protocol::Array<int>>* result) {
194 *result = protocol::Array<int>::create();
195 for (size_t index = 0; index < backend_node_ids->length(); ++index)
196 (*result)->addItem(backend_node_ids->get(index));
197 return ui_devtools::protocol::Response::OK();
198 }
199
200 ui_devtools::protocol::Response UIDevToolsDOMAgent::setInspectedNode(
201 int node_id) {
202 return ui_devtools::protocol::Response::OK();
203 }
204
152 void UIDevToolsDOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) { 205 void UIDevToolsDOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) {
153 // When parent is null, only need to update |node_id_to_ui_element_|. 206 // When parent is null, only need to update |node_id_to_ui_element_|.
154 if (!parent) { 207 if (!parent) {
155 node_id_to_ui_element_[child->node_id()] = child; 208 node_id_to_ui_element_[child->node_id()] = child;
156 return; 209 return;
157 } 210 }
158 // If tree is being built, don't add child to dom tree again. 211 // If tree is being built, don't add child to dom tree again.
159 if (is_building_tree_) 212 if (is_building_tree_)
160 return; 213 return;
161 DCHECK(node_id_to_ui_element_.count(parent->node_id())); 214 DCHECK(node_id_to_ui_element_.count(parent->node_id()));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 251 }
199 252
200 void UIDevToolsDOMAgent::RemoveObserver(UIDevToolsDOMAgentObserver* observer) { 253 void UIDevToolsDOMAgent::RemoveObserver(UIDevToolsDOMAgentObserver* observer) {
201 observers_.RemoveObserver(observer); 254 observers_.RemoveObserver(observer);
202 } 255 }
203 256
204 UIElement* UIDevToolsDOMAgent::GetElementFromNodeId(int node_id) { 257 UIElement* UIDevToolsDOMAgent::GetElementFromNodeId(int node_id) {
205 return node_id_to_ui_element_[node_id]; 258 return node_id_to_ui_element_[node_id];
206 } 259 }
207 260
261 ui_devtools::protocol::Response UIDevToolsDOMAgent::HighlightNode(
262 std::unique_ptr<ui_devtools::protocol::Overlay::HighlightConfig>
263 highlight_config,
264 int node_id) {
265 if (!layer_for_highlighting_) {
266 layer_for_highlighting_.reset(
267 new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR));
268 layer_for_highlighting_->set_name("HighlightingLayer");
269 }
270
271 std::pair<aura::Window*, gfx::Rect> window_and_bounds =
272 node_id_to_ui_element_.count(node_id)
273 ? node_id_to_ui_element_[node_id]->GetNodeWindowAndBounds()
274 : std::make_pair<aura::Window*, gfx::Rect>(nullptr, gfx::Rect());
275
276 if (!window_and_bounds.first) {
277 return ui_devtools::protocol::Response::Error("No node found with that id");
278 }
279 SkColor content_color =
280 RGBAToSkColor(highlight_config->getContentColor(nullptr));
281 UpdateHighlight(window_and_bounds, content_color);
282
283 if (!layer_for_highlighting_->visible())
284 layer_for_highlighting_->SetVisible(true);
285
286 return ui_devtools::protocol::Response::OK();
287 }
288
289 void UIDevToolsDOMAgent::FindElementByEventHandler(const gfx::Point& p,
290 int* element_id) {
291 for (auto* element_window : window_element_root_->children()) {
292 aura::Window* window =
293 UIElement::GetBackingElement<aura::Window, WindowElement>(
294 element_window);
295 if (!window->bounds().Contains(p))
296 return;
297 aura::Window* point_window = window->GetEventHandlerForPoint(p);
298
299 if (point_window) {
300 views::Widget* widget =
301 views::Widget::GetWidgetForNativeWindow(point_window);
302
303 if (widget) {
304 views::View* view = widget->GetRootView();
305
306 if (view) {
307 gfx::Point p_inside(p);
308 aura::Window::ConvertPointToTarget(window, point_window, &p_inside);
309 views::View* point_view = view->GetEventHandlerForPoint(p_inside);
310
311 DCHECK(point_view);
312 *element_id = FindUIElementIdForView(element_window, point_view);
313 } else {
314 *element_id = FindUIElementIdForWidget(element_window, widget);
315 }
316 } else {
317 *element_id = FindUIElementIdForWindow(element_window, point_window);
318 }
319 }
320 }
321 }
322
208 void UIDevToolsDOMAgent::OnHostInitialized(aura::WindowTreeHost* host) { 323 void UIDevToolsDOMAgent::OnHostInitialized(aura::WindowTreeHost* host) {
209 root_windows_.push_back(host->window()); 324 root_windows_.push_back(host->window());
210 } 325 }
211 326
212 void UIDevToolsDOMAgent::OnNodeBoundsChanged(int node_id) { 327 void UIDevToolsDOMAgent::OnNodeBoundsChanged(int node_id) {
213 for (auto& observer : observers_) 328 for (auto& observer : observers_)
214 observer.OnNodeBoundsChanged(node_id); 329 observer.OnNodeBoundsChanged(node_id);
215 } 330 }
216 331
217 std::unique_ptr<ui_devtools::protocol::DOM::Node> 332 std::unique_ptr<ui_devtools::protocol::DOM::Node>
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 aura::client::ScreenPositionClient* screen_position_client = 461 aura::client::ScreenPositionClient* screen_position_client =
347 aura::client::GetScreenPositionClient(root); 462 aura::client::GetScreenPositionClient(root);
348 463
349 gfx::Rect bounds(window_and_bounds.second); 464 gfx::Rect bounds(window_and_bounds.second);
350 gfx::Point origin = bounds.origin(); 465 gfx::Point origin = bounds.origin();
351 screen_position_client->ConvertPointFromScreen(root, &origin); 466 screen_position_client->ConvertPointFromScreen(root, &origin);
352 bounds.set_origin(origin); 467 bounds.set_origin(origin);
353 layer_for_highlighting_->SetBounds(bounds); 468 layer_for_highlighting_->SetBounds(bounds);
354 } 469 }
355 470
356 ui_devtools::protocol::Response UIDevToolsDOMAgent::HighlightNode(
357 std::unique_ptr<ui_devtools::protocol::DOM::HighlightConfig>
358 highlight_config,
359 int node_id) {
360 if (!layer_for_highlighting_) {
361 layer_for_highlighting_.reset(
362 new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR));
363 layer_for_highlighting_->set_name("HighlightingLayer");
364 }
365
366 std::pair<aura::Window*, gfx::Rect> window_and_bounds =
367 node_id_to_ui_element_.count(node_id)
368 ? node_id_to_ui_element_[node_id]->GetNodeWindowAndBounds()
369 : std::make_pair<aura::Window*, gfx::Rect>(nullptr, gfx::Rect());
370
371 if (!window_and_bounds.first) {
372 return ui_devtools::protocol::Response::Error("No node found with that id");
373 }
374 SkColor content_color =
375 RGBAToSkColor(highlight_config->getContentColor(nullptr));
376 UpdateHighlight(window_and_bounds, content_color);
377
378 if (!layer_for_highlighting_->visible())
379 layer_for_highlighting_->SetVisible(true);
380
381 return ui_devtools::protocol::Response::OK();
382 }
383
384 } // namespace ui_devtools 471 } // namespace ui_devtools
OLDNEW
« no previous file with comments | « components/ui_devtools/views/ui_devtools_dom_agent.h ('k') | components/ui_devtools/views/ui_devtools_overlay_agent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698