1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the demonstration applications of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #ifdef QT_OPENGL_SUPPORT
46 #include "arthurwidgets.h"
47 #include "hoverpoints.h"
51 HoverPoints::HoverPoints(QWidget
*widget
, PointShape shape
)
55 widget
->installEventFilter(this);
57 m_connectionType
= CurveConnection
;
60 m_pointPen
= QPen(QColor(255, 255, 255, 191), 1);
61 m_connectionPen
= QPen(QColor(255, 255, 255, 127), 2);
62 m_pointBrush
= QBrush(QColor(191, 191, 191, 127));
63 m_pointSize
= QSize(11, 11);
68 connect(this, SIGNAL(pointsChanged(const QPolygonF
&)),
69 m_widget
, SLOT(update()));
73 void HoverPoints::setEnabled(bool enabled
)
75 if (m_enabled
!= enabled
) {
82 bool HoverPoints::eventFilter(QObject
*object
, QEvent
*event
)
84 if (object
== m_widget
&& m_enabled
) {
85 switch (event
->type()) {
87 case QEvent::MouseButtonPress
:
89 QMouseEvent
*me
= (QMouseEvent
*) event
;
91 QPointF clickPos
= me
->pos();
93 for (int i
=0; i
<m_points
.size(); ++i
) {
95 if (m_shape
== CircleShape
)
96 path
.addEllipse(pointBoundingRect(i
));
98 path
.addRect(pointBoundingRect(i
));
100 if (path
.contains(clickPos
)) {
106 if (me
->button() == Qt::LeftButton
) {
111 // Insert sort for x or y
112 if (m_sortType
== XSort
) {
113 for (int i
=0; i
<m_points
.size(); ++i
)
114 if (m_points
.at(i
).x() > clickPos
.x()) {
118 } else if (m_sortType
== YSort
) {
119 for (int i
=0; i
<m_points
.size(); ++i
)
120 if (m_points
.at(i
).y() > clickPos
.y()) {
126 m_points
.insert(pos
, clickPos
);
127 m_locks
.insert(pos
, 0);
128 m_currentIndex
= pos
;
131 m_currentIndex
= index
;
135 } else if (me
->button() == Qt::RightButton
) {
136 if (index
>= 0 && m_editable
) {
137 if (m_locks
[index
] == 0) {
138 m_locks
.remove(index
);
139 m_points
.remove(index
);
149 case QEvent::MouseButtonRelease
:
153 case QEvent::MouseMove
:
154 if (m_currentIndex
>= 0)
155 movePoint(m_currentIndex
, ((QMouseEvent
*)event
)->pos());
160 QResizeEvent
*e
= (QResizeEvent
*) event
;
161 if (e
->oldSize().width() == 0 || e
->oldSize().height() == 0)
163 qreal stretch_x
= e
->size().width() / qreal(e
->oldSize().width());
164 qreal stretch_y
= e
->size().height() / qreal(e
->oldSize().height());
165 for (int i
=0; i
<m_points
.size(); ++i
) {
166 QPointF p
= m_points
[i
];
167 movePoint(i
, QPointF(p
.x() * stretch_x
, p
.y() * stretch_y
), false);
176 QWidget
*that_widget
= m_widget
;
178 QApplication::sendEvent(object
, event
);
179 m_widget
= that_widget
;
181 #ifdef QT_OPENGL_SUPPORT
182 ArthurFrame
*af
= qobject_cast
<ArthurFrame
*>(that_widget
);
183 if (af
&& af
->usesOpenGL())
184 af
->glWidget()->swapBuffers();
197 void HoverPoints::paintPoints()
200 #ifdef QT_OPENGL_SUPPORT
201 ArthurFrame
*af
= qobject_cast
<ArthurFrame
*>(m_widget
);
202 if (af
&& af
->usesOpenGL())
203 p
.begin(af
->glWidget());
210 p
.setRenderHint(QPainter::Antialiasing
);
212 if (m_connectionPen
.style() != Qt::NoPen
&& m_connectionType
!= NoConnection
) {
213 p
.setPen(m_connectionPen
);
215 if (m_connectionType
== CurveConnection
) {
217 path
.moveTo(m_points
.at(0));
218 for (int i
=1; i
<m_points
.size(); ++i
) {
219 QPointF p1
= m_points
.at(i
-1);
220 QPointF p2
= m_points
.at(i
);
221 qreal distance
= p2
.x() - p1
.x();
223 path
.cubicTo(p1
.x() + distance
/ 2, p1
.y(),
224 p1
.x() + distance
/ 2, p2
.y(),
229 p
.drawPolyline(m_points
);
233 p
.setPen(m_pointPen
);
234 p
.setBrush(m_pointBrush
);
236 for (int i
=0; i
<m_points
.size(); ++i
) {
237 QRectF bounds
= pointBoundingRect(i
);
238 if (m_shape
== CircleShape
)
239 p
.drawEllipse(bounds
);
245 static QPointF
bound_point(const QPointF
&point
, const QRectF
&bounds
, int lock
)
249 qreal left
= bounds
.left();
250 qreal right
= bounds
.right();
251 qreal top
= bounds
.top();
252 qreal bottom
= bounds
.bottom();
254 if (p
.x() < left
|| (lock
& HoverPoints::LockToLeft
)) p
.setX(left
);
255 else if (p
.x() > right
|| (lock
& HoverPoints::LockToRight
)) p
.setX(right
);
257 if (p
.y() < top
|| (lock
& HoverPoints::LockToTop
)) p
.setY(top
);
258 else if (p
.y() > bottom
|| (lock
& HoverPoints::LockToBottom
)) p
.setY(bottom
);
263 void HoverPoints::setPoints(const QPolygonF
&points
)
266 for (int i
=0; i
<points
.size(); ++i
)
267 m_points
<< bound_point(points
.at(i
), boundingRect(), 0);
270 if (m_points
.size() > 0) {
271 m_locks
.resize(m_points
.size());
278 void HoverPoints::movePoint(int index
, const QPointF
&point
, bool emitUpdate
)
280 m_points
[index
] = bound_point(point
, boundingRect(), m_locks
.at(index
));
286 inline static bool x_less_than(const QPointF
&p1
, const QPointF
&p2
)
288 return p1
.x() < p2
.x();
292 inline static bool y_less_than(const QPointF
&p1
, const QPointF
&p2
)
294 return p1
.y() < p2
.y();
297 void HoverPoints::firePointChange()
299 // printf("HoverPoints::firePointChange(), current=%d\n", m_currentIndex);
301 if (m_sortType
!= NoSort
) {
304 if (m_currentIndex
!= -1) {
305 oldCurrent
= m_points
[m_currentIndex
];
308 if (m_sortType
== XSort
)
309 qSort(m_points
.begin(), m_points
.end(), x_less_than
);
310 else if (m_sortType
== YSort
)
311 qSort(m_points
.begin(), m_points
.end(), y_less_than
);
313 // Compensate for changed order...
314 if (m_currentIndex
!= -1) {
315 for (int i
=0; i
<m_points
.size(); ++i
) {
316 if (m_points
[i
] == oldCurrent
) {
323 // printf(" - firePointChange(), current=%d\n", m_currentIndex);
327 // for (int i=0; i<m_points.size(); ++i) {
328 // printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n",
329 // i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i));
332 emit
pointsChanged(m_points
);