summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Nazarov <i.nazarov@samsung.com>2017-04-05 17:41:32 +0300
committerIgor Nazarov <i.nazarov@samsung.com>2017-04-05 17:41:32 +0300
commit581e583758436c3c33498d16417b4bc371a37a11 (patch)
treed33fa3054a3a6eef391a3d669d068f63dd0415ad
parenta9909779e98e616ce403627cd6831fb2c12fadd4 (diff)
downloadgallery-581e583758436c3c33498d16417b4bc371a37a11.tar.gz
gallery-581e583758436c3c33498d16417b4bc371a37a11.tar.bz2
gallery-581e583758436c3c33498d16417b4bc371a37a11.zip
TizenRefApp-8321 [Gallery] Implement TouchParser
- Added TouchParser class with initial parsing of tap and double tap gestures. Change-Id: Ia7ae94a3db52ff4367dc033eb007814c2d99d143
-rw-r--r--inc/presentation/TouchParser.h61
-rw-r--r--inc/presentation/types.h2
-rw-r--r--src/presentation/TouchParser.cpp147
3 files changed, 210 insertions, 0 deletions
diff --git a/inc/presentation/TouchParser.h b/inc/presentation/TouchParser.h
new file mode 100644
index 0000000..2c65fb3
--- /dev/null
+++ b/inc/presentation/TouchParser.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GALLERY_PRESENTATION_TOUCH_PARSER_H__
+#define __GALLERY_PRESENTATION_TOUCH_PARSER_H__
+
+#include "ucl/gui/Widget.h"
+
+#include "types.h"
+
+namespace gallery {
+
+ class TouchParser final : public ucl::RefCountAware {
+ public:
+ using TapHandler = ucl::Delegate<void(int x, int y)>;
+
+ private:
+ friend class ucl::RefCountObj<TouchParser>;
+ TouchParser(ucl::RefCountObjBase &rc, ucl::Widget &eventSource);
+ virtual ~TouchParser();
+
+ public:
+ void setTapHandler(TapHandler handler);
+ void setDoubleTapHandler(TapHandler handler);
+
+ private:
+ void onMouseDown(ucl::Widget &widget, void *eventInfo);
+ void onMouseUp(ucl::Widget &widget, void *eventInfo);
+ void onMouseMove(ucl::Widget &widget, void *eventInfo);
+
+ void updateIsTapPossible(int flags, int curX, int curY);
+
+ bool isFastTap(ucl::UInt curTime, int curX, int curY) const;
+ double calcDownDistance(int curX, int curY) const;
+
+ private:
+ TapHandler m_tapHandler;
+ TapHandler m_doubleTapHandler;
+ ucl::UInt m_downTime;
+ int m_downX;
+ int m_downY;
+ int m_tapCounter;
+ bool m_isMouseDown;
+ bool m_isTapPossible;
+ };
+}
+
+#endif // __GALLERY_PRESENTATION_TOUCH_PARSER_H__
diff --git a/inc/presentation/types.h b/inc/presentation/types.h
index d34fbb4..4e277c8 100644
--- a/inc/presentation/types.h
+++ b/inc/presentation/types.h
@@ -25,6 +25,8 @@ namespace gallery {
class IImageGridListener;
+ UCL_DECLARE_REF_ALIASES(TouchParser);
+
UCL_DECLARE_REF_ALIASES(ImageGrid);
UCL_DECLARE_REF_ALIASES(ImageViewer);
diff --git a/src/presentation/TouchParser.cpp b/src/presentation/TouchParser.cpp
new file mode 100644
index 0000000..a556fd5
--- /dev/null
+++ b/src/presentation/TouchParser.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "presentation/TouchParser.h"
+
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+ constexpr auto TAP_MOVE_THRESHOLD = 30;
+ constexpr auto FAST_TAP_DISTANCE = 60;
+ constexpr auto FAST_TAP_DELAY_MS = 300;
+}}}
+
+namespace gallery {
+
+ using namespace ucl;
+
+ TouchParser::TouchParser(RefCountObjBase &rc, Widget &eventSource) :
+ RefCountAware(&rc),
+ m_downTime(0),
+ m_downX(0),
+ m_downY(0),
+ m_tapCounter(0),
+ m_isMouseDown(false),
+ m_isTapPossible(false)
+ {
+ eventSource.addEventHandler(WidgetEvent::MOUSE_DOWN,
+ WEAK_DELEGATE(TouchParser::onMouseDown, asWeak(*this)));
+
+ eventSource.addEventHandler(WidgetEvent::MOUSE_UP,
+ WEAK_DELEGATE(TouchParser::onMouseUp, asWeak(*this)));
+
+ eventSource.addEventHandler(WidgetEvent::MOUSE_MOVE,
+ WEAK_DELEGATE(TouchParser::onMouseMove, asWeak(*this)));
+ }
+
+ TouchParser::~TouchParser()
+ {
+ }
+
+ void TouchParser::setTapHandler(TapHandler handler)
+ {
+ m_tapHandler = handler;
+ }
+
+ void TouchParser::setDoubleTapHandler(TapHandler handler)
+ {
+ m_doubleTapHandler = handler;
+ }
+
+ void TouchParser::onMouseDown(Widget &widget, void *eventInfo)
+ {
+ if (m_isMouseDown) {
+ return;
+ }
+ m_isMouseDown = true;
+
+ const auto e = static_cast<Evas_Event_Mouse_Down *>(eventInfo);
+
+ if (!isFastTap(e->timestamp, e->canvas.x, e->canvas.y)) {
+ m_tapCounter = 0;
+ } else if (m_doubleTapHandler && (m_tapCounter == 1)) {
+ m_doubleTapHandler(m_downX, m_downY);
+ }
+
+ m_downTime = e->timestamp;
+ m_downX = e->canvas.x;
+ m_downY = e->canvas.y;
+ m_isTapPossible = true;
+ }
+
+ void TouchParser::onMouseUp(Widget &widget, void *eventInfo)
+ {
+ if (!m_isMouseDown) {
+ return;
+ }
+ m_isMouseDown = false;
+
+ const auto e = static_cast<Evas_Event_Mouse_Up *>(eventInfo);
+
+ updateIsTapPossible(e->event_flags, e->canvas.x, e->canvas.y);
+
+ if (!m_isTapPossible) {
+ m_tapCounter = 0;
+ return;
+ }
+
+ ++m_tapCounter;
+
+ if (m_tapHandler) {
+ m_tapHandler(e->canvas.x, e->canvas.y);
+ }
+ }
+
+ void TouchParser::onMouseMove(Widget &widget, void *eventInfo)
+ {
+ if (!m_isMouseDown || !m_isTapPossible) {
+ return;
+ }
+
+ const auto e = static_cast<Evas_Event_Mouse_Move *>(eventInfo);
+
+ updateIsTapPossible(e->event_flags, e->cur.canvas.x, e->cur.canvas.y);
+ }
+
+ void TouchParser::updateIsTapPossible(const int flags,
+ const int curX, const int curY)
+ {
+ if (!m_isTapPossible) {
+ return;
+ }
+ if ((flags & EVAS_EVENT_FLAG_ON_HOLD) || (calcDownDistance(curX, curY) >
+ ELM_SCALE_SIZE(impl::TAP_MOVE_THRESHOLD))) {
+ m_isTapPossible = false;
+ }
+ }
+
+ bool TouchParser::isFastTap(const UInt curTime,
+ const int curX, const int curY) const
+ {
+ return (((curTime - m_downTime) <= impl::FAST_TAP_DELAY_MS) &&
+ (calcDownDistance(curX, curY) <=
+ ELM_SCALE_SIZE(impl::FAST_TAP_DISTANCE)));
+ }
+
+ double TouchParser::calcDownDistance(int curX, int curY) const
+ {
+ const auto dx = (curX - m_downX);
+ const auto dy = (curY - m_downY);
+
+ return sqrt(1.0 * dx * dx + 1.0 * dy * dy);
+ }
+}