diff options
author | Marco Bubke <marco.bubke@nokia.com> | 2011-06-23 14:48:03 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@nokia.com> | 2011-06-23 15:22:31 +0200 |
commit | 5b8565ec05dda9a3c7401a5e7247defe3bcc89a6 (patch) | |
tree | d2c4101ee868a323231f7522931db72f2d7a7c12 /src | |
parent | 20c4cb67f129510180e46946b64e7d4b86683396 (diff) | |
download | qtquickcontrols-5b8565ec05dda9a3c7401a5e7247defe3bcc89a6.tar.gz |
Desktop components are now installable
Diffstat (limited to 'src')
-rw-r--r-- | src/src.pro | 2 | ||||
-rw-r--r-- | src/styleitem/qdeclarativefolderlistmodel.cpp | 488 | ||||
-rw-r--r-- | src/styleitem/qdeclarativefolderlistmodel.h | 133 | ||||
-rw-r--r-- | src/styleitem/qrangemodel.cpp | 520 | ||||
-rw-r--r-- | src/styleitem/qrangemodel.h | 111 | ||||
-rw-r--r-- | src/styleitem/qrangemodel_p.h | 92 | ||||
-rw-r--r-- | src/styleitem/qstyleitem.cpp | 1067 | ||||
-rw-r--r-- | src/styleitem/qstyleitem.h | 234 | ||||
-rw-r--r-- | src/styleitem/qstyleplugin.cpp | 98 | ||||
-rw-r--r-- | src/styleitem/qstyleplugin.h | 58 | ||||
-rw-r--r-- | src/styleitem/qtmenu.cpp | 143 | ||||
-rw-r--r-- | src/styleitem/qtmenu.h | 86 | ||||
-rw-r--r-- | src/styleitem/qtmenubar.cpp | 57 | ||||
-rw-r--r-- | src/styleitem/qtmenubar.h | 65 | ||||
-rw-r--r-- | src/styleitem/qtmenuitem.cpp | 61 | ||||
-rw-r--r-- | src/styleitem/qtmenuitem.h | 69 | ||||
-rw-r--r-- | src/styleitem/qwheelarea.cpp | 186 | ||||
-rw-r--r-- | src/styleitem/qwheelarea.h | 104 | ||||
-rw-r--r-- | src/styleitem/styleitem.pro | 45 |
19 files changed, 3619 insertions, 0 deletions
diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 00000000..b06387a2 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = styleitem diff --git a/src/styleitem/qdeclarativefolderlistmodel.cpp b/src/styleitem/qdeclarativefolderlistmodel.cpp new file mode 100644 index 00000000..93b9d76c --- /dev/null +++ b/src/styleitem/qdeclarativefolderlistmodel.cpp @@ -0,0 +1,488 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![code] +#include "qdeclarativefolderlistmodel.h" +#include <QDirModel> +#include <QDebug> +#include <qdeclarativecontext.h> + +#ifndef QT_NO_DIRMODEL + +QT_BEGIN_NAMESPACE + +class QDeclarativeFolderListModelPrivate +{ +public: + QDeclarativeFolderListModelPrivate() + : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0) { + nameFilters << QLatin1String("*"); + } + + void updateSorting() { + QDir::SortFlags flags = 0; + switch(sortField) { + case QDeclarativeFolderListModel::Unsorted: + flags |= QDir::Unsorted; + break; + case QDeclarativeFolderListModel::Name: + flags |= QDir::Name; + break; + case QDeclarativeFolderListModel::Time: + flags |= QDir::Time; + break; + case QDeclarativeFolderListModel::Size: + flags |= QDir::Size; + break; + case QDeclarativeFolderListModel::Type: + flags |= QDir::Type; + break; + } + + if (sortReversed) + flags |= QDir::Reversed; + + model.setSorting(flags); + } + + QDirModel model; + QUrl folder; + QStringList nameFilters; + QModelIndex folderIndex; + QDeclarativeFolderListModel::SortField sortField; + bool sortReversed; + int count; +}; + +/*! + \qmlclass FolderListModel QDeclarativeFolderListModel + \ingroup qml-working-with-data + \brief The FolderListModel provides a model of the contents of a file system folder. + + FolderListModel provides access to information about the contents of a folder + in the local file system, exposing a list of files to views and other data components. + + \note This type is made available by importing the \c Qt.labs.folderlistmodel module. + \e{Elements in the Qt.labs module are not guaranteed to remain compatible + in future versions.} + + \bold{import Qt.labs.folderlistmodel 1.0} + + The \l folder property specifies the folder to access. Information about the + files and directories in the folder is supplied via the model's interface. + Components access names and paths via the following roles: + + \list + \o fileName + \o filePath + \endlist + + Additionally a file entry can be differentiated from a folder entry via the + isFolder() method. + + \section1 Filtering + + Various properties can be set to filter the number of files and directories + ˚ exposed by the model. + + The \l nameFilters property can be set to contain a list of wildcard filters + that are applied to names of files and directories, causing only those that + match the filters to be exposed. + + Directories can be included or excluded using the \l showDirs property, and + navigation directories can also be excluded by setting the \l showDotAndDotDot + property to false. + + It is sometimes useful to limit the files and directories exposed to those + that the user can access. The \l showOnlyReadable property can be set to + enable this feature. + + \section1 Example Usage + + The following example shows a FolderListModel being used to provide a list + of QML files in a \l ListView: + + \snippet doc/src/snippets/declarative/folderlistmodel.qml 0 + + \section1 Path Separators + + Qt uses "/" as a universal directory separator in the same way that "/" is + used as a path separator in URLs. If you always use "/" as a directory + separator, Qt will translate your paths to conform to the underlying + operating system. + + \sa {QML Data Models} +*/ + +QDeclarativeFolderListModel::QDeclarativeFolderListModel(QObject *parent) + : QAbstractListModel(parent) +{ + QHash<int, QByteArray> roles; + roles[FileNameRole] = "fileName"; + roles[FilePathRole] = "filePath"; + roles[FileSizeRole] = "fileSize"; + setRoleNames(roles); + + d = new QDeclarativeFolderListModelPrivate; + d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot); + connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int)) + , this, SLOT(inserted(const QModelIndex&,int,int))); + connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int)) + , this, SLOT(removed(const QModelIndex&,int,int))); + connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)) + , this, SLOT(handleDataChanged(const QModelIndex&,const QModelIndex&))); + connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh())); + connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh())); +} + +QDeclarativeFolderListModel::~QDeclarativeFolderListModel() +{ + delete d; +} + +QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) const +{ + QVariant rv; + QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex); + if (modelIndex.isValid()) { + if (role == FileNameRole) + rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString(); + else if (role == FilePathRole) + rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString()); + else if (role == FileSizeRole) + rv = d->model.data(d->model.index(index.row(), 1, d->folderIndex), Qt::DisplayRole).toString(); + } + return rv; +} + +/*! + \qmlproperty int FolderListModel::count + + Returns the number of items in the current folder that match the + filter criteria. +*/ +int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return d->count; +} + +/*! + \qmlproperty string FolderListModel::folder + + The \a folder property holds a URL for the folder that the model is + currently providing. + + The value is a URL expressed as a string, and must be a \c file: or \c qrc: + URL, or a relative URL. + + By default, the value is an invalid URL. +*/ +QUrl QDeclarativeFolderListModel::folder() const +{ + return d->folder; +} + +void QDeclarativeFolderListModel::setFolder(const QUrl &folder) +{ + if (folder == d->folder) + return; + QModelIndex index = d->model.index(folder.toLocalFile()); + if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) { + + d->folder = folder; + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + emit folderChanged(); + } +} + +/*! + \qmlproperty url FolderListModel::parentFolder + + Returns the URL of the parent of of the current \l folder. +*/ +QUrl QDeclarativeFolderListModel::parentFolder() const +{ + QString localFile = d->folder.toLocalFile(); + if (!localFile.isEmpty()) { + QDir dir(localFile); +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) + if (dir.isRoot()) + dir.setPath(""); + else +#endif + dir.cdUp(); + localFile = dir.path(); + } else { + int pos = d->folder.path().lastIndexOf(QLatin1Char('/')); + if (pos == -1) + return QUrl(); + localFile = d->folder.path().left(pos); + } + return QUrl::fromLocalFile(localFile); +} + +/*! + \qmlproperty list<string> FolderListModel::nameFilters + + The \a nameFilters property contains a list of file name filters. + The filters may include the ? and * wildcards. + + The example below filters on PNG and JPEG files: + + \qml + FolderListModel { + nameFilters: [ "*.png", "*.jpg" ] + } + \endqml + + \note Directories are not excluded by filters. +*/ +QStringList QDeclarativeFolderListModel::nameFilters() const +{ + return d->nameFilters; +} + +void QDeclarativeFolderListModel::setNameFilters(const QStringList &filters) +{ + d->nameFilters = filters; + d->model.setNameFilters(d->nameFilters); +} + +void QDeclarativeFolderListModel::classBegin() +{ +} + +void QDeclarativeFolderListModel::componentComplete() +{ + if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile())) + setFolder(QUrl(QLatin1String("file://")+QDir::currentPath())); + + if (!d->folderIndex.isValid()) + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); +} + +/*! + \qmlproperty enumeration FolderListModel::sortField + + The \a sortField property contains field to use for sorting. sortField + may be one of: + \list + \o Unsorted - no sorting is applied. The order is system default. + \o Name - sort by filename + \o Time - sort by time modified + \o Size - sort by file size + \o Type - sort by file type (extension) + \endlist + + \sa sortReversed +*/ +QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const +{ + return d->sortField; +} + +void QDeclarativeFolderListModel::setSortField(SortField field) +{ + if (field != d->sortField) { + d->sortField = field; + d->updateSorting(); + } +} + +/*! + \qmlproperty bool FolderListModel::sortReversed + + If set to true, reverses the sort order. The default is false. + + \sa sortField +*/ +bool QDeclarativeFolderListModel::sortReversed() const +{ + return d->sortReversed; +} + +void QDeclarativeFolderListModel::setSortReversed(bool rev) +{ + if (rev != d->sortReversed) { + d->sortReversed = rev; + d->updateSorting(); + } +} + +/*! + \qmlmethod bool FolderListModel::isFolder(int index) + + Returns true if the entry \a index is a folder; otherwise + returns false. +*/ +bool QDeclarativeFolderListModel::isFolder(int index) const +{ + if (index != -1) { + QModelIndex idx = d->model.index(index, 0, d->folderIndex); + if (idx.isValid()) + return d->model.isDir(idx); + } + return false; +} + +void QDeclarativeFolderListModel::refresh() +{ + d->folderIndex = QModelIndex(); + if (d->count) { + emit beginRemoveRows(QModelIndex(), 0, d->count-1); + d->count = 0; + emit endRemoveRows(); + } + d->folderIndex = d->model.index(d->folder.toLocalFile()); + int newcount = d->model.rowCount(d->folderIndex); + if (newcount) { + emit beginInsertRows(QModelIndex(), 0, newcount-1); + d->count = newcount; + emit endInsertRows(); + } +} + +void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end) +{ + if (index == d->folderIndex) { + emit beginInsertRows(QModelIndex(), start, end); + d->count = d->model.rowCount(d->folderIndex); + emit endInsertRows(); + } +} + +void QDeclarativeFolderListModel::removed(const QModelIndex &index, int start, int end) +{ + if (index == d->folderIndex) { + emit beginRemoveRows(QModelIndex(), start, end); + d->count = d->model.rowCount(d->folderIndex); + emit endRemoveRows(); + } +} + +void QDeclarativeFolderListModel::handleDataChanged(const QModelIndex &start, const QModelIndex &end) +{ + if (start.parent() == d->folderIndex) + emit dataChanged(index(start.row(),0), index(end.row(),0)); +} + +/*! + \qmlproperty bool FolderListModel::showDirs + + If true, directories are included in the model; otherwise only files + are included. + + By default, this property is true. + + Note that the nameFilters are not applied to directories. + + \sa showDotAndDotDot +*/ +bool QDeclarativeFolderListModel::showDirs() const +{ + return d->model.filter() & QDir::AllDirs; +} + +void QDeclarativeFolderListModel::setShowDirs(bool on) +{ + if (!(d->model.filter() & QDir::AllDirs) == !on) + return; + if (on) + d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives); + else + d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives)); +} + +/*! + \qmlproperty bool FolderListModel::showDotAndDotDot + + If true, the "." and ".." directories are included in the model; otherwise + they are excluded. + + By default, this property is false. + + \sa showDirs +*/ +bool QDeclarativeFolderListModel::showDotAndDotDot() const +{ + return !(d->model.filter() & QDir::NoDotAndDotDot); +} + +void QDeclarativeFolderListModel::setShowDotAndDotDot(bool on) +{ + if (!(d->model.filter() & QDir::NoDotAndDotDot) == on) + return; + if (on) + d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot); + else + d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot); +} + +/*! + \qmlproperty bool FolderListModel::showOnlyReadable + + If true, only readable files and directories are shown; otherwise all files + and directories are shown. + + By default, this property is false. + + \sa showDirs +*/ +bool QDeclarativeFolderListModel::showOnlyReadable() const +{ + return d->model.filter() & QDir::Readable; +} + +void QDeclarativeFolderListModel::setShowOnlyReadable(bool on) +{ + if (!(d->model.filter() & QDir::Readable) == !on) + return; + if (on) + d->model.setFilter(d->model.filter() | QDir::Readable); + else + d->model.setFilter(d->model.filter() & ~QDir::Readable); +} + +//![code] +QT_END_NAMESPACE + +#endif // QT_NO_DIRMODEL diff --git a/src/styleitem/qdeclarativefolderlistmodel.h b/src/styleitem/qdeclarativefolderlistmodel.h new file mode 100644 index 00000000..53ea3f1b --- /dev/null +++ b/src/styleitem/qdeclarativefolderlistmodel.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEFOLDERLISTMODEL_H +#define QDECLARATIVEFOLDERLISTMODEL_H + +#include <qdeclarative.h> +#include <QStringList> +#include <QUrl> +#include <QAbstractListModel> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeContext; +class QModelIndex; + +class QDeclarativeFolderListModelPrivate; + +class QDeclarativeFolderListModel : public QAbstractListModel, public QDeclarativeParserStatus +{ + Q_OBJECT + Q_INTERFACES(QDeclarativeParserStatus) + + Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged) + Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) + Q_PROPERTY(SortField sortField READ sortField WRITE setSortField) + Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed) + Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs) + Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot) + Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable) + Q_PROPERTY(int count READ count NOTIFY countChanged) +public: + QDeclarativeFolderListModel(QObject *parent = 0); + ~QDeclarativeFolderListModel(); + + enum Roles { FileNameRole = Qt::UserRole+1, FilePathRole = Qt::UserRole+2, FileSizeRole = Qt::UserRole+3 }; + + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + + int count() const { return rowCount(QModelIndex()); } + + QUrl folder() const; + void setFolder(const QUrl &folder); + + QUrl parentFolder() const; + + QStringList nameFilters() const; + void setNameFilters(const QStringList &filters); + + enum SortField { Unsorted, Name, Time, Size, Type }; + SortField sortField() const; + void setSortField(SortField field); + Q_ENUMS(SortField) + + bool sortReversed() const; + void setSortReversed(bool rev); + + bool showDirs() const; + void setShowDirs(bool); + bool showDotAndDotDot() const; + void setShowDotAndDotDot(bool); + bool showOnlyReadable() const; + void setShowOnlyReadable(bool); + Q_INVOKABLE bool isFolder(int index) const; + virtual void classBegin(); + virtual void componentComplete(); + +Q_SIGNALS: + void folderChanged(); + void countChanged(); + +private Q_SLOTS: + void refresh(); + void inserted(const QModelIndex &index, int start, int end); + void removed(const QModelIndex &index, int start, int end); + void handleDataChanged(const QModelIndex &start, const QModelIndex &end); + +private: + Q_DISABLE_COPY(QDeclarativeFolderListModel) + QDeclarativeFolderListModelPrivate *d; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeFolderListModel) + +QT_END_HEADER + +#endif // QDECLARATIVEFOLDERLISTMODEL_H diff --git a/src/styleitem/qrangemodel.cpp b/src/styleitem/qrangemodel.cpp new file mode 100644 index 00000000..83c106ec --- /dev/null +++ b/src/styleitem/qrangemodel.cpp @@ -0,0 +1,520 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +/*! + \class QRangeModel + \brief The QRangeModel class, helps users to build components that depend + on some value and/or position to be in a certain range previously defined + + With this class, the user sets a value range and a position range, which + represent the valid values/positions the model can assume. It is worth telling + that the value property always has priority over the position property. A nice use + case, would be a Slider implementation with the help of QRangeModel. If the user sets + a value range to [0,100], a position range to [50,100] and sets the value + to 80, the equivalent position would be 90. After that, if the user decides to + resize the slider, the value would be the same, but the knob position would + be updated due to the new position range. + + \ingroup qt-components +*/ + +#include <QEvent> +#include <QApplication> +#include <QGraphicsSceneEvent> +#include <QDebug> + +#ifndef QT_NO_ACCESSIBILITY +#include <QAccessible> +#endif + +#include "qrangemodel.h" +#include "qrangemodel_p.h" + +QRangeModelPrivate::QRangeModelPrivate(QRangeModel *qq) + : q_ptr(qq) +{ +} + +QRangeModelPrivate::~QRangeModelPrivate() +{ +} + +void QRangeModelPrivate::init() +{ + minimum = 0; + maximum = 99; + stepSize = 0; + value = 0; + pos = 0; + posatmin = 0; + posatmax = 0; + inverted = false; +} + +/*! + Calculates the position that is going to be seen outside by the component + that is using QRangeModel. It takes into account the \l stepSize, + \l positionAtMinimum, \l positionAtMaximum properties + and \a position that is passed as parameter. +*/ + +qreal QRangeModelPrivate::publicPosition(qreal position) const +{ + // Calculate the equivalent stepSize for the position property. + const qreal min = effectivePosAtMin(); + const qreal max = effectivePosAtMax(); + const qreal valueRange = maximum - minimum; + const qreal positionValueRatio = valueRange ? (max - min) / valueRange : 0; + const qreal positionStep = stepSize * positionValueRatio; + + if (positionStep == 0) + return (min < max) ? qBound(min, position, max) : qBound(max, position, min); + + const int stepSizeMultiplier = (position - min) / positionStep; + + // Test whether value is below minimum range + if (stepSizeMultiplier < 0) + return min; + + qreal leftEdge = (stepSizeMultiplier * positionStep) + min; + qreal rightEdge = ((stepSizeMultiplier + 1) * positionStep) + min; + + if (min < max) { + leftEdge = qMin(leftEdge, max); + rightEdge = qMin(rightEdge, max); + } else { + leftEdge = qMax(leftEdge, max); + rightEdge = qMax(rightEdge, max); + } + + if (qAbs(leftEdge - position) <= qAbs(rightEdge - position)) + return leftEdge; + return rightEdge; +} + +/*! + Calculates the value that is going to be seen outside by the component + that is using QRangeModel. It takes into account the \l stepSize, + \l minimumValue, \l maximumValue properties + and \a value that is passed as parameter. +*/ + +qreal QRangeModelPrivate::publicValue(qreal value) const +{ + // It is important to do value-within-range check this + // late (as opposed to during setPosition()). The reason is + // QML bindings; a position that is initially invalid because it lays + // outside the range, might become valid later if the range changes. + + if (stepSize == 0) + return qBound(minimum, value, maximum); + + const int stepSizeMultiplier = (value - minimum) / stepSize; + + // Test whether value is below minimum range + if (stepSizeMultiplier < 0) + return minimum; + + const qreal leftEdge = qMin(maximum, (stepSizeMultiplier * stepSize) + minimum); + const qreal rightEdge = qMin(maximum, ((stepSizeMultiplier + 1) * stepSize) + minimum); + const qreal middle = (leftEdge + rightEdge) / 2; + + return (value <= middle) ? leftEdge : rightEdge; +} + +/*! + Checks if the \l value or \l position, that is seen by the user, has changed and emits the changed signal if it + has changed. +*/ + +void QRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition) +{ + Q_Q(QRangeModel); + + // Effective value and position might have changed even in cases when e.g. d->value is + // unchanged. This will be the case when operating with values outside range: + const qreal newValue = q->value(); + const qreal newPosition = q->position(); + if (!qFuzzyCompare(newValue, oldValue)) + emit q->valueChanged(newValue); + if (!qFuzzyCompare(newPosition, oldPosition)) + emit q->positionChanged(newPosition); +} + +/*! + Constructs a QRangeModel with \a parent +*/ + +QRangeModel::QRangeModel(QObject *parent) + : QObject(parent), d_ptr(new QRangeModelPrivate(this)) +{ + Q_D(QRangeModel); + d->init(); +} + +/*! + \internal + Constructs a QRangeModel with private class pointer \a dd and \a parent +*/ + +QRangeModel::QRangeModel(QRangeModelPrivate &dd, QObject *parent) + : QObject(parent), d_ptr(&dd) +{ + Q_D(QRangeModel); + d->init(); +} + +/*! + Destroys the QRangeModel +*/ + +QRangeModel::~QRangeModel() +{ + delete d_ptr; + d_ptr = 0; +} + +/*! + Sets the range of valid positions, that \l position can assume externally, with + \a min and \a max. + Such range is represented by \l positionAtMinimum and \l positionAtMaximum +*/ + +void QRangeModel::setPositionRange(qreal min, qreal max) +{ + Q_D(QRangeModel); + + bool emitPosAtMinChanged = !qFuzzyCompare(min, d->posatmin); + bool emitPosAtMaxChanged = !qFuzzyCompare(max, d->posatmax); + + if (!(emitPosAtMinChanged || emitPosAtMaxChanged)) + return; + + const qreal oldPosition = position(); + d->posatmin = min; + d->posatmax = max; + + // When a new positionRange is defined, the position property must be updated based on the value property. + // For instance, imagine that you have a valueRange of [0,100] and a position range of [20,100], + // if a user set the value to 50, the position would be 60. If this positionRange is updated to [0,100], then + // the new position, based on the value (50), will be 50. + // If the newPosition is different than the old one, it must be updated, in order to emit + // the positionChanged signal. + d->pos = d->equivalentPosition(d->value); + + if (emitPosAtMinChanged) + emit positionAtMinimumChanged(d->posatmin); + if (emitPosAtMaxChanged) + emit positionAtMaximumChanged(d->posatmax); + + d->emitValueAndPositionIfChanged(value(), oldPosition); +} +/*! + Sets the range of valid values, that \l value can assume externally, with + \a min and \a max. The range has the following constraint: \a min must be less or equal \a max + Such range is represented by \l minimumValue and \l maximumValue +*/ + +void QRangeModel::setRange(qreal min, qreal max) +{ + Q_D(QRangeModel); + + bool emitMinimumChanged = !qFuzzyCompare(min, d->minimum); + bool emitMaximumChanged = !qFuzzyCompare(max, d->maximum); + + if (!(emitMinimumChanged || emitMaximumChanged)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + + d->minimum = min; + d->maximum = qMax(min, max); + + // Update internal position if it was changed. It can occurs if internal value changes, due to range update + d->pos = d->equivalentPosition(d->value); + + if (emitMinimumChanged) + emit minimumChanged(d->minimum); + if (emitMaximumChanged) + emit maximumChanged(d->maximum); + + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::minimumValue + \brief the minimum value that \l value can assume + + This property's default value is 0 +*/ + +void QRangeModel::setMinimum(qreal min) +{ + Q_D(const QRangeModel); + setRange(min, d->maximum); +} + +qreal QRangeModel::minimum() const +{ + Q_D(const QRangeModel); + return d->minimum; +} + +/*! + \property QRangeModel::maximumValue + \brief the maximum value that \l value can assume + + This property's default value is 99 +*/ + +void QRangeModel::setMaximum(qreal max) +{ + Q_D(const QRangeModel); + // if the new maximum value is smaller than + // minimum, update minimum too + setRange(qMin(d->minimum, max), max); +} + +qreal QRangeModel::maximum() const +{ + Q_D(const QRangeModel); + return d->maximum; +} + +/*! + \property QRangeModel::stepSize + \brief the value that is added to the \l value and \l position property + + Example: If a user sets a range of [0,100] and stepSize + to 30, the valid values that are going to be seen externally would be: 0, 30, 60, 90, 100. +*/ + +void QRangeModel::setStepSize(qreal stepSize) +{ + Q_D(QRangeModel); + + stepSize = qMax(qreal(0.0), stepSize); + if (qFuzzyCompare(stepSize, d->stepSize)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + d->stepSize = stepSize; + + emit stepSizeChanged(d->stepSize); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +qreal QRangeModel::stepSize() const +{ + Q_D(const QRangeModel); + return d->stepSize; +} + +/*! + Returns a valid position, respecting the \l positionAtMinimum, + \l positionAtMaximum and the \l stepSize properties. + Such calculation is based on the parameter \a value (which is valid externally). +*/ + +qreal QRangeModel::positionForValue(qreal value) const +{ + Q_D(const QRangeModel); + + const qreal unconstrainedPosition = d->equivalentPosition(value); + return d->publicPosition(unconstrainedPosition); +} + +/*! + \property QRangeModel::position + \brief the current position of the model + + Represents a valid external position, based on the \l positionAtMinimum, + \l positionAtMaximum and the \l stepSize properties. + The user can set it internally with a position, that is not within the current position range, + since it can become valid if the user changes the position range later. +*/ + +qreal QRangeModel::position() const +{ + Q_D(const QRangeModel); + + // Return the internal position but observe boundaries and + // stepSize restrictions. + return d->publicPosition(d->pos); +} + +void QRangeModel::setPosition(qreal newPosition) +{ + Q_D(QRangeModel); + + if (qFuzzyCompare(newPosition, d->pos)) + return; + + const qreal oldPosition = position(); + const qreal oldValue = value(); + + // Update position and calculate new value + d->pos = newPosition; + d->value = d->equivalentValue(d->pos); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::positionAtMinimum + \brief the minimum value that \l position can assume + + This property's default value is 0 +*/ + +void QRangeModel::setPositionAtMinimum(qreal min) +{ + Q_D(QRangeModel); + setPositionRange(min, d->posatmax); +} + +qreal QRangeModel::positionAtMinimum() const +{ + Q_D(const QRangeModel); + return d->posatmin; +} + +/*! + \property QRangeModel::positionAtMaximum + \brief the maximum value that \l position can assume + + This property's default value is 0 +*/ + +void QRangeModel::setPositionAtMaximum(qreal max) +{ + Q_D(QRangeModel); + setPositionRange(d->posatmin, max); +} + +qreal QRangeModel::positionAtMaximum() const +{ + Q_D(const QRangeModel); + return d->posatmax; +} + +/*! + Returns a valid value, respecting the \l minimumValue, + \l maximumValue and the \l stepSize properties. + Such calculation is based on the parameter \a position (which is valid externally). +*/ + +qreal QRangeModel::valueForPosition(qreal position) const +{ + Q_D(const QRangeModel); + + const qreal unconstrainedValue = d->equivalentValue(position); + return d->publicValue(unconstrainedValue); +} + +/*! + \property QRangeModel::value + \brief the current value of the model + + Represents a valid external value, based on the \l minimumValue, + \l maximumValue and the \l stepSize properties. + The user can set it internally with a value, that is not within the current range, + since it can become valid if the user changes the range later. +*/ + +qreal QRangeModel::value() const +{ + Q_D(const QRangeModel); + + // Return internal value but observe boundaries and + // stepSize restrictions + return d->publicValue(d->value); +} + +void QRangeModel::setValue(qreal newValue) +{ + Q_D(QRangeModel); + + if (qFuzzyCompare(newValue, d->value)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + + // Update relative value and position + d->value = newValue; + d->pos = d->equivalentPosition(d->value); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::inverted + \brief the model is inverted or not + + The model can be represented with an inverted behavior, e.g. when \l value assumes + the maximum value (represented by \l maximumValue) the \l position will be at its + minimum (represented by \l positionAtMinimum). +*/ + +void QRangeModel::setInverted(bool inverted) +{ + Q_D(QRangeModel); + if (inverted == d->inverted) + return; + + d->inverted = inverted; + emit invertedChanged(d->inverted); + + // After updating the internal value, the position property can change. + setPosition(d->equivalentPosition(d->value)); +} + +bool QRangeModel::inverted() const +{ + Q_D(const QRangeModel); + return d->inverted; +} + +/*! + Sets the \l value to \l minimumValue. +*/ + +void QRangeModel::toMinimum() +{ + Q_D(const QRangeModel); + setValue(d->minimum); +} + +/*! + Sets the \l value to \l maximumValue. +*/ + +void QRangeModel::toMaximum() +{ + Q_D(const QRangeModel); + setValue(d->maximum); +} diff --git a/src/styleitem/qrangemodel.h b/src/styleitem/qrangemodel.h new file mode 100644 index 00000000..6144281e --- /dev/null +++ b/src/styleitem/qrangemodel.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QRANGEMODEL_H +#define QRANGEMODEL_H + +#include <QtCore/qobject.h> +#include <QtGui/qgraphicsitem.h> +#include <QtGui/qabstractslider.h> +#include <QtDeclarative/qdeclarative.h> + +class QRangeModelPrivate; + +class QRangeModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true) + Q_PROPERTY(qreal minimumValue READ minimum WRITE setMinimum NOTIFY minimumChanged) + Q_PROPERTY(qreal maximumValue READ maximum WRITE setMaximum NOTIFY maximumChanged) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged) + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(qreal positionAtMinimum READ positionAtMinimum WRITE setPositionAtMinimum NOTIFY positionAtMinimumChanged) + Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged) + Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged) + +public: + QRangeModel(QObject *parent = 0); + virtual ~QRangeModel(); + + void setRange(qreal min, qreal max); + void setPositionRange(qreal min, qreal max); + + void setStepSize(qreal stepSize); + qreal stepSize() const; + + void setMinimum(qreal min); + qreal minimum() const; + + void setMaximum(qreal max); + qreal maximum() const; + + void setPositionAtMinimum(qreal posAtMin); + qreal positionAtMinimum() const; + + void setPositionAtMaximum(qreal posAtMax); + qreal positionAtMaximum() const; + + void setInverted(bool inverted); + bool inverted() const; + + qreal value() const; + qreal position() const; + + Q_INVOKABLE qreal valueForPosition(qreal position) const; + Q_INVOKABLE qreal positionForValue(qreal value) const; + +public Q_SLOTS: + void toMinimum(); + void toMaximum(); + void setValue(qreal value); + void setPosition(qreal position); + +Q_SIGNALS: + void valueChanged(qreal value); + void positionChanged(qreal position); + + void stepSizeChanged(qreal stepSize); + + void invertedChanged(bool inverted); + + void minimumChanged(qreal min); + void maximumChanged(qreal max); + void positionAtMinimumChanged(qreal min); + void positionAtMaximumChanged(qreal max); + +protected: + QRangeModel(QRangeModelPrivate &dd, QObject *parent); + QRangeModelPrivate* d_ptr; + +private: + Q_DISABLE_COPY(QRangeModel) + Q_DECLARE_PRIVATE(QRangeModel) + +}; + +QML_DECLARE_TYPE(QRangeModel) + +#endif // QRANGEMODEL_H diff --git a/src/styleitem/qrangemodel_p.h b/src/styleitem/qrangemodel_p.h new file mode 100644 index 00000000..cb72ceff --- /dev/null +++ b/src/styleitem/qrangemodel_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QRANGEMODEL_P_H +#define QRANGEMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Components 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 "qrangemodel.h" + +class QRangeModelPrivate +{ + Q_DECLARE_PUBLIC(QRangeModel) +public: + QRangeModelPrivate(QRangeModel *qq); + virtual ~QRangeModelPrivate(); + + void init(); + + qreal posatmin, posatmax; + qreal minimum, maximum, stepSize, pos, value; + + uint inverted : 1; + + QRangeModel *q_ptr; + + inline qreal effectivePosAtMin() const { + return inverted ? posatmax : posatmin; + } + + inline qreal effectivePosAtMax() const { + return inverted ? posatmin : posatmax; + } + + inline qreal equivalentPosition(qreal value) const { + // Return absolute position from absolute value + const qreal valueRange = maximum - minimum; + if (valueRange == 0) + return effectivePosAtMin(); + + const qreal scale = (effectivePosAtMax() - effectivePosAtMin()) / valueRange; + return (value - minimum) * scale + effectivePosAtMin(); + } + + inline qreal equivalentValue(qreal pos) const { + // Return absolute value from absolute position + const qreal posRange = effectivePosAtMax() - effectivePosAtMin(); + if (posRange == 0) + return minimum; + + const qreal scale = (maximum - minimum) / posRange; + return (pos - effectivePosAtMin()) * scale + minimum; + } + + qreal publicPosition(qreal position) const; + qreal publicValue(qreal value) const; + void emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition); +}; + +#endif // QRANGEMODEL_P_H diff --git a/src/styleitem/qstyleitem.cpp b/src/styleitem/qstyleitem.cpp new file mode 100644 index 00000000..603e53c4 --- /dev/null +++ b/src/styleitem/qstyleitem.cpp @@ -0,0 +1,1067 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstyleitem.h" + +#include <QtGui/QPainter> +#include <QtGui/QStyle> +#include <QtGui/QStyleOption> +#include <QtGui/QApplication> +#include <QtGui/QMainWindow> +#include <QtGui/QGroupBox> +#include <QtGui/QToolBar> +#include <QtGui/QMenu> +#include <QtCore/QStringBuilder> + + +QStyleItem::QStyleItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_dummywidget(0), + m_styleoption(0), + m_type(Undefined), + m_sunken(false), + m_raised(false), + m_active(true), + m_selected(false), + m_focus(false), + m_on(false), + m_horizontal(true), + m_sharedWidget(false), + m_minimum(0), + m_maximum(100), + m_value(0), + m_paintMargins(0) +{ + setFlag(QGraphicsItem::ItemHasNoContents, false); + setCacheMode(QGraphicsItem::DeviceCoordinateCache); + setSmooth(true); + + connect(this, SIGNAL(infoChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(onChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(selectedChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(textChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(raisedChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(sunkenChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(hoverChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(maximumChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(minimumChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(valueChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(horizontalChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(focusChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem())); + connect(this, SIGNAL(elementTypeChanged()), this, SLOT(updateItem())); +} + +QStyleItem::~QStyleItem() +{ + delete m_styleoption; + m_styleoption = 0; + + if (!m_sharedWidget) { + delete m_dummywidget; + m_dummywidget = 0; + } +} + +void QStyleItem::initStyleOption() +{ + QString type = elementType(); + if (m_styleoption) + m_styleoption->state = 0; + + switch (m_itemType) { + case Button: { + if (!m_styleoption) + m_styleoption = new QStyleOptionButton(); + + QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption); + opt->text = text(); + opt->features = (activeControl() == "default") ? + QStyleOptionButton::DefaultButton : + QStyleOptionButton::None; + } + break; + case ItemRow: { + if (!m_styleoption) + m_styleoption = new QStyleOptionViewItemV4(); + + QStyleOptionViewItemV4 *opt = qstyleoption_cast<QStyleOptionViewItemV4*>(m_styleoption); + opt->features = 0; + if (activeControl() == "alternate") + opt->features |= QStyleOptionViewItemV2::Alternate; + } + break; + + case Splitter: { + if (!m_styleoption) { + m_styleoption = new QStyleOption; + } + } + break; + + case Item: { + if (!m_styleoption) { + m_styleoption = new QStyleOptionViewItemV4(); + } + QStyleOptionViewItemV4 *opt = qstyleoption_cast<QStyleOptionViewItemV4*>(m_styleoption); + opt->features = QStyleOptionViewItemV4::HasDisplay; + opt->text = text(); + opt->textElideMode = Qt::ElideRight; + QPalette pal = m_styleoption->palette; + pal.setBrush(QPalette::Base, Qt::NoBrush); + m_styleoption->palette = pal; + } + break; + case Header: { + if (!m_styleoption) + m_styleoption = new QStyleOptionHeader(); + + QStyleOptionHeader *opt = qstyleoption_cast<QStyleOptionHeader*>(m_styleoption); + opt->text = text(); + opt->sortIndicator = activeControl() == "down" ? + QStyleOptionHeader::SortDown + : activeControl() == "up" ? + QStyleOptionHeader::SortUp : QStyleOptionHeader::None; + if (activeControl() == QLatin1String("beginning")) + opt->position = QStyleOptionHeader::Beginning; + else if (activeControl() == QLatin1String("end")) + opt->position = QStyleOptionHeader::End; + else if (activeControl() == QLatin1String("only")) + opt->position = QStyleOptionHeader::OnlyOneSection; + else + opt->position = QStyleOptionHeader::Middle; + + } + break; + case ToolButton :{ + if (!m_styleoption) + m_styleoption = new QStyleOptionToolButton(); + + QStyleOptionToolButton *opt = + qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption); + opt->subControls = QStyle::SC_ToolButton; + opt->state |= QStyle::State_AutoRaise; + opt->activeSubControls = QStyle::SC_ToolButton; + } + break; + case ToolBar: { + if (!m_styleoption) + m_styleoption = new QStyleOptionToolBar(); + } + break; + case Tab: { + if (!m_styleoption) + m_styleoption = new QStyleOptionTabV3(); + + QStyleOptionTabV3 *opt = + qstyleoption_cast<QStyleOptionTabV3*>(m_styleoption); + opt->text = text(); + opt->shape = info() == "South" ? QTabBar::RoundedSouth : QTabBar::RoundedNorth; + if (activeControl() == QLatin1String("beginning")) + opt->position = QStyleOptionTabV3::Beginning; + else if (activeControl() == QLatin1String("end")) + opt->position = QStyleOptionTabV3::End; + else if (activeControl() == QLatin1String("only")) + opt->position = QStyleOptionTabV3::OnlyOneTab; + else + opt->position = QStyleOptionTabV3::Middle; + + } break; + + case Menu: { + if (!m_styleoption) + m_styleoption = new QStyleOptionMenuItem(); + } + break; + case Frame: { + if (!m_styleoption) + m_styleoption = new QStyleOptionFrameV3(); + + QStyleOptionFrameV3 *opt = qstyleoption_cast<QStyleOptionFrameV3*>(m_styleoption); + opt->frameShape = QFrame::StyledPanel; + opt->lineWidth = 1; + opt->midLineWidth = 1; + } + break; + case TabFrame: { + if (!m_styleoption) + m_styleoption = new QStyleOptionTabWidgetFrameV2(); + QStyleOptionTabWidgetFrameV2 *opt = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(m_styleoption); + opt->shape = (info() == "South") ? QTabBar::RoundedSouth : QTabBar::RoundedNorth; + if (minimum()) + opt->selectedTabRect = QRect(value(), 0, minimum(), height()); + opt->tabBarSize = QSize(minimum() , height()); + // oxygen style needs this hack + opt->leftCornerWidgetSize = QSize(value(), 0); + } + break; + case MenuItem: + case ComboBoxItem: + { + if (!m_styleoption) + m_styleoption = new QStyleOptionMenuItem(); + + QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption); + opt->checked = false; + opt->text = text(); + opt->palette = widget()->palette(); + } + break; + case CheckBox: + case RadioButton: + { + if (!m_styleoption) + m_styleoption = new QStyleOptionButton(); + + QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption); + if (!on()) + opt->state |= QStyle::State_Off; + opt->text = text(); + } + break; + case Edit: { + if (!m_styleoption) + m_styleoption = new QStyleOptionFrameV3(); + + QStyleOptionFrameV3 *opt = qstyleoption_cast<QStyleOptionFrameV3*>(m_styleoption); + opt->lineWidth = 1; // this must be non-zero + } + break; + case ComboBox :{ + if (!m_styleoption) + m_styleoption = new QStyleOptionComboBox(); + QStyleOptionComboBox *opt = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption); + opt->currentText = text(); + } + break; + case SpinBox: { + if (!m_styleoption) + m_styleoption = new QStyleOptionSpinBox(); + + QStyleOptionSpinBox *opt = qstyleoption_cast<QStyleOptionSpinBox*>(m_styleoption); + opt->frame = true; + if (value() & 0x1) + opt->activeSubControls = QStyle::SC_SpinBoxUp; + else if (value() & (1<<1)) + opt->activeSubControls = QStyle::SC_SpinBoxDown; + opt->subControls = QStyle::SC_All; + opt->stepEnabled = 0; + if (value() & (1<<2)) + opt->stepEnabled |= QAbstractSpinBox::StepUpEnabled; + if (value() & (1<<3)) + opt->stepEnabled |= QAbstractSpinBox::StepDownEnabled; + } + break; + case Slider: + case Dial: + { + if (!m_styleoption) + m_styleoption = new QStyleOptionSlider(); + + QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption); + opt->minimum = minimum(); + opt->maximum = maximum(); + // ### fixme - workaround for KDE inverted dial + opt->sliderPosition = value(); + opt->singleStep = step(); + + if (opt->singleStep) + { + qreal numOfSteps = (opt->maximum - opt->minimum) / opt->singleStep; + + // at least 5 pixels between tick marks + if (numOfSteps && (width() / numOfSteps < 5)) + opt->tickInterval = qRound((5*numOfSteps / width()) + 0.5)*step(); + else + opt->tickInterval = opt->singleStep; + } + else // default Qt-components implementation + opt->tickInterval = opt->maximum != opt->minimum ? 1200 / (opt->maximum - opt->minimum) : 0; + + if (style() == QLatin1String("oxygen") && type == QLatin1String("dial")) + opt->sliderValue = maximum() - value(); + else + opt->sliderValue = value(); + opt->subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle; + opt->tickPosition = (activeControl() == "below") ? + QSlider::TicksBelow : (activeControl() == "above" ? + QSlider::TicksAbove: + QSlider::NoTicks); + if (opt->tickPosition != QSlider::NoTicks) + opt->subControls |= QStyle::SC_SliderTickmarks; + + opt->activeSubControls = QStyle::SC_None; + } + break; + case ProgressBar: { + if (QProgressBar *bar= qobject_cast<QProgressBar*>(widget())){ + bar->setMaximum(maximum()); + bar->setMinimum(minimum()); + if (maximum() != minimum()) + bar->setValue(1); + } + if (!m_styleoption) + m_styleoption = new QStyleOptionProgressBarV2(); + + QStyleOptionProgressBarV2 *opt = qstyleoption_cast<QStyleOptionProgressBarV2*>(m_styleoption); + opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical; + opt->minimum = minimum(); + opt->maximum = maximum(); + opt->progress = value(); + } + break; + case GroupBox: { + if (!m_styleoption) + m_styleoption = new QStyleOptionGroupBox(); + + QStyleOptionGroupBox *opt = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption); + opt->text = text(); + opt->lineWidth = 1; + opt->subControls = QStyle::SC_GroupBoxLabel; + if (sunken()) // Qt draws an ugly line here so I ignore it + opt->subControls |= QStyle::SC_GroupBoxFrame; + else + opt->features |= QStyleOptionFrameV2::Flat; + if (activeControl() == "checkbox") + opt->subControls |= QStyle::SC_GroupBoxCheckBox; + + if (QGroupBox *group= qobject_cast<QGroupBox*>(widget())) { + group->setTitle(text()); + group->setCheckable(opt->subControls & QStyle::SC_GroupBoxCheckBox); + } + } + break; + case ScrollBar: { + if (!m_styleoption) + m_styleoption = new QStyleOptionSlider(); + + QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption); + opt->minimum = minimum(); + opt->maximum = maximum(); + opt->pageStep = horizontal() ? width() : height(); + opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical; + opt->sliderPosition = value(); + opt->sliderValue = value(); + opt->activeSubControls = (activeControl() == QLatin1String("up")) + ? QStyle::SC_ScrollBarSubLine : + (activeControl() == QLatin1String("down")) ? + QStyle::SC_ScrollBarAddLine: + QStyle::SC_ScrollBarSlider; + + opt->sliderValue = value(); + opt->subControls = QStyle::SC_All; + + QScrollBar *bar = qobject_cast<QScrollBar *>(widget()); + bar->setMaximum(maximum()); + bar->setMinimum(minimum()); + bar->setValue(value()); + } + break; + default: + break; + } + + if (!m_styleoption) + m_styleoption = new QStyleOption(); + + m_styleoption->rect = QRect(m_paintMargins, m_paintMargins, width() - 2* m_paintMargins, height() - 2 * m_paintMargins); + + if (isEnabled()) + m_styleoption->state |= QStyle::State_Enabled; + if (m_active) + m_styleoption->state |= QStyle::State_Active; + if (m_sunken) + m_styleoption->state |= QStyle::State_Sunken; + if (m_raised) + m_styleoption->state |= QStyle::State_Raised; + if (m_selected) + m_styleoption->state |= QStyle::State_Selected; + if (m_focus) + m_styleoption->state |= QStyle::State_HasFocus; + if (m_on) + m_styleoption->state |= QStyle::State_On; + if (m_hover) + m_styleoption->state |= QStyle::State_MouseOver; + if (m_horizontal) + m_styleoption->state |= QStyle::State_Horizontal; + + if (widget()) { + widget()->ensurePolished(); + if (type == QLatin1String("tab") && style() != QLatin1String("mac")) { + // Some styles actually check the beginning and end position + // using widget geometry, so we have to trick it + widget()->setGeometry(0, 0, width(), height()); + if (activeControl() != "beginning") + m_styleoption->rect.translate(1, 0); // Don't position at start of widget + if (activeControl() != "end") + widget()->resize(200, height()); + } +#ifdef Q_WS_WIN + else widget()->resize(width(), height()); +#endif + + widget()->setEnabled(isEnabled()); + m_styleoption->fontMetrics = widget()->fontMetrics(); + if (!m_styleoption->palette.resolve()) + m_styleoption->palette = widget()->palette(); + if (m_hint.contains("mac.mini")) { + widget()->setAttribute(Qt::WA_MacMiniSize); + } else if (m_hint.contains("mac.small")) { + widget()->setAttribute(Qt::WA_MacSmallSize); + } + } +} + +/* + * Property style + * + * Returns a simplified style name. + * + * QMacStyle = "mac" + * QWindowsXPStyle = "windowsxp" + * QPlastiqueStyle = "plastique" + */ + +QString QStyleItem::style() const +{ + QString style = qApp->style()->metaObject()->className(); + style = style.toLower(); + if (style.contains(QLatin1String("oxygen"))) + return QLatin1String("oxygen"); + if (style.startsWith(QLatin1Char('q'))) + style = style.right(style.length() - 1); + if (style.endsWith("style")) + style = style.left(style.length() - 5); + return style.toLower(); +} + +QString QStyleItem::hitTest(int px, int py) +{ + QStyle::SubControl subcontrol = QStyle::SC_All; + initStyleOption(); + switch (m_itemType) { + case SpinBox :{ + subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_SpinBox, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + QPoint(px,py), 0); + if (subcontrol == QStyle::SC_SpinBoxUp) + return "up"; + else if (subcontrol == QStyle::SC_SpinBoxDown) + return "down"; + + } + break; + + case Slider: { + subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_Slider, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + QPoint(px,py), 0); + if (subcontrol == QStyle::SC_SliderHandle) + return "handle"; + + } + break; + case ScrollBar: { + subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_ScrollBar, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + QPoint(px,py), 0); + if (subcontrol == QStyle::SC_ScrollBarSlider) + return "handle"; + + if (subcontrol == QStyle::SC_ScrollBarSubLine + || subcontrol == QStyle::SC_ScrollBarSubPage) + return "up"; + + if (subcontrol == QStyle::SC_ScrollBarAddLine + || subcontrol == QStyle::SC_ScrollBarAddPage) + return "down"; + } + break; + default: + break; + } + return "none"; +} + +QSize QStyleItem::sizeFromContents(int width, int height) +{ + initStyleOption(); + + QSize size; + switch (m_itemType) { + case CheckBox: + size = qApp->style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height), widget()); + break; + case ToolButton: + size = qApp->style()->sizeFromContents(QStyle::CT_ToolButton, m_styleoption, QSize(width,height), widget()); + break; + case Button: + size = qApp->style()->sizeFromContents(QStyle::CT_PushButton, m_styleoption, QSize(width,height), widget()); + break; + case Tab: + size = qApp->style()->sizeFromContents(QStyle::CT_TabBarTab, m_styleoption, QSize(width,height), widget()); + break; + case ComboBox: + size = qApp->style()->sizeFromContents(QStyle::CT_ComboBox, m_styleoption, QSize(width,height), widget()); + break; + case SpinBox: + size = qApp->style()->sizeFromContents(QStyle::CT_SpinBox, m_styleoption, QSize(width,height), widget()); + break; + case Slider: + size = qApp->style()->sizeFromContents(QStyle::CT_Slider, m_styleoption, QSize(width,height), widget()); + break; + case ProgressBar: + size = qApp->style()->sizeFromContents(QStyle::CT_ProgressBar, m_styleoption, QSize(width,height), widget()); + break; + case Edit: + size = qApp->style()->sizeFromContents(QStyle::CT_LineEdit, m_styleoption, QSize(width,height), widget()); + break; + case GroupBox: + size = qApp->style()->sizeFromContents(QStyle::CT_GroupBox, m_styleoption, QSize(width,height), widget()); + break; + case Header: + size = qApp->style()->sizeFromContents(QStyle::CT_HeaderSection, m_styleoption, QSize(width,height), widget()); +#ifdef Q_WS_MAC + if (style() =="mac") + size.setHeight(15); +#endif + break; + case ItemRow: + case Item: //fall through + size = qApp->style()->sizeFromContents(QStyle::CT_ItemViewItem, m_styleoption, QSize(width,height), widget()); + break; + default: + break; + } + +#ifdef Q_WS_MAC + // ### hack - With even heights, the text baseline is off on mac + if (size.height() %2 == 0) + size.setHeight(size.height() + 1); +#endif + return size; +} + + +int QStyleItem::pixelMetric(const QString &metric) +{ + + if (metric == "scrollbarExtent") + return qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, widget()); + else if (metric == "defaultframewidth") + return qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, widget()); + else if (metric == "taboverlap") + return qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 , widget()); + else if (metric == "tabbaseoverlap") +#ifdef Q_WS_WIN + // On windows the tabbar paintmargin extends the overlap by one pixels + return 1 + qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, 0 , widget()); +#else + return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, 0 , widget()); +#endif + else if (metric == "tabhspace") + return qApp->style()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0 , widget()); + else if (metric == "tabvspace") + return qApp->style()->pixelMetric(QStyle::PM_TabBarTabVSpace, 0 , widget()); + else if (metric == "tabbaseheight") + return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0 , widget()); + else if (metric == "tabvshift") + return qApp->style()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, 0 , widget()); + else if (metric == "menuhmargin") + return qApp->style()->pixelMetric(QStyle::PM_MenuHMargin, 0 , widget()); + else if (metric == "menuvmargin") + return qApp->style()->pixelMetric(QStyle::PM_MenuVMargin, 0 , widget()); + else if (metric == "menupanelwidth") + return qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0 , widget()); + else if (metric == "splitterwidth") + return qApp->style()->pixelMetric(QStyle::PM_SplitterWidth, 0 , widget()); + // This metric is incorrectly negative on oxygen + else if (metric == "scrollbarspacing") + return abs(qApp->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, 0 , widget())); + return 0; +} + +QVariant QStyleItem::styleHint(const QString &metric) +{ + initStyleOption(); + if (metric == "comboboxpopup") { + return qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, m_styleoption); + } else if (metric == "highlightedTextColor") { + if (widget()) + return widget()->palette().highlightedText().color().name(); + return qApp->palette().highlightedText().color().name(); + } else if (metric == "textColor") { + if (widget()) + return widget()->palette().text().color().name(); + return qApp->palette().text().color().name(); + } else if (metric == "focuswidget") { + return qApp->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget); + + } else if (metric == "tabbaralignment") { + int result = qApp->style()->styleHint(QStyle::SH_TabBar_Alignment); + if (result == Qt::AlignCenter) + return "center"; + return "left"; + + } else if (metric == "framearoundcontents") + return qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents); + return 0; +} + +void QStyleItem::setCursor(const QString &str) +{ + if (m_cursor != str) { + m_cursor = str; + if (m_cursor == "sizehorcursor") + QDeclarativeItem::setCursor(Qt::SizeHorCursor); + else if (m_cursor == "sizevercursor") + QDeclarativeItem::setCursor(Qt::SizeVerCursor); + else if (m_cursor == "sizeallcursor") + QDeclarativeItem::setCursor(Qt::SizeAllCursor); + else if (m_cursor == "splithcursor") + QDeclarativeItem::setCursor(Qt::SplitHCursor); + else if (m_cursor == "splitvcursor") + QDeclarativeItem::setCursor(Qt::SplitVCursor); + else if (m_cursor == "wait") + QDeclarativeItem::setCursor(Qt::WaitCursor); + emit cursorChanged(); + } +} + +void QStyleItem::setElementType(const QString &str) +{ + if (m_type == str) + return; + + m_type = str; + + emit elementTypeChanged(); + + if (m_dummywidget && !m_sharedWidget) { + delete m_dummywidget; + m_dummywidget = 0; + } + + if (m_styleoption) { + delete m_styleoption; + m_styleoption = 0; + } + + // Only enable visible if the widget can animate + bool visible = false; + if (str == "menu" || str == "menuitem") { + // Since these are used by the delegate, it makes no + // sense to re-create them per item + static QWidget *menu = new QMenu(); + m_sharedWidget = true; + m_dummywidget = menu; + m_itemType = (str == "menu") ? Menu : MenuItem; + } else if (str == "item" || str == "itemrow" || str == "header") { + // Since these are used by the delegate, it makes no + // sense to re-create them per item + static QTreeView *menu = new QTreeView(); + menu->setAttribute(Qt::WA_MacMiniSize); + m_sharedWidget = true; + if (str == "header") { + m_dummywidget = menu->header(); + if (style() == "mac") { // The default qt font seems to big + QFont font = m_dummywidget->font(); + font.setPointSize(11); + m_dummywidget->setFont(font); + } + m_itemType = Header; + } else { + m_dummywidget = menu; + m_itemType = (str == "item") ? Item : ItemRow; + } + } else if (str == "groupbox") { + // Since these are used by the delegate, it makes no + // sense to re-create them per item + static QGroupBox *group = new QGroupBox(); + m_sharedWidget = true; + m_dummywidget = group; + m_itemType = GroupBox; + } else if (str == "tabframe" || str == "tab") { + static QTabWidget *tabframe = new QTabWidget(); + m_sharedWidget = true; + if (str == "tab") { + m_dummywidget = tabframe->findChild<QTabBar*>(); + m_itemType = Tab; + } else { + m_dummywidget = tabframe; + m_itemType = TabFrame; + } + } else if (str == "comboboxitem") { + // Gtk uses qobject cast, hence we need to separate this from menuitem + // On mac, we temporarily use the menu item because it has more accurate + // palette. +#ifdef Q_WS_MAC + static QMenu *combo = new QMenu(); +#else + static QComboBox *combo = new QComboBox(); +#endif + m_sharedWidget = true; + m_dummywidget = combo; + m_itemType = ComboBoxItem; + } else if (str == "toolbar") { + static QToolBar *tb = 0; + if (!tb) { + QMainWindow *mw = new QMainWindow(); + tb = new QToolBar(mw); + } + m_dummywidget = tb; + m_itemType = ToolBar; + } else if (str == "toolbutton") { + static QToolButton *tb = 0; + static QToolBar *bar = 0; + // KDE animations are too broken with these widgets + if (style() != QLatin1String("oxygen")) { + if (!tb) { + bar = new QToolBar(0); + tb = new QToolButton(bar); + } + } + m_sharedWidget = true; + m_dummywidget = tb; + m_itemType = ToolButton; + } else if (str == "slider") { + static QSlider *slider = new QSlider(); + m_sharedWidget = true; + m_dummywidget = slider; + m_itemType = Slider; + } else if (str == "frame") { + static QFrame *frame = new QFrame(); + m_sharedWidget = true; + m_dummywidget = frame; + m_itemType = Frame; + } else if (str == "combobox") { + m_dummywidget = new QComboBox(); + visible = true; + m_itemType = ComboBox; + } else if (str == "splitter") { + visible = true; + m_itemType = Splitter; + } else if (str == "progressbar") { + m_dummywidget = new QProgressBar(); + visible = true; + m_itemType = ProgressBar; + } else if (str == "button") { + m_dummywidget = new QPushButton(); + visible = true; + m_itemType = Button; + } else if (str == "checkbox") { + m_dummywidget = new QCheckBox(); + visible = true; + m_itemType = CheckBox; + } else if (str == "radiobutton") { + m_dummywidget = new QRadioButton(); + visible = true; + m_itemType = RadioButton; + } else if (str == "edit") { + m_dummywidget = new QLineEdit(); + visible = true; + m_itemType = Edit; + } else if (str == "spinbox") { +#ifndef Q_WS_WIN // Vista spinbox is currently not working due to grabwidget + m_dummywidget = new QSpinBox(); + visible = true; +#endif + m_itemType = SpinBox; + } else if (str == "scrollbar") { + m_dummywidget = new QScrollBar(); + visible = true; + m_itemType = ScrollBar; + } else if (str == "widget") { + m_itemType = Widget; + } else if (str == "focusframe") { + m_itemType = FocusFrame; + } else if (str == "dial") { + m_itemType = Dial; + } + if (m_dummywidget) { + m_dummywidget->installEventFilter(this); + m_dummywidget->setAttribute(Qt::WA_QuitOnClose, false); // dont keep app open + m_dummywidget->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_dummywidget->winId(); +#ifdef Q_WS_MAC + m_dummywidget->setGeometry(-1000, 0, 10,10); + m_dummywidget->setVisible(visible); // Mac require us to set the visibility before this +#endif + m_dummywidget->setAttribute(Qt::WA_DontShowOnScreen); + m_dummywidget->setVisible(visible); + } +} + +bool QStyleItem::eventFilter(QObject *o, QEvent *e) { + if (e->type() == QEvent::Paint) { + updateItem(); + return true; + } + return QObject::eventFilter(o, e); +} + +void QStyleItem::showToolTip(const QString &str) +{ + QPointF scene = mapToScene(width() - 20, 0); + QPoint global = qApp->focusWidget()->mapToGlobal(scene.toPoint()); + QToolTip::showText(QPoint(global.x(), global.y()), str); +} + +QRect QStyleItem::subControlRect(const QString &subcontrolString) +{ + QStyle::SubControl subcontrol = QStyle::SC_None; + initStyleOption(); + switch (m_itemType) { + case SpinBox: + { + QStyle::ComplexControl control = QStyle::CC_SpinBox; + if (subcontrolString == QLatin1String("down")) + subcontrol = QStyle::SC_SpinBoxDown; + else if (subcontrolString == QLatin1String("up")) + subcontrol = QStyle::SC_SpinBoxUp; + else if (subcontrolString == QLatin1String("edit")){ + subcontrol = QStyle::SC_SpinBoxEditField; + } + return qApp->style()->subControlRect(control, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + subcontrol, widget()); + + } + break; + case Slider: + { + QStyle::ComplexControl control = QStyle::CC_Slider; + if (subcontrolString == QLatin1String("handle")) + subcontrol = QStyle::SC_SliderHandle; + else if (subcontrolString == QLatin1String("groove")) + subcontrol = QStyle::SC_SliderGroove; + return qApp->style()->subControlRect(control, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + subcontrol, widget()); + + } + break; + case ScrollBar: + { + QStyle::ComplexControl control = QStyle::CC_ScrollBar; + if (subcontrolString == QLatin1String("slider")) + subcontrol = QStyle::SC_ScrollBarSlider; + if (subcontrolString == QLatin1String("groove")) + subcontrol = QStyle::SC_ScrollBarGroove; + else if (subcontrolString == QLatin1String("handle")) + subcontrol = QStyle::SC_ScrollBarSlider; + else if (subcontrolString == QLatin1String("add")) + subcontrol = QStyle::SC_ScrollBarAddPage; + else if (subcontrolString == QLatin1String("sub")) + subcontrol = QStyle::SC_ScrollBarSubPage; + return qApp->style()->subControlRect(control, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + subcontrol, widget()); + } + break; + default: + break; + } + return QRect(); +} + +void QStyleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + if (width() < 1 || height() <1) + return; + + initStyleOption(); + + if (widget()) { + painter->save(); + painter->setFont(widget()->font()); + painter->translate(-m_styleoption->rect.left() + m_paintMargins, 0); + } + + switch (m_itemType) { + case Button: + qApp->style()->drawControl(QStyle::CE_PushButton, m_styleoption, painter, widget()); + break; + case ItemRow :{ + QPixmap pixmap; + // Only draw through style once + const QString pmKey = QLatin1Literal("itemrow") % QString::number(m_styleoption->state,16) % activeControl(); + if (!QPixmapCache::find(pmKey, pixmap) || pixmap.width() < width() || height() != pixmap.height()) { + int newSize = width(); + pixmap = QPixmap(newSize, height()); + pixmap.fill(Qt::transparent); + QPainter pixpainter(&pixmap); + qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, m_styleoption, &pixpainter, widget()); + if (!qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected) && selected()) + pixpainter.fillRect(m_styleoption->rect, m_styleoption->palette.highlight()); + QPixmapCache::insert(pmKey, pixmap); + } + painter->drawPixmap(0, 0, pixmap); + } + break; + case Item: + qApp->style()->drawControl(QStyle::CE_ItemViewItem, m_styleoption, painter, widget()); + break; + case Header: + widget()->resize(m_styleoption->rect.size()); // macstyle explicitly uses the widget height + qApp->style()->drawControl(QStyle::CE_Header, m_styleoption, painter, widget()); + break; + case ToolButton: + qApp->style()->drawComplexControl(QStyle::CC_ToolButton, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget()); + break; + case Tab: + qApp->style()->drawControl(QStyle::CE_TabBarTab, m_styleoption, painter, widget()); + break; + case Frame: + qApp->style()->drawControl(QStyle::CE_ShapedFrame, m_styleoption, painter, widget()); + break; + case FocusFrame: + qApp->style()->drawControl(QStyle::CE_FocusFrame, m_styleoption, painter, widget()); + break; + case TabFrame: + qApp->style()->drawPrimitive(QStyle::PE_FrameTabWidget, m_styleoption, painter, widget()); + break; + case MenuItem: + case ComboBoxItem: // fall through + qApp->style()->drawControl(QStyle::CE_MenuItem, m_styleoption, painter, widget()); + break; + case CheckBox: + qApp->style()->drawControl(QStyle::CE_CheckBox, m_styleoption, painter, widget()); + break; + case RadioButton: + qApp->style()->drawControl(QStyle::CE_RadioButton, m_styleoption, painter, widget()); + break; + case Edit: + qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, m_styleoption, painter, widget()); + break; + case Widget: + qApp->style()->drawPrimitive(QStyle::PE_Widget, m_styleoption, painter, widget()); + break; + case Splitter: + qApp->style()->drawControl(QStyle::CE_Splitter, m_styleoption, painter, widget()); + break; + case ComboBox: + qApp->style()->drawComplexControl(QStyle::CC_ComboBox, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + painter, widget()); + qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, m_styleoption, painter, widget()); + break; + case SpinBox: + qApp->style()->drawComplexControl(QStyle::CC_SpinBox, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + painter, widget()); + break; + case Slider: + qApp->style()->drawComplexControl(QStyle::CC_Slider, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + painter, widget()); + break; + case Dial: + qApp->style()->drawComplexControl(QStyle::CC_Dial, + qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), + painter, widget()); + break; + case ProgressBar: + qApp->style()->drawControl(QStyle::CE_ProgressBar, m_styleoption, painter, widget()); + break; + case ToolBar: + qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter, widget()); + break; + case GroupBox: + qApp->style()->drawComplexControl(QStyle::CC_GroupBox, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget()); + break; + case ScrollBar: + qApp->style()->drawComplexControl(QStyle::CC_ScrollBar, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget()); + break; + case Menu: { + if (QMenu *menu = qobject_cast<QMenu*>(widget())) { + m_styleoption->palette = menu->palette(); + } + QStyleHintReturnMask val; + qApp->style()->styleHint(QStyle::SH_Menu_Mask, m_styleoption, widget(), &val); + painter->save(); + painter->setClipRegion(val.region); + painter->fillRect(m_styleoption->rect, m_styleoption->palette.window()); + painter->restore(); + qApp->style()->drawPrimitive(QStyle::PE_PanelMenu, m_styleoption, painter, widget()); + + QStyleOptionFrame frame; + frame.lineWidth = qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth); + frame.midLineWidth = 0; + frame.rect = m_styleoption->rect; + qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter, widget()); + } + break; + default: + break; + } + if (widget()) + painter->restore(); +} + +int QStyleItem::textWidth(const QString &text) +{ + if (widget()) + return widget()->fontMetrics().boundingRect(text).width(); + return qApp->fontMetrics().boundingRect(text).width(); +} + +int QStyleItem::fontHeight() +{ + if (widget()) + return widget()->fontMetrics().height(); + return qApp->fontMetrics().height(); +} + +QString QStyleItem::fontFamily() +{ + if (widget()) + return widget()->font().family(); + return qApp->font().family(); +} + +double QStyleItem::fontPointSize() +{ + if (widget()) + return widget()->font().pointSizeF(); + return qApp->font().pointSizeF(); +} diff --git a/src/styleitem/qstyleitem.h b/src/styleitem/qstyleitem.h new file mode 100644 index 00000000..166b39fa --- /dev/null +++ b/src/styleitem/qstyleitem.h @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STYLEWRAPPER_H +#define STYLEWRAPPER_H + +#include <QDeclarativeItem> +#include <QtGui/QStyle> +#include <QtGui> +#include <QEvent> + +class QStyleItem: public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY( bool sunken READ sunken WRITE setSunken NOTIFY sunkenChanged) + Q_PROPERTY( bool raised READ raised WRITE setRaised NOTIFY raisedChanged) + Q_PROPERTY( bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY( bool selected READ selected WRITE setSelected NOTIFY selectedChanged) + Q_PROPERTY( bool focus READ focus WRITE setFocus NOTIFY focusChanged) + Q_PROPERTY( bool on READ on WRITE setOn NOTIFY onChanged) + Q_PROPERTY( bool hover READ hover WRITE setHover NOTIFY hoverChanged) + Q_PROPERTY( bool horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged) + + Q_PROPERTY( QString elementType READ elementType WRITE setElementType NOTIFY elementTypeChanged) + Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY( QString activeControl READ activeControl WRITE setActiveControl NOTIFY activeControlChanged) + Q_PROPERTY( QString info READ info WRITE setInfo NOTIFY infoChanged) + Q_PROPERTY( QString style READ style NOTIFY styleChanged) + Q_PROPERTY( QString hint READ hint WRITE setHint NOTIFY hintChanged) + Q_PROPERTY( QString cursor READ cursor WRITE setCursor NOTIFY cursorChanged) + + // For range controls + Q_PROPERTY( int minimum READ minimum WRITE setMinimum NOTIFY minimumChanged) + Q_PROPERTY( int maximum READ maximum WRITE setMaximum NOTIFY maximumChanged) + Q_PROPERTY( int value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY( int step READ step WRITE setStep NOTIFY stepChanged) + Q_PROPERTY( int paintMargins READ paintMargins WRITE setPaintMargins NOTIFY paintMarginsChanged) + + Q_PROPERTY( QString fontFamily READ fontFamily) + Q_PROPERTY( double fontPointSize READ fontPointSize) + Q_PROPERTY( int fontHeight READ fontHeight NOTIFY fontHeightChanged) + +public: + enum Type { + Undefined, + Button, + RadioButton, + CheckBox, + ComboBox, + ComboBoxItem, + Dial, + ToolBar, + ToolButton, + Tab, + TabFrame, + Frame, + FocusFrame, + SpinBox, + Slider, + ScrollBar, + ProgressBar, + Edit, + GroupBox, + Header, + Item, + ItemRow, + Splitter, + Menu, + MenuItem, + Widget + }; + + QStyleItem(QDeclarativeItem *parent = 0); + ~QStyleItem(); + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + + bool sunken() const { return m_sunken; } + bool raised() const { return m_raised; } + bool active() const { return m_active; } + bool selected() const { return m_selected; } + bool focus() const { return m_focus; } + bool on() const { return m_on; } + bool hover() const { return m_hover; } + bool horizontal() const { return m_horizontal; } + + int minimum() const { return m_minimum; } + int maximum() const { return m_maximum; } + int step() const { return m_step; } + int value() const { return m_value; } + int paintMargins() const { return m_paintMargins; } + + QString elementType() const { return m_type; } + QString text() const { return m_text; } + QString cursor() const { return m_cursor; } + QString activeControl() const { return m_activeControl; } + QString info() const { return m_info; } + QString hint() const { return m_hint; } + QString style() const; + + void setSunken(bool sunken) { if (m_sunken != sunken) {m_sunken = sunken; emit sunkenChanged();}} + void setRaised(bool raised) { if (m_raised!= raised) {m_raised = raised; emit raisedChanged();}} + void setActive(bool active) { if (m_active!= active) {m_active = active; emit activeChanged();}} + void setSelected(bool selected) { if (m_selected!= selected) {m_selected = selected; emit selectedChanged();}} + void setFocus(bool focus) { if (m_focus != focus) {m_focus = focus; emit focusChanged();}} + void setOn(bool on) { if (m_on != on) {m_on = on ; emit onChanged();}} + void setHover(bool hover) { if (m_hover != hover) {m_hover = hover ; emit hoverChanged();}} + void setHorizontal(bool horizontal) { if (m_horizontal != horizontal) {m_horizontal = horizontal; emit horizontalChanged();}} + void setMinimum(int minimum) { if (m_minimum!= minimum) {m_minimum = minimum; emit minimumChanged();}} + void setMaximum(int maximum) { if (m_maximum != maximum) {m_maximum = maximum; emit maximumChanged();}} + void setValue(int value) { if (m_value!= value) {m_value = value; emit valueChanged();}} + void setStep(int step) { if (m_step != step) { m_step = step; emit stepChanged(); }} + void setPaintMargins(int value) { + Q_UNUSED(value) +#ifdef Q_WS_WIN //only vista style needs this hack + if (m_paintMargins!= value) {m_paintMargins = value;} +#endif + } + void setCursor(const QString &str); + void setElementType(const QString &str); + void setText(const QString &str) { if (m_text != str) {m_text = str; emit textChanged();}} + void setActiveControl(const QString &str) { if (m_activeControl != str) {m_activeControl = str; emit activeControlChanged();}} + void setInfo(const QString &str) { if (m_info != str) {m_info = str; emit infoChanged();}} + void setHint(const QString &str) { if (m_hint != str) {m_hint= str; emit hintChanged();}} + + bool eventFilter(QObject *, QEvent *); + virtual void initStyleOption (); + QWidget *widget(){ return m_dummywidget; } + + int fontHeight(); + QString fontFamily(); + double fontPointSize(); + + +public Q_SLOTS: + int pixelMetric(const QString&); + QVariant styleHint(const QString&); + QSize sizeFromContents(int width, int height); + void updateItem(){update();} + QString hitTest(int x, int y); + QRect subControlRect(const QString &subcontrolString); + void showToolTip(const QString &str); + int textWidth(const QString &); + +Q_SIGNALS: + void elementTypeChanged(); + void textChanged(); + void sunkenChanged(); + void raisedChanged(); + void activeChanged(); + void selectedChanged(); + void focusChanged(); + void onChanged(); + void hoverChanged(); + void horizontalChanged(); + void minimumChanged(); + void maximumChanged(); + void stepChanged(); + void valueChanged(); + void activeControlChanged(); + void infoChanged(); + void styleChanged(); + void paintMarginsChanged(); + void hintChanged(); + void cursorChanged(); + void fontHeightChanged(); + +protected: + QWidget *m_dummywidget; + QStyleOption *m_styleoption; + Type m_itemType; + + QString m_type; + QString m_cursor; + QString m_text; + QString m_activeControl; + QString m_info; + QString m_hint; + + bool m_sunken; + bool m_raised; + bool m_active; + bool m_selected; + bool m_focus; + bool m_hover; + bool m_on; + bool m_horizontal; + bool m_sharedWidget; + + int m_minimum; + int m_maximum; + int m_value; + int m_step; + int m_paintMargins; +}; + +#endif //STYLEWRAPPER_H diff --git a/src/styleitem/qstyleplugin.cpp b/src/styleitem/qstyleplugin.cpp new file mode 100644 index 00000000..0f308c21 --- /dev/null +++ b/src/styleitem/qstyleplugin.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qdeclarative.h> +#include "qstyleplugin.h" +#include "qstyleitem.h" +#include "qrangemodel.h" +#include "qtmenu.h" +#include "qtmenubar.h" +#include "qtmenuitem.h" +#include "qwheelarea.h" +#include <qdeclarativeextensionplugin.h> + +#include <qdeclarativeengine.h> +#include <qdeclarative.h> +#include <qdeclarativeitem.h> +#include <qdeclarativeimageprovider.h> +#include <qdeclarativeview.h> +#include <QApplication> +#include <QImage> + +// Load icons from desktop theme +class DesktopIconProvider : public QDeclarativeImageProvider +{ +public: + DesktopIconProvider() + : QDeclarativeImageProvider(QDeclarativeImageProvider::Pixmap) + { + } + + QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) + { + Q_UNUSED(requestedSize); + Q_UNUSED(size); + int pos = id.lastIndexOf('/'); + QString iconName = id.right(id.length() - pos); + int width = qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize); + return QIcon::fromTheme(iconName).pixmap(width); + } +}; + + +void StylePlugin::registerTypes(const char *uri) +{ + qDebug() << "register" << uri; + qmlRegisterType<QStyleItem>(uri, 0, 1, "QStyleItem"); + qmlRegisterType<QRangeModel>(uri, 0, 1, "RangeModel"); + qmlRegisterType<QGraphicsDropShadowEffect>(uri, 0, 1, "DropShadow"); + qmlRegisterType<QDeclarativeFolderListModel>(uri, 0, 1, "FileSystemModel"); + qmlRegisterType<QWheelArea>(uri, 0, 1, "WheelArea"); + qmlRegisterType<QtMenu>(uri, 0, 1, "MenuBase"); + qmlRegisterType<QtMenuBar>(uri, 0, 1, "MenuBarBase"); + qmlRegisterType<QtMenuItem>(uri, 0, 1, "MenuItemBase"); +} + +void StylePlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri) +{ + Q_UNUSED(uri); + engine->addImageProvider("desktoptheme", new DesktopIconProvider); +} + +Q_EXPORT_PLUGIN2(styleplugin, StylePlugin); diff --git a/src/styleitem/qstyleplugin.h b/src/styleitem/qstyleplugin.h new file mode 100644 index 00000000..648add70 --- /dev/null +++ b/src/styleitem/qstyleplugin.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STYLEPLUGIN_H +#define STYLEPLUGIN_H + +#include <QDeclarativeExtensionPlugin> +#include <QtScript/QScriptValue> +#include <QtCore/QTimer> +#include <QFileSystemModel> +#include "qdeclarativefolderlistmodel.h" + + +class StylePlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + void registerTypes(const char *uri); + void initializeEngine(QDeclarativeEngine *engine, const char *uri); +}; + +#endif // STYLEPLUGIN_H diff --git a/src/styleitem/qtmenu.cpp b/src/styleitem/qtmenu.cpp new file mode 100644 index 00000000..e7fa3706 --- /dev/null +++ b/src/styleitem/qtmenu.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** 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 Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#include "qtmenu.h" +#include "qdebug.h" +#include <qapplication.h> + +QtMenu::QtMenu(QDeclarativeItem *parent) + : QDeclarativeItem(parent), m_selectedIndex(0), m_highlightedIndex(0) +{ + m_menu = new QMenu(0); + connect(m_menu, SIGNAL(aboutToHide()), this, SIGNAL(menuClosed())); +} + +QtMenu::~QtMenu() +{ + delete m_menu; +} + +void QtMenu::setTitle(const QString &title) +{ + m_title = title; +} + +QString QtMenu::title() const +{ + return m_title; +} + +void QtMenu::setSelectedIndex(int index) +{ + m_selectedIndex = index; + QList<QAction *> actionList = m_menu->actions(); + if (m_selectedIndex >= 0 && m_selectedIndex < actionList.size()) + m_menu->setActiveAction(actionList[m_selectedIndex]); + emit selectedIndexChanged(); +} + +void QtMenu::setHoveredIndex(int index) +{ + m_highlightedIndex = index; + QList<QAction *> actionList = m_menu->actions(); + if (m_highlightedIndex >= 0 && m_highlightedIndex < actionList.size()) + m_menu->setActiveAction(actionList[m_highlightedIndex]); + emit hoveredIndexChanged(); +} + +QDeclarativeListProperty<QtMenuItem> QtMenu::menuItems() +{ + return QDeclarativeListProperty<QtMenuItem>(this, m_menuItems); +} + +void QtMenu::closePopup() +{ + m_menu->close(); +} + +void QtMenu::showPopup(qreal x, qreal y, int atActionIndex) +{ + if (m_menu->isVisible()) + return; + + // If atActionIndex is valid, x and y is specified from the + // the position of the corresponding QAction: + QAction *atAction = 0; + if (atActionIndex >= 0 && atActionIndex < m_menu->actions().size()) + atAction = m_menu->actions()[atActionIndex]; + + // x,y are in view coordinates, QMenu expects screen coordinates + // ### activeWindow hack + QPoint screenPosition = QApplication::activeWindow()->mapToGlobal(QPoint(x, y)); + + setHoveredIndex(m_selectedIndex); + m_menu->popup(screenPosition, atAction); +} + +void QtMenu::clearMenuItems() +{ + m_menu->clear(); +} + +void QtMenu::addMenuItem(const QString &text) +{ + QAction *action = new QAction(text, m_menu); + connect(action, SIGNAL(triggered()), this, SLOT(emitSelected())); + connect(action, SIGNAL(hovered()), this, SLOT(emitHovered())); + m_menu->insertAction(0, action); + + if (m_menu->actions().size() == 1) + // Inform QML that the selected action (0) now has changed contents: + emit selectedIndexChanged(); +} + +QString QtMenu::itemTextAt(int index) const +{ + QList<QAction *> actionList = m_menu->actions(); + if (index >= 0 && index < actionList.size()) + return actionList[index]->text(); + else + return ""; +} + +void QtMenu::emitSelected() +{ + QAction *act = qobject_cast<QAction *>(sender()); + if (!act) + return; + m_selectedIndex = m_menu->actions().indexOf(act); + emit selectedIndexChanged(); +} + +void QtMenu::emitHovered() +{ + QAction *act = qobject_cast<QAction *>(sender()); + if (!act) + return; + m_highlightedIndex = m_menu->actions().indexOf(act); + emit hoveredIndexChanged(); +} + diff --git a/src/styleitem/qtmenu.h b/src/styleitem/qtmenu.h new file mode 100644 index 00000000..17abc383 --- /dev/null +++ b/src/styleitem/qtmenu.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QTMLMENU_H +#define QTMLMENU_H + +#include <QtGui/qmenu.h> +#include <QtDeclarative/qdeclarative.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtDeclarative/QDeclarativeListProperty> +#include "qtmenuitem.h" +class QtMenu : public QDeclarativeItem +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle) + Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectedIndexChanged) + Q_PROPERTY(int hoveredIndex READ hoveredIndex WRITE setHoveredIndex NOTIFY hoveredIndexChanged) + + // The only reason we declare a list of menu items here, is so we can make it a default + // property from within QML, if needed. The reason we don't implement the code for using + // the list here, is that we expect the QML code to mix both ListModel and MenuItems API for + // adding menu items. And we don't wan't to decide how to mix those two API-s from here. So the only + // API in his class will be 'addMenuItem' and 'clearMenuItems'. + Q_PROPERTY(QDeclarativeListProperty<QtMenuItem> menuItems READ menuItems NOTIFY menuItemsChanged) + Q_CLASSINFO("DefaultProperty", "menuItems") +public: + QtMenu(QDeclarativeItem *parent = 0); + virtual ~QtMenu(); + + void setTitle(const QString &title); + QString title() const; + int selectedIndex() const { return m_selectedIndex; } + void setSelectedIndex(int index); + int hoveredIndex() const { return m_highlightedIndex; } + void setHoveredIndex(int index); + QDeclarativeListProperty<QtMenuItem> menuItems(); + + Q_INVOKABLE void showPopup(qreal x, qreal y, int atActionIndex = -1); + Q_INVOKABLE void closePopup(); + Q_INVOKABLE void clearMenuItems(); + Q_INVOKABLE void addMenuItem(const QString &text); + Q_INVOKABLE QString itemTextAt(int index) const; + +Q_SIGNALS: + void selectedIndexChanged(); + void hoveredIndexChanged(); + void menuClosed(); + void menuItemsChanged(); +private Q_SLOTS: + void emitSelected(); + void emitHovered(); +private: + QString m_title; + int m_selectedIndex; + int m_highlightedIndex; + QWidget *dummy; + QMenu *m_menu; + QList<QtMenuItem *> m_menuItems; +}; + +QML_DECLARE_TYPE(QtMenu) + +#endif // QTMLMENU_H diff --git a/src/styleitem/qtmenubar.cpp b/src/styleitem/qtmenubar.cpp new file mode 100644 index 00000000..7257795a --- /dev/null +++ b/src/styleitem/qtmenubar.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtmenubar.h" + +#include <QtGui/QMenu> + +QtMenuBar::QtMenuBar(QDeclarativeItem *parent) + : QDeclarativeItem(parent) +{ + setFlag(QGraphicsItem::ItemHasNoContents, false); +} + +QtMenuBar::~QtMenuBar() +{ +} + +QDeclarativeListProperty<QtMenu> QtMenuBar::menus() +{ + return QDeclarativeListProperty<QtMenu>(this, m_menus); +} diff --git a/src/styleitem/qtmenubar.h b/src/styleitem/qtmenubar.h new file mode 100644 index 00000000..4c402b85 --- /dev/null +++ b/src/styleitem/qtmenubar.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMENUBAR_H +#define QTMENUBAR_H + +#include <QDeclarativeItem> +#include <QtGui> + +#include "qtmenu.h" + +class QtMenuBar: public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QDeclarativeListProperty<QtMenu> menus READ menus) +public: + QtMenuBar(QDeclarativeItem *parent = 0); + ~QtMenuBar(); + + QDeclarativeListProperty<QtMenu> menus(); + + //void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + +private: + QList<QtMenu *> m_menus; +}; + +#endif //QTMENUBAR_H diff --git a/src/styleitem/qtmenuitem.cpp b/src/styleitem/qtmenuitem.cpp new file mode 100644 index 00000000..902db5f3 --- /dev/null +++ b/src/styleitem/qtmenuitem.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtmenuitem.h" + +QtMenuItem::QtMenuItem(QObject *parent) + : QObject(parent) +{ + +} + +QtMenuItem::~QtMenuItem() +{ +} + +void QtMenuItem::setText(const QString &text) +{ + m_text = text; + emit textChanged(); +} + +QString QtMenuItem::text() +{ + return m_text; +} diff --git a/src/styleitem/qtmenuitem.h b/src/styleitem/qtmenuitem.h new file mode 100644 index 00000000..4bc60409 --- /dev/null +++ b/src/styleitem/qtmenuitem.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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 examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMENUITEM_H +#define QTMENUITEM_H + +#include <QtCore/QObject> + +class QtMenuItem: public QObject +{ + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + + Q_OBJECT +public: + QtMenuItem(QObject *parent = 0); + ~QtMenuItem(); + + void setText(const QString &text); + QString text(); + + Q_INVOKABLE void emitHovered() { emit hovered(); } + Q_INVOKABLE void emitSelected() { emit selected(); } + +Q_SIGNALS: + void selected(); + void hovered(); + void textChanged(); + +private: + QString m_text; +}; + +#endif //QTMENUITEM_H diff --git a/src/styleitem/qwheelarea.cpp b/src/styleitem/qwheelarea.cpp new file mode 100644 index 00000000..1a7ae9e6 --- /dev/null +++ b/src/styleitem/qwheelarea.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qwheelarea.h" + + +QWheelArea::QWheelArea(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + _horizontalMinimumValue(0), + _horizontalMaximumValue(0), + _verticalMinimumValue(0), + _verticalMaximumValue(0), + _horizontalValue(0), + _verticalValue(0), + _verticalDelta(0), + _horizontalDelta(0) +{} + +QWheelArea::~QWheelArea() {} + +bool QWheelArea::event (QEvent * e) { + switch(e->type()) { + case QEvent::GraphicsSceneWheel: { + QGraphicsSceneWheelEvent *we = static_cast<QGraphicsSceneWheelEvent*>(e); + if(we) { + switch(we->orientation()) { + case Qt::Horizontal: + setHorizontalDelta(we->delta()); + break; + case Qt::Vertical: + setVerticalDelta(we->delta()); + } + return true; + } + } + case QEvent::Wheel: { + QWheelEvent *we = static_cast<QWheelEvent*>(e); + if(we) { + switch(we->orientation()) { + case Qt::Horizontal: + setHorizontalDelta(we->delta()); + + break; + case Qt::Vertical: + setVerticalDelta(we->delta()); + + } + return true; + } + } + default: break; + } + return QDeclarativeItem::event(e); +} + +void QWheelArea::setHorizontalMinimumValue(qreal min) +{ + _horizontalMinimumValue = min; +} + +qreal QWheelArea::horizontalMinimumValue() const +{ + return _horizontalMinimumValue; +} + +void QWheelArea::setHorizontalMaximumValue(qreal max) +{ + _horizontalMaximumValue = max; +} +qreal QWheelArea::horizontalMaximumValue() const +{ + return _horizontalMaximumValue; +} + +void QWheelArea::setVerticalMinimumValue(qreal min) +{ + _verticalMinimumValue = min; +} + +qreal QWheelArea::verticalMinimumValue() const +{ + return _verticalMinimumValue; +} + +void QWheelArea::setVerticalMaximumValue(qreal max) +{ + _verticalMaximumValue = max; +} + +qreal QWheelArea::verticalMaximumValue() const +{ + return _verticalMaximumValue; +} + +void QWheelArea::setHorizontalValue(qreal val) +{ + if (val > _horizontalMaximumValue) + _horizontalValue = _horizontalMaximumValue; + else if (val < _horizontalMinimumValue) + _horizontalValue = _horizontalMinimumValue; + else + _horizontalValue = val; + emit(horizontalValueChanged()); +} + +qreal QWheelArea::horizontalValue() const +{ + return _horizontalValue; +} + +void QWheelArea::setVerticalValue(qreal val) +{ + if (val > _verticalMaximumValue) + _verticalValue = _verticalMaximumValue; + else if (val < _verticalMinimumValue) + _verticalValue = _verticalMinimumValue; + else + _verticalValue = val; + emit(verticalValueChanged()); +} + +qreal QWheelArea::verticalValue() const +{ + return _verticalValue; +} + +void QWheelArea::setVerticalDelta(qreal d) +{ + _verticalDelta = d/15; + setVerticalValue(_verticalValue - _verticalDelta); + emit(verticalWheelMoved()); +} + +qreal QWheelArea::verticalDelta() const +{ + return _verticalDelta; +} + +void QWheelArea::setHorizontalDelta(qreal d) +{ + _horizontalDelta = d/15; + setHorizontalValue(_horizontalValue - _horizontalDelta); + emit(horizontalWheelMoved()); +} + +qreal QWheelArea::horizontalDelta() const +{ + return _horizontalDelta; +} diff --git a/src/styleitem/qwheelarea.h b/src/styleitem/qwheelarea.h new file mode 100644 index 00000000..f1d7016a --- /dev/null +++ b/src/styleitem/qwheelarea.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions contained +** in the Technology Preview License Agreement accompanying this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QWHEELAREA_H +#define QWHEELAREA_H + + +#include <QtCore/qobject.h> +#include <QtDeclarative/qdeclarative.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtCore/qcoreevent.h> +#include <QtGui/qevent.h> +#include <QtGui/qgraphicssceneevent.h> + +class QWheelArea : public QDeclarativeItem +{ + Q_OBJECT + Q_PROPERTY(qreal verticalDelta READ verticalDelta WRITE setVerticalDelta NOTIFY verticalWheelMoved) + Q_PROPERTY(qreal horizontalDelta READ horizontalDelta WRITE setHorizontalDelta NOTIFY horizontalWheelMoved) + Q_PROPERTY(qreal horizontalMinimumValue READ horizontalMinimumValue WRITE setHorizontalMinimumValue) + Q_PROPERTY(qreal horizontalMaximumValue READ horizontalMaximumValue WRITE setHorizontalMaximumValue) + Q_PROPERTY(qreal verticalMinimumValue READ verticalMinimumValue WRITE setVerticalMinimumValue) + Q_PROPERTY(qreal verticalMaximumValue READ verticalMaximumValue WRITE setVerticalMaximumValue) + Q_PROPERTY(qreal horizontalValue READ horizontalValue WRITE setHorizontalValue) + Q_PROPERTY(qreal verticalValue READ verticalValue WRITE setVerticalValue) + + +public: + QWheelArea(QDeclarativeItem *parent = 0); + + virtual ~QWheelArea(); + + virtual bool event (QEvent * e); + + void setHorizontalMinimumValue(qreal min); + qreal horizontalMinimumValue() const; + + void setHorizontalMaximumValue(qreal min); + qreal horizontalMaximumValue() const; + + void setVerticalMinimumValue(qreal min); + qreal verticalMinimumValue() const; + + void setVerticalMaximumValue(qreal min); + qreal verticalMaximumValue() const; + + void setHorizontalValue(qreal val); + qreal horizontalValue() const; + + void setVerticalValue(qreal val); + qreal verticalValue() const; + + void setVerticalDelta(qreal d); + qreal verticalDelta() const; + + void setHorizontalDelta(qreal d); + qreal horizontalDelta() const; + +Q_SIGNALS: + void verticalValueChanged(); + void horizontalValueChanged(); + void verticalWheelMoved(); + void horizontalWheelMoved(); + +private: + qreal _horizontalMinimumValue; + qreal _horizontalMaximumValue; + qreal _verticalMinimumValue; + qreal _verticalMaximumValue; + qreal _horizontalValue; + qreal _verticalValue; + qreal _verticalDelta; + qreal _horizontalDelta; + + Q_DISABLE_COPY(QWheelArea) +}; + +QML_DECLARE_TYPE(QWheelArea) + + +#endif // QWHEELAREA_H diff --git a/src/styleitem/styleitem.pro b/src/styleitem/styleitem.pro new file mode 100644 index 00000000..a05848e9 --- /dev/null +++ b/src/styleitem/styleitem.pro @@ -0,0 +1,45 @@ +TEMPLATE = lib +CONFIG += qt plugin +QT += declarative +QT += script + +TARGET = styleplugin + +DESTDIR = ../../components/plugin +OBJECTS_DIR = obj +MOC_DIR = moc + +HEADERS += qtmenu.h \ + qtmenubar.h \ + qtmenuitem.h \ + qrangemodel_p.h \ + qrangemodel.h \ + qstyleplugin.h \ + qdeclarativefolderlistmodel.h \ + qstyleitem.h \ + qwheelarea.h + +SOURCES += qtmenu.cpp \ + qtmenubar.cpp \ + qtmenuitem.cpp \ + qrangemodel.cpp \ + qstyleplugin.cpp \ + qdeclarativefolderlistmodel.cpp \ + qstyleitem.cpp \ + qwheelarea.cpp + +TARGETPATH = QtDesktop/plugin + +symbian { + INSTALL_IMPORTS = /resource/qt/imports +} else { + INSTALL_IMPORTS = $$[QT_INSTALL_IMPORTS] +} + +target.path = $$INSTALL_IMPORTS/$$TARGETPATH + +INSTALLS += target + +symbian { + DEPLOYMENT += target +}
\ No newline at end of file |