mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Expose drag image via CefDragData (issue #1715)
This commit is contained in:
		| @@ -39,6 +39,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "include/capi/cef_base_capi.h" | #include "include/capi/cef_base_capi.h" | ||||||
|  | #include "include/capi/cef_image_capi.h" | ||||||
| #include "include/capi/cef_stream_capi.h" | #include "include/capi/cef_stream_capi.h" | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| @@ -195,6 +196,22 @@ typedef struct _cef_drag_data_t { | |||||||
|   /// |   /// | ||||||
|   void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self, |   void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self, | ||||||
|       const cef_string_t* path, const cef_string_t* display_name); |       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; | } cef_drag_data_t; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "include/cef_base.h" | #include "include/cef_base.h" | ||||||
|  | #include "include/cef_image.h" | ||||||
| #include "include/cef_stream.h" | #include "include/cef_stream.h" | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| @@ -193,6 +194,25 @@ class CefDragData : public virtual CefBaseRefCounted { | |||||||
|   /// |   /// | ||||||
|   /*--cef(optional_param=display_name)--*/ |   /*--cef(optional_param=display_name)--*/ | ||||||
|   virtual void AddFile(const CefString& path, const CefString& display_name) =0; |   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<CefImage> 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_ | #endif  // CEF_INCLUDE_CEF_DRAG_DATA_H_ | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include <utility> | #include <utility> | ||||||
|  |  | ||||||
| #include "libcef/browser/browser_host_impl.h" | #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/render_widget_host_view_osr.h" | ||||||
| #include "libcef/browser/osr/web_contents_view_osr.h" | #include "libcef/browser/osr/web_contents_view_osr.h" | ||||||
| #include "libcef/common/drag_data_impl.h" | #include "libcef/common/drag_data_impl.h" | ||||||
| @@ -435,7 +436,11 @@ void CefBrowserPlatformDelegateOsr::StartDragging( | |||||||
|   CefRefPtr<CefRenderHandler> handler = |   CefRefPtr<CefRenderHandler> handler = | ||||||
|       browser_->GetClient()->GetRenderHandler(); |       browser_->GetClient()->GetRenderHandler(); | ||||||
|   if (handler.get()) { |   if (handler.get()) { | ||||||
|     CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(drop_data)); |     CefRefPtr<CefImage> cef_image(new CefImageImpl(image)); | ||||||
|  |     CefPoint cef_image_pos(image_offset.x(), image_offset.y()); | ||||||
|  |     CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(drop_data, | ||||||
|  |                                                              cef_image, | ||||||
|  |                                                              cef_image_pos)); | ||||||
|     drag_data->SetReadOnly(true); |     drag_data->SetReadOnly(true); | ||||||
|     base::MessageLoop::ScopedNestableTaskAllower allow( |     base::MessageLoop::ScopedNestableTaskAllower allow( | ||||||
|         base::MessageLoop::current()); |         base::MessageLoop::current()); | ||||||
|   | |||||||
| @@ -19,6 +19,15 @@ CefDragDataImpl::CefDragDataImpl(const content::DropData& data) | |||||||
|       read_only_(false) { |       read_only_(false) { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CefDragDataImpl::CefDragDataImpl(const content::DropData& data, | ||||||
|  |                                  CefRefPtr<CefImage> image, | ||||||
|  |                                  const CefPoint& image_hotspot) | ||||||
|  |     : data_(data), | ||||||
|  |       image_(image), | ||||||
|  |       image_hotspot_(image_hotspot), | ||||||
|  |       read_only_(false) { | ||||||
|  | } | ||||||
|  |  | ||||||
| CefDragDataImpl::CefDragDataImpl() | CefDragDataImpl::CefDragDataImpl() | ||||||
|     : read_only_(false) { |     : read_only_(false) { | ||||||
| } | } | ||||||
| @@ -31,7 +40,7 @@ CefRefPtr<CefDragData> CefDragDataImpl::Clone() { | |||||||
|   CefDragDataImpl* drag_data = NULL; |   CefDragDataImpl* drag_data = NULL; | ||||||
|   { |   { | ||||||
|     base::AutoLock lock_scope(lock_); |     base::AutoLock lock_scope(lock_); | ||||||
|     drag_data = new CefDragDataImpl(data_); |     drag_data = new CefDragDataImpl(data_, image_, image_hotspot_); | ||||||
|   } |   } | ||||||
|   return drag_data; |   return drag_data; | ||||||
| } | } | ||||||
| @@ -187,3 +196,18 @@ void CefDragDataImpl::SetReadOnly(bool read_only) { | |||||||
|  |  | ||||||
|   read_only_ = read_only; |   read_only_ = read_only; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CefRefPtr<CefImage> 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; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "include/cef_drag_data.h" | #include "include/cef_drag_data.h" | ||||||
|  | #include "include/cef_image.h" | ||||||
|  |  | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| @@ -18,6 +19,9 @@ class CefDragDataImpl : public CefDragData { | |||||||
|  public: |  public: | ||||||
|   CefDragDataImpl(); |   CefDragDataImpl(); | ||||||
|   explicit CefDragDataImpl(const content::DropData& data); |   explicit CefDragDataImpl(const content::DropData& data); | ||||||
|  |   CefDragDataImpl(const content::DropData& data, | ||||||
|  |                   CefRefPtr<CefImage> image, | ||||||
|  |                   const CefPoint& image_hotspot); | ||||||
|  |  | ||||||
|   CefRefPtr<CefDragData> Clone() override; |   CefRefPtr<CefDragData> Clone() override; | ||||||
|   bool IsReadOnly() override; |   bool IsReadOnly() override; | ||||||
| @@ -41,6 +45,9 @@ class CefDragDataImpl : public CefDragData { | |||||||
|   void SetFragmentBaseURL(const CefString& fragment) override; |   void SetFragmentBaseURL(const CefString& fragment) override; | ||||||
|   void ResetFileContents() override; |   void ResetFileContents() override; | ||||||
|   void AddFile(const CefString& path, const CefString& display_name) override; |   void AddFile(const CefString& path, const CefString& display_name) override; | ||||||
|  |   CefRefPtr<CefImage> GetImage() override; | ||||||
|  |   CefPoint GetImageHotspot() override; | ||||||
|  |   bool HasImage() override; | ||||||
|  |  | ||||||
|   // This method is not safe. Use Lock/Unlock to get mutually exclusive access. |   // This method is not safe. Use Lock/Unlock to get mutually exclusive access. | ||||||
|   content::DropData* drop_data() { |   content::DropData* drop_data() { | ||||||
| @@ -53,6 +60,8 @@ class CefDragDataImpl : public CefDragData { | |||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   content::DropData data_; |   content::DropData data_; | ||||||
|  |   CefRefPtr<CefImage> image_; | ||||||
|  |   CefPoint image_hotspot_; | ||||||
|  |  | ||||||
|   // True if this object is read-only. |   // True if this object is read-only. | ||||||
|   bool read_only_; |   bool read_only_; | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "libcef_dll/cpptoc/drag_data_cpptoc.h" | #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/cpptoc/stream_writer_cpptoc.h" | ||||||
| #include "libcef_dll/transfer_util.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)); |       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<CefImage> _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 | }  // namespace | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -395,6 +440,9 @@ CefDragDataCppToC::CefDragDataCppToC() { | |||||||
|   GetStruct()->set_fragment_base_url = drag_data_set_fragment_base_url; |   GetStruct()->set_fragment_base_url = drag_data_set_fragment_base_url; | ||||||
|   GetStruct()->reset_file_contents = drag_data_reset_file_contents; |   GetStruct()->reset_file_contents = drag_data_reset_file_contents; | ||||||
|   GetStruct()->add_file = drag_data_add_file; |   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<CefDragData> CefCppToCRefCounted<CefDragDataCppToC, | template<> CefRefPtr<CefDragData> CefCppToCRefCounted<CefDragDataCppToC, | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "libcef_dll/ctocpp/drag_data_ctocpp.h" | #include "libcef_dll/ctocpp/drag_data_ctocpp.h" | ||||||
|  | #include "libcef_dll/ctocpp/image_ctocpp.h" | ||||||
| #include "libcef_dll/ctocpp/stream_writer_ctocpp.h" | #include "libcef_dll/ctocpp/stream_writer_ctocpp.h" | ||||||
| #include "libcef_dll/transfer_util.h" | #include "libcef_dll/transfer_util.h" | ||||||
|  |  | ||||||
| @@ -372,6 +373,48 @@ void CefDragDataCToCpp::AddFile(const CefString& path, | |||||||
|       display_name.GetStruct()); |       display_name.GetStruct()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CefRefPtr<CefImage> 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. | // CONSTRUCTOR - Do not edit by hand. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,6 +54,9 @@ class CefDragDataCToCpp | |||||||
|   void SetFragmentBaseURL(const CefString& base_url) OVERRIDE; |   void SetFragmentBaseURL(const CefString& base_url) OVERRIDE; | ||||||
|   void ResetFileContents() OVERRIDE; |   void ResetFileContents() OVERRIDE; | ||||||
|   void AddFile(const CefString& path, const CefString& display_name) OVERRIDE; |   void AddFile(const CefString& path, const CefString& display_name) OVERRIDE; | ||||||
|  |   CefRefPtr<CefImage> GetImage() OVERRIDE; | ||||||
|  |   CefPoint GetImageHotspot() OVERRIDE; | ||||||
|  |   bool HasImage() OVERRIDE; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // CEF_LIBCEF_DLL_CTOCPP_DRAG_DATA_CTOCPP_H_ | #endif  // CEF_LIBCEF_DLL_CTOCPP_DRAG_DATA_CTOCPP_H_ | ||||||
|   | |||||||
| @@ -1007,6 +1007,27 @@ class OSRTestHandler : public RoutingTestHandler, | |||||||
|                      CefRenderHandler::DragOperationsMask allowed_ops, |                      CefRenderHandler::DragOperationsMask allowed_ops, | ||||||
|                      int x, int y) override { |                      int x, int y) override { | ||||||
|     if (test_type_ == OSR_TEST_DRAG_DROP_START_DRAGGING && started()) { |     if (test_type_ == OSR_TEST_DRAG_DROP_START_DRAGGING && started()) { | ||||||
|  |       // Verify the drag image representation. | ||||||
|  |       EXPECT_TRUE(drag_data->HasImage()); | ||||||
|  |       CefRefPtr<CefImage> 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<int>(image->GetWidth()), | ||||||
|  |                     GetScaledInt(kDragDivRect.width), 1); | ||||||
|  |         EXPECT_NEAR(static_cast<int>(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(); |       DestroySucceededTestSoon(); | ||||||
|       return false; |       return false; | ||||||
|     } else if ((test_type_ == OSR_TEST_DRAG_DROP_UPDATE_CURSOR || |     } else if ((test_type_ == OSR_TEST_DRAG_DROP_UPDATE_CURSOR || | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user