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

Side by Side Diff: ash/common/devtools/ash_devtools_dom_agent.cc

Issue 2542243002: Add hovering feature to AshDevToolsDOMAgent (Closed)
Patch Set: Remove UI_DEVTOOLS_EXPORT, will fix later Created 4 years 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
« no previous file with comments | « ash/common/devtools/ash_devtools_dom_agent.h ('k') | components/ui_devtools/devtools_server.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ash/common/devtools/ash_devtools_dom_agent.h" 5 #include "ash/common/devtools/ash_devtools_dom_agent.h"
6 6
7 #include "ash/common/wm_lookup.h" 7 #include "ash/common/wm_lookup.h"
8 #include "ash/common/wm_root_window_controller.h"
8 #include "ash/common/wm_window.h" 9 #include "ash/common/wm_window.h"
10 #include "ash/public/cpp/shell_window_ids.h"
9 #include "components/ui_devtools/devtools_server.h" 11 #include "components/ui_devtools/devtools_server.h"
12 #include "third_party/skia/include/core/SkColor.h"
13 #include "ui/display/display.h"
14 #include "ui/views/background.h"
15 #include "ui/views/border.h"
10 16
11 namespace ash { 17 namespace ash {
12 namespace devtools { 18 namespace devtools {
13 19
14 namespace { 20 namespace {
15 using namespace ui::devtools::protocol; 21 using namespace ui::devtools::protocol;
16 // TODO(mhashmi): Make ids reusable 22 // TODO(mhashmi): Make ids reusable
17 DOM::NodeId node_ids = 1; 23 DOM::NodeId node_ids = 1;
18 24
19 std::unique_ptr<DOM::Node> BuildNode( 25 std::unique_ptr<DOM::Node> BuildNode(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 for (int i = 0, count = parent->child_count(); i < count; i++) { 78 for (int i = 0, count = parent->child_count(); i < count; i++) {
73 if (view == parent->child_at(i)) { 79 if (view == parent->child_at(i)) {
74 view_index = i; 80 view_index = i;
75 break; 81 break;
76 } 82 }
77 } 83 }
78 DCHECK_GE(view_index, 0); 84 DCHECK_GE(view_index, 0);
79 return view_index == 0 ? nullptr : parent->child_at(view_index - 1); 85 return view_index == 0 ? nullptr : parent->child_at(view_index - 1);
80 } 86 }
81 87
88 void DCHECKColorBounds(int value) {
89 DCHECK_GE(value, 0);
90 DCHECK_LE(value, 255);
sadrul 2016/12/07 17:37:49 Maybe return (value & 0xff) from here, and use tha
91 }
92
93 SkColor RGBAToSkColor(DOM::RGBA* rgba) {
94 if (!rgba)
95 return SkColorSetARGB(0, 0, 0, 0);
96 // Default alpha value is 0 (not visible) and need to convert alpha decimal
97 // percentage value to hex
98 int a = static_cast<int>(rgba->getA(0) * 255);
99 int r = rgba->getR();
100 int g = rgba->getG();
101 int b = rgba->getB();
102 DCHECKColorBounds(a);
103 DCHECKColorBounds(r);
104 DCHECKColorBounds(g);
105 DCHECKColorBounds(b);
106 return SkColorSetARGB(a, r, g, b);
107 }
108
82 } // namespace 109 } // namespace
83 110
84 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) { 111 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) {
85 DCHECK(shell_); 112 DCHECK(shell_);
86 } 113 }
87 114
88 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() { 115 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() {
89 RemoveObservers(); 116 RemoveObservers();
90 } 117 }
91 118
92 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() { 119 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() {
93 Reset(); 120 Reset();
94 return ui::devtools::protocol::Response::OK(); 121 return ui::devtools::protocol::Response::OK();
95 } 122 }
96 123
97 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument( 124 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument(
98 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) { 125 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) {
99 *out_root = BuildInitialTree(); 126 *out_root = BuildInitialTree();
100 return ui::devtools::protocol::Response::OK(); 127 return ui::devtools::protocol::Response::OK();
101 } 128 }
102 129
130 ui::devtools::protocol::Response AshDevToolsDOMAgent::highlightNode(
131 std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig>
132 highlight_config,
133 ui::devtools::protocol::Maybe<int> node_id) {
134 return HighlightNode(std::move(highlight_config), node_id.fromJust());
135 }
136
137 ui::devtools::protocol::Response AshDevToolsDOMAgent::hideHighlight() {
138 if (widget_for_highlighting_ && widget_for_highlighting_->IsVisible())
139 widget_for_highlighting_->Hide();
140 return ui::devtools::protocol::Response::OK();
141 }
142
103 // Handles removing windows. 143 // Handles removing windows.
104 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window, 144 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window,
105 const TreeChangeParams& params) { 145 const TreeChangeParams& params) {
106 // Only trigger this when window == params.old_parent. 146 // Only trigger this when window == params.old_parent.
107 // Only removals are handled here. Removing a node can occur as a result of 147 // Only removals are handled here. Removing a node can occur as a result of
108 // reorganizing a window or just destroying it. OnWindowTreeChanged 148 // reorganizing a window or just destroying it. OnWindowTreeChanged
109 // is only called if there is a new_parent. The only case this method isn't 149 // is only called if there is a new_parent. The only case this method isn't
110 // called is when adding a node because old_parent is then null. 150 // called is when adding a node because old_parent is then null.
111 // Finally, We only trigger this 0 or 1 times as an old_parent will 151 // Finally, We only trigger this 0 or 1 times as an old_parent will
112 // either exist and only call this callback once, or not at all. 152 // either exist and only call this callback once, or not at all.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 return BuildNode("root", nullptr, std::move(children)); 256 return BuildNode("root", nullptr, std::move(children));
217 } 257 }
218 258
219 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow( 259 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow(
220 ash::WmWindow* window) { 260 ash::WmWindow* window) {
221 DCHECK(!window_to_node_id_map_.count(window)); 261 DCHECK(!window_to_node_id_map_.count(window));
222 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 262 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
223 views::Widget* widget = window->GetInternalWidget(); 263 views::Widget* widget = window->GetInternalWidget();
224 if (widget) 264 if (widget)
225 children->addItem(BuildTreeForRootWidget(widget)); 265 children->addItem(BuildTreeForRootWidget(widget));
226 for (ash::WmWindow* child : window->GetChildren()) 266 for (ash::WmWindow* child : window->GetChildren()) {
227 children->addItem(BuildTreeForWindow(child)); 267 if (!IsHighlightingWindow(child))
268 children->addItem(BuildTreeForWindow(child));
269 }
228 270
229 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = 271 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
230 BuildNode("Window", GetAttributes(window), std::move(children)); 272 BuildNode("Window", GetAttributes(window), std::move(children));
231 if (!window->HasObserver(this)) 273 if (!window->HasObserver(this))
232 window->AddObserver(this); 274 window->AddObserver(this);
233 window_to_node_id_map_[window] = node->getNodeId(); 275 window_to_node_id_map_[window] = node->getNodeId();
234 node_id_to_window_map_[node->getNodeId()] = window; 276 node_id_to_window_map_[node->getNodeId()] = window;
235 return node; 277 return node;
236 } 278 }
237 279
(...skipping 20 matching lines...) Expand all
258 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = 300 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
259 BuildNode("View", GetAttributes(view), std::move(children)); 301 BuildNode("View", GetAttributes(view), std::move(children));
260 if (!view->HasObserver(this)) 302 if (!view->HasObserver(this))
261 view->AddObserver(this); 303 view->AddObserver(this);
262 view_to_node_id_map_[view] = node->getNodeId(); 304 view_to_node_id_map_[view] = node->getNodeId();
263 node_id_to_view_map_[node->getNodeId()] = view; 305 node_id_to_view_map_[node->getNodeId()] = view;
264 return node; 306 return node;
265 } 307 }
266 308
267 void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) { 309 void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) {
310 if (IsHighlightingWindow(window))
311 return;
312
268 DCHECK(window_to_node_id_map_.count(window->GetParent())); 313 DCHECK(window_to_node_id_map_.count(window->GetParent()));
269 WmWindow* prev_sibling = FindPreviousSibling(window); 314 WmWindow* prev_sibling = FindPreviousSibling(window);
270 frontend()->childNodeInserted( 315 frontend()->childNodeInserted(
271 window_to_node_id_map_[window->GetParent()], 316 window_to_node_id_map_[window->GetParent()],
272 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0, 317 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0,
273 BuildTreeForWindow(window)); 318 BuildTreeForWindow(window));
274 } 319 }
275 320
276 void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window, 321 void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window,
277 bool remove_observer) { 322 bool remove_observer) {
278 DCHECK(window); 323 DCHECK(window);
324 if (IsHighlightingWindow(window))
325 return;
326
279 if (window->GetInternalWidget()) 327 if (window->GetInternalWidget())
280 RemoveWidgetTree(window->GetInternalWidget(), remove_observer); 328 RemoveWidgetTree(window->GetInternalWidget(), remove_observer);
281 329
282 for (ash::WmWindow* child : window->GetChildren()) 330 for (ash::WmWindow* child : window->GetChildren())
283 RemoveWindowTree(child, remove_observer); 331 RemoveWindowTree(child, remove_observer);
284 332
285 RemoveWindowNode(window, remove_observer); 333 RemoveWindowNode(window, remove_observer);
286 } 334 }
287 335
288 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window, 336 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 for (auto& pair : window_to_node_id_map_) 432 for (auto& pair : window_to_node_id_map_)
385 pair.first->RemoveObserver(this); 433 pair.first->RemoveObserver(this);
386 for (auto& pair : widget_to_node_id_map_) 434 for (auto& pair : widget_to_node_id_map_)
387 pair.first->RemoveRemovalsObserver(this); 435 pair.first->RemoveRemovalsObserver(this);
388 for (auto& pair : view_to_node_id_map_) 436 for (auto& pair : view_to_node_id_map_)
389 pair.first->RemoveObserver(this); 437 pair.first->RemoveObserver(this);
390 } 438 }
391 439
392 void AshDevToolsDOMAgent::Reset() { 440 void AshDevToolsDOMAgent::Reset() {
393 RemoveObservers(); 441 RemoveObservers();
442 widget_for_highlighting_.reset();
394 window_to_node_id_map_.clear(); 443 window_to_node_id_map_.clear();
395 widget_to_node_id_map_.clear(); 444 widget_to_node_id_map_.clear();
396 view_to_node_id_map_.clear(); 445 view_to_node_id_map_.clear();
397 node_id_to_window_map_.clear(); 446 node_id_to_window_map_.clear();
398 node_id_to_widget_map_.clear(); 447 node_id_to_widget_map_.clear();
399 node_id_to_view_map_.clear(); 448 node_id_to_view_map_.clear();
400 node_ids = 1; 449 node_ids = 1;
401 } 450 }
402 451
452 AshDevToolsDOMAgent::WindowAndBoundsPair
453 AshDevToolsDOMAgent::GetNodeWindowAndBounds(int node_id) {
454 WmWindow* window = GetWindowFromNodeId(node_id);
455 if (window)
456 return std::make_pair(window, window->GetBoundsInScreen());
457
458 views::Widget* widget = GetWidgetFromNodeId(node_id);
459 if (widget) {
460 return std::make_pair(WmLookup::Get()->GetWindowForWidget(widget),
461 widget->GetWindowBoundsInScreen());
462 }
463
464 views::View* view = GetViewFromNodeId(node_id);
465 if (view) {
466 gfx::Rect bounds = view->GetBoundsInScreen();
467 return std::make_pair(
468 WmLookup::Get()->GetWindowForWidget(view->GetWidget()), bounds);
469 }
470
471 return std::make_pair(nullptr, gfx::Rect());
472 }
473
474 void AshDevToolsDOMAgent::InitializeHighlightingWidget() {
475 DCHECK(!widget_for_highlighting_);
476 widget_for_highlighting_.reset(new views::Widget);
477 views::Widget::InitParams params;
478 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
479 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
480 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
481 params.opacity = views::Widget::InitParams::WindowOpacity::TRANSLUCENT_WINDOW;
482 params.name = "HighlightingWidget";
483 shell_->GetPrimaryRootWindowController()
484 ->ConfigureWidgetInitParamsForContainer(widget_for_highlighting_.get(),
485 kShellWindowId_OverlayContainer,
486 &params);
487 params.keep_on_top = true;
488 params.accept_events = false;
489 widget_for_highlighting_->Init(params);
490 }
491
492 void AshDevToolsDOMAgent::UpdateHighlight(
493 const WindowAndBoundsPair& window_and_bounds,
494 SkColor background,
495 SkColor border) {
496 constexpr int kBorderThickness = 1;
497 views::View* root_view = widget_for_highlighting_->GetRootView();
498 root_view->SetBorder(views::CreateSolidBorder(kBorderThickness, border));
499 root_view->set_background(
500 views::Background::CreateSolidBackground(background));
501 WmLookup::Get()
502 ->GetWindowForWidget(widget_for_highlighting_.get())
503 ->SetBoundsInScreen(window_and_bounds.second,
504 window_and_bounds.first->GetDisplayNearestWindow());
505 }
506
507 ui::devtools::protocol::Response AshDevToolsDOMAgent::HighlightNode(
508 std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig>
509 highlight_config,
510 int node_id) {
511 if (!widget_for_highlighting_)
512 InitializeHighlightingWidget();
513
514 WindowAndBoundsPair window_and_bounds(GetNodeWindowAndBounds(node_id));
515
516 if (!window_and_bounds.first)
517 return ui::devtools::protocol::Response::Error(
518 "No node found with that id");
519
520 SkColor border_color =
521 RGBAToSkColor(highlight_config->getBorderColor(nullptr));
522 SkColor content_color =
523 RGBAToSkColor(highlight_config->getContentColor(nullptr));
524 UpdateHighlight(window_and_bounds, content_color, border_color);
525
526 if (!widget_for_highlighting_->IsVisible())
527 widget_for_highlighting_->Show();
528
529 return ui::devtools::protocol::Response::OK();
530 }
531
532 bool AshDevToolsDOMAgent::IsHighlightingWindow(WmWindow* window) {
533 return widget_for_highlighting_ &&
534 window->GetInternalWidget() == widget_for_highlighting_.get();
535 }
536
403 } // namespace devtools 537 } // namespace devtools
404 } // namespace ash 538 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/devtools/ash_devtools_dom_agent.h ('k') | components/ui_devtools/devtools_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698