Text Selection Handlers not updated with the correct position
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / API / efl / tizen / TextSelectionHandle.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_WEBKIT2_TEXT_SELECTION)
29 #include "TextSelectionHandle.h"
30
31 #include <Edje.h>
32
33 using namespace WebCore;
34
35 namespace WebKit {
36
37 Ecore_Job* TextSelectionHandle::s_job = 0;
38
39 TextSelectionHandle::TextSelectionHandle(Evas_Object* object, const char* themePath, const char* part, bool isLeft, TextSelection* textSelection)
40     : m_isLeft(isLeft)
41     , m_widget(object)
42     , m_textSelection(textSelection)
43     , m_position(IntPoint(0, 0))
44     , m_isMouseDowned(false)
45     , m_isTop(false)
46 {
47     Evas* evas = evas_object_evas_get(object);
48     m_icon = edje_object_add(evas);
49
50     if (!m_icon)
51         return;
52
53     if (!edje_object_file_set(m_icon, themePath, part))
54         return;
55
56     edje_object_signal_emit(m_icon, "edje,focus,in", "edje");
57     edje_object_signal_emit(m_icon, "elm,state,bottom", "elm");
58     evas_object_smart_member_add(m_icon, object);
59
60     evas_object_propagate_events_set(m_icon, false);
61     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown, this);
62     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove, this);
63     evas_object_event_callback_add(m_icon, EVAS_CALLBACK_MOUSE_UP, onMouseUp, this);
64 }
65
66 TextSelectionHandle::~TextSelectionHandle()
67 {
68     evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown);
69     evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove);
70     evas_object_event_callback_del(m_icon, EVAS_CALLBACK_MOUSE_UP, onMouseUp);
71     evas_object_del(m_icon);
72     if (s_job) {
73         ecore_job_del(s_job);
74         s_job = 0;
75     }
76 }
77
78 void TextSelectionHandle::move(const IntPoint& point, const IntRect& selectionRect)
79 {
80     IntPoint movePoint = point;
81     const int reverseMargin = 32;
82     int x, y, deviceWidth, deviceHeight;
83     int handleHeight;
84
85     edje_object_part_geometry_get(m_icon, "handle", 0, 0, 0, &handleHeight);
86     evas_object_geometry_get(m_widget, &x, &y, &deviceWidth, &deviceHeight);
87
88     if ((m_isLeft && (movePoint.x() <= reverseMargin)) || (!m_isLeft && (movePoint.x() >= deviceWidth - reverseMargin))) {
89         if ((movePoint.y() + handleHeight) > (y + deviceHeight)) {
90             movePoint.setY(movePoint.y() - selectionRect.height());
91             edje_object_signal_emit(m_icon, "elm,state,top,reversed", "elm");
92             m_isTop = true;
93         } else {
94             edje_object_signal_emit(m_icon, "elm,state,bottom,reversed", "elm");
95             m_isTop = false;
96         }
97     }
98     else {
99         if ((movePoint.y() + handleHeight) > (y + deviceHeight)) {
100             movePoint.setY(movePoint.y() - selectionRect.height());
101             edje_object_signal_emit(m_icon, "elm,state,top", "elm");
102             m_isTop = true;
103         } else {
104             edje_object_signal_emit(m_icon, "elm,state,bottom", "elm");
105             m_isTop = false;
106         }
107     }
108
109     evas_object_move(m_icon, movePoint.x(), movePoint.y());
110     m_position = movePoint;
111
112 }
113
114 void TextSelectionHandle::show()
115 {
116     evas_object_show(m_icon);
117 }
118
119 void TextSelectionHandle::hide()
120 {
121     evas_object_hide(m_icon);
122 }
123
124 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
125 const IntRect TextSelectionHandle::getHandleRect()
126 {
127     if (!evas_object_visible_get(m_icon))
128         return IntRect();
129
130     int x, y;
131     evas_object_geometry_get(m_icon, &x, &y, 0, 0);
132
133     int partX, partY, partWidth, partHeight;
134     edje_object_part_geometry_get(m_icon, "handle", &partX, &partY, &partWidth, &partHeight);
135
136     WebCore::IntRect handleRect(x + partX, y + partY, partWidth, partHeight);
137     return handleRect;
138 }
139 #endif
140
141 // callbacks
142 void TextSelectionHandle::mouseDown(const IntPoint& point)
143 {
144 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
145     edje_object_signal_emit(m_icon, "mouse,down,1", "handle");
146 #endif
147
148     setIsMouseDowned(true);
149     setFirstDownMousePosition(point);
150     setMousePosition(point);
151     m_textSelection->handleMouseDown(this, m_mousePosition);
152 }
153
154 void TextSelectionHandle::mouseMove(const IntPoint& point)
155 {
156     if (!m_textSelection->isMagnifierVisible())
157         return;
158
159     setMousePosition(point);
160
161     if (!s_job)
162        s_job = ecore_job_add(update, this);
163 }
164
165 void TextSelectionHandle::mouseUp()
166 {
167 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
168     edje_object_signal_emit(m_icon, "mouse,up,1", "handle");
169 #endif
170
171     if (m_textSelection->isEnabled())
172         setIsMouseDowned(false);
173
174     m_textSelection->handleMouseUp(this, m_mousePosition);
175 }
176
177 void TextSelectionHandle::onMouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
178 {
179     Evas_Event_Mouse_Down* event = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
180     TextSelectionHandle* handle = static_cast<TextSelectionHandle*>(data);
181
182     handle->mouseDown(IntPoint(event->canvas.x, event->canvas.y));
183 }
184
185 void TextSelectionHandle::onMouseMove(void* data, Evas*, Evas_Object*, void* eventInfo)
186 {
187     Evas_Event_Mouse_Move* event = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
188     TextSelectionHandle* handle = static_cast<TextSelectionHandle*>(data);
189
190     handle->mouseMove(IntPoint(event->cur.canvas.x, event->cur.canvas.y));
191 }
192
193 void TextSelectionHandle::onMouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
194 {
195     TextSelectionHandle* handle = static_cast<TextSelectionHandle*>(data);
196
197     handle->mouseUp();
198 }
199
200 // job
201 void TextSelectionHandle::update(void* data)
202 {
203     TextSelectionHandle* handle = static_cast<TextSelectionHandle*>(data);
204     int deltaX = handle->m_mousePosition.x() - handle->m_firstDownMousePosition.x();
205     int deltaY = handle->m_mousePosition.y() - handle->m_firstDownMousePosition.y();
206
207     if (deltaX || deltaY) {
208         WebCore::IntPoint movePosition;
209
210         movePosition.setX(handle->m_basePositionForMove.x() + deltaX);
211         movePosition.setY(handle->m_basePositionForMove.y() + deltaY);
212
213         handle->m_textSelection->handleMouseMove(handle, movePosition);
214     }
215     TextSelectionHandle::s_job = 0;
216 }
217
218 } // namespace WebKit
219
220 #endif // TIZEN_WEBKIT2_TEXT_SELECTION