blob: b00ed58d9339822a7201ecb616febd41cdfd3f51 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative 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$
**
****************************************************************************/
#ifndef QDECLARATIVEITEM_P_H
#define QDECLARATIVEITEM_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qdeclarativeitem.h"
#include "private/qdeclarativeanchors_p.h"
#include "private/qdeclarativeanchors_p_p.h"
#include "private/qdeclarativeitemchangelistener_p.h"
#include <private/qpodvector_p.h>
#include <private/qdeclarativestate_p.h>
#include <private/qdeclarativenullablevalue_p_p.h>
#include <private/qdeclarativenotifier_p.h>
#include <private/qdeclarativeglobal_p.h>
#include <qdeclarative.h>
#include <qdeclarativecontext.h>
#include <QtCore/qlist.h>
#include <QtCore/qdebug.h>
#include <private/qgraphicsitem_p.h>
QT_BEGIN_NAMESPACE
class QNetworkReply;
class QDeclarativeItemKeyFilter;
class QDeclarativeLayoutMirroringAttached;
//### merge into private?
class QDeclarativeContents : public QObject, public QDeclarativeItemChangeListener
{
Q_OBJECT
public:
QDeclarativeContents(QDeclarativeItem *item);
~QDeclarativeContents();
QRectF rectF() const;
void childRemoved(QDeclarativeItem *item);
void childAdded(QDeclarativeItem *item);
void calcGeometry() { calcWidth(); calcHeight(); }
void complete();
Q_SIGNALS:
void rectChanged(QRectF);
protected:
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
void itemDestroyed(QDeclarativeItem *item);
//void itemVisibilityChanged(QDeclarativeItem *item)
private:
void calcHeight(QDeclarativeItem *changed = 0);
void calcWidth(QDeclarativeItem *changed = 0);
QDeclarativeItem *m_item;
qreal m_x;
qreal m_y;
qreal m_width;
qreal m_height;
};
class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeItem)
public:
QDeclarativeItemPrivate()
: _anchors(0), _contents(0),
baselineOffset(0),
_anchorLines(0),
_stateGroup(0), origin(QDeclarativeItem::Center),
widthValid(false), heightValid(false),
componentComplete(true), keepMouse(false),
smooth(false), transformOriginDirty(true), doneEventPreHandler(false),
inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
inheritMirrorFromParent(false), inheritMirrorFromItem(false), keyHandler(0),
mWidth(0), mHeight(0), mImplicitWidth(0), mImplicitHeight(0), attachedLayoutDirection(0), hadSubFocusItem(false)
{
QGraphicsItemPrivate::acceptedMouseButtons = 0;
isDeclarativeItem = 1;
QGraphicsItemPrivate::flags = QGraphicsItem::GraphicsItemFlags(
QGraphicsItem::ItemHasNoContents
| QGraphicsItem::ItemIsFocusable
| QGraphicsItem::ItemNegativeZStacksBehindParent);
}
void init(QDeclarativeItem *parent)
{
Q_Q(QDeclarativeItem);
if (parent) {
QDeclarative_setParent_noEvent(q, parent);
q->setParentItem(parent);
QDeclarativeItemPrivate *parentPrivate = QDeclarativeItemPrivate::get(parent);
setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
}
baselineOffset.invalidate();
mouseSetsFocus = false;
}
bool isMirrored() const {
return effectiveLayoutMirror;
}
// Private Properties
qreal width() const;
void setWidth(qreal);
void resetWidth();
qreal height() const;
void setHeight(qreal);
void resetHeight();
virtual qreal implicitWidth() const;
virtual qreal implicitHeight() const;
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
void resolveLayoutMirror();
void setImplicitLayoutMirror(bool mirror, bool inherit);
void setLayoutMirror(bool mirror);
QDeclarativeListProperty<QObject> data();
QDeclarativeListProperty<QObject> resources();
QDeclarativeListProperty<QDeclarativeState> states();
QDeclarativeListProperty<QDeclarativeTransition> transitions();
QString state() const;
void setState(const QString &);
QDeclarativeAnchorLine left() const;
QDeclarativeAnchorLine right() const;
QDeclarativeAnchorLine horizontalCenter() const;
QDeclarativeAnchorLine top() const;
QDeclarativeAnchorLine bottom() const;
QDeclarativeAnchorLine verticalCenter() const;
QDeclarativeAnchorLine baseline() const;
// data property
static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
static int data_count(QDeclarativeListProperty<QObject> *);
static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
static void data_clear(QDeclarativeListProperty<QObject> *);
// resources property
static QObject *resources_at(QDeclarativeListProperty<QObject> *, int);
static void resources_append(QDeclarativeListProperty<QObject> *, QObject *);
static int resources_count(QDeclarativeListProperty<QObject> *);
static void resources_clear(QDeclarativeListProperty<QObject> *);
// transform property
static int transform_count(QDeclarativeListProperty<QGraphicsTransform> *list);
static void transform_append(QDeclarativeListProperty<QGraphicsTransform> *list, QGraphicsTransform *);
static QGraphicsTransform *transform_at(QDeclarativeListProperty<QGraphicsTransform> *list, int);
static void transform_clear(QDeclarativeListProperty<QGraphicsTransform> *list);
static QDeclarativeItemPrivate* get(QDeclarativeItem *item)
{
return item->d_func();
}
// Accelerated property accessors
QDeclarativeNotifier parentNotifier;
static void parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e);
QDeclarativeAnchors *anchors() {
if (!_anchors) {
Q_Q(QDeclarativeItem);
_anchors = new QDeclarativeAnchors(q);
if (!componentComplete)
_anchors->classBegin();
}
return _anchors;
}
QDeclarativeAnchors *_anchors;
QDeclarativeContents *_contents;
QDeclarativeNullableValue<qreal> baselineOffset;
struct AnchorLines {
AnchorLines(QGraphicsObject *);
QDeclarativeAnchorLine left;
QDeclarativeAnchorLine right;
QDeclarativeAnchorLine hCenter;
QDeclarativeAnchorLine top;
QDeclarativeAnchorLine bottom;
QDeclarativeAnchorLine vCenter;
QDeclarativeAnchorLine baseline;
};
mutable AnchorLines *_anchorLines;
AnchorLines *anchorLines() const {
Q_Q(const QDeclarativeItem);
if (!_anchorLines) _anchorLines =
new AnchorLines(const_cast<QDeclarativeItem *>(q));
return _anchorLines;
}
enum ChangeType {
Geometry = 0x01,
SiblingOrder = 0x02,
Visibility = 0x04,
Opacity = 0x08,
Destroyed = 0x10
};
Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
struct ChangeListener {
ChangeListener(QDeclarativeItemChangeListener *l, QDeclarativeItemPrivate::ChangeTypes t) : listener(l), types(t) {}
QDeclarativeItemChangeListener *listener;
QDeclarativeItemPrivate::ChangeTypes types;
bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
};
void addItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types) {
changeListeners.append(ChangeListener(listener, types));
}
void removeItemChangeListener(QDeclarativeItemChangeListener *, ChangeTypes types);
QPODVector<ChangeListener,4> changeListeners;
QDeclarativeStateGroup *_states();
QDeclarativeStateGroup *_stateGroup;
QDeclarativeItem::TransformOrigin origin:5;
bool widthValid:1;
bool heightValid:1;
bool componentComplete:1;
bool keepMouse:1;
bool smooth:1;
bool transformOriginDirty : 1;
bool doneEventPreHandler : 1;
bool inheritedLayoutMirror:1;
bool effectiveLayoutMirror:1;
bool isMirrorImplicit:1;
bool inheritMirrorFromParent:1;
bool inheritMirrorFromItem:1;
QDeclarativeItemKeyFilter *keyHandler;
qreal mWidth;
qreal mHeight;
qreal mImplicitWidth;
qreal mImplicitHeight;
QDeclarativeLayoutMirroringAttached* attachedLayoutDirection;
bool hadSubFocusItem;
QPointF computeTransformOrigin() const;
virtual void setPosHelper(const QPointF &pos)
{
Q_Q(QDeclarativeItem);
QRectF oldGeometry(this->pos.x(), this->pos.y(), mWidth, mHeight);
QGraphicsItemPrivate::setPosHelper(pos);
q->geometryChanged(QRectF(this->pos.x(), this->pos.y(), mWidth, mHeight), oldGeometry);
}
// Reimplemented from QGraphicsItemPrivate
virtual void subFocusItemChange()
{
bool hasSubFocusItem = subFocusItem != 0;
if (((flags & QGraphicsItem::ItemIsFocusScope) || !parent) && hasSubFocusItem != hadSubFocusItem)
emit q_func()->activeFocusChanged(hasSubFocusItem);
//see also QDeclarativeItemPrivate::focusChanged
hadSubFocusItem = hasSubFocusItem;
}
// Reimplemented from QGraphicsItemPrivate
virtual void focusScopeItemChange(bool isSubFocusItem)
{
emit q_func()->focusChanged(isSubFocusItem);
}
// Reimplemented from QGraphicsItemPrivate
virtual void siblingOrderChange()
{
Q_Q(QDeclarativeItem);
for(int ii = 0; ii < changeListeners.count(); ++ii) {
const QDeclarativeItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QDeclarativeItemPrivate::SiblingOrder) {
change.listener->itemSiblingOrderChanged(q);
}
}
}
// Reimplemented from QGraphicsItemPrivate
virtual void transformChanged();
virtual void focusChanged(bool);
virtual void mirrorChange() {};
static qint64 consistentTime;
static void setConsistentTime(qint64 t);
static void start(QElapsedTimer &);
static qint64 elapsed(QElapsedTimer &);
static qint64 restart(QElapsedTimer &);
};
/*
Key filters can be installed on a QDeclarativeItem, but not removed. Currently they
are only used by attached objects (which are only destroyed on Item
destruction), so this isn't a problem. If in future this becomes any form
of public API, they will have to support removal too.
*/
class QDeclarativeItemKeyFilter
{
public:
QDeclarativeItemKeyFilter(QDeclarativeItem * = 0);
virtual ~QDeclarativeItemKeyFilter();
virtual void keyPressed(QKeyEvent *event, bool post);
virtual void keyReleased(QKeyEvent *event, bool post);
virtual void inputMethodEvent(QInputMethodEvent *event, bool post);
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
virtual void componentComplete();
bool m_processPost;
private:
QDeclarativeItemKeyFilter *m_next;
};
class QDeclarativeKeyNavigationAttachedPrivate : public QObjectPrivate
{
public:
QDeclarativeKeyNavigationAttachedPrivate()
: QObjectPrivate(), left(0), right(0), up(0), down(0), tab(0), backtab(0) {}
QDeclarativeItem *left;
QDeclarativeItem *right;
QDeclarativeItem *up;
QDeclarativeItem *down;
QDeclarativeItem *tab;
QDeclarativeItem *backtab;
};
class QDeclarativeKeyNavigationAttached : public QObject, public QDeclarativeItemKeyFilter
{
Q_OBJECT
Q_DECLARE_PRIVATE(QDeclarativeKeyNavigationAttached)
Q_PROPERTY(QDeclarativeItem *left READ left WRITE setLeft NOTIFY leftChanged)
Q_PROPERTY(QDeclarativeItem *right READ right WRITE setRight NOTIFY rightChanged)
Q_PROPERTY(QDeclarativeItem *up READ up WRITE setUp NOTIFY upChanged)
Q_PROPERTY(QDeclarativeItem *down READ down WRITE setDown NOTIFY downChanged)
Q_PROPERTY(QDeclarativeItem *tab READ tab WRITE setTab NOTIFY tabChanged)
Q_PROPERTY(QDeclarativeItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
Q_ENUMS(Priority)
public:
QDeclarativeKeyNavigationAttached(QObject * = 0);
QDeclarativeItem *left() const;
void setLeft(QDeclarativeItem *);
QDeclarativeItem *right() const;
void setRight(QDeclarativeItem *);
QDeclarativeItem *up() const;
void setUp(QDeclarativeItem *);
QDeclarativeItem *down() const;
void setDown(QDeclarativeItem *);
QDeclarativeItem *tab() const;
void setTab(QDeclarativeItem *);
QDeclarativeItem *backtab() const;
void setBacktab(QDeclarativeItem *);
enum Priority { BeforeItem, AfterItem };
Priority priority() const;
void setPriority(Priority);
static QDeclarativeKeyNavigationAttached *qmlAttachedProperties(QObject *);
Q_SIGNALS:
void leftChanged();
void rightChanged();
void upChanged();
void downChanged();
void tabChanged();
void backtabChanged();
void priorityChanged();
private:
virtual void keyPressed(QKeyEvent *event, bool post);
virtual void keyReleased(QKeyEvent *event, bool post);
void setFocusNavigation(QDeclarativeItem *currentItem, const char *dir);
};
class QDeclarativeLayoutMirroringAttached : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
public:
explicit QDeclarativeLayoutMirroringAttached(QObject *parent = 0);
bool enabled() const;
void setEnabled(bool);
void resetEnabled();
bool childrenInherit() const;
void setChildrenInherit(bool);
static QDeclarativeLayoutMirroringAttached *qmlAttachedProperties(QObject *);
Q_SIGNALS:
void enabledChanged();
void childrenInheritChanged();
private:
friend class QDeclarativeItemPrivate;
QDeclarativeItemPrivate *itemPrivate;
};
class QDeclarativeKeysAttachedPrivate : public QObjectPrivate
{
public:
QDeclarativeKeysAttachedPrivate()
: QObjectPrivate(), inPress(false), inRelease(false)
, inIM(false), enabled(true), imeItem(0), item(0)
{}
bool isConnected(const char *signalName);
QGraphicsItem *finalFocusProxy(QGraphicsItem *item) const
{
QGraphicsItem *fp;
while ((fp = item->focusProxy()))
item = fp;
return item;
}
//loop detection
bool inPress:1;
bool inRelease:1;
bool inIM:1;
bool enabled : 1;
QGraphicsItem *imeItem;
QList<QDeclarativeItem *> targets;
QDeclarativeItem *item;
};
class QDeclarativeKeysAttached : public QObject, public QDeclarativeItemKeyFilter
{
Q_OBJECT
Q_DECLARE_PRIVATE(QDeclarativeKeysAttached)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QDeclarativeListProperty<QDeclarativeItem> forwardTo READ forwardTo)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
Q_ENUMS(Priority)
public:
QDeclarativeKeysAttached(QObject *parent=0);
~QDeclarativeKeysAttached();
bool enabled() const { Q_D(const QDeclarativeKeysAttached); return d->enabled; }
void setEnabled(bool enabled) {
Q_D(QDeclarativeKeysAttached);
if (enabled != d->enabled) {
d->enabled = enabled;
emit enabledChanged();
}
}
enum Priority { BeforeItem, AfterItem};
Priority priority() const;
void setPriority(Priority);
QDeclarativeListProperty<QDeclarativeItem> forwardTo() {
Q_D(QDeclarativeKeysAttached);
return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets);
}
virtual void componentComplete();
static QDeclarativeKeysAttached *qmlAttachedProperties(QObject *);
Q_SIGNALS:
void enabledChanged();
void priorityChanged();
void pressed(QDeclarativeKeyEvent *event);
void released(QDeclarativeKeyEvent *event);
void digit0Pressed(QDeclarativeKeyEvent *event);
void digit1Pressed(QDeclarativeKeyEvent *event);
void digit2Pressed(QDeclarativeKeyEvent *event);
void digit3Pressed(QDeclarativeKeyEvent *event);
void digit4Pressed(QDeclarativeKeyEvent *event);
void digit5Pressed(QDeclarativeKeyEvent *event);
void digit6Pressed(QDeclarativeKeyEvent *event);
void digit7Pressed(QDeclarativeKeyEvent *event);
void digit8Pressed(QDeclarativeKeyEvent *event);
void digit9Pressed(QDeclarativeKeyEvent *event);
void leftPressed(QDeclarativeKeyEvent *event);
void rightPressed(QDeclarativeKeyEvent *event);
void upPressed(QDeclarativeKeyEvent *event);
void downPressed(QDeclarativeKeyEvent *event);
void tabPressed(QDeclarativeKeyEvent *event);
void backtabPressed(QDeclarativeKeyEvent *event);
void asteriskPressed(QDeclarativeKeyEvent *event);
void numberSignPressed(QDeclarativeKeyEvent *event);
void escapePressed(QDeclarativeKeyEvent *event);
void returnPressed(QDeclarativeKeyEvent *event);
void enterPressed(QDeclarativeKeyEvent *event);
void deletePressed(QDeclarativeKeyEvent *event);
void spacePressed(QDeclarativeKeyEvent *event);
void backPressed(QDeclarativeKeyEvent *event);
void cancelPressed(QDeclarativeKeyEvent *event);
void selectPressed(QDeclarativeKeyEvent *event);
void yesPressed(QDeclarativeKeyEvent *event);
void noPressed(QDeclarativeKeyEvent *event);
void context1Pressed(QDeclarativeKeyEvent *event);
void context2Pressed(QDeclarativeKeyEvent *event);
void context3Pressed(QDeclarativeKeyEvent *event);
void context4Pressed(QDeclarativeKeyEvent *event);
void callPressed(QDeclarativeKeyEvent *event);
void hangupPressed(QDeclarativeKeyEvent *event);
void flipPressed(QDeclarativeKeyEvent *event);
void menuPressed(QDeclarativeKeyEvent *event);
void volumeUpPressed(QDeclarativeKeyEvent *event);
void volumeDownPressed(QDeclarativeKeyEvent *event);
private:
virtual void keyPressed(QKeyEvent *event, bool post);
virtual void keyReleased(QKeyEvent *event, bool post);
virtual void inputMethodEvent(QInputMethodEvent *, bool post);
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
const QByteArray keyToSignal(int key) {
QByteArray keySignal;
if (key >= Qt::Key_0 && key <= Qt::Key_9) {
keySignal = "digit0Pressed";
keySignal[5] = '0' + (key - Qt::Key_0);
} else {
int i = 0;
while (sigMap[i].key && sigMap[i].key != key)
++i;
keySignal = sigMap[i].sig;
}
return keySignal;
}
struct SigMap {
int key;
const char *sig;
};
static const SigMap sigMap[];
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeItemPrivate::ChangeTypes);
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeKeysAttached)
QML_DECLARE_TYPEINFO(QDeclarativeKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QDeclarativeKeyNavigationAttached)
QML_DECLARE_TYPEINFO(QDeclarativeKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QDeclarativeLayoutMirroringAttached)
QML_DECLARE_TYPEINFO(QDeclarativeLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QDECLARATIVEITEM_P_H