diff --git a/include/capi/cef_drag_data_capi.h b/include/capi/cef_drag_data_capi.h index e1fcfd8cf..38de241e4 100644 --- a/include/capi/cef_drag_data_capi.h +++ b/include/capi/cef_drag_data_capi.h @@ -39,6 +39,7 @@ #pragma once #include "include/capi/cef_base_capi.h" +#include "include/capi/cef_image_capi.h" #include "include/capi/cef_stream_capi.h" #ifdef __cplusplus @@ -195,6 +196,22 @@ typedef struct _cef_drag_data_t { /// void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self, const cef_string_t* path, const cef_string_t* display_name); + + /// + // Get the image representation of drag data. May return NULL if no image + // representation is available. + /// + struct _cef_image_t* (CEF_CALLBACK *get_image)(struct _cef_drag_data_t* self); + + /// + // Get the image hotspot (drag start location relative to image dimensions). + /// + cef_point_t (CEF_CALLBACK *get_image_hotspot)(struct _cef_drag_data_t* self); + + /// + // Returns true (1) if an image representation of drag data is available. + /// + int (CEF_CALLBACK *has_image)(struct _cef_drag_data_t* self); } cef_drag_data_t; diff --git a/include/cef_drag_data.h b/include/cef_drag_data.h index 29b85e844..23644dad9 100644 --- a/include/cef_drag_data.h +++ b/include/cef_drag_data.h @@ -39,6 +39,7 @@ #pragma once #include "include/cef_base.h" +#include "include/cef_image.h" #include "include/cef_stream.h" #include @@ -193,6 +194,25 @@ class CefDragData : public virtual CefBaseRefCounted { /// /*--cef(optional_param=display_name)--*/ virtual void AddFile(const CefString& path, const CefString& display_name) =0; + + /// + // Get the image representation of drag data. May return NULL if no image + // representation is available. + /// + /*--cef()--*/ + virtual CefRefPtr GetImage() =0; + + /// + // Get the image hotspot (drag start location relative to image dimensions). + /// + /*--cef()--*/ + virtual CefPoint GetImageHotspot() =0; + + /// + // Returns true if an image representation of drag data is available. + /// + /*--cef()--*/ + virtual bool HasImage() =0; }; #endif // CEF_INCLUDE_CEF_DRAG_DATA_H_ diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index efe9514a2..11ecd70f6 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -7,6 +7,7 @@ #include #include "libcef/browser/browser_host_impl.h" +#include "libcef/browser/image_impl.h" #include "libcef/browser/osr/render_widget_host_view_osr.h" #include "libcef/browser/osr/web_contents_view_osr.h" #include "libcef/common/drag_data_impl.h" @@ -435,7 +436,11 @@ void CefBrowserPlatformDelegateOsr::StartDragging( CefRefPtr handler = browser_->GetClient()->GetRenderHandler(); if (handler.get()) { - CefRefPtr drag_data(new CefDragDataImpl(drop_data)); + CefRefPtr cef_image(new CefImageImpl(image)); + CefPoint cef_image_pos(image_offset.x(), image_offset.y()); + CefRefPtr drag_data(new CefDragDataImpl(drop_data, + cef_image, + cef_image_pos)); drag_data->SetReadOnly(true); base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); diff --git a/libcef/common/drag_data_impl.cc b/libcef/common/drag_data_impl.cc index a8e2c8e1c..6db3da394 100644 --- a/libcef/common/drag_data_impl.cc +++ b/libcef/common/drag_data_impl.cc @@ -19,6 +19,15 @@ CefDragDataImpl::CefDragDataImpl(const content::DropData& data) read_only_(false) { } +CefDragDataImpl::CefDragDataImpl(const content::DropData& data, + CefRefPtr image, + const CefPoint& image_hotspot) + : data_(data), + image_(image), + image_hotspot_(image_hotspot), + read_only_(false) { +} + CefDragDataImpl::CefDragDataImpl() : read_only_(false) { } @@ -31,7 +40,7 @@ CefRefPtr CefDragDataImpl::Clone() { CefDragDataImpl* drag_data = NULL; { base::AutoLock lock_scope(lock_); - drag_data = new CefDragDataImpl(data_); + drag_data = new CefDragDataImpl(data_, image_, image_hotspot_); } return drag_data; } @@ -187,3 +196,18 @@ void CefDragDataImpl::SetReadOnly(bool read_only) { read_only_ = read_only; } + +CefRefPtr CefDragDataImpl::GetImage() { + base::AutoLock lock_scope(lock_); + return image_; +} + +CefPoint CefDragDataImpl::GetImageHotspot() { + base::AutoLock lock_scope(lock_); + return image_hotspot_; +} + +bool CefDragDataImpl::HasImage() { + base::AutoLock lock_scope(lock_); + return image_ ? true : false; +} diff --git a/libcef/common/drag_data_impl.h b/libcef/common/drag_data_impl.h index 64f29ed37..37c398d2e 100644 --- a/libcef/common/drag_data_impl.h +++ b/libcef/common/drag_data_impl.h @@ -7,6 +7,7 @@ #pragma once #include "include/cef_drag_data.h" +#include "include/cef_image.h" #include @@ -18,6 +19,9 @@ class CefDragDataImpl : public CefDragData { public: CefDragDataImpl(); explicit CefDragDataImpl(const content::DropData& data); + CefDragDataImpl(const content::DropData& data, + CefRefPtr image, + const CefPoint& image_hotspot); CefRefPtr Clone() override; bool IsReadOnly() override; @@ -41,6 +45,9 @@ class CefDragDataImpl : public CefDragData { void SetFragmentBaseURL(const CefString& fragment) override; void ResetFileContents() override; void AddFile(const CefString& path, const CefString& display_name) override; + CefRefPtr GetImage() override; + CefPoint GetImageHotspot() override; + bool HasImage() override; // This method is not safe. Use Lock/Unlock to get mutually exclusive access. content::DropData* drop_data() { @@ -53,6 +60,8 @@ class CefDragDataImpl : public CefDragData { private: content::DropData data_; + CefRefPtr image_; + CefPoint image_hotspot_; // True if this object is read-only. bool read_only_; diff --git a/libcef_dll/cpptoc/drag_data_cpptoc.cc b/libcef_dll/cpptoc/drag_data_cpptoc.cc index 381b88b92..01a397932 100644 --- a/libcef_dll/cpptoc/drag_data_cpptoc.cc +++ b/libcef_dll/cpptoc/drag_data_cpptoc.cc @@ -11,6 +11,7 @@ // #include "libcef_dll/cpptoc/drag_data_cpptoc.h" +#include "libcef_dll/cpptoc/image_cpptoc.h" #include "libcef_dll/cpptoc/stream_writer_cpptoc.h" #include "libcef_dll/transfer_util.h" @@ -367,6 +368,50 @@ void CEF_CALLBACK drag_data_add_file(struct _cef_drag_data_t* self, CefString(display_name)); } +struct _cef_image_t* CEF_CALLBACK drag_data_get_image( + struct _cef_drag_data_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefDragDataCppToC::Get(self)->GetImage(); + + // Return type: refptr_same + return CefImageCppToC::Wrap(_retval); +} + +cef_point_t CEF_CALLBACK drag_data_get_image_hotspot( + struct _cef_drag_data_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return CefPoint(); + + // Execute + cef_point_t _retval = CefDragDataCppToC::Get(self)->GetImageHotspot(); + + // Return type: simple + return _retval; +} + +int CEF_CALLBACK drag_data_has_image(struct _cef_drag_data_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefDragDataCppToC::Get(self)->HasImage(); + + // Return type: bool + return _retval; +} + } // namespace @@ -395,6 +440,9 @@ CefDragDataCppToC::CefDragDataCppToC() { GetStruct()->set_fragment_base_url = drag_data_set_fragment_base_url; GetStruct()->reset_file_contents = drag_data_reset_file_contents; GetStruct()->add_file = drag_data_add_file; + GetStruct()->get_image = drag_data_get_image; + GetStruct()->get_image_hotspot = drag_data_get_image_hotspot; + GetStruct()->has_image = drag_data_has_image; } template<> CefRefPtr CefCppToCRefCounted CefDragDataCToCpp::GetImage() { + cef_drag_data_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_image)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_image_t* _retval = _struct->get_image(_struct); + + // Return type: refptr_same + return CefImageCToCpp::Wrap(_retval); +} + +CefPoint CefDragDataCToCpp::GetImageHotspot() { + cef_drag_data_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_image_hotspot)) + return CefPoint(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_point_t _retval = _struct->get_image_hotspot(_struct); + + // Return type: simple + return _retval; +} + +bool CefDragDataCToCpp::HasImage() { + cef_drag_data_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, has_image)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->has_image(_struct); + + // Return type: bool + return _retval?true:false; +} + // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/drag_data_ctocpp.h b/libcef_dll/ctocpp/drag_data_ctocpp.h index 5b202710d..202623881 100644 --- a/libcef_dll/ctocpp/drag_data_ctocpp.h +++ b/libcef_dll/ctocpp/drag_data_ctocpp.h @@ -54,6 +54,9 @@ class CefDragDataCToCpp void SetFragmentBaseURL(const CefString& base_url) OVERRIDE; void ResetFileContents() OVERRIDE; void AddFile(const CefString& path, const CefString& display_name) OVERRIDE; + CefRefPtr GetImage() OVERRIDE; + CefPoint GetImageHotspot() OVERRIDE; + bool HasImage() OVERRIDE; }; #endif // CEF_LIBCEF_DLL_CTOCPP_DRAG_DATA_CTOCPP_H_ diff --git a/tests/ceftests/os_rendering_unittest.cc b/tests/ceftests/os_rendering_unittest.cc index b118ac661..06dadba35 100644 --- a/tests/ceftests/os_rendering_unittest.cc +++ b/tests/ceftests/os_rendering_unittest.cc @@ -1007,6 +1007,27 @@ class OSRTestHandler : public RoutingTestHandler, CefRenderHandler::DragOperationsMask allowed_ops, int x, int y) override { if (test_type_ == OSR_TEST_DRAG_DROP_START_DRAGGING && started()) { + // Verify the drag image representation. + EXPECT_TRUE(drag_data->HasImage()); + CefRefPtr image = drag_data->GetImage(); + EXPECT_TRUE(image.get() != NULL); + if (image.get()) { + // Drag image height seems to always be + 1px greater than the drag rect + // on Linux. Therefore allow it to be +/- 1px. + EXPECT_NEAR(static_cast(image->GetWidth()), + GetScaledInt(kDragDivRect.width), 1); + EXPECT_NEAR(static_cast(image->GetHeight()), + GetScaledInt(kDragDivRect.height), 1); + } + // During testing hotspot (x, y) was (15, 23) at 1x scale and (15, 18) at + // 2x scale. Since the mechanism for determining this position is unclear + // test only that it falls within the rect boundaries. + CefPoint hotspot = drag_data->GetImageHotspot(); + EXPECT_GT(hotspot.x, 0); + EXPECT_LT(hotspot.x, GetScaledInt(kDragDivRect.width)); + EXPECT_GT(hotspot.y, 0); + EXPECT_LT(hotspot.y, GetScaledInt(kDragDivRect.height)); + DestroySucceededTestSoon(); return false; } else if ((test_type_ == OSR_TEST_DRAG_DROP_UPDATE_CURSOR ||