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()) {
179 r = (focusRingColor.red() * focusRingColor.alpha()) / 255;
180 g = (focusRingColor.green() * focusRingColor.alpha()) / 255;
181 b = (focusRingColor.blue() * focusRingColor.alpha()) / 255;
182 evas_object_color_set(m_focusRingObject, r, g, b, focusRingColor.alpha());
183 evas_object_move(m_focusRingObject, focusRingRect.x(), focusRingRect.y());
184 evas_object_resize(m_focusRingObject, focusRingRect.width(), focusRingRect.height());
186 viewRect.inflate(-m_imageOuterWidth);
188 if (focusRingRect.intersects(viewRect))
189 focusRingRect.intersect(viewRect);
191 if (viewRect.x() > focusRingRect.x()) {
192 focusRingRect.setX(viewRect.x());
193 focusRingRect.setWidth(1);
194 } else if (viewRect.maxX() < focusRingRect.maxX()) {
195 focusRingRect.setX(viewRect.maxX());
196 focusRingRect.setWidth(1);
198 if (viewRect.y() > focusRingRect.y()) {
199 focusRingRect.setY(viewRect.y());
200 focusRingRect.setHeight(1);
201 } else if (viewRect.maxY() < focusRingRect.maxY()) {
202 focusRingRect.setY(viewRect.maxY());
203 focusRingRect.setHeight(1);
207 evas_object_move(m_focusRingObject, focusRingRect.x() - m_imageOuterWidth, focusRingRect.y() - m_imageOuterWidth);
209 int width = focusRingRect.width() + m_imageOuterWidth * 2;
210 int height = focusRingRect.height() + m_imageOuterWidth * 2;
211 evas_object_image_fill_set(m_focusRingObject, 0, 0, width, height);
212 evas_object_resize(m_focusRingObject, width, height);
215 evas_object_show(m_focusRingObject);
218 void FocusRing::requestToHide(bool immediately)
226 ecore_timer_del(m_hideTimer);
227 m_hideTimer = ecore_timer_add((double)s_hideTimerTime/1000.0, hideTimerCallback, this);
230 Eina_Bool FocusRing::hideTimerCallback(void* data)
232 static_cast<FocusRing*>(data)->hide();
233 return ECORE_CALLBACK_CANCEL;
236 void FocusRing::hide(bool onlyColorDrawing)
238 if (!m_imagePath.isNull() && onlyColorDrawing)
242 ecore_timer_del(m_showTimer);
247 ecore_timer_del(m_hideTimer);
251 if (m_focusRingObject && evas_object_visible_get(m_focusRingObject))
252 evas_object_hide(m_focusRingObject);
257 void FocusRing::updateScrollAndScale(const WebCore::IntPoint& previousScrollPosition, float previousScale)
259 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
260 if (m_rect.isEmpty())
263 FloatRect rect(m_rect);
264 rect.moveBy(previousScrollPosition);
265 rect.scale(1 / previousScale);
267 show(enclosingIntRect(rect));
269 UNUSED_PARAM(previousScrollPosition);
270 UNUSED_PARAM(previousScale);
274 IntPoint FocusRing::centerPointInScreen()
276 if (m_rect.isEmpty())
277 return IntPoint(-1, -1);
279 IntPoint point(m_rect.center());
281 evas_object_geometry_get(m_viewImpl->view(), &x, &y, 0, 0);
287 #endif // #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)