@@ -0,0 +1,150 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "FloatingFlickable.h"
18+
19+#include <private/qquickflickable_p.h>
20+#include "DirectionalDragArea.h"
21+
22+#include <QDebug>
23+
24+FloatingFlickable::FloatingFlickable(QQuickItem *parent)
25+ : QQuickItem(parent)
26+ , m_mousePressed(false)
27+{
28+ m_dragArea = new DirectionalDragArea(this);
29+ m_dragArea->setWidth(width());
30+ m_dragArea->setHeight(height());
31+ m_dragArea->setDirection(Direction::Horizontal);
32+ connect(m_dragArea, &DirectionalDragArea::touchXChanged,
33+ this, &FloatingFlickable::onDragAreaTouchPosChanged);
34+ connect(m_dragArea, &DirectionalDragArea::touchYChanged,
35+ this, &FloatingFlickable::onDragAreaTouchPosChanged);
36+ connect(m_dragArea, &DirectionalDragArea::draggingChanged,
37+ this, &FloatingFlickable::onDragAreaDraggingChanged);
38+ connect(m_dragArea, &DirectionalDragArea::directionChanged, this, &FloatingFlickable::directionChanged);
39+
40+ m_flickable = new QQuickFlickable(this);
41+ m_flickable->setEnabled(false);
42+ m_flickable->setWidth(width());
43+ m_flickable->setHeight(height());
44+ connect(m_flickable, &QQuickFlickable::contentWidthChanged, this, &FloatingFlickable::contentWidthChanged);
45+ connect(m_flickable, &QQuickFlickable::contentHeightChanged, this, &FloatingFlickable::contentHeightChanged);
46+ connect(m_flickable, &QQuickFlickable::contentXChanged, this, &FloatingFlickable::contentXChanged);
47+ connect(m_flickable, &QQuickFlickable::contentYChanged, this, &FloatingFlickable::contentYChanged);
48+
49+ connect(this, &QQuickItem::widthChanged, this, &FloatingFlickable::updateChildrenWidth);
50+ connect(this, &QQuickItem::heightChanged, this, &FloatingFlickable::updateChildrenHeight);
51+}
52+
53+qreal FloatingFlickable::contentWidth() const
54+{
55+ return m_flickable->contentWidth();
56+}
57+
58+void FloatingFlickable::setContentWidth(qreal contentWidth)
59+{
60+ m_flickable->setContentWidth(contentWidth);
61+}
62+
63+qreal FloatingFlickable::contentHeight() const
64+{
65+ return m_flickable->contentHeight();
66+}
67+
68+void FloatingFlickable::setContentHeight(qreal contentHeight)
69+{
70+ m_flickable->setContentHeight(contentHeight);
71+}
72+
73+qreal FloatingFlickable::contentX() const
74+{
75+ return m_flickable->contentX();
76+}
77+
78+void FloatingFlickable::setContentX(qreal contentX)
79+{
80+ m_flickable->setContentX(contentX);
81+}
82+
83+qreal FloatingFlickable::contentY() const
84+{
85+ return m_flickable->contentY();
86+}
87+
88+void FloatingFlickable::setContentY(qreal contentY)
89+{
90+ m_flickable->setContentY(contentY);
91+}
92+
93+Direction::Type FloatingFlickable::direction() const
94+{
95+ return m_dragArea->direction();
96+}
97+
98+void FloatingFlickable::setDirection(Direction::Type direction)
99+{
100+ m_dragArea->setDirection(direction);
101+ if (Direction::isHorizontal(direction)) {
102+ m_flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
103+ } else {
104+ m_flickable->setFlickableDirection(QQuickFlickable::VerticalFlick);
105+ }
106+}
107+
108+void FloatingFlickable::updateChildrenWidth()
109+{
110+ m_dragArea->setWidth(width());
111+ m_flickable->setWidth(width());
112+}
113+
114+void FloatingFlickable::updateChildrenHeight()
115+{
116+ m_dragArea->setHeight(height());
117+ m_flickable->setHeight(height());
118+}
119+
120+void FloatingFlickable::onDragAreaTouchPosChanged(qreal)
121+{
122+ if (m_mousePressed) {
123+ QMouseEvent mouseEvent(QEvent::MouseMove,
124+ QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
125+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
126+
127+ QCoreApplication::sendEvent(m_flickable, &mouseEvent);
128+
129+ }
130+}
131+
132+void FloatingFlickable::onDragAreaDraggingChanged(bool dragging)
133+{
134+ if (dragging && !m_mousePressed) {
135+ QMouseEvent mouseEvent(QEvent::MouseButtonPress,
136+ QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
137+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
138+
139+ QCoreApplication::sendEvent(m_flickable, &mouseEvent);
140+ m_mousePressed = true;
141+
142+ } else if (!dragging && m_mousePressed) {
143+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease,
144+ QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
145+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
146+
147+ QCoreApplication::sendEvent(m_flickable, &mouseEvent);
148+ m_mousePressed = false;
149+ }
150+}