2 * Copyright (C) 2012 Samsung Electronics
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #include "FocusRing.h"
23 #include "EwkViewImpl.h"
24 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
25 #include "PageClientImpl.h"
27 #if ENABLE(TOUCH_ADJUSTMENT)
28 #include <Elementary.h>
31 using namespace WebKit;
32 using namespace WebCore;
34 FocusRing::FocusRing(EwkViewImpl* viewImpl)
35 : m_viewImpl(viewImpl)
36 , m_focusRingObject(0)
37 , m_imageOuterWidth(0)
38 , m_imageInnerWidth(0)
44 FocusRing::~FocusRing()
47 ecore_timer_del(m_showTimer);
50 ecore_timer_del(m_hideTimer);
52 if (m_focusRingObject)
53 evas_object_del(m_focusRingObject);
56 Eina_Bool FocusRing::showTimerCallback(void* data)
58 static_cast<FocusRing*>(data)->show(IntRect());
59 return ECORE_CALLBACK_CANCEL;
62 void FocusRing::setImage(const String& path, int outerWidth, int innerWidth)
64 if (m_imagePath == path && m_imageOuterWidth == outerWidth && m_imageInnerWidth == innerWidth)
68 m_imageOuterWidth = outerWidth;
69 m_imageInnerWidth = innerWidth;
71 if (m_focusRingObject) {
72 evas_object_del(m_focusRingObject);
73 m_focusRingObject = 0;
77 void FocusRing::requestToShow(const IntPoint& position, bool immediately)
79 if (!m_imagePath.isNull())
83 if (m_focusRingObject && evas_object_visible_get(m_focusRingObject))
87 ecore_timer_del(m_showTimer);
91 m_position = position;
97 m_position = position;
100 ecore_timer_del(m_showTimer);
101 m_showTimer = ecore_timer_add((double)s_showTimerTime/1000.0, showTimerCallback, this);
104 void FocusRing::show(const IntRect& rect, const bool includeOnlyImage)
106 if (rect.isEmpty()) {
108 ecore_timer_del(m_showTimer);
113 PageClientImpl* pageClientImpl = m_viewImpl->pageClient.get();
114 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
116 IntRect focusRingRect(rect);
117 Color focusRingColor;
119 if (rect.isEmpty()) {
120 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
121 IntPoint contentsPosition = m_viewImpl->transformFromScene().mapPoint(m_position);
122 #if ENABLE(TOUCH_ADJUSTMENT)
123 Evas_Coord size = elm_config_finger_size_get();
124 IntSize fingerSize = IntSize(size, size);
125 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
126 double scaleFactor = pageClientImpl->scaleFactor();
127 if (scaleFactor - 1 > numeric_limits<float>::epsilon())
128 fingerSize.scale(1 / scaleFactor, 1 / scaleFactor);
130 WebHitTestResult::Data hitTestResultData = m_viewImpl->page()->hitTestResultAtPoint(contentsPosition, WebHitTestResult::HitTestModeDefault, fingerSize);
132 WebHitTestResult::Data hitTestResultData = m_viewImpl->page()->hitTestResultAtPoint(contentsPosition);
134 if (hitTestResultData.focusedRect.isEmpty())
137 if (!hitTestResultData.absoluteImageURL.isEmpty() && hitTestResultData.absoluteLinkURL.isEmpty()) {
138 if (!includeOnlyImage)
142 focusRingRect = hitTestResultData.focusedRect;
143 focusRingColor = hitTestResultData.focusedColor;
144 #endif // #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
147 focusRingRect = m_viewImpl->transformToScene().mapRect(focusRingRect);
149 Evas_Coord_Rectangle viewGeometry;
150 evas_object_geometry_get(m_viewImpl->view(), &viewGeometry.x, &viewGeometry.y, &viewGeometry.w, &viewGeometry.h);
151 IntRect viewRect(viewGeometry.x, viewGeometry.y, viewGeometry.w, viewGeometry.h);
152 focusRingRect.intersect(viewRect);
153 if (focusRingRect.isEmpty()) {
158 m_rect = focusRingRect;
159 m_rect.move(-viewGeometry.x, -viewGeometry.y);
161 if (m_focusRingObject)
162 evas_object_hide(m_focusRingObject);
164 if (m_imagePath.isNull())
165 m_focusRingObject = evas_object_rectangle_add(evas_object_evas_get(m_viewImpl->view()));
167 m_focusRingObject = evas_object_image_add(evas_object_evas_get(m_viewImpl->view()));
168 evas_object_image_file_set(m_focusRingObject, m_imagePath.utf8().data(), 0);
169 int border = m_imageOuterWidth + m_imageInnerWidth;
170 evas_object_image_border_set(m_focusRingObject, border, border, border, border);
173 evas_object_smart_member_add(m_focusRingObject, m_viewImpl->view());
174 evas_object_repeat_events_set(m_focusRingObject, true);
177 if (m_imagePath.isNull()) {
178 evas_object_color_set(m_focusRingObject, focusRingColor.red(), focusRingColor.green(), focusRingColor.blue(), focusRingColor.alpha());
179 evas_object_move(m_focusRingObject, focusRingRect.x(), focusRingRect.y());
180 evas_object_resize(m_focusRingObject, focusRingRect.width(), focusRingRect.height());
182 viewRect.inflate(-m_imageOuterWidth);
184 if (focusRingRect.intersects(viewRect))
185 focusRingRect.intersect(viewRect);
187 if (viewRect.x() > focusRingRect.x()) {
188 focusRingRect.setX(viewRect.x());
189 focusRingRect.setWidth(1);
190 } else if (viewRect.maxX() < focusRingRect.maxX()) {
191 focusRingRect.setX(viewRect.maxX());
192 focusRingRect.setWidth(1);
194 if (viewRect.y() > focusRingRect.y()) {
195 focusRingRect.setY(viewRect.y());
196 focusRingRect.setHeight(1);
197 } else if (viewRect.maxY() < focusRingRect.maxY()) {
198 focusRingRect.setY(viewRect.maxY());
199 focusRingRect.setHeight(1);
203 evas_object_move(m_focusRingObject, focusRingRect.x() - m_imageOuterWidth, focusRingRect.y() - m_imageOuterWidth);
205 int width = focusRingRect.width() + m_imageOuterWidth * 2;
206 int height = focusRingRect.height() + m_imageOuterWidth * 2;
207 evas_object_image_fill_set(m_focusRingObject, 0, 0, width, height);
208 evas_object_resize(m_focusRingObject, width, height);
211 evas_object_show(m_focusRingObject);
214 void FocusRing::requestToHide(bool immediately)
222 ecore_timer_del(m_hideTimer);
223 m_hideTimer = ecore_timer_add((double)s_hideTimerTime/1000.0, hideTimerCallback, this);
226 Eina_Bool FocusRing::hideTimerCallback(void* data)
228 static_cast<FocusRing*>(data)->hide();
229 return ECORE_CALLBACK_CANCEL;
232 void FocusRing::hide(bool onlyColorDrawing)
234 if (!m_imagePath.isNull() && onlyColorDrawing)
238 ecore_timer_del(m_showTimer);
243 ecore_timer_del(m_hideTimer);
247 if (m_focusRingObject && evas_object_visible_get(m_focusRingObject))
248 evas_object_hide(m_focusRingObject);
253 void FocusRing::updateScrollAndScale(const WebCore::IntPoint& previousScrollPosition, float previousScale)
255 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
256 if (m_rect.isEmpty())
259 FloatRect rect(m_rect);
260 rect.moveBy(previousScrollPosition);
261 rect.scale(1 / previousScale);
263 show(enclosingIntRect(rect));
265 UNUSED_PARAM(previousScrollPosition);
266 UNUSED_PARAM(previousScale);
270 IntPoint FocusRing::centerPointInScreen()
272 if (m_rect.isEmpty())
273 return IntPoint(-1, -1);
275 IntPoint point(m_rect.center());
277 evas_object_geometry_get(m_viewImpl->view(), &x, &y, 0, 0);
283 #endif // #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)