Index: content/browser/devtools/renderer_overrides_handler.cc |
diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc |
index d700dee9459362adad5459477dd16d4503bf795a..74c5462c73799589ca6525a9d09083eb568f84f8 100644 |
--- a/content/browser/devtools/renderer_overrides_handler.cc |
+++ b/content/browser/devtools/renderer_overrides_handler.cc |
@@ -22,6 +22,8 @@ |
#include "content/browser/renderer_host/render_view_host_delegate.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
#include "content/browser/renderer_host/render_widget_host_view_base.h" |
+#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/common/cursors/webcursor.h" |
#include "content/common/view_messages.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/content_browser_client.h" |
@@ -40,6 +42,7 @@ |
#include "content/public/common/referrer.h" |
#include "ipc/ipc_sender.h" |
#include "net/base/net_util.h" |
+#include "third_party/WebKit/public/platform/WebCursorInfo.h" |
#include "third_party/WebKit/public/platform/WebScreenInfo.h" |
#include "third_party/WebKit/public/web/WebInputEvent.h" |
#include "ui/gfx/codec/jpeg_codec.h" |
@@ -71,6 +74,7 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) |
: agent_(agent), |
has_last_compositor_frame_metadata_(false), |
capture_retry_count_(0), |
+ color_picker_enabled_(false), |
weak_factory_(this) { |
RegisterCommandHandler( |
devtools::DOM::setFileInputFiles::kName, |
@@ -142,6 +146,11 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) |
&RendererOverridesHandler::PageQueryUsageAndQuota, |
base::Unretained(this))); |
RegisterCommandHandler( |
+ devtools::Page::setColorPickerEnabled::kName, |
+ base::Bind( |
+ &RendererOverridesHandler::PageSetColorPickerEnabled, |
+ base::Unretained(this))); |
+ RegisterCommandHandler( |
devtools::Input::emulateTouchFromMouseEvent::kName, |
base::Bind( |
&RendererOverridesHandler::InputEmulateTouchFromMouseEvent, |
@@ -164,6 +173,8 @@ void RendererOverridesHandler::OnSwapCompositorFrame( |
if (screencast_command_) |
InnerSwapCompositorFrame(); |
+ if (color_picker_enabled_) |
+ UpdateColorPickerFrame(); |
} |
void RendererOverridesHandler::OnVisibilityChanged(bool visible) { |
@@ -833,6 +844,165 @@ void RendererOverridesHandler::NotifyScreencastVisibility(bool visible) { |
devtools::Page::screencastVisibilityChanged::kName, params); |
} |
+scoped_refptr<DevToolsProtocol::Response> |
+RendererOverridesHandler::PageSetColorPickerEnabled( |
+ scoped_refptr<DevToolsProtocol::Command> command) { |
+ base::DictionaryValue* params = command->params(); |
+ bool color_picker_enabled; |
+ if (!params || !params->GetBoolean( |
+ devtools::Page::setColorPickerEnabled::kParamEnabled, |
+ &color_picker_enabled)) { |
+ return command->InvalidParamResponse( |
+ devtools::Page::setColorPickerEnabled::kParamEnabled); |
+ } |
+ RenderViewHostImpl* host = GetRenderViewHostImpl(); |
+ if (!host) |
+ return command->InternalErrorResponse("Could not connect to view"); |
+ |
+ SetColorPickerEnabled(color_picker_enabled); |
+ return command->SuccessResponse(NULL); |
+} |
+ |
+void RendererOverridesHandler::SetColorPickerEnabled(bool enabled) { |
+ if (color_picker_enabled_ == enabled) |
+ return; |
+ |
+ RenderViewHostImpl* host = GetRenderViewHostImpl(); |
+ color_picker_enabled_ = enabled; |
+ |
+ if (enabled) { |
+ UpdateColorPickerFrame(); |
+ host->SetInterceptingMouseCallback( |
+ base::Bind(&RendererOverridesHandler::HandleMouseEvent, |
+ weak_factory_.GetWeakPtr())); |
+ } else { |
+ color_picker_frame_.reset(); |
+ host->SetInterceptingMouseCallback( |
+ RenderWidgetHostImpl::InterceptingMouseCallback()); |
+ } |
+ |
+ WebCursor pointer_cursor; |
+ WebCursor::CursorInfo cursor_info; |
+ cursor_info.type = blink::WebCursorInfo::TypePointer; |
+ pointer_cursor.InitFromCursorInfo(cursor_info); |
+ |
+ host->SetCursor(pointer_cursor); |
+} |
+ |
+void RendererOverridesHandler::UpdateColorPickerFrame() { |
+ RenderViewHostImpl* host = GetRenderViewHostImpl(); |
+ if (!host) |
+ return; |
+ RenderWidgetHostViewBase* view = |
+ static_cast<RenderWidgetHostViewBase*>(host->GetView()); |
+ gfx::Size size = view->GetViewBounds().size(); |
+ view->CopyFromCompositingSurface( |
+ gfx::Rect(size), size, |
+ base::Bind(&RendererOverridesHandler::ColorPickerFrameUpdated, |
+ weak_factory_.GetWeakPtr()), |
+ kN32_SkColorType); |
+} |
+ |
+void RendererOverridesHandler::ColorPickerFrameUpdated( |
+ bool succeeded, |
+ const SkBitmap& bitmap) { |
+ if (succeeded) |
+ color_picker_frame_ = bitmap; |
+} |
+ |
+void RendererOverridesHandler::HandleMouseEvent( |
+ const blink::WebMouseEvent& event) { |
+ |
+ if (color_picker_frame_.drawsNothing()) { |
+ if (event.button == blink::WebMouseEvent::ButtonLeft) |
+ SetColorPickerEnabled(false); |
+ return; |
+ } |
+ |
+ if (event.button == blink::WebMouseEvent::ButtonLeft) { |
+ color_picker_frame_.lockPixels(); |
+ SkColor color = color_picker_frame_.getColor(event.x, event.y); |
+ color_picker_frame_.unlockPixels(); |
+ base::DictionaryValue* color_dict = new base::DictionaryValue(); |
+ color_dict->SetInteger("r", SkColorGetR(color)); |
+ color_dict->SetInteger("g", SkColorGetG(color)); |
+ color_dict->SetInteger("b", SkColorGetB(color)); |
+ color_dict->SetInteger("a", SkColorGetA(color)); |
+ base::DictionaryValue* response = new base::DictionaryValue(); |
+ response->Set(devtools::Page::colorPicked::kParamColor, color_dict); |
+ SendNotification(devtools::Page::colorPicked::kName, response); |
+ } |
+ |
+ const int kCursorSize = 150; |
+ const int kDiameter = 110; |
+ const int kHotspotRadius = 5; |
+ const int kPixelSize = 10; |
+ int padding = (kCursorSize - kDiameter) / 2; |
+ int hotspot = padding + kHotspotRadius; |
+ |
+ skia::RefPtr<SkCanvas> canvas = |
+ skia::AdoptRef(SkCanvas::NewRasterN32(kCursorSize, kCursorSize)); |
+ |
+ SkPaint paint; |
+ paint.setStrokeWidth(2); |
+ paint.setColor(SK_ColorDKGRAY); |
+ paint.setStyle(SkPaint::kStroke_Style); |
+ paint.setAntiAlias(true); |
+ canvas->drawCircle(hotspot, hotspot, kHotspotRadius, paint); |
+ canvas->drawLine(hotspot + kHotspotRadius - 1, |
+ hotspot + kHotspotRadius - 1, |
+ kCursorSize / 2, kCursorSize / 2, |
+ paint); |
+ |
+ SkPath clip_path; |
+ clip_path.addOval(SkRect::MakeXYWH(padding, padding, kDiameter, kDiameter)); |
+ clip_path.close(); |
+ canvas->clipPath(clip_path, SkRegion::kIntersect_Op, true); |
+ |
+ SkRect src_rect = SkRect::MakeXYWH(event.x - 5, event.y - 5, 11, 11); |
+ SkRect dst_rect = SkRect::MakeXYWH(padding, padding, kDiameter, kDiameter); |
+ canvas->drawBitmapRectToRect(color_picker_frame_, &src_rect, dst_rect); |
+ |
+ paint.setStrokeWidth(1); |
+ paint.setAntiAlias(false); |
+ paint.setColor(SK_ColorGRAY); |
+ for (int i = padding; i < kCursorSize - padding; i += kPixelSize) { |
+ canvas->drawLine(i, padding, i, kCursorSize - padding, paint); |
+ canvas->drawLine(padding, i, kCursorSize - padding, i, paint); |
+ } |
+ |
+ SkRect pixel = SkRect::MakeXYWH(kCursorSize / 2 - kHotspotRadius, |
+ kCursorSize / 2 - kHotspotRadius, |
+ kPixelSize, kPixelSize); |
+ paint.setColor(SK_ColorRED); |
+ canvas->drawRect(pixel, paint); |
+ |
+ paint.setStrokeWidth(2); |
+ paint.setColor(SK_ColorDKGRAY); |
+ paint.setAntiAlias(true); |
+ canvas->drawCircle(kCursorSize / 2, kCursorSize / 2, kDiameter / 2, paint); |
+ |
+ SkBitmap result; |
+ result.allocN32Pixels(kCursorSize, kCursorSize); |
+ canvas->readPixels(&result, 0, 0); |
+ |
+ WebCursor cursor; |
+ WebCursor::CursorInfo cursor_info; |
+ cursor_info.type = blink::WebCursorInfo::TypeCustom; |
+ cursor_info.image_scale_factor = 1; |
+ cursor_info.custom_image = result; |
+ cursor_info.hotspot = |
+ gfx::Point(hotspot, hotspot); |
+#if defined(OS_WIN) |
+ cursor_info.external_handle = 0; |
+#endif |
+ |
+ cursor.InitFromCursorInfo(cursor_info); |
+ RenderViewHostImpl* rvh = GetRenderViewHostImpl(); |
+ if (rvh) |
+ rvh->SetCursor(cursor); |
+} |
+ |
// Input agent handlers ------------------------------------------------------ |
scoped_refptr<DevToolsProtocol::Response> |