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)
79 if (!m_imagePath.isNull())
82 m_position = position;
85 ecore_timer_del(m_showTimer);
86 m_showTimer = ecore_timer_add((double)s_showTimerTime/1000.0, showTimerCallback, this);
89 void FocusRing::show(const IntRect& rect, const bool includeOnlyImage)
93 ecore_timer_del(m_showTimer);
98 PageClientImpl* pageClientImpl = m_viewImpl->pageClient.get();
99 EINA_SAFETY_ON_NULL_RETURN(pageClientImpl);
101 IntRect focusRingRect(rect);
102 Color focusRingColor;
104 if (rect.isEmpty()) {
105 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
106 IntPoint contentsPosition = m_viewImpl->transformFromScene().mapPoint(m_position);
107 #if ENABLE(TOUCH_ADJUSTMENT)
108 Evas_Coord size = elm_config_finger_size_get();
109 IntSize fingerSize = IntSize(size, size);
110 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
111 double scaleFactor = pageClientImpl->scaleFactor();
112 if (scaleFactor - 1 > numeric_limits<float>::epsilon())
113 fingerSize.scale(1 / scaleFactor, 1 / scaleFactor);
115 WebHitTestResult::Data hitTestResultData = m_viewImpl->page()->hitTestResultAtPoint(contentsPosition, WebHitTestResult::HitTestModeDefault, fingerSize);
117 WebHitTestResult::Data hitTestResultData = m_viewImpl->page()->hitTestResultAtPoint(contentsPosition);
119 if (hitTestResultData.focusedRect.isEmpty())
122 if (!hitTestResultData.absoluteImageURL.isEmpty() && hitTestResultData.absoluteLinkURL.isEmpty()) {
123 if (!includeOnlyImage)
127 focusRingRect = hitTestResultData.focusedRect;
128 focusRingColor = hitTestResultData.focusedColor;
129 #endif // #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
132 focusRingRect = m_viewImpl->transformToScene().mapRect(focusRingRect);
134 Evas_Coord_Rectangle viewGeometry;
135 evas_object_geometry_get(m_viewImpl->view(), &viewGeometry.x, &viewGeometry.y, &viewGeometry.w, &viewGeometry.h);
136 IntRect viewRect(viewGeometry.x, viewGeometry.y, viewGeometry.w, viewGeometry.h);
137 focusRingRect.intersect(viewRect);
138 if (focusRingRect.isEmpty()) {
143 m_rect = focusRingRect;
144 m_rect.move(-viewGeometry.x, -viewGeometry.y);
146 if (m_focusRingObject)
147 evas_object_hide(m_focusRingObject);
149 if (m_imagePath.isNull())
150 m_focusRingObject = evas_object_rectangle_add(evas_object_evas_get(m_viewImpl->view()));
152 m_focusRingObject = evas_object_image_add(evas_object_evas_get(m_viewImpl->view()));
153 evas_object_image_file_set(m_focusRingObject, m_imagePath.utf8().data(), 0);
154 int border = m_imageOuterWidth + m_imageInnerWidth;
155 evas_object_image_border_set(m_focusRingObject, border, border, border, border);
158 evas_object_smart_member_add(m_focusRingObject, m_viewImpl->view());
159 evas_object_repeat_events_set(m_focusRingObject, true);
162 if (m_imagePath.isNull()) {
163 evas_object_color_set(m_focusRingObject, focusRingColor.red(), focusRingColor.green(), focusRingColor.blue(), focusRingColor.alpha());
164 evas_object_move(m_focusRingObject, focusRingRect.x(), focusRingRect.y());
165 evas_object_resize(m_focusRingObject, focusRingRect.width(), focusRingRect.height());
167 viewRect.inflate(-m_imageOuterWidth);
169 if (focusRingRect.intersects(viewRect))
170 focusRingRect.intersect(viewRect);
172 if (viewRect.x() > focusRingRect.x()) {
173 focusRingRect.setX(viewRect.x());
174 focusRingRect.setWidth(1);
175 } else if (viewRect.maxX() < focusRingRect.maxX()) {
176 focusRingRect.setX(viewRect.maxX());
177 focusRingRect.setWidth(1);
179 if (viewRect.y() > focusRingRect.y()) {
180 focusRingRect.setY(viewRect.y());
181 focusRingRect.setHeight(1);
182 } else if (viewRect.maxY() < focusRingRect.maxY()) {
183 focusRingRect.setY(viewRect.maxY());
184 focusRingRect.setHeight(1);
188 evas_object_move(m_focusRingObject, focusRingRect.x() - m_imageOuterWidth, focusRingRect.y() - m_imageOuterWidth);
190 int width = focusRingRect.width() + m_imageOuterWidth * 2;
191 int height = focusRingRect.height() + m_imageOuterWidth * 2;
192 evas_object_image_fill_set(m_focusRingObject, 0, 0, width, height);
193 evas_object_resize(m_focusRingObject, width, height);
196 evas_object_show(m_focusRingObject);
199 void FocusRing::requestToHide(bool immediately)
207 ecore_timer_del(m_hideTimer);
208 m_hideTimer = ecore_timer_add((double)s_hideTimerTime/1000.0, hideTimerCallback, this);
211 Eina_Bool FocusRing::hideTimerCallback(void* data)
213 static_cast<FocusRing*>(data)->hide();
214 return ECORE_CALLBACK_CANCEL;
217 void FocusRing::hide(bool onlyColorDrawing)
219 if (!m_imagePath.isNull() && onlyColorDrawing)
223 ecore_timer_del(m_showTimer);
228 ecore_timer_del(m_hideTimer);
232 if (m_focusRingObject && evas_object_visible_get(m_focusRingObject))
233 evas_object_hide(m_focusRingObject);
238 void FocusRing::updateScrollAndScale(const WebCore::IntPoint& previousScrollPosition, float previousScale)
240 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
241 if (m_rect.isEmpty())
244 FloatRect rect(m_rect);
245 rect.moveBy(previousScrollPosition);
246 rect.scale(1 / previousScale);
248 show(enclosingIntRect(rect));
250 UNUSED_PARAM(previousScrollPosition);
251 UNUSED_PARAM(previousScale);
255 IntPoint FocusRing::centerPointInScreen()
257 if (m_rect.isEmpty())
258 return IntPoint(-1, -1);
260 IntPoint point(m_rect.center());
262 evas_object_geometry_get(m_viewImpl->view(), &x, &y, 0, 0);
268 #endif // #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)