summaryrefslogtreecommitdiffstats
path: root/src/threed/scene/qglpicknode.cpp
blob: 08358f38048e04e59c79d7790ef075d7bd10ac32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qglpicknode.h"
#include "qglabstractscene.h"

#include <QtGui/qevent.h>

/*!
    \class QGLPickNode
    \brief The QGLPickNode class enables picking for objects in a 3D scene.
    \since 4.8
    \ingroup qt3d
    \ingroup qt3d::scene

    QGLPickNode is a QObject sub-class, relatively light-weight, that can
    shadow QSceneObject instances and provide picking capability.  The
    QGLPickNode instance receives events sent to it by picking views, such
    as the QGLView class, and emits relevant signals in response.

    QGLSceneObjects wanting to support picking, should implement the methods
    \list
    \o QGLSceneNode::pickNode()
    \o QGLSceneNode::setPickNode()
    \endlist
    and also implement rendering such that the QGLPainter has the relevant
    \l{QGLPainter::setObjectPickId()}{pick id function} called.

    These functions are already implemented for the QGLSceneNode object type.

    Picking can then be simply enabled by calling the QGLAbstractScene function
    setPickable() to turn on picking and generate pick nodes for the relevant
    scene objects.

    In order to respond to picking, the view class should simply register the
    picknodes, and connect a relevant slot to the pick nodes signal.

    For the QGLView class that code is simply:
    \code
    QList<QGLPickNode *>nodes = manager->pickNodes();
    foreach (QGLPickNode *node, nodes)
    {
        registerObject(node->id(), node);
        connect(node, SIGNAL(clicked()),
                this, SLOT(objectPicked()));
    }
    \endcode

    The pick nodes should be unregistered with similar code for the QGLView if
    switching to a different scene.

    To be able to recover the relevant QGLSceneNode inside the called slot,
    the object may be set onto the QGLPickNode with the setTarget() function,
    and recovered with target() inside the slot, since the QGLPickNode will
    be the sender() for the slot.

    QGLSceneNode already sets itself as the target during the pick enable step.

    \sa QGLSceneNode, QGLView
*/

/*!
    Construct a new QGLPickNode object managed by and parented onto
    the \a parent scene.  The nextPickId() function will be called on
    \a parent to assign a pick id to this new node.
*/
QGLPickNode::QGLPickNode(QGLAbstractScene *parent) :
    QObject(parent), m_id(-1), m_target(0)
{
    if (parent)
        m_id = parent->nextPickId();
}

/*!
    \fn int QGLPickNode::id() const
    Returns the unique id for this node.  This value is assigned by
    the parent scene for this node and should be different for every
    node in the scene.  Returns -1 if the id has not been set yet.

    \sa setId()
*/

/*!
    \fn void QGLPickNode::setId(int id)
    Sets the unique \a id for this node.  Generally this function should not
    be needed, since the constructor causes a unique id to be obtained
    from the parent scene.  This function exists mainly for testing
    purposes.

    \sa id()
*/

/*!
    \fn QGLSceneNode *QGLPickNode::target() const
    Returns the QGLSceneNode which is the target of this pick node;
    null if the target has not been set yet.

    \sa setTarget()
*/

/*!
    \fn void QGLPickNode::setTarget(QGLSceneNode *target)
    Sets the \a target for this pick node.

    \sa target()
*/

/*!
    \fn void QGLPickNode::pressed()
    Signal emitted when the scene object for this node has the mouse pressed
    while the cursor is on the object in the scene.
*/

/*!
    \fn void QGLPickNode::released()
    Signal emitted when the scene object for this node has the mouse released
    while the cursor is on the object in the scene.
*/

/*!
    \fn void QGLPickNode::clicked()
    Signal emitted when the scene object for this node has the mouse pressed
    and then released while the cursor is on the object in the scene.
*/

/*!
    \fn void QGLPickNode::doubleClicked()
    Signal emitted when the scene object for this node has the mouse clicked
    twice in succession while the cursor is on the object in the scene.
*/

/*!
    \fn void QGLPickNode::hoverChanged()
    Signal emitted when the scene object for this node has the mouse moved
    into or out of this object in the scene.
*/

/*!
    \internal
*/
bool QGLPickNode::event(QEvent *e)
{
    // ripped off from teaservice demo, but not before the same code
    // was ripped off and put in item3d.cpp - those should probably all
    // use this implementation here
    if (e->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *me = (QMouseEvent *)e;
        if (me->button() == Qt::LeftButton)
            emit pressed();
    }
    else if (e->type() == QEvent::MouseButtonRelease)
    {
        QMouseEvent *me = (QMouseEvent *)e;
        if (me->button() == Qt::LeftButton)
        {
            emit released();
            if (me->x() >= 0)   // Positive: inside object, Negative: outside.
                emit clicked();
        }
    }
    else if (e->type() == QEvent::MouseButtonDblClick)
    {
        emit doubleClicked();
    }
    else if (e->type() == QEvent::Enter)
    {
        //m_hovering = true;
        emit hoverChanged();
    }
    else if (e->type() == QEvent::Leave)
    {
        //m_hovering = false;
        emit hoverChanged();
    }
    return QObject::event(e);
}