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

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

Issue 2542243002: Add hovering feature to AshDevToolsDOMAgent (Closed)
Patch Set: Mask colors when converting RGBA to SkColor 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 int MaskColor(int value) {
89 return value & 0xff;
90 }
91
92 SkColor RGBAToSkColor(DOM::RGBA* rgba) {
93 if (!rgba)
94 return SkColorSetARGB(0, 0, 0, 0);
95 // Default alpha value is 0 (not visible) and need to convert alpha decimal
96 // percentage value to hex
97 return SkColorSetARGB(MaskColor(static_cast<int>(rgba->getA(0) * 255)),
98 MaskColor(rgba->getR()), MaskColor(rgba->getG()),
99 MaskColor(rgba->getB()));
100 }
101
82 } // namespace 102 } // namespace
83 103
84 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) { 104 AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) {
85 DCHECK(shell_); 105 DCHECK(shell_);
86 } 106 }
87 107
88 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() { 108 AshDevToolsDOMAgent::~AshDevToolsDOMAgent() {
89 RemoveObservers(); 109 RemoveObservers();
90 } 110 }
91 111
92 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() { 112 ui::devtools::protocol::Response AshDevToolsDOMAgent::disable() {
93 Reset(); 113 Reset();
94 return ui::devtools::protocol::Response::OK(); 114 return ui::devtools::protocol::Response::OK();
95 } 115 }
96 116
97 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument( 117 ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument(
98 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) { 118 std::unique_ptr<ui::devtools::protocol::DOM::Node>* out_root) {
99 *out_root = BuildInitialTree(); 119 *out_root = BuildInitialTree();
100 return ui::devtools::protocol::Response::OK(); 120 return ui::devtools::protocol::Response::OK();
101 } 121 }
102 122
123 ui::devtools::protocol::Response AshDevToolsDOMAgent::highlightNode(
124 std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig>
125 highlight_config,
126 ui::devtools::protocol::Maybe<int> node_id) {
127 return HighlightNode(std::move(highlight_config), node_id.fromJust());
128 }
129
130 ui::devtools::protocol::Response AshDevToolsDOMAgent::hideHighlight() {
131 if (widget_for_highlighting_ && widget_for_highlighting_->IsVisible())
132 widget_for_highlighting_->Hide();
133 return ui::devtools::protocol::Response::OK();
134 }
135
103 // Handles removing windows. 136 // Handles removing windows.
104 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window, 137 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window,
105 const TreeChangeParams& params) { 138 const TreeChangeParams& params) {
106 // Only trigger this when window == params.old_parent. 139 // Only trigger this when window == params.old_parent.
107 // Only removals are handled here. Removing a node can occur as a result of 140 // Only removals are handled here. Removing a node can occur as a result of
108 // reorganizing a window or just destroying it. OnWindowTreeChanged 141 // 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 142 // 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. 143 // 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 144 // 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. 145 // 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)); 249 return BuildNode("root", nullptr, std::move(children));
217 } 250 }
218 251
219 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow( 252 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow(
220 ash::WmWindow* window) { 253 ash::WmWindow* window) {
221 DCHECK(!window_to_node_id_map_.count(window)); 254 DCHECK(!window_to_node_id_map_.count(window));
222 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 255 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
223 views::Widget* widget = window->GetInternalWidget(); 256 views::Widget* widget = window->GetInternalWidget();
224 if (widget) 257 if (widget)
225 children->addItem(BuildTreeForRootWidget(widget)); 258 children->addItem(BuildTreeForRootWidget(widget));
226 for (ash::WmWindow* child : window->GetChildren()) 259 for (ash::WmWindow* child : window->GetChildren()) {
227 children->addItem(BuildTreeForWindow(child)); 260 if (!IsHighlightingWindow(child))
261 children->addItem(BuildTreeForWindow(child));
262 }
228 263
229 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = 264 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
230 BuildNode("Window", GetAttributes(window), std::move(children)); 265 BuildNode("Window", GetAttributes(window), std::move(children));
231 if (!window->HasObserver(this)) 266 if (!window->HasObserver(this))
232 window->AddObserver(this); 267 window->AddObserver(this);
233 window_to_node_id_map_[window] = node->getNodeId(); 268 window_to_node_id_map_[window] = node->getNodeId();
234 node_id_to_window_map_[node->getNodeId()] = window; 269 node_id_to_window_map_[node->getNodeId()] = window;
235 return node; 270 return node;
236 } 271 }
237 272
(...skipping 20 matching lines...) Expand all
258 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = 293 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
259 BuildNode("View", GetAttributes(view), std::move(children)); 294 BuildNode("View", GetAttributes(view), std::move(children));
260 if (!view->HasObserver(this)) 295 if (!view->HasObserver(this))
261 view->AddObserver(this); 296 view->AddObserver(this);
262 view_to_node_id_map_[view] = node->getNodeId(); 297 view_to_node_id_map_[view] = node->getNodeId();
263 node_id_to_view_map_[node->getNodeId()] = view; 298 node_id_to_view_map_[node->getNodeId()] = view;
264 return node; 299 return node;
265 } 300 }
266 301
267 void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) { 302 void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) {
303 if (IsHighlightingWindow(window))
304 return;
305
268 DCHECK(window_to_node_id_map_.count(window->GetParent())); 306 DCHECK(window_to_node_id_map_.count(window->GetParent()));
269 WmWindow* prev_sibling = FindPreviousSibling(window); 307 WmWindow* prev_sibling = FindPreviousSibling(window);
270 frontend()->childNodeInserted( 308 frontend()->childNodeInserted(
271 window_to_node_id_map_[window->GetParent()], 309 window_to_node_id_map_[window->GetParent()],
272 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0, 310 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0,
273 BuildTreeForWindow(window)); 311 BuildTreeForWindow(window));
274 } 312 }
275 313
276 void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window, 314 void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window,
277 bool remove_observer) { 315 bool remove_observer) {
278 DCHECK(window); 316 DCHECK(window);
317 if (IsHighlightingWindow(window))
318 return;
319
279 if (window->GetInternalWidget()) 320 if (window->GetInternalWidget())
280 RemoveWidgetTree(window->GetInternalWidget(), remove_observer); 321 RemoveWidgetTree(window->GetInternalWidget(), remove_observer);
281 322
282 for (ash::WmWindow* child : window->GetChildren()) 323 for (ash::WmWindow* child : window->GetChildren())
283 RemoveWindowTree(child, remove_observer); 324 RemoveWindowTree(child, remove_observer);
284 325
285 RemoveWindowNode(window, remove_observer); 326 RemoveWindowNode(window, remove_observer);
286 } 327 }
287 328
288 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window, 329 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_) 425 for (auto& pair : window_to_node_id_map_)
385 pair.first->RemoveObserver(this); 426 pair.first->RemoveObserver(this);
386 for (auto& pair : widget_to_node_id_map_) 427 for (auto& pair : widget_to_node_id_map_)
387 pair.first->RemoveRemovalsObserver(this); 428 pair.first->RemoveRemovalsObserver(this);
388 for (auto& pair : view_to_node_id_map_) 429 for (auto& pair : view_to_node_id_map_)
389 pair.first->RemoveObserver(this); 430 pair.first->RemoveObserver(this);
390 } 431 }
391 432
392 void AshDevToolsDOMAgent::Reset() { 433 void AshDevToolsDOMAgent::Reset() {
393 RemoveObservers(); 434 RemoveObservers();
435 widget_for_highlighting_.reset();
394 window_to_node_id_map_.clear(); 436 window_to_node_id_map_.clear();
395 widget_to_node_id_map_.clear(); 437 widget_to_node_id_map_.clear();
396 view_to_node_id_map_.clear(); 438 view_to_node_id_map_.clear();
397 node_id_to_window_map_.clear(); 439 node_id_to_window_map_.clear();
398 node_id_to_widget_map_.clear(); 440 node_id_to_widget_map_.clear();
399 node_id_to_view_map_.clear(); 441 node_id_to_view_map_.clear();
400 node_ids = 1; 442 node_ids = 1;
401 } 443 }
402 444
445 AshDevToolsDOMAgent::WindowAndBoundsPair
446 AshDevToolsDOMAgent::GetNodeWindowAndBounds(int node_id) {
447 WmWindow* window = GetWindowFromNodeId(node_id);
448 if (window)
449 return std::make_pair(window, window->GetBoundsInScreen());
450
451 views::Widget* widget = GetWidgetFromNodeId(node_id);
452 if (widget) {
453 return std::make_pair(WmLookup::Get()->GetWindowForWidget(widget),
454 widget->GetWindowBoundsInScreen());
455 }
456
457 views::View* view = GetViewFromNodeId(node_id);
458 if (view) {
459 gfx::Rect bounds = view->GetBoundsInScreen();
460 return std::make_pair(
461 WmLookup::Get()->GetWindowForWidget(view->GetWidget()), bounds);
462 }
463
464 return std::make_pair(nullptr, gfx::Rect());
465 }
466
467 void AshDevToolsDOMAgent::InitializeHighlightingWidget() {
468 DCHECK(!widget_for_highlighting_);
469 widget_for_highlighting_.reset(new views::Widget);
470 views::Widget::InitParams params;
471 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
472 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
473 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
474 params.opacity = views::Widget::InitParams::WindowOpacity::TRANSLUCENT_WINDOW;
475 params.name = "HighlightingWidget";
476 shell_->GetPrimaryRootWindowController()
477 ->ConfigureWidgetInitParamsForContainer(widget_for_highlighting_.get(),
478 kShellWindowId_OverlayContainer,
479 &params);
480 params.keep_on_top = true;
481 params.accept_events = false;
482 widget_for_highlighting_->Init(params);
483 }
484
485 void AshDevToolsDOMAgent::UpdateHighlight(
486 const WindowAndBoundsPair& window_and_bounds,
487 SkColor background,
488 SkColor border) {
489 constexpr int kBorderThickness = 1;
490 views::View* root_view = widget_for_highlighting_->GetRootView();
491 root_view->SetBorder(views::CreateSolidBorder(kBorderThickness, border));
492 root_view->set_background(
493 views::Background::CreateSolidBackground(background));
494 WmLookup::Get()
495 ->GetWindowForWidget(widget_for_highlighting_.get())
496 ->SetBoundsInScreen(window_and_bounds.second,
497 window_and_bounds.first->GetDisplayNearestWindow());
498 }
499
500 ui::devtools::protocol::Response AshDevToolsDOMAgent::HighlightNode(
501 std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig>
502 highlight_config,
503 int node_id) {
504 if (!widget_for_highlighting_)
505 InitializeHighlightingWidget();
506
507 WindowAndBoundsPair window_and_bounds(GetNodeWindowAndBounds(node_id));
508
509 if (!window_and_bounds.first)
510 return ui::devtools::protocol::Response::Error(
511 "No node found with that id");
512
513 SkColor border_color =
514 RGBAToSkColor(highlight_config->getBorderColor(nullptr));
515 SkColor content_color =
516 RGBAToSkColor(highlight_config->getContentColor(nullptr));
517 UpdateHighlight(window_and_bounds, content_color, border_color);
518
519 if (!widget_for_highlighting_->IsVisible())
520 widget_for_highlighting_->Show();
521
522 return ui::devtools::protocol::Response::OK();
523 }
524
525 bool AshDevToolsDOMAgent::IsHighlightingWindow(WmWindow* window) {
526 return widget_for_highlighting_ &&
527 window->GetInternalWidget() == widget_for_highlighting_.get();
528 }
529
403 } // namespace devtools 530 } // namespace devtools
404 } // namespace ash 531 } // 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