Fixed drag position issue
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / API / efl / tizen / DragHandle.cpp
1 /*
2  * Copyright (C) 2012 Samsung Electronics
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if ENABLE(TIZEN_DRAG_SUPPORT)
29 #include "DragHandle.h"
30
31 #include <Edje.h>
32
33 using namespace WebCore;
34
35 namespace WebKit {
36
37 const int s_widthMargin = 20;
38 const int s_heightMargin = 10;
39 const int s_cancelImageXMargin = 26;
40 const int s_cancelImageYMargin = 36;
41 const double s_minIconWidth = 110;
42 const double s_minIconHeight = 100;
43 const double s_minImageLength = 90;
44 const double s_maxImageLength = 300;
45
46 DragHandle::DragHandle(Evas_Object* object, const String& theme, const String& path, Drag* drag)
47     : m_view(object)
48     , m_drag(drag)
49     , m_dragJob(0)
50 {
51     Evas_Object* topWidget = elm_object_top_widget_get(elm_object_parent_widget_get(object));
52     if (!topWidget)
53         topWidget = m_view;
54
55     m_icon = elm_layout_add(topWidget);
56     m_cancelIcon = elm_layout_add(topWidget);
57
58     if (!m_icon || !m_cancelIcon)
59         return;
60
61     if (!elm_layout_file_set(m_icon, theme.utf8().data(), path.utf8().data()) || !elm_layout_file_set(m_cancelIcon, theme.utf8().data(), "drag_cancel"))
62         return;
63
64     evas_object_smart_member_add(m_icon, m_view);
65     evas_object_smart_member_add(m_cancelIcon, m_view);
66
67     evas_object_propagate_events_set(m_icon, false);
68     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_DOWN, mouseDown, this);
69     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_MOVE, mouseMove, this);
70     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_UP, mouseUp, this);
71     evas_object_propagate_events_set(m_cancelIcon, false);
72     evas_object_event_callback_add(m_cancelIcon, EVAS_CALLBACK_MOUSE_DOWN, cancelMouseDown, this);
73     evas_object_event_callback_add(m_cancelIcon, EVAS_CALLBACK_MOUSE_UP, cancelMouseUp, this);
74 }
75
76 DragHandle::~DragHandle()
77 {
78     if (m_dragJob) {
79         ecore_job_del(m_dragJob);
80         m_dragJob = 0;
81     }
82
83     if (m_icon) {
84         evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_DOWN, mouseDown);
85         evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_MOVE, mouseMove);
86         evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_UP, mouseUp);
87         evas_object_del(m_icon);
88     }
89
90     if (m_cancelIcon) {
91         evas_object_event_callback_del(m_cancelIcon, EVAS_CALLBACK_MOUSE_DOWN, cancelMouseDown);
92         evas_object_event_callback_del(m_cancelIcon, EVAS_CALLBACK_MOUSE_UP, cancelMouseUp);
93         evas_object_del(m_cancelIcon);
94     }
95 }
96
97 void DragHandle::move(const IntPoint& point)
98 {
99     if (m_icon) {
100         Evas_Coord x, y, width, height;
101         evas_object_geometry_get(m_view, &x, &y, &width, &height);
102
103         double dragX, dragY;
104         if ((point.x() - m_dragImageWidth / 2) < s_cancelImageXMargin)
105             dragX = s_cancelImageXMargin;
106         else if ((point.x() - m_dragImageWidth / 2) > (width - m_dragImageWidth))
107             dragX = width - m_dragImageWidth;
108         else
109             dragX = point.x() - m_dragImageWidth / 2;
110         if ((point.y() - m_dragImageHeight / 2) < (y + s_cancelImageYMargin))
111             dragY = y + s_cancelImageYMargin;
112         else if ((point.y() - m_dragImageHeight / 2) > (y + height - m_dragImageHeight))
113             dragY = y + height - m_dragImageHeight;
114         else
115             dragY = point.y() - m_dragImageHeight / 2;
116
117         evas_object_move(m_icon, dragX, dragY);
118         evas_object_move(m_cancelIcon, dragX - s_cancelImageXMargin, dragY - s_cancelImageYMargin);
119     }
120 }
121
122 void DragHandle::show()
123 {
124     if (m_icon) {
125         if (m_drag->getDragImage()) {
126             elm_object_signal_emit(m_icon, "dragndrop,link,hide", "dragndrop");
127             elm_object_signal_emit(m_icon, "dragndrop,image,show", "dragndrop");
128
129             m_dragImageWidth = cairo_image_surface_get_width(m_drag->getDragImage()->createCairoSurface().get());
130             m_dragImageHeight = cairo_image_surface_get_height(m_drag->getDragImage()->createCairoSurface().get());
131
132             if (m_dragImage)
133                 m_dragImage = 0;
134
135             if (m_dragImageWidth < s_minImageLength) {
136                 m_dragImageWidth *= 1.5;
137                 m_dragImageHeight *= 1.5;
138             }
139
140             if (m_dragImageHeight > s_maxImageLength) {
141                 m_dragImageWidth = m_dragImageWidth * (s_maxImageLength / m_dragImageHeight);
142                 m_dragImageHeight = s_maxImageLength;
143             }
144             if (m_dragImageWidth > s_maxImageLength) {
145                 m_dragImageHeight = m_dragImageHeight * (s_maxImageLength / m_dragImageWidth);
146                 m_dragImageWidth = s_maxImageLength;
147             }
148
149             if (m_dragImageWidth < s_minImageLength)
150                 m_dragImageWidth = s_minImageLength;
151             if (m_dragImageHeight < s_minImageLength)
152                 m_dragImageHeight = s_minImageLength;
153
154             m_dragImage = ewk_util_image_from_cairo_surface_add(evas_object_evas_get(m_drag->getViewImpl()->view()), m_drag->getDragImage()->createCairoSurface().get());
155             evas_object_size_hint_min_set(m_dragImage, m_dragImageWidth, m_dragImageHeight);
156             evas_object_resize(m_dragImage, m_dragImageWidth, m_dragImageHeight);
157             evas_object_image_filled_set(m_dragImage, EINA_TRUE);
158             evas_object_show(m_dragImage);
159
160             m_dragImageWidth += s_widthMargin;
161             m_dragImageHeight += s_heightMargin;
162
163             evas_object_resize(m_icon, m_dragImageWidth, m_dragImageHeight);
164             elm_object_part_content_set(m_icon, "swallow", m_dragImage);
165         } else {
166             elm_object_signal_emit(m_icon, "dragndrop,image,hide", "dragndrop");
167             elm_object_signal_emit(m_icon, "dragndrop,link,show", "dragndrop");
168
169             m_dragImageWidth = s_minIconWidth;
170             m_dragImageHeight = s_minIconHeight;
171
172             evas_object_resize(m_icon, m_dragImageWidth, m_dragImageHeight);
173         }
174         evas_object_show(m_icon);
175         evas_object_show(m_cancelIcon);
176     }
177 }
178
179 void DragHandle::hide()
180 {
181     if (m_icon) {
182         evas_object_hide(m_icon);
183         evas_object_hide(m_cancelIcon);
184
185         elm_object_signal_emit(m_icon, "dragndrop,drop,out", "dragndrop");
186         elm_object_signal_emit(m_cancelIcon, "dragndrop,cancel,default", "dragndrop");
187     }
188 }
189
190 void DragHandle::updateHandleIcon(bool isDropAble)
191 {
192     if(!m_icon)
193         return;
194
195     if (isDropAble)
196         elm_object_signal_emit(m_icon, "dragndrop,drop,in", "dragndrop");
197     else
198         elm_object_signal_emit(m_icon, "dragndrop,drop,out", "dragndrop");
199 }
200
201 // callbacks
202 void DragHandle::cancelMouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
203 {
204     DragHandle* handle = static_cast<DragHandle*>(data);
205     elm_object_signal_emit(handle->cancelIcon(), "dragndrop,cancel,press", "dragndrop");
206 }
207
208 void DragHandle::cancelMouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
209 {
210     DragHandle* handle = static_cast<DragHandle*>(data);
211     elm_object_signal_emit(handle->cancelIcon(), "dragndrop,cancel,default", "dragndrop");
212     handle->hide();
213 }
214
215 void DragHandle::mouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
216 {
217     Evas_Event_Mouse_Down* event = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
218     DragHandle* handle = static_cast<DragHandle*>(data);
219
220     handle->setMousePosition(IntPoint(event->canvas.x, event->canvas.y));
221     handle->m_drag->handleMouseDown(handle);
222 }
223
224 void DragHandle::mouseMove(void* data, Evas*, Evas_Object*, void* eventInfo)
225 {
226     Evas_Event_Mouse_Move* event = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
227     DragHandle* handle = static_cast<DragHandle*>(data);
228
229     handle->setMousePosition(IntPoint(event->cur.canvas.x, event->cur.canvas.y));
230
231     if (!handle->m_dragJob)
232        handle->m_dragJob = ecore_job_add(update, data);
233 }
234
235 void DragHandle::mouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
236 {
237     DragHandle* handle = static_cast<DragHandle*>(data);
238     handle->m_drag->handleMouseUp(handle);
239 }
240
241 // job
242 void DragHandle::update(void* data)
243 {
244     DragHandle* handle = static_cast<DragHandle*>(data);
245     handle->m_drag->handleMouseMove(handle);
246     handle->m_dragJob = 0;
247 }
248
249 } // namespace WebKit
250
251 #endif // TIZEN_DRAG_SUPPORT