This patch adds implementation of Drag&Drop for EFL port.
D&D will be enabled after long press and allows to drag
any elements.
Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=10755
Reviewed by: Antonio Gomes, Piotr Tworek
Change-Id: I3fec12f5bcbd3544b08ba4bd24b23419f828d1fe
Signed-off-by: Daniel Waślicki <d.waslicki@samsung.com>
event.data.tap.height = size;
}
+ if ((event.type == blink::WebInputEvent::GestureScrollBegin ||
+ event.type == blink::WebInputEvent::GestureScrollUpdate ||
+ event.type == blink::WebInputEvent::GestureScrollEnd) &&
+ eweb_view()->IsDragging()) {
+ // Disable screen scrolling while D&D is active.
+ event.data.scrollUpdate.deltaX = 0;
+ event.data.scrollUpdate.deltaY = 0;
+ }
+
if (event.type == blink::WebInputEvent::GestureTapDown) {
// Webkit does not stop a fling-scroll on tap-down. So explicitly send an
// event to stop any in-progress flings.
return;
}
- // If supporting RenderWidgetHostViewEfl::GetNativeView(), following lines
- // will be enabled similar to GTK+ port
- RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
- web_contents_->GetRenderWidgetHostView());
-
- // If the host is already used by the drag_dest_, there's no point in deleting
- // the old one to create an identical copy.
-
- /*if (drag_dest_.get() && drag_dest_->widget() == content_view)
- return;*/
-
- // Clear the currently connected drag drop signals by deleting the old
- // drag_dest_ before creating the new one.
- drag_dest_.reset();
// Create the new drag_dest_.
- drag_dest_.reset(new WebDragDestEfl(web_contents_, view));
+ drag_dest_.reset(new WebDragDestEfl(web_contents_, GetEWebView()));
if (delegate_)
- drag_dest_->set_delegate(delegate_->GetDragDestDelegate());
+ drag_dest_->SetDelegate(delegate_->GetDragDestDelegate());
}
void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
}
DropData* WebContentsViewEfl::GetDropData() const {
- NOTIMPLEMENTED();
- return 0;
+ if (drag_dest_.get())
+ return drag_dest_->GetDropData();
+ return nullptr;
}
gfx::Rect WebContentsViewEfl::GetViewBounds() const {
}
#endif
+void WebContentsViewEfl::StartDragging(const DropData& drop_data,
+ blink::WebDragOperationsMask allowed_ops,
+ const gfx::ImageSkia& image,
+ const gfx::Vector2d& image_offset,
+ const DragEventSourceInfo& event_info) {
+ if (drag_dest_.get()) {
+ drag_dest_->SetDropData(drop_data);
+ drag_dest_->SetAction(allowed_ops);
+ }
+
+ if (!drag_source_)
+ drag_source_.reset(new WebDragSourceEfl(web_contents_, GetEWebView()));
+
+ if (!drag_source_->StartDragging(drop_data, allowed_ops,
+ event_info.event_location, *image.bitmap(), image_offset)) {
+ web_contents_->SystemDragEnded();
+ }
+}
+
+bool WebContentsViewEfl::IsDragging() const {
+ if (!drag_source_)
+ return false;
+ return drag_source_->IsDragging();
+}
+
void WebContentsViewEfl::SetOrientation(int orientation) {
RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(
web_contents_->GetRenderWidgetHostView());
#define WEB_CONTENTS_VIEW_EFL
#include "browser/web_contents/web_drag_dest_efl.h"
+#include "browser/web_contents/web_drag_source_efl.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "tizen_webview/public/tw_view_mode.h"
#endif
void UpdateDragDest(RenderViewHost* host);
+ void StartDragging(const DropData& drop_data,
+ blink::WebDragOperationsMask allowed_ops,
+ const gfx::ImageSkia& image,
+ const gfx::Vector2d& image_offset,
+ const DragEventSourceInfo& event_info) override;
+
+ bool IsDragging() const;
+
void SetViewMode(tizen_webview::View_Mode mode);
virtual void UpdateFormNavigation(int formElementCount, int currentNodeIndex,
// The size we want the view to be.
gfx::Size requested_size_;
- // The helper object that handles drag destination related interactions with
- // EFL.
+ // Helpers handling drag source/destination related interactions with EFL.
+ scoped_ptr<WebDragSourceEfl> drag_source_;
scoped_ptr<WebDragDestEfl> drag_dest_;
-
tizen_webview::View_Mode view_mode_;
int orientation_;
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "web_drag_dest_efl.h"
+#include "browser/web_contents/web_drag_dest_efl.h"
-#include <string>
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/utf_string_conversions.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_drag_dest_delegate.h"
-#include "content/public/common/url_constants.h"
-#include "net/base/net_util.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-#include "ui/base/clipboard/custom_data_helper.h"
-
-#include "browser/renderer_host/render_widget_host_view_efl.h"
+#include "ui/gfx/screen.h"
using blink::WebDragOperation;
-using blink::WebDragOperationNone;
-using blink::WebDragOperationCopy;
namespace content {
-#if defined(OS_TIZEN)
-static void drag_state_enter_cb(void *data, Evas_Object *obj) {
- WebDragDestEfl *webdragdestefl = (WebDragDestEfl *)data;
+namespace {
+static void DragStateEnterCb(void* data, Evas_Object*) {
+ WebDragDestEfl* web_drag_dest_efl = static_cast<WebDragDestEfl*>(data);
+ web_drag_dest_efl->DragStateEnter();
+}
- webdragdestefl->drop_data_.reset(new DropData);
+static void DragStateLeaveCb(void* data, Evas_Object*) {
+ WebDragDestEfl* web_drag_dest_efl = static_cast<WebDragDestEfl*>(data);
+ web_drag_dest_efl->DragStateLeave();
+}
- if (webdragdestefl->delegate())
- webdragdestefl->delegate()->DragInitialize(webdragdestefl->web_contents());
+static void DragPosCb(void* data, Evas_Object*, Evas_Coord x,
+ Evas_Coord y, Elm_Xdnd_Action action) {
+ WebDragDestEfl* web_drag_dest_efl = static_cast<WebDragDestEfl*>(data);
+ web_drag_dest_efl->DragPos(x, y, action);
}
-static void drag_state_leave_cb(void *data, Evas_Object *obj) {
- WebDragDestEfl *webdragdestefl = (WebDragDestEfl *)data;
+static Eina_Bool DragDropCb(void* data, Evas_Object*,
+ Elm_Selection_Data* drop) {
+ WebDragDestEfl *web_drag_dest_efl = static_cast<WebDragDestEfl*>(data);
+ return web_drag_dest_efl->DragDrop(drop);
+}
+} // namespace
+
+WebDragDestEfl::WebDragDestEfl(WebContents* web_contents, EWebView* eweb_view)
+ : eweb_view_(eweb_view),
+ web_contents_(web_contents),
+ delegate_(nullptr),
+ drag_initialized_(false),
+ modifier_flags_(0) {
+ device_scale_factor_ = gfx::Screen::GetNativeScreen()->
+ GetPrimaryDisplay().device_scale_factor();
+
+ SetDragCallbacks();
+}
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&WebDragDestEfl::DragLeave, webdragdestefl->method_factory_.GetWeakPtr()));
+WebDragDestEfl::~WebDragDestEfl() {
+ UnsetDragCallbacks();
}
-static void drag_Pos(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action) {
- WebDragDestEfl *webdragdestefl = (WebDragDestEfl *)data;
+void WebDragDestEfl::SetDragCallbacks() {
+ elm_drop_target_add(eweb_view_->evas_object(), ELM_SEL_FORMAT_TEXT,
+ DragStateEnterCb, this,
+ DragStateLeaveCb, this,
+ DragPosCb, this,
+ DragDropCb, this);
+}
- gfx::Rect rect = webdragdestefl->render_widget_host_view()->GetBoundsInRootWindow();
- gfx::Point point = gfx::Point(rect.x(), rect.y());
+void WebDragDestEfl::UnsetDragCallbacks() {
+#if defined(TIZEN_LEGACY_V_2_2_1)
+ elm_drop_target_del(eweb_view_->evas_object());
+#else
+ elm_drop_target_del(eweb_view_->evas_object(), ELM_SEL_FORMAT_TEXT,
+ DragStateEnterCb, this,
+ DragStateLeaveCb, this,
+ DragPosCb, this,
+ DragDropCb, this);
+#endif
+}
- webdragdestefl->GetRenderViewHost()->DragTargetDragOver(
- point,
- point,
- WebDragOperationCopy,
- blink::WebInputEvent::ControlKey);
+void WebDragDestEfl::ResetDragCallbacks() {
+ UnsetDragCallbacks();
+ SetDragCallbacks();
+}
- if (webdragdestefl->delegate())
- webdragdestefl->delegate()->OnDragOver();
+void WebDragDestEfl::DragStateEnter() {
+ if (!delegate_)
+ return;
+ delegate_->DragInitialize(web_contents_);
}
-static Eina_Bool drag_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *drop) {
- WebDragDestEfl *webdragdestefl = (WebDragDestEfl *)data;
- webdragdestefl->drop_data_->text = base::NullableString16(base::UTF8ToUTF16(std::string(reinterpret_cast<const char*>(drop->data))),
- false);
+void WebDragDestEfl::DragStateLeave() {
+ GetRenderViewHost()->DragTargetDragLeave();
+ if (delegate_)
+ delegate_->OnDragLeave();
+}
- gfx::Rect rect = webdragdestefl->render_widget_host_view()->GetBoundsInRootWindow();
- gfx::Point point = gfx::Point(rect.x(), rect.y());
+void WebDragDestEfl::DragPos(Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action) {
+ gfx::Point screen_pt = gfx::Point(x / device_scale_factor_, y / device_scale_factor_);
+ float page_scale = eweb_view_->GetScale();
+ last_pointer_pos_ = screen_pt;
+ gfx::Point client_pt = gfx::Point(screen_pt.x() / page_scale, screen_pt.y() / page_scale);
+
+ if (!drag_initialized_) {
+ GetRenderViewHost()->DragTargetDragEnter(
+ *drop_data_,
+ client_pt,
+ screen_pt,
+ drag_action_,
+ modifier_flags_);
+
+ if (delegate_)
+ delegate_->OnDragEnter();
+
+ drag_initialized_ = true;
+ }
+
+ GetRenderViewHost()->DragTargetDragOver(
+ client_pt,
+ screen_pt,
+ drag_action_,
+ modifier_flags_);
+
+ if (!delegate_)
+ return;
+ delegate_->OnDragOver();
+}
- webdragdestefl->GetRenderViewHost()->DragTargetDragEnter(
- *webdragdestefl->drop_data_.get(),
- point,
- point,
- WebDragOperationCopy,
- blink::WebInputEvent::ControlKey);
+Eina_Bool WebDragDestEfl::DragDrop(Elm_Selection_Data* data) {
+ float page_scale = eweb_view_->GetScale();
- if (webdragdestefl->delegate())
- webdragdestefl->delegate()->OnDragEnter();
+ gfx::Point client_pt =
+ gfx::Point(last_pointer_pos_.x() / page_scale, last_pointer_pos_.y() / page_scale);
- // Efl port need to check this, GTK+ port has drag data received & drag drop two callbacks
- webdragdestefl->method_factory_.InvalidateWeakPtrs();
+ GetRenderViewHost()->DragTargetDrop(
+ client_pt,
+ last_pointer_pos_,
+ modifier_flags_);
- webdragdestefl->GetRenderViewHost()->
- DragTargetDrop(point, point, blink::WebInputEvent::ControlKey);
+ if (delegate_)
+ delegate_->OnDrop();
- if (webdragdestefl->delegate())
- webdragdestefl->delegate()->OnDrop();
+ drag_initialized_ = false;
+ // Invoking via message loop to not mess around with target
+ // from within one of its callbacks.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&WebDragDestEfl::ResetDragCallbacks, base::Unretained(this)));
return EINA_TRUE;
}
-#endif // OS_TIZEN
-
-WebDragDestEfl::WebDragDestEfl(WebContents* web_contents, RenderWidgetHostViewEfl *rwhvefl)
- : method_factory_(this),
- rwhvefl_(rwhvefl),
- web_contents_(web_contents) {
-#if defined(OS_TIZEN)
- elm_drop_target_add(rwhvefl_->eweb_view()->evas_object(), ELM_SEL_FORMAT_TEXT,
- drag_state_enter_cb, this,
- drag_state_leave_cb, this,
- drag_Pos, this,
- drag_drop_cb, this);
-#endif // OS_TIZEN
-}
-
-WebDragDestEfl::~WebDragDestEfl() {
-#if defined(OS_TIZEN)
-#if defined(TIZEN_LEGACY_V_2_2_1)
- elm_drop_target_del(rwhvefl_->eweb_view()->evas_object());
-#else
- elm_drop_target_del(
- rwhvefl_->eweb_view()->evas_object(), ELM_SEL_FORMAT_TEXT,
- drag_state_enter_cb, this,
- drag_state_leave_cb, this,
- drag_Pos, this,
- drag_drop_cb, this);
-#endif
-#endif // OS_TIZEN
-}
void WebDragDestEfl::DragLeave() {
GetRenderViewHost()->DragTargetDragLeave();
- if (delegate())
- delegate()->OnDragLeave();
+ if (delegate_)
+ delegate_->OnDragLeave();
drop_data_.reset();
}
-RenderViewHostImpl* WebDragDestEfl::GetRenderViewHost() const {
- return static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost());
+void WebDragDestEfl::SetDropData(const DropData& drop_data) {
+ drop_data_.reset(new DropData(drop_data));
+}
+
+RenderViewHost* WebDragDestEfl::GetRenderViewHost() const {
+ return web_contents_->GetRenderViewHost();
}
} // namespace content
#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_EFL_H_
#define CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_EFL_H_
-#include "base/gtest_prod_util.h"
+#include <Elementary.h>
+
#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/common/content_export.h"
#include "content/public/common/drop_data.h"
+#include "eweb_view.h"
#include "third_party/WebKit/public/web/WebDragOperation.h"
-
-#include <Ecore.h>
-#include <Ecore_Evas.h>
-#include <Ecore_Input.h>
-#include "ecore_x_wrapper.h"
-#include <Elementary.h>
+#include "ui/gfx/point.h"
namespace content {
-class RenderViewHostImpl;
class WebContents;
class WebDragDestDelegate;
-class RenderWidgetHostViewEfl;
-
-#define EFL_CONTENT_EXPORT __attribute__((visibility("default")))
+class RenderViewHost;
-class EFL_CONTENT_EXPORT WebDragDestEfl {
+class WebDragDestEfl {
public:
- WebDragDestEfl(WebContents* web_contents, RenderWidgetHostViewEfl* rwhvefl);
+ WebDragDestEfl(WebContents* web_contents, EWebView* eweb_view);
~WebDragDestEfl();
+ blink::WebDragOperationsMask GetAction() { return drag_action_; }
+ WebDragDestDelegate* GetDelegate() const { return delegate_; }
+ DropData* GetDropData() { return drop_data_.get(); }
+ RenderViewHost* GetRenderViewHost() const;
+ WebContents* GetWebContents() { return web_contents_; }
+
+ void ResetDropData() { drop_data_.reset(); }
+ void SetAction(blink::WebDragOperationsMask allowed_ops) { drag_action_ = allowed_ops; }
+ void SetDelegate(WebDragDestDelegate* delegate) { delegate_ = delegate; }
+ void SetDropData(const DropData& drop_data);
+
// Informs the renderer when a system drag has left the render view.
// See OnDragLeave().
void DragLeave();
- WebDragDestDelegate* delegate() const { return delegate_; }
- void set_delegate(WebDragDestDelegate* delegate) { delegate_ = delegate; }
-
- RenderViewHostImpl* GetRenderViewHost() const;
-
- RenderWidgetHostViewEfl* render_widget_host_view() { return rwhvefl_; }
-
- WebContents* web_contents() { return web_contents_; }
-
- // EFL port - public variables for now, need to add get methods to make private,
- // faced build errors with scoped_ptr, base::WeakPtrFactory methods.
+ // EFL callbacks
+ void DragStateEnter();
+ void DragStateLeave();
+ void DragPos(Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action);
+ Eina_Bool DragDrop(Elm_Selection_Data *);
- // The data for the current drag, or NULL if |context_| is NULL.
- scoped_ptr<DropData> drop_data_;
+ private:
+ void SetDragCallbacks();
+ void UnsetDragCallbacks();
+ void ResetDragCallbacks();
- base::WeakPtrFactory<WebDragDestEfl> method_factory_;
+ // Flag that indicates which modifier buttons (alt, shift, ctrl) are pressed
+ const int modifier_flags_;
- private:
// A delegate that can receive drag information about drag events.
WebDragDestDelegate* delegate_;
// The render view.
- RenderWidgetHostViewEfl *rwhvefl_;
+ EWebView* eweb_view_;
WebContents* web_contents_;
+ // Drag operation - copy, move or link
+ blink::WebDragOperationsMask drag_action_;
+
+ float device_scale_factor_;
+
+ gfx::Point last_pointer_pos_;
+
+ bool drag_initialized_;
+
+ // The data for the current drag, or NULL if |context_| is NULL.
+ scoped_ptr<DropData> drop_data_;
+
DISALLOW_COPY_AND_ASSIGN(WebDragDestEfl);
};
} // namespace content
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a license that can be
+// found in the LICENSE file.
+
+#include "browser/web_contents/web_drag_source_efl.h"
+
+#include "web_contents_delegate_efl.h"
+#include "content/browser/download/drag_download_util.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/drop_data.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "ui/gfx/screen.h"
+
+namespace content {
+
+namespace {
+blink::WebDragOperation GetWebOperationFromMask(
+ blink::WebDragOperationsMask allowed_ops)
+{
+ if (allowed_ops & blink::WebDragOperationCopy)
+ return blink::WebDragOperationCopy;
+ if (allowed_ops & blink::WebDragOperationLink)
+ return blink::WebDragOperationLink;
+ if (allowed_ops & blink::WebDragOperationMove)
+ return blink::WebDragOperationMove;
+ if (allowed_ops & blink::WebDragOperationGeneric)
+ return blink::WebDragOperationGeneric;
+ if (allowed_ops & blink::WebDragOperationPrivate)
+ return blink::WebDragOperationPrivate;
+ if (allowed_ops & blink::WebDragOperationDelete)
+ return blink::WebDragOperationDelete;
+ return blink::WebDragOperationNone;
+}
+
+Evas_Object* DragIconCreateCb(void* data, Evas_Object* win,
+ Evas_Coord* xoff, Evas_Coord* yoff) {
+ WebDragSourceEfl* web_drag_source_efl = static_cast<WebDragSourceEfl*>(data);
+ return web_drag_source_efl->DragIconCreate(win, xoff, yoff);
+}
+
+void DragPosCb(void* data, Evas_Object* obj, Evas_Coord x, Evas_Coord y,
+ Elm_Xdnd_Action action) {
+ WebDragSourceEfl *web_drag_source_efl = static_cast<WebDragSourceEfl*>(data);
+ web_drag_source_efl->DragPos(x, y, action);
+}
+
+void DragAcceptCb(void* data, Evas_Object* obj, Eina_Bool doaccept) {
+}
+
+void DragStateCb(void* data, Evas_Object* obj) {
+ WebDragSourceEfl* web_drag_source_efl = static_cast<WebDragSourceEfl*>(data);
+ web_drag_source_efl->DragState();
+}
+
+} // namespace
+
+WebDragSourceEfl::WebDragSourceEfl(WebContents* web_contents, EWebView* eweb_view)
+ : web_contents_(static_cast<WebContentsImpl*>(web_contents)),
+ eweb_view_(eweb_view),
+ drag_failed_(false),
+ drag_started_(false) {
+}
+
+WebDragSourceEfl::~WebDragSourceEfl() {
+}
+
+bool WebDragSourceEfl::StartDragging(const DropData& drop_data,
+ blink::WebDragOperationsMask allowed_ops,
+ const gfx::Point& root_location,
+ const SkBitmap& image,
+ const gfx::Vector2d& image_offset) {
+ // Guard against re-starting before previous drag completed.
+ if (drag_started_) {
+ NOTREACHED();
+ return false;
+ }
+
+ int targets_mask = 0;
+ drop_data_.reset(new DropData(drop_data));
+
+ if (!drop_data.text.string().empty())
+ targets_mask |= ELM_SEL_FORMAT_TEXT;
+ if (drop_data.url.is_valid())
+ targets_mask |= ELM_SEL_FORMAT_TEXT;
+ if (!drop_data.html.string().empty())
+ targets_mask |= ELM_SEL_FORMAT_HTML;
+ if (!drop_data.file_contents.empty())
+ targets_mask |= ELM_SEL_FORMAT_IMAGE;
+ if (!drop_data.download_metadata.empty() &&
+ ParseDownloadMetadata(drop_data.download_metadata,
+ &wide_download_mime_type_,
+ &download_file_name_,
+ &download_url_))
+ targets_mask |= ELM_SEL_FORMAT_IMAGE;
+ if (!drop_data.custom_data.empty())
+ targets_mask |= ELM_SEL_FORMAT_NONE;
+
+ int action = 0;
+
+ if (allowed_ops & blink::WebDragOperationCopy)
+ action |= ELM_XDND_ACTION_COPY;
+ if (allowed_ops & blink::WebDragOperationLink)
+ action |= ELM_XDND_ACTION_LINK ;
+ if (allowed_ops & blink::WebDragOperationMove)
+ action |= ELM_XDND_ACTION_MOVE;
+ if(!action)
+ action = ELM_XDND_ACTION_UNKNOWN;
+
+ image_ = image;
+ image_offset_ = image_offset;
+ drag_action_ = allowed_ops;
+ drag_failed_ = false;
+ device_scale_factor_ = gfx::Screen::GetNativeScreen()->
+ GetPrimaryDisplay().device_scale_factor();
+
+ drag_started_ = elm_drag_start(eweb_view_->evas_object(),
+ static_cast<Elm_Sel_Format>(targets_mask),
+ reinterpret_cast<char*>(drop_data_.get()),
+ static_cast<Elm_Xdnd_Action>(action),
+ DragIconCreateCb, this,
+ DragPosCb, this,
+ DragAcceptCb, this,
+ DragStateCb, this);
+
+ // Sometimes the drag fails to start; |drag_started_| will be false and we won't
+ // get a drag-end signal.
+ if (!drag_started_) {
+ LOG(WARNING) << "Failed to start drag and drop";
+ drag_failed_ = true;
+ drop_data_.reset();
+ return false;
+ }
+
+ return true;
+}
+
+Evas_Object* WebDragSourceEfl::DragIconCreate(
+ Evas_Object* win, Evas_Coord* xoff, Evas_Coord* yoff) const {
+ int w = image_.width(), h = image_.height(), x, y;
+
+ gfx::Point position = eweb_view_->GetContextMenuPosition();
+
+ // set icon position above the touch point
+ x = position.x() - w / 2;
+ y = position.y() - h;
+
+ if (xoff) *xoff = x;
+ if (yoff) *yoff = y;
+ Evas* evas = evas_object_evas_get(win);
+ Evas_Object* icon = evas_object_image_add(evas);
+ evas_object_image_size_set(icon, w, h);
+ evas_object_image_alpha_set(icon, EINA_TRUE);
+ evas_object_image_data_copy_set(icon, image_.pixelRef()->pixels());
+ evas_object_size_hint_align_set(icon,
+ EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(icon,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_move(icon, x, y);
+ evas_object_image_fill_set(icon, 0, 0, w, h);
+ evas_object_resize(icon, w, h);
+ evas_object_show(icon);
+
+ return icon;
+}
+
+void WebDragSourceEfl::DragPos(Evas_Coord x, Evas_Coord y,
+ Elm_Xdnd_Action action) {
+ gfx::Point screen_pt = gfx::Point(x / device_scale_factor_,
+ y / device_scale_factor_);
+ last_pointer_pos_ = screen_pt;
+}
+
+void WebDragSourceEfl::DragState() {
+ double page_scale = eweb_view_->GetScale();
+
+ gfx::Point client_pt = gfx::Point(last_pointer_pos_.x() / page_scale,
+ last_pointer_pos_.y() / page_scale);
+
+ web_contents_->DragSourceEndedAt(
+ client_pt.x(), client_pt.y(),
+ last_pointer_pos_.x(), last_pointer_pos_.y(),
+ GetWebOperationFromMask(drag_action_));
+
+ web_contents_->SystemDragEnded();
+ drag_started_ = false;
+}
+
+} // namespace content
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_SOURCE_EFL_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_SOURCE_EFL_H_
+
+#include <Elementary.h>
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/strings/string16.h"
+#include "eweb_view.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/WebKit/public/web/WebDragOperation.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/vector2d.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class WebContents;
+class WebContentsImpl;
+
+struct DropData;
+
+// WebDragSourceEfl takes care of managing the drag from a WebContents
+// with Efl.
+class WebDragSourceEfl {
+ public:
+ explicit WebDragSourceEfl(WebContents* web_contents, EWebView* eweb_view);
+ virtual ~WebDragSourceEfl();
+
+ // Starts a drag for the WebContents this object was created for.
+ // Returns false if the drag could not be started.
+ bool StartDragging(const DropData& drop_data,
+ blink::WebDragOperationsMask allowed_ops,
+ const gfx::Point& root_location,
+ const SkBitmap& image,
+ const gfx::Vector2d& image_offset);
+
+ void Reset() { drag_started_ = false; }
+ void SetLastPoint(gfx::Point point) { last_point_ = point; }
+ bool IsDragging() { return drag_started_; }
+
+ // EFL callbacks
+ Evas_Object* DragIconCreate(Evas_Object* win, Evas_Coord* xoff, Evas_Coord* yoff) const;
+ void DragPos(Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action);
+ void DragState();
+
+ private:
+ EWebView* eweb_view_;
+
+ // The tab we're manging the drag for.
+ WebContentsImpl* web_contents_;
+
+ // The drop data for the current drag (for drags that originate in the render
+ // view). Non-NULL iff there is a current drag.
+ scoped_ptr<DropData> drop_data_;
+
+ // The image used for depicting the drag, and the offset between the cursor
+ // and the top left pixel.
+ SkBitmap image_;
+ gfx::Vector2d image_offset_;
+
+ // Whether the current drag has failed. Meaningless if we are not the source
+ // for a current drag.
+ bool drag_failed_;
+
+ // True set once drag starts. A false value indicates that there is
+ // no drag currently in progress.
+ bool drag_started_;
+
+ // Last registered point from drag_pos_cb callback.
+ gfx::Point last_point_;
+
+ // Maks of all available drag actions linke copy, move or link
+ blink::WebDragOperationsMask drag_action_;
+
+ // The file mime type for a drag-out download.
+ base::string16 wide_download_mime_type_;
+
+ // The file name to be saved to for a drag-out download.
+ base::FilePath download_file_name_;
+
+ // The URL to download from for a drag-out download.
+ GURL download_url_;
+
+ float device_scale_factor_;
+
+ gfx::Point last_pointer_pos_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebDragSourceEfl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_SOURCE_EFL_H_
'browser/web_contents/web_contents_view_efl.h',
'browser/web_contents/web_drag_dest_efl.cc',
'browser/web_contents/web_drag_dest_efl.h',
+ 'browser/web_contents/web_drag_source_efl.cc',
+ 'browser/web_contents/web_drag_source_efl.h',
'browser/web_view_browser_message_filter.h',
'browser/web_view_browser_message_filter.cc',
'browser/webdata/web_data_service.cc',
#include "cc/base/switches.h"
#include "ui/events/event_switches.h"
#include "extensions/common/switches.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_switches.h"
#include "url/gurl.h"
p_command_line->AppendSwitch(cc::switches::kEnableParallelCanvasMode);
#endif
+ p_command_line->AppendSwitch(switches::kEnableTouchDragDrop);
+
if (p_command_line->HasSwitch(switches::kDisableIpcSandbox))
p_command_line->AppendSwitch(switches::kDisableRendererZygote);
screen_orientation_ == 90 ||
screen_orientation_ == 180 ||
screen_orientation_ == 270) {
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(web_contents_.get());
- WebContentsViewEfl* web_contents_view = static_cast<WebContentsViewEfl*>(web_contents->GetView());
- web_contents_view->SetOrientation(screen_orientation_);
+ GetWebContentsViewEfl()->SetOrientation(screen_orientation_);
// workaround for platform issue not resizing popup after rotation
// this should be removed when when proper fix will be applied for platorm.
}
}
+content::WebContentsViewEfl* EWebView::GetWebContentsViewEfl() const {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+ return static_cast<WebContentsViewEfl*>(wc->GetView());
+}
+
void EWebView::HandlePostponedGesture(int x, int y, ui::EventType type) {
LOG(INFO) << "HandlePostponedGesture :: " << type;
switch (type) {
convertedParams.x += x;
convertedParams.y += y;
+ context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
+
if (!selection_controller_->IsShowingMagnifier() &&
selection_controller_->IsCaretSelection()) {
if(!context_menu_->PopulateAndShowContextMenu(convertedParams))
SmartCallback<EWebViewCallbacks::SetCertificatePem>().call(pem_certificate_.c_str());
}
+bool EWebView::IsDragging() const {
+ return GetWebContentsViewEfl()->IsDragging();
+}
+
void EWebView::ShowFileChooser(const content::FileChooserParams& params) {
RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
if (!render_view_host)
}
void EWebView::SetViewMode(tizen_webview::View_Mode view_mode) {
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(web_contents_.get());
- WebContentsViewEfl *web_contents_view = static_cast<WebContentsViewEfl*>(web_contents->GetView());
- web_contents_view->SetViewMode(view_mode);
+ GetWebContentsViewEfl()->SetViewMode(view_mode);
+}
+
+gfx::Point EWebView::GetContextMenuPosition() const {
+ return context_menu_position_;
}
#ifdef TIZEN_CONTENTS_DETECTION
class WebContentsDelegateEfl;
class ContextMenuControllerEfl;
class DevToolsDelegateEfl;
+class WebContentsViewEfl;
#ifdef TIZEN_CONTENTS_DETECTION
class PopupControllerEfl;
#endif
void DidChangeContentsArea(int width, int height);
void SetBrowserFont();
void SetCertificatePem(const std::string& certificate);
+ bool IsDragging() const;
void RequestColorPicker(int r, int g, int b, int a);
void DismissColorPicker();
void SetOverrideEncoding(const std::string& encoding);
void SetViewMode(tizen_webview::View_Mode view_mode);
+ gfx::Point GetContextMenuPosition() const;
+
/// ---- Event handling
bool HandleShow();
bool HandleHide();
tizen_webview::Hit_Test*);
void HandleTapGesture(int x, int y, tizen_webview::Hit_Test_Mode mode,
tizen_webview::Hit_Test*);
+ content::WebContentsViewEfl* GetWebContentsViewEfl() const;
#if defined(OS_TIZEN_MOBILE) && !defined(EWK_BRINGUP)
static void cameraResultCb(service_h request, service_h reply,
gfx::Vector2d previous_scroll_position_;
+ gfx::Point context_menu_position_;
+
std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*> hit_test_callback_;
// only tizen_webview::WebView can create and delete this
EWebView(tizen_webview::WebView* owner, tizen_webview::WebContext*, Evas_Object* smart_object);