42 #ifdef QT_OPENGL_SUPPORT
57 widget->installEventFilter(
this);
58 widget->setAttribute(Qt::WA_AcceptTouchEvents);
63 m_pointPen = QPen(QColor(255, 255, 255, 191), 1);
64 m_connectionPen = QPen(QColor(255, 255, 255, 127), 2);
65 m_pointBrush = QBrush(QColor(191, 191, 191, 127));
66 m_pointSize = QSize(11, 11);
70 m_dialog =
new QColorDialog();
73 m_widget, SLOT(update()));
79 if (m_enabled != enabled) {
88 if (
object == m_widget && m_enabled) {
89 switch (event->type()) {
90 case QEvent::MouseButtonPress:
92 if (!m_fingerPointMapping.isEmpty())
94 QMouseEvent *me = (QMouseEvent *) event;
95 QPointF clickPos = me->pos();
97 for (
int i=0; i<m_points.size(); ++i) {
100 path.addEllipse(pointBoundingRect(i));
102 path.addRect(pointBoundingRect(i));
104 if (path.contains(clickPos)) {
110 if (me->button() == Qt::LeftButton) {
116 if (m_sortType ==
XSort) {
117 for (
int i=0; i<m_points.size(); ++i)
118 if (m_points.at(i).x() > clickPos.x()) {
122 }
else if (m_sortType ==
YSort) {
123 for (
int i=0; i<m_points.size(); ++i)
124 if (m_points.at(i).y() > clickPos.y()) {
130 QColor color = QColor(
"black");
131 m_points.insert(pos, clickPos);
132 m_locks.insert(pos, 0);
133 m_currentIndex = pos;
138 m_currentIndex = index;
142 }
else if (me->button() == Qt::RightButton) {
143 if (index >= 0 && m_editable) {
144 if (m_locks[index] == 0) {
145 m_locks.remove(index);
146 m_points.remove(index);
153 }
else if (me->button() == Qt::MiddleButton) {
154 if (index >= 0 && m_editable) {
155 QColor color = QColorDialog::getColor();
156 if(color.isValid()) {
167 case QEvent::MouseButtonRelease:
168 if (!m_fingerPointMapping.isEmpty())
173 case QEvent::MouseMove:
174 if (!m_fingerPointMapping.isEmpty())
176 if (m_currentIndex >= 0) {
177 movePoint(m_currentIndex, ((QMouseEvent *)event)->pos());
183 case QEvent::TouchBegin:
184 case QEvent::TouchUpdate:
186 const QTouchEvent *
const touchEvent =
static_cast<const QTouchEvent*
>(event);
187 const QList<QTouchEvent::TouchPoint>
points = touchEvent->touchPoints();
188 const qreal
pointSize = qMax(m_pointSize.width(), m_pointSize.height());
189 foreach (
const QTouchEvent::TouchPoint &touchPoint, points) {
190 const int id = touchPoint.id();
191 switch (touchPoint.state()) {
192 case Qt::TouchPointPressed:
195 QSet<int> activePoints = QSet<int>::fromList(m_fingerPointMapping.values());
196 int activePoint = -1;
198 const int pointsCount = m_points.size();
199 const int activePointCount = activePoints.size();
200 if (pointsCount == 2 && activePointCount == 1) {
201 activePoint = activePoints.contains(0) ? 1 : 0;
203 for (
int i=0; i<pointsCount; ++i) {
204 if (activePoints.contains(i))
207 qreal d = QLineF(touchPoint.pos(), m_points.at(i)).length();
208 if ((distance < 0 && d < 12 * pointSize) || d < distance) {
215 if (activePoint != -1) {
216 m_fingerPointMapping.insert(touchPoint.id(), activePoint);
217 movePoint(activePoint, touchPoint.pos());
221 case Qt::TouchPointReleased:
224 QHash<int,int>::iterator it = m_fingerPointMapping.find(
id);
225 movePoint(it.value(), touchPoint.pos());
226 m_fingerPointMapping.erase(it);
229 case Qt::TouchPointMoved:
232 const int pointIdx = m_fingerPointMapping.value(
id, -1);
234 movePoint(pointIdx, touchPoint.pos());
241 if (m_fingerPointMapping.isEmpty()) {
249 case QEvent::TouchEnd:
250 if (m_fingerPointMapping.isEmpty()) {
259 QResizeEvent *e = (QResizeEvent *) event;
260 if (e->oldSize().width() == 0 || e->oldSize().height() == 0)
262 qreal stretch_x = e->size().width() / qreal(e->oldSize().width());
263 qreal stretch_y = e->size().height() / qreal(e->oldSize().height());
264 for (
int i=0; i<m_points.size(); ++i) {
265 QPointF p = m_points[i];
266 movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y),
false);
275 QWidget *that_widget = m_widget;
277 QApplication::sendEvent(
object, event);
278 m_widget = that_widget;
280 #ifdef QT_OPENGL_SUPPORT
282 if (af && af->usesOpenGL())
283 af->glWidget()->swapBuffers();
299 #ifdef QT_OPENGL_SUPPORT
301 if (af && af->usesOpenGL())
302 p.begin(af->glWidget());
309 p.setRenderHint(QPainter::Antialiasing);
311 if (m_connectionPen.style() != Qt::NoPen && m_connectionType !=
NoConnection) {
312 p.setPen(m_connectionPen);
316 path.moveTo(m_points.at(0));
317 for (
int i=1; i<m_points.size(); ++i) {
318 QPointF p1 = m_points.at(i-1);
319 QPointF p2 = m_points.at(i);
320 qreal distance = p2.x() - p1.x();
322 path.cubicTo(p1.x() + distance / 2, p1.y(),
323 p1.x() + distance / 2, p2.y(),
328 p.drawPolyline(m_points);
332 p.setPen(m_pointPen);
333 p.setBrush(m_pointBrush);
335 for (
int i=0; i<m_points.size(); ++i) {
336 QRectF bounds = pointBoundingRect(i);
338 p.drawEllipse(bounds);
344 static QPointF bound_point(
const QPointF &point,
const QRectF &bounds,
int lock)
348 qreal left = bounds.left();
349 qreal right = bounds.right();
350 qreal top = bounds.top();
351 qreal bottom = bounds.bottom();
365 if (points.size() != m_points.size())
366 m_fingerPointMapping.clear();
368 for (
int i=0; i<points.size(); ++i)
369 m_points << bound_point(points.at(i),
boundingRect(), 0);
372 if (m_points.size() > 0) {
373 m_locks.resize(m_points.size());
380 void HoverPoints::movePoint(
int index,
const QPointF &point,
bool emitUpdate)
382 m_points[index] = bound_point(point,
boundingRect(), m_locks.at(index));
388 inline static bool x_less_than(
const QPointF &p1,
const QPointF &p2)
390 return p1.x() < p2.x();
394 inline static bool y_less_than(
const QPointF &p1,
const QPointF &p2)
396 return p1.y() < p2.y();
403 if (m_sortType !=
NoSort) {
406 if (m_currentIndex != -1) {
407 oldCurrent = m_points[m_currentIndex];
410 if (m_sortType ==
XSort)
411 qSort(m_points.begin(), m_points.end(), x_less_than);
412 else if (m_sortType ==
YSort)
413 qSort(m_points.begin(), m_points.end(), y_less_than);
416 if (m_currentIndex != -1) {
417 for (
int i=0; i<m_points.size(); ++i) {
418 if (m_points[i] == oldCurrent) {