summaryrefslogtreecommitdiff
path: root/src/plugins/qmldesigner/components
diff options
context:
space:
mode:
authorJörg Schummer <ext-jorg.2.schummer@nokia.com>2010-02-16 17:24:18 +0200
committerKai Koehne <kai.koehne@nokia.com>2010-02-16 16:39:32 +0100
commit2791cfbdd1d8c7a1c1d9201ae95e7ea3b4fa43de (patch)
treea51e8a9abd75b454fbeb671f5ae089d91b9f475f /src/plugins/qmldesigner/components
parent6585742fc7fe9fe8453204558ce0d910b230396a (diff)
downloadqt-creator-2791cfbdd1d8c7a1c1d9201ae95e7ea3b4fa43de.tar.gz
QmlDesigner.ItemLibrary: integrated the new Qml-based item library
Task-number: BAUHAUS-204 Task-number: BAUHAUS-207 Task-number: BAUHAUS-339 Task-number: BAUHAUS-365 Task-number: BAUHAUS-374 Reviewed-by: kkoehne
Diffstat (limited to 'src/plugins/qmldesigner/components')
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h5
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png (renamed from src/plugins/qmldesigner/components/itemlibrary/default-icon.png)bin341 -> 341 bytes
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp293
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h24
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri5
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc12
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui278
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp573
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h162
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp109
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h66
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml87
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml144
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml34
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml151
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml151
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml140
17 files changed, 1708 insertions, 526 deletions
diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
index e200d8427e..0daca6b5c7 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
@@ -121,6 +121,11 @@ class CustomItemLibraryDrag : public QDrag {
void exec()
{ QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::startCustomDrag(m_pixmap, m_preview, m_mimeData); }
+ public slots:
+ void stopDrag() {
+ QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::endCustomDrag();
+ }
+
private:
QPixmap m_pixmap, m_preview;
QMimeData *m_mimeData;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/default-icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png
index a90779f02a..a90779f02a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/default-icon.png
+++ b/src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png
Binary files differ
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
index d778c56f8e..da5f34c4e0 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
@@ -52,6 +52,11 @@
#include <QFile>
#include <QDirModel>
#include <QFileIconProvider>
+#include <QImageReader>
+
+#include <QmlView>
+#include <QmlGraphicsItem>
+#include <private/qmlengine_p.h>
namespace QmlDesigner {
@@ -59,119 +64,127 @@ namespace QmlDesigner {
class MyFileIconProvider : public QFileIconProvider
{
public:
- MyFileIconProvider() : QFileIconProvider()
+ MyFileIconProvider(const QSize &iconSize)
+ : QFileIconProvider(),
+ m_iconSize(iconSize)
{}
+
virtual QIcon icon ( const QFileInfo & info ) const
{
QPixmap pixmap(info.absoluteFilePath());
- if (pixmap.isNull())
- return QFileIconProvider::icon(info);
- else return pixmap; //pixmap.scaled(128, 128, Qt::KeepAspectRatio);
- }
-};
-
-
+ if (pixmap.isNull()) {
+ QIcon defaultIcon(QFileIconProvider::icon(info));
+ pixmap = defaultIcon.pixmap(defaultIcon.actualSize(m_iconSize));
+ }
-class GrabHelper {
- Q_DISABLE_COPY(GrabHelper)
-public:
- GrabHelper();
- QPixmap grabItem(QGraphicsItem *item);
+ if (pixmap.width() == m_iconSize.width()
+ && pixmap.height() == m_iconSize.height())
+ return pixmap;
+
+ if ((pixmap.width() > m_iconSize.width())
+ || (pixmap.height() > m_iconSize.height()))
+ return pixmap.scaled(m_iconSize, Qt::KeepAspectRatio);
+
+ QPoint offset((m_iconSize.width() - pixmap.width()) / 2,
+ (m_iconSize.height() - pixmap.height()) / 2);
+ QImage newIcon(m_iconSize, QImage::Format_ARGB32_Premultiplied);
+ newIcon.fill(Qt::transparent);
+ QPainter painter(&newIcon);
+ painter.drawPixmap(offset, pixmap);
+ return QPixmap::fromImage(newIcon);
+ }
private:
- QGraphicsScene m_scene;
- QGraphicsView m_view;
+ QSize m_iconSize;
};
-GrabHelper::GrabHelper()
-{
- m_view.setScene(&m_scene);
- m_view.setFrameShape(QFrame::NoFrame);
- m_view.setAlignment(Qt::AlignLeft|Qt::AlignTop);
- m_view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- m_view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-}
-
-QPixmap GrabHelper::grabItem(QGraphicsItem *item)
-{
- if (item->scene()) {
- qWarning("%s: WARNING: Attempt to grab item that is part of another scene!", Q_FUNC_INFO);
- return QPixmap();
- }
- // Temporarily add the item, resize the view widget and grab it.
- m_scene.addItem(item);
- item->setPos(0.0, 0.0);
- const QSize size = item->boundingRect().size().toSize();
- QPixmap rc;
- if (!size.isEmpty()) { // We have seen horses barf...
- m_view.resize(size);
- rc = QPixmap::grabWidget(&m_view);
- }
- m_scene.removeItem(item);
- return rc;
-}
// ---------- ItemLibraryPrivate
class ItemLibraryPrivate {
public:
ItemLibraryPrivate(QObject *object);
- ~ItemLibraryPrivate();
Ui::ItemLibrary m_ui;
Internal::ItemLibraryModel *m_itemLibraryModel;
+ QmlView *m_itemsView;
QDirModel *m_resourcesDirModel;
- QSortFilterProxyModel *m_filterProxy;
- GrabHelper *m_grabHelper;
QString m_resourcePath;
+ QSize m_itemIconSize, m_resIconSize;
+ MyFileIconProvider m_iconProvider;
};
ItemLibraryPrivate::ItemLibraryPrivate(QObject *object) :
m_itemLibraryModel(0),
- m_grabHelper(0)
+ m_itemsView(0),
+ m_itemIconSize(32, 32),
+ m_resIconSize(32, 32),
+ m_iconProvider(m_resIconSize)
{
m_resourcePath = QDir::currentPath();
Q_UNUSED(object);
}
-ItemLibraryPrivate::~ItemLibraryPrivate()
-{
- delete m_grabHelper;
-}
-
ItemLibrary::ItemLibrary(QWidget *parent) :
QFrame(parent),
m_d(new ItemLibraryPrivate(this))
{
m_d->m_ui.setupUi(this);
- m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(this);
+ layout()->setContentsMargins(3, 3, 3, 3);
+ layout()->setSpacing(3);
+
m_d->m_resourcesDirModel = new QDirModel(this);
- m_d->m_filterProxy = new QSortFilterProxyModel(this);
- m_d->m_filterProxy->setSourceModel(m_d->m_itemLibraryModel);
- m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_filterProxy);
- m_d->m_filterProxy->setDynamicSortFilter(true);
- m_d->m_ui.ItemLibraryTreeView->setRealModel(m_d->m_itemLibraryModel);
- m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(64, 64));
+
+ m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_resourcesDirModel);
+ m_d->m_ui.ItemLibraryTreeView->setIconSize(m_d->m_resIconSize);
+ m_d->m_ui.ItemLibraryTreeView->setColumnHidden(1, true);
+ m_d->m_ui.ItemLibraryTreeView->setColumnHidden(2, true);
+ m_d->m_ui.ItemLibraryTreeView->setColumnHidden(3, true);
m_d->m_ui.ItemLibraryTreeView->setSortingEnabled(true);
m_d->m_ui.ItemLibraryTreeView->setHeaderHidden(true);
m_d->m_ui.ItemLibraryTreeView->setIndentation(10);
- m_d->m_ui.ItemLibraryTreeView->setAnimated(true);
m_d->m_ui.ItemLibraryTreeView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_d->m_ui.ItemLibraryTreeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_d->m_ui.ItemLibraryTreeView->setAttribute(Qt::WA_MacShowFocusRect, false);
- m_d->m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_d->m_filterProxy->setFilterRole(Qt::UserRole);
- m_d->m_filterProxy->setSortRole(Qt::DisplayRole);
- connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), m_d->m_filterProxy, SLOT(setFilterRegExp(QString)));
- connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setNameFilter(QString)));
- connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(expandAll()));
- connect(m_d->m_ui.buttonItems, SIGNAL(toggled (bool)), this, SLOT(itemLibraryButton()));
- connect(m_d->m_ui.buttonResources, SIGNAL(toggled (bool)), this, SLOT(resourcesButton()));
- connect(m_d->m_ui.ItemLibraryTreeView, SIGNAL(itemActivated(const QString&)), this, SIGNAL(itemActivated(const QString&)));
+ m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath));
+
+ const QString qmlSourcePath(":/ItemLibrary/qml/ItemsView.qml");
+ QFile qmlSourceFile(qmlSourcePath);
+ qmlSourceFile.open(QFile::ReadOnly);
+ Q_ASSERT(qmlSourceFile.isOpen());
+ QString qmlSource(qmlSourceFile.readAll());
+
+ m_d->m_itemsView = new QmlView(this);
+ m_d->m_itemsView->setQml(qmlSource, qmlSourcePath);
+ m_d->m_itemsView->setAttribute(Qt::WA_OpaquePaintEvent);
+ m_d->m_itemsView->setAttribute(Qt::WA_NoSystemBackground);
+ m_d->m_itemsView->setAcceptDrops(false);
+ m_d->m_itemsView->setFocusPolicy(Qt::ClickFocus);
+ m_d->m_itemsView->setContentResizable(true);
+ m_d->m_ui.ItemLibraryGridLayout->addWidget(m_d->m_itemsView, 0, 0);
+
+ m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(QmlEnginePrivate::getScriptEngine(m_d->m_itemsView->engine()), this);
+ m_d->m_itemLibraryModel->setItemIconSize(m_d->m_itemIconSize);
+ m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryModel"), m_d->m_itemLibraryModel);
+ m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_d->m_itemIconSize.width());
+ m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_d->m_itemIconSize.height());
+
+ m_d->m_itemsView->execute();
+
+ connect(m_d->m_itemsView->root(), SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int)));
+ connect(m_d->m_itemsView->root(), SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int)));
+ connect(this, SIGNAL(expandAllItems()), m_d->m_itemsView->root(), SLOT(expandAll()));
+
+ connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setSearchFilter(QString)));
m_d->m_ui.lineEdit->setDragEnabled(false);
- setNameFilter("");
- MyFileIconProvider *fileIconProvider = new MyFileIconProvider();
- m_d->m_resourcesDirModel->setIconProvider(fileIconProvider);
+ connect(m_d->m_ui.buttonItems, SIGNAL(clicked()), this, SLOT(itemLibraryButtonToggled()));
+ connect(m_d->m_ui.buttonResources, SIGNAL(clicked()), this, SLOT(resourcesButtonToggled()));
+
+ m_d->m_ui.buttonItems->setChecked(true);
+ itemLibraryButtonToggled();
+ setSearchFilter("");
+
+ m_d->m_resourcesDirModel->setIconProvider(&m_d->m_iconProvider);
setWindowTitle(tr("Library", "Title of library view"));
@@ -194,8 +207,6 @@ ItemLibrary::ItemLibrary(QWidget *parent) :
QString styleSheet = QLatin1String(file.readAll());
m_d->m_ui.ItemLibraryTreeView->setStyleSheet(styleSheet);
}
-
- m_d->m_ui.buttonItems->setChecked(true);
}
ItemLibrary::~ItemLibrary()
@@ -203,48 +214,44 @@ ItemLibrary::~ItemLibrary()
delete m_d;
}
-void ItemLibrary::setNameFilter(const QString &nameFilter)
-{
- QStringList nameFilterList;
- nameFilterList.append(nameFilter + "*.gif");
- nameFilterList.append(nameFilter + "*.png");
- nameFilterList.append(nameFilter + "*.jpg");
- nameFilterList.append(nameFilter + "*.");
- m_d->m_resourcesDirModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
- m_d->m_resourcesDirModel->setNameFilters(nameFilterList);
- if (m_d->m_ui.ItemLibraryTreeView->model() == m_d->m_resourcesDirModel)
- m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath));
-}
-
-void ItemLibrary::itemLibraryButton()
+void ItemLibrary::setSearchFilter(const QString &searchFilter)
{
if (m_d->m_ui.buttonItems->isChecked()) {
- m_d->m_filterProxy->setSourceModel(m_d->m_itemLibraryModel);
- m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_filterProxy);
- m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(64, 64));
- m_d->m_ui.buttonResources->setChecked(false);
- m_d->m_ui.ItemLibraryTreeView->setRealModel(m_d->m_itemLibraryModel);
- expandAll();
+ m_d->m_itemLibraryModel->setSearchText(searchFilter);
+ m_d->m_itemsView->update();
+ emit expandAllItems();
+ } else {
+ QStringList nameFilterList;
+ if (searchFilter.contains('.')) {
+ nameFilterList.append(QString("*%1*").arg(searchFilter));
+ } else {
+ foreach (const QByteArray &extension, QImageReader::supportedImageFormats()) {
+ nameFilterList.append(QString("*%1*.%2").arg(searchFilter, QString::fromAscii(extension)));
+ }
+ }
+
+ m_d->m_resourcesDirModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
+ m_d->m_resourcesDirModel->setNameFilters(nameFilterList);
+ if (m_d->m_ui.ItemLibraryTreeView->model() == m_d->m_resourcesDirModel)
+ m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath));
+ m_d->m_ui.ItemLibraryTreeView->expandToDepth(1);
}
}
-void ItemLibrary::resourcesButton()
+void ItemLibrary::itemLibraryButtonToggled()
{
- if (m_d->m_ui.buttonResources->isChecked()) {
- m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_resourcesDirModel);
- m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(32, 32));
- m_d->m_ui.buttonItems->setChecked(false);
- m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath));
- m_d->m_ui.ItemLibraryTreeView->setColumnHidden(1, true);
- m_d->m_ui.ItemLibraryTreeView->setColumnHidden(2, true);
- m_d->m_ui.ItemLibraryTreeView->setColumnHidden(3, true);
- expandAll();
- }
+ m_d->m_ui.LibraryStackedWidget->setCurrentIndex(0);
+ m_d->m_ui.buttonItems->setChecked(true);
+ m_d->m_ui.buttonResources->setChecked(false);
+ setSearchFilter(m_d->m_ui.lineEdit->text());
}
-void ItemLibrary::addItemLibraryInfo(const ItemLibraryInfo &itemLibraryInfo)
+void ItemLibrary::resourcesButtonToggled()
{
- m_d->m_itemLibraryModel->addItemLibraryInfo(itemLibraryInfo);
+ m_d->m_ui.LibraryStackedWidget->setCurrentIndex(1);
+ m_d->m_ui.buttonResources->setChecked(true);
+ m_d->m_ui.buttonItems->setChecked(false);
+ setSearchFilter(m_d->m_ui.lineEdit->text());
}
void ItemLibrary::setResourcePath(const QString &resourcePath)
@@ -252,70 +259,30 @@ void ItemLibrary::setResourcePath(const QString &resourcePath)
m_d->m_resourcePath = resourcePath;
}
-void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo)
+void ItemLibrary::startDragAndDrop(int itemLibId)
{
- m_d->m_itemLibraryModel->clear();
-
- foreach (const QString &type, metaInfo.itemLibraryItems()) {
- NodeMetaInfo nodeInfo = metaInfo.nodeMetaInfo(type);
-
- QList<ItemLibraryInfo> itemLibraryRepresentationList = metaInfo.itemLibraryRepresentations(nodeInfo);
-
- if (!metaInfo.hasNodeMetaInfo(type))
- qWarning() << "ItemLibrary: type not declared: " << type;
- if (!itemLibraryRepresentationList.isEmpty() && metaInfo.hasNodeMetaInfo(type)) {
- foreach (ItemLibraryInfo itemLibraryRepresentation, itemLibraryRepresentationList) {
- QImage image(64, 64, QImage::Format_RGB32); // = m_d->m_queryView->paintObject(nodeInfo, itemLibraryRepresentation.properties()); TODO
- image.fill(0xffffffff);
- if (!image.isNull()) {
- QPainter p(&image);
- QPen pen(Qt::gray);
- pen.setWidth(2);
- p.setPen(pen);
- p.drawRect(1, 1, image.width() - 2, image.height() - 2);
- }
- QIcon icon = itemLibraryRepresentation.icon();
- if (itemLibraryRepresentation.icon().isNull())
- itemLibraryRepresentation.setIcon(QIcon(":/ItemLibrary/images/default-icon.png"));
-
- if (itemLibraryRepresentation.category().isEmpty())
- itemLibraryRepresentation.setCategory(nodeInfo.category());
- if (!image.isNull()) {
- itemLibraryRepresentation.setDragIcon(QPixmap::fromImage(image));
- addItemLibraryInfo(itemLibraryRepresentation);
- }
- }
- } else {
- QImage image; // = m_d->m_queryView->paintObject(nodeInfo); TODO we have to render image
- QIcon icon = nodeInfo.icon();
- if (icon.isNull())
- icon = QIcon(":/ItemLibrary/images/default-icon.png");
-
- ItemLibraryInfo itemLibraryInfo;
- itemLibraryInfo.setName(type);
- itemLibraryInfo.setTypeName(nodeInfo.typeName());
- itemLibraryInfo.setCategory(nodeInfo.category());
- itemLibraryInfo.setIcon(icon);
- itemLibraryInfo.setMajorVersion(nodeInfo.majorVersion());
- itemLibraryInfo.setMinorVersion(nodeInfo.minorVersion());
- itemLibraryInfo.setDragIcon(QPixmap::fromImage(image));
- addItemLibraryInfo(itemLibraryInfo);
- }
- }
- expandAll();
+ QMimeData *mimeData = m_d->m_itemLibraryModel->getMimeData(itemLibId);
+ CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this);
+ const QImage image = qvariant_cast<QImage>(mimeData->imageData());
+
+ drag->setPixmap(m_d->m_itemLibraryModel->getIcon(itemLibId).pixmap(32, 32));
+ drag->setPreview(QPixmap::fromImage(image));
+ drag->setMimeData(mimeData);
+
+ connect(m_d->m_itemsView->root(), SIGNAL(stopDragAndDrop()), drag, SLOT(stopDrag()));
+
+ drag->exec();
}
-void ItemLibrary::expandAll()
+void ItemLibrary::showItemInfo(int /*itemLibId*/)
{
- m_d->m_ui.ItemLibraryTreeView->expandToDepth(1);
+// qDebug() << "showing item info about id" << itemLibId;
}
-void ItemLibrary::contextMenuEvent (QContextMenuEvent *event)
+void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo)
{
- event->accept();
- QMenu menu;
- menu.addAction(tr("About plugins..."));
- menu.exec(event->globalPos());
+ m_d->m_itemLibraryModel->update(metaInfo);
}
}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
index 28295292e7..6adf53504d 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
@@ -48,6 +48,7 @@ class ItemLibrary : public QFrame
{
Q_OBJECT
Q_DISABLE_COPY(ItemLibrary)
+
public:
ItemLibrary(QWidget *parent = 0);
virtual ~ItemLibrary();
@@ -55,28 +56,25 @@ public:
void addItemLibraryInfo(const ItemLibraryInfo &ItemLibraryInfo);
void setMetaInfo(const MetaInfo &metaInfo);
- // Helper for creating widget box items. Note that this temporarily
- // adds the item to a scene, so, the item must not be associated
- // with a scene.
-
public Q_SLOTS:
- void expandAll();
- void itemLibraryButton();
- void resourcesButton();
- void setNameFilter(const QString &nameFilter);
+ void itemLibraryButtonToggled();
+ void resourcesButtonToggled();
+
+ void setSearchFilter(const QString &nameFilter);
void setResourcePath(const QString &resourcePath);
+
+ void startDragAndDrop(int itemLibId);
+ void showItemInfo(int itemLibId);
+
signals:
void itemActivated(const QString& itemName);
-
-protected:
- virtual void contextMenuEvent (QContextMenuEvent * event);
+ void expandAllItems();
private:
ItemLibraryPrivate *m_d;
};
-//class ItemLibraryFilter : public QObject
-
}
#endif // ITEMLIBRARY_H
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
index b8212323f1..470a6295d7 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
@@ -6,7 +6,8 @@ VPATH += $$PWD
INCLUDEPATH += $$PWD
# Input
-HEADERS += itemlibrary.h itemlibrarymodel.h customdraganddrop.h
+HEADERS += itemlibrary.h customdraganddrop.h itemlibrarymodel.h itemlibrarytreeview.h
FORMS += itemlibrary.ui
-SOURCES += itemlibrary.cpp itemlibrarymodel.cpp customdraganddrop.cpp
+SOURCES += itemlibrary.cpp customdraganddrop.cpp itemlibrarymodel.cpp itemlibrarytreeview.cpp
RESOURCES += itemlibrary.qrc
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
index c1d136b81d..e4d27b0476 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
@@ -1,5 +1,13 @@
<RCC>
- <qresource prefix="/ItemLibrary/images" >
- <file>default-icon.png</file>
+ <qresource prefix="/ItemLibrary" >
+ <file>qml/ItemsView.qml</file>
+ <file>qml/ItemsViewStyle.qml</file>
+ <file>qml/SectionView.qml</file>
+ <file>qml/ItemView.qml</file>
+ <file>qml/Scrollbar.qml</file>
+ <file>qml/Selector.qml</file>
+
+ <file>images/item-default-icon.png</file>
</qresource>
</RCC>
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui
index 029896d37b..0321e53235 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui
@@ -7,104 +7,220 @@
<x>0</x>
<y>0</y>
<width>497</width>
- <height>792</height>
+ <height>635</height>
</rect>
</property>
<property name="windowTitle">
<string>ItemLibrary</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>2</number>
- </property>
- <property name="topMargin">
- <number>6</number>
- </property>
- <property name="rightMargin">
- <number>2</number>
- </property>
- <property name="bottomMargin">
- <number>2</number>
- </property>
- <property name="horizontalSpacing">
- <number>4</number>
- </property>
- <item row="0" column="0">
- <spacer name="horizontalSpacer_2">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>6</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonItems">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Items</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>6</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonResources">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Resources</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>6</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>6</width>
- <height>27</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Filter: </string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLineEdit" name="lineEdit"/>
- </item>
- <item row="0" column="3">
- <widget class="QToolButton" name="buttonItems">
- <property name="minimumSize">
- <size>
- <width>80</width>
- <height>30</height>
- </size>
- </property>
- <property name="text">
- <string>Items</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
</widget>
</item>
- <item row="0" column="4">
- <widget class="QToolButton" name="buttonResources">
- <property name="minimumSize">
- <size>
- <width>80</width>
- <height>30</height>
- </size>
- </property>
- <property name="text">
- <string>Resources</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <property name="autoExclusive">
- <bool>false</bool>
- </property>
- </widget>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>6</width>
+ <height>6</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>6</width>
+ <height>6</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
- <item row="1" column="0" colspan="5">
+ <item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="5">
- <widget class="QmlDesigner::Internal::ItemLibraryTreeView" name="ItemLibraryTreeView">
- <property name="enabled">
- <bool>true</bool>
+ <item>
+ <widget class="QStackedWidget" name="LibraryStackedWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
</property>
+ <widget class="QWidget" name="page_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="ItemLibraryGridLayout"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QmlDesigner::Internal::ItemLibraryTreeView" name="ItemLibraryTreeView">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -114,7 +230,7 @@
<customwidget>
<class>QmlDesigner::Internal::ItemLibraryTreeView</class>
<extends>QTreeView</extends>
- <header>itemlibrarymodel.h</header>
+ <header>itemlibrarytreeview.h</header>
</customwidget>
</customwidgets>
<resources/>
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
index 89e81f8313..b21a3830c3 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
@@ -1,297 +1,460 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** 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 are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
#include "itemlibrarymodel.h"
-#include "itemlibrary.h"
-#include "customdraganddrop.h"
-
-#include <QtCore/QMimeData>
-#include <QtCore/QDebug>
+#include "metainfo.h"
-#include <QtGui/QImage>
-#include <QtGui/QPixmap>
-#include <QtGui/QDrag>
-#include <QSortFilterProxyModel>
+#include <QVariant>
+#include <QMimeData>
#include <QPainter>
-#include <QLabel>
-#include <itemlibraryinfo.h>
-#include <QDirModel>
+#include <QPen>
+#include <qdebug.h>
-enum { debug = 0 };
-// Store data and a type enumeration along with the QStandardItem
-enum ItemType { CategoryItem, WidgetItem };
-enum Roles { TypeRole = Qt::UserRole + 1,
- DataRole = Qt::UserRole + 2,
- DragPixmapRole = Qt::UserRole + 3};
+namespace QmlDesigner {
+
+namespace Internal {
-static inline ItemType itemType(const QStandardItem *item)
+template <class T>
+ItemLibrarySortedModel<T>::ItemLibrarySortedModel(QObject *parent) :
+ QmlListModel(parent)
{
- return static_cast<ItemType>(item->data(TypeRole).toInt());
}
-static inline QmlDesigner::ItemLibraryInfo widgetItemData(const QStandardItem *item)
+
+template <class T>
+ItemLibrarySortedModel<T>::~ItemLibrarySortedModel()
{
- const QVariant data = item->data(DataRole);
- if (!data.isValid())
- return QmlDesigner::ItemLibraryInfo();
- return qvariant_cast<QmlDesigner::ItemLibraryInfo>(data);
+ clearElements();
}
+template <class T>
+void ItemLibrarySortedModel<T>::clearElements()
+{
+ while (m_elementOrder.count() > 0)
+ removeElement(m_elementOrder.at(0).libId);
+}
-namespace QmlDesigner {
-namespace Internal {
-// Cache a drag pixmap on the icon using the DragPixmapRole data field.
-static QImage cachedDragImage(const ItemLibraryInfo &ItemLibraryInfo,
- QStandardItem *item)
+template <class T>
+void ItemLibrarySortedModel<T>::addElement(T *element, int libId)
{
- const QVariant cached = item->data(DragPixmapRole);
- if (cached.type() != QVariant::Invalid)
- return qvariant_cast<QImage>(cached);
- // TODO: Grab using factory
- const QIcon icon = ItemLibraryInfo.dragIcon();
- if (icon.isNull())
- return QImage();
- const QList<QSize> sizes = icon.availableSizes();
- if (sizes.isEmpty())
- return QImage();
- const QImage image = icon.pixmap(sizes.front()).toImage();
- item->setData(image, DragPixmapRole);
- return image;
+ struct order_struct orderEntry;
+ orderEntry.libId = libId;
+ orderEntry.visible = false;
+
+ int pos = 0;
+ while ((pos < m_elementOrder.count()) &&
+ (*(m_elementModels.value(m_elementOrder.at(pos).libId)) < *element))
+ ++pos;
+
+ m_elementModels.insert(libId, element);
+ m_elementOrder.insert(pos, orderEntry);
+
+ setElementVisible(libId, true);
}
-ItemLibraryModel::ItemLibraryModel(QObject *parent) :
- QStandardItemModel(parent)
+template <class T>
+void ItemLibrarySortedModel<T>::removeElement(int libId)
{
- setSupportedDragActions(Qt::CopyAction);
+ T *element = m_elementModels.value(libId);
+ int pos = findElement(libId);
+ struct order_struct orderEntry = m_elementOrder.at(pos);
+
+ setElementVisible(libId, false);
+
+ m_elementModels.remove(libId);
+ m_elementOrder.removeAt(pos);
+
+ delete element;
}
-static inline QStandardItem *categoryToItem(const QString &g)
+
+template <class T>
+bool ItemLibrarySortedModel<T>::elementVisible(int libId) const
{
- QStandardItem *rc = new QStandardItem(g);
- rc->setFlags(Qt::ItemIsEnabled);
- rc->setData(QVariant(CategoryItem), TypeRole);
- rc->setData(g, Qt::UserRole);
- return rc;
+ int pos = findElement(libId);
+ return m_elementOrder.at(pos).visible;
}
-static QStandardItem *customWidgetDataToItem(const ItemLibraryInfo &ItemLibraryInfo)
+template <class T>
+void ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible)
{
- QStandardItem *item = new QStandardItem(ItemLibraryInfo.name());
- const QIcon icon = ItemLibraryInfo.icon();
- if (!icon.isNull() && !icon.availableSizes().empty()) {
- item->setIcon(icon);
- if (icon.availableSizes().count() == 1) {
- item->setSizeHint(icon.availableSizes().first() + QSize(1, 1));
- }
+ int pos = findElement(libId),
+ offset = 0;
+
+ if (m_elementOrder.at(pos).visible == visible)
+ return;
+
+ for (int i = 0; (i + offset) < pos;) {
+ if (m_elementOrder.at(i + offset).visible)
+ ++i;
+ else
+ ++offset;
}
- item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsDragEnabled|Qt::ItemIsSelectable);
- item->setData(qVariantFromValue(ItemLibraryInfo), DataRole);
- item->setData(QVariant(WidgetItem), TypeRole);
- item->setData(ItemLibraryInfo.name(), Qt::UserRole);
- return item;
+ if (visible)
+ insert(pos - offset, *(m_elementModels.value(libId)));
+ else
+ remove(pos - offset);
+
+ m_elementOrder[pos].visible = visible;
}
-void ItemLibraryModel::addItemLibraryInfo(const ItemLibraryInfo &itemLibraryInfo)
+template <class T>
+const QMap<int, T *> &ItemLibrarySortedModel<T>::elements() const
{
- QStandardItem *categoryItem = findCategoryItem(itemLibraryInfo.category());
- if (!categoryItem) {
- categoryItem = categoryToItem(itemLibraryInfo.category());
- appendRow(categoryItem);
- }
- categoryItem->appendRow(customWidgetDataToItem(itemLibraryInfo));
- QString filterList = categoryItem->data(Qt::UserRole).toString();
- filterList += itemLibraryInfo.name();
- categoryItem->setData(filterList, Qt::UserRole);
+ return m_elementModels;
+}
+
+
+template <class T>
+T *ItemLibrarySortedModel<T>::elementModel(int libId)
+{
+ return m_elementModels.value(libId);
}
-QStandardItem *ItemLibraryModel::findCategoryItem(const QString &category)
+
+template <class T>
+int ItemLibrarySortedModel<T>::findElement(int libId) const
{
- const QStandardItem *root = invisibleRootItem();
- const int rowCount = root->rowCount();
- for (int i = 0 ; i < rowCount; i++) {
- QStandardItem *categoryItem = root->child(i, 0);
- if (categoryItem->text() == category)
- return categoryItem;
+ int i = 0;
+ QListIterator<struct order_struct> it(m_elementOrder);
+
+ while (it.hasNext()) {
+ if (it.next().libId == libId)
+ return i;
+ ++i;
}
- return 0;
+
+ return -1;
+}
+
+
+
+
+ItemLibraryItemModel::ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName)
+ : QScriptValue(scriptEngine->newObject()),
+ m_scriptEngine(scriptEngine),
+ m_libId(itemLibId),
+ m_name(itemName),
+ m_icon(),
+ m_iconSize(64, 64)
+{
+ QScriptValue pixmapScriptValue(m_scriptEngine->newVariant(QPixmap()));
+
+ setProperty(QLatin1String("itemLibId"), itemLibId);
+ setProperty(QLatin1String("itemName"), itemName);
+ setProperty(QLatin1String("itemPixmap"), pixmapScriptValue);
}
-Qt::DropActions ItemLibraryModel::supportedDragActions() const
+
+ItemLibraryItemModel::~ItemLibraryItemModel()
{
- return Qt::CopyAction;
+ setProperty(QLatin1String("itemPixmap"), QVariant::Invalid);
}
-Qt::DropActions ItemLibraryModel::supportedDropActions() const
+
+int ItemLibraryItemModel::itemLibId() const
{
- return Qt::IgnoreAction;
+ return m_libId;
}
-QStringList ItemLibraryModel::mimeTypes () const
+
+QString ItemLibraryItemModel::itemName() const
{
- if (debug)
- qDebug() << Q_FUNC_INFO;
- return QStringList(QLatin1String("text/xml"));
+ return m_name;
}
-QByteArray ItemLibraryInfoToByteArray(const ItemLibraryInfo &ItemLibraryInfo)
+
+void ItemLibraryItemModel::setItemIcon(const QIcon &itemIcon)
{
- QByteArray byteArray;
- QDataStream stream(&byteArray, QIODevice::WriteOnly);
+ m_icon = itemIcon;
+
+ QScriptValue pixmapScriptValue(m_scriptEngine->newVariant(m_icon.pixmap(m_iconSize)));
+ setProperty(QLatin1String("itemPixmap"), pixmapScriptValue);
+}
- stream << ItemLibraryInfo;
- return byteArray;
+void ItemLibraryItemModel::setItemIconSize(const QSize &itemIconSize)
+{
+ m_iconSize = itemIconSize;
+// qDebug() << "set icon size" << itemIconSize;
+ setItemIcon(m_icon);
}
-QMimeData *ItemLibraryModel::mimeData(const QModelIndexList &indexes) const
+
+bool ItemLibraryItemModel::operator<(const ItemLibraryItemModel &other) const
{
- if (debug)
- qDebug() << Q_FUNC_INFO << indexes.size();
- if (indexes.size() != 1)
- return 0;
- QStandardItem *item = itemFromIndex (indexes.front());
- if (!item || itemType(item) != WidgetItem)
- return 0;
- QMimeData *mimeData = new QMimeData;
+ return itemName() < other.itemName();
+}
+
+
- ItemLibraryInfo ItemLibraryInfo(widgetItemData(item));
- const QImage image = cachedDragImage(ItemLibraryInfo, item);
- if (!image.isNull())
- mimeData->setImageData(image);
+ItemLibrarySectionModel::ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString &sectionName, QObject *parent)
+ : QScriptValue(scriptEngine->newObject()),
+ m_name(sectionName),
+ m_sectionEntries(parent)
+{
+ QScriptValue::setProperty(QLatin1String("sectionLibId"), sectionLibId);
+ QScriptValue::setProperty(QLatin1String("sectionName"), sectionName);
+ QScriptValue::setProperty(QLatin1String("sectionEntries"),
+ scriptEngine->newVariant(QVariant::fromValue(static_cast<QmlListModel *>(&m_sectionEntries))));
+}
- mimeData->setData("application/vnd.bauhaus.itemlibraryinfo", ItemLibraryInfoToByteArray(ItemLibraryInfo));
- mimeData->removeFormat("text/plain");
+QString ItemLibrarySectionModel::sectionName() const
+{
+ return m_name;
+}
+
- return mimeData;
+void ItemLibrarySectionModel::addSectionEntry(ItemLibraryItemModel *sectionEntry)
+{
+ m_sectionEntries.addElement(sectionEntry, sectionEntry->itemLibId());
}
-ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) :
- QTreeView(parent)
+
+void ItemLibrarySectionModel::removeSectionEntry(int itemLibId)
{
- setDragEnabled(true);
- setDragDropMode(QAbstractItemView::DragOnly);
- connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &)));
+ m_sectionEntries.removeElement(itemLibId);
}
-// We need to implement startDrag ourselves since we cannot
-// otherwise influence drag pixmap and hotspot in the standard
-// implementation.
-void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */)
+
+bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText)
{
- if (debug)
- qDebug() << Q_FUNC_INFO;
- QMimeData *mimeData = model()->mimeData(selectedIndexes());
- if (!mimeData)
- return;
+ bool haveVisibleItems = false;
+ QMap<int, ItemLibraryItemModel *>::const_iterator itemIt = m_sectionEntries.elements().constBegin();
+ while (itemIt != m_sectionEntries.elements().constEnd()) {
- if (qobject_cast<QSortFilterProxyModel*>(model())) {
- QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(selectedIndexes().front());
+ bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText);
+ m_sectionEntries.setElementVisible(itemIt.key(), itemVisible);
- QStandardItem *item = m_model->itemFromIndex(index);
+ if (itemVisible)
+ haveVisibleItems = true;
+
+ ++itemIt;
+ }
- if (!item)
- return;
+ return haveVisibleItems;
+}
- CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this);
- const QImage image = qvariant_cast<QImage>(mimeData->imageData());
- drag->setPixmap(item->icon().pixmap(32, 32));
- drag->setPreview(QPixmap::fromImage(image));
- drag->setMimeData(mimeData);
- drag->exec();
+void ItemLibrarySectionModel::updateItemIconSize(const QSize &itemIconSize)
+{
+ foreach (ItemLibraryItemModel *item, m_sectionEntries.elements().values()) {
+ item->setItemIconSize(itemIconSize);
+ }
+}
+
+
+bool ItemLibrarySectionModel::operator<(const ItemLibrarySectionModel &other) const
+{
+ return sectionName() < other.sectionName();
+}
+
+
+
+
+
+ItemLibraryModel::ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent)
+ : ItemLibrarySortedModel<ItemLibrarySectionModel>(parent),
+ m_scriptEngine(scriptEngine),
+ m_metaInfo(0),
+ m_searchText(""),
+ m_itemIconSize(64, 64),
+ m_nextLibId(0)
+{
+}
+
+
+ItemLibraryModel::~ItemLibraryModel()
+{
+ if (m_metaInfo)
+ delete m_metaInfo;
+}
+
+
+QString ItemLibraryModel::searchText() const
+{
+ return m_searchText;
+}
+
+
+void ItemLibraryModel::setSearchText(const QString &searchText)
+{
+ QString lowerSearchText = searchText.toLower();
+
+ if (m_searchText != lowerSearchText) {
+ m_searchText = lowerSearchText;
+ emit searchTextChanged();
+
+ updateVisibility();
+ }
+}
+
+
+void ItemLibraryModel::setItemIconSize(const QSize &itemIconSize)
+{
+ m_itemIconSize = itemIconSize;
+
+ foreach (ItemLibrarySectionModel *section, elements().values())
+ section->updateItemIconSize(itemIconSize);
+}
+
+
+void ItemLibraryModel::update(const MetaInfo &metaInfo)
+{
+ QMap<QString, int> sections;
+
+ clearElements();
+ m_itemInfos.clear();
+
+ if (!m_metaInfo) {
+ m_metaInfo = new MetaInfo(metaInfo);
} else {
- QDirModel *dirModel = qobject_cast<QDirModel*>(model());
- Q_ASSERT(dirModel);
- QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front());
- QPixmap pixmap(fileInfo.absoluteFilePath());
- if (!pixmap.isNull()) {
- CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this);
- drag->setPreview(pixmap);
- drag->setPixmap(QIcon(pixmap).pixmap(128, 128));
- QMimeData *mimeData = new QMimeData;
- mimeData->setData("application/vnd.bauhaus.libraryresource", fileInfo.absoluteFilePath().toLatin1());
- drag->setMimeData(mimeData);
- drag->exec();
+ *m_metaInfo = metaInfo;
+ }
+
+ foreach (const QString &type, metaInfo.itemLibraryItems()) {
+ foreach (const ItemLibraryInfo &itemLibraryRepresentation, itemLibraryRepresentations(type)) {
+
+ QString itemSectionName = itemLibraryRepresentation.category();
+ ItemLibrarySectionModel *sectionModel;
+ ItemLibraryItemModel *itemModel;
+ int itemId = m_nextLibId++, sectionId;
+
+ if (sections.contains(itemSectionName)) {
+ sectionId = sections.value(itemSectionName);
+ sectionModel = elementModel(sectionId);
+ } else {
+ sectionId = m_nextLibId++;
+ sectionModel = new ItemLibrarySectionModel(m_scriptEngine.data(), sectionId, itemSectionName, this);
+ addElement(sectionModel, sectionId);
+ sections.insert(itemSectionName, sectionId);
+ }
+
+ m_itemInfos.insert(itemId, itemLibraryRepresentation);
+
+ itemModel = new ItemLibraryItemModel(m_scriptEngine.data(), itemId, itemLibraryRepresentation.name());
+ itemModel->setItemIcon(itemLibraryRepresentation.icon());
+ itemModel->setItemIconSize(m_itemIconSize);
+ sectionModel->addSectionEntry(itemModel);
}
}
+
+ updateVisibility();
+}
+
+
+QString ItemLibraryModel::getTypeName(int libId)
+{
+ return m_itemInfos.value(libId).typeName();
}
-static ItemLibraryInfo ItemLibraryInfoFromData(const QByteArray &data)
+
+QMimeData *ItemLibraryModel::getMimeData(int libId)
{
- QDataStream stream(data);
+ QMimeData *mimeData = new QMimeData();
+
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << m_itemInfos.value(libId);
+ mimeData->setData(QLatin1String("application/vnd.bauhaus.itemlibraryinfo"), data);
+
+ const QIcon icon = m_itemInfos.value(libId).dragIcon();
+ if (!icon.isNull()) {
+ const QList<QSize> sizes = icon.availableSizes();
+ if (!sizes.isEmpty())
+ mimeData->setImageData(icon.pixmap(sizes.front()).toImage());
+ }
- ItemLibraryInfo itemLibraryInfo;
- stream >> itemLibraryInfo;
+ mimeData->removeFormat(QLatin1String("text/plain"));
- return itemLibraryInfo;
+ return mimeData;
}
-void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/)
+
+QIcon ItemLibraryModel::getIcon(int libId)
{
- QMimeData *mimeData = model()->mimeData(selectedIndexes());
- if (!mimeData)
- return;
+ return m_itemInfos.value(libId).icon();
+}
+
- QString name;
- if (qobject_cast<QSortFilterProxyModel*>(model())) {
- QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(selectedIndexes().front());
+void ItemLibraryModel::updateVisibility()
+{
+ QMap<int, ItemLibrarySectionModel *>::const_iterator sectionIt = elements().constBegin();
+ while (sectionIt != elements().constEnd()) {
- QStandardItem *item = m_model->itemFromIndex(index);
+ ItemLibrarySectionModel *sectionModel = sectionIt.value();
+ QString sectionSearchText = m_searchText;
- if (!item)
- return;
+ if (sectionModel->sectionName().toLower().contains(m_searchText))
+ sectionSearchText = "";
- ItemLibraryInfo itemLibraryInfo = ItemLibraryInfoFromData(mimeData->data("application/vnd.bauhaus.itemlibraryinfo"));
- QString type = itemLibraryInfo.name();
+ bool sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText);
+ setElementVisible(sectionIt.key(), sectionVisibility);
- name = "item^" + type;
- emit itemActivated(name);
- } else {
- QDirModel *dirModel = qobject_cast<QDirModel*>(model());
- Q_ASSERT(dirModel);
- QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front());
- QPixmap pixmap(fileInfo.absoluteFilePath());
- if (!pixmap.isNull()) {
- name = "image^" + fileInfo.absoluteFilePath();
- emit itemActivated(name);
+ ++sectionIt;
+ }
+
+ emit visibilityUpdated();
+}
+
+
+QList<ItemLibraryInfo> ItemLibraryModel::itemLibraryRepresentations(const QString &type)
+{
+ NodeMetaInfo nodeInfo = m_metaInfo->nodeMetaInfo(type);
+ QList<ItemLibraryInfo> itemLibraryRepresentationList = m_metaInfo->itemLibraryRepresentations(nodeInfo);
+
+ QImage dragImage(64, 64, QImage::Format_RGB32); // TODO: draw item drag icon
+ dragImage.fill(0xffffffff);
+ QPainter p(&dragImage);
+ QPen pen(Qt::gray);
+ pen.setWidth(2);
+ p.setPen(pen);
+ p.drawRect(1, 1, dragImage.width() - 2, dragImage.height() - 2);
+ QPixmap dragPixmap(QPixmap::fromImage(dragImage));
+
+ if (!m_metaInfo->hasNodeMetaInfo(type))
+ qWarning() << "ItemLibrary: type not declared: " << type;
+
+ static QIcon defaultIcon(QLatin1String(":/ItemLibrary/images/item-default-icon.png"));
+
+ if (itemLibraryRepresentationList.isEmpty() || !m_metaInfo->hasNodeMetaInfo(type)) {
+ QIcon icon = nodeInfo.icon();
+ if (icon.isNull())
+ icon = defaultIcon;
+
+ ItemLibraryInfo itemLibraryInfo;
+ itemLibraryInfo.setName(type);
+ itemLibraryInfo.setTypeName(nodeInfo.typeName());
+ itemLibraryInfo.setCategory(nodeInfo.category());
+ itemLibraryInfo.setIcon(icon);
+ itemLibraryInfo.setDragIcon(dragPixmap);
+ itemLibraryInfo.setMajorVersion(nodeInfo.majorVersion());
+ itemLibraryInfo.setMinorVersion(nodeInfo.minorVersion());
+ itemLibraryRepresentationList.append(itemLibraryInfo);
+ }
+ else {
+ foreach (ItemLibraryInfo itemLibraryRepresentation, itemLibraryRepresentationList) {
+ QIcon icon = itemLibraryRepresentation.icon();
+ if (itemLibraryRepresentation.icon().isNull())
+ itemLibraryRepresentation.setIcon(defaultIcon);
+
+ if (itemLibraryRepresentation.dragIcon().isNull())
+ itemLibraryRepresentation.setDragIcon(dragPixmap);
+
+ if (itemLibraryRepresentation.category().isEmpty())
+ itemLibraryRepresentation.setCategory(nodeInfo.category());
}
}
+
+ return itemLibraryRepresentationList;
}
} // namespace Internal
} // namespace QmlDesigner
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
index 4c4e00d136..22a1beef7a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
@@ -1,91 +1,133 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** 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 are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
#ifndef ITEMLIBRARYMODEL_H
#define ITEMLIBRARYMODEL_H
-#include <QtGui/QStandardItemModel>
-#include <QtGui/QTreeView>
-#include <QDrag>
-#include <QDebug>
-#include <QTimeLine>
+#include <QMap>
+#include <QIcon>
+#include <QVariant>
+#include <QScriptEngine>
+#include <private/qmllistmodel_p.h>
-QT_BEGIN_NAMESPACE
-class QLabel;
-QT_END_NAMESPACE
+class QMimeData;
namespace QmlDesigner {
+class MetaInfo;
class ItemLibraryInfo;
namespace Internal {
-// QStandardItemModel-based model for the widget box.
-class ItemLibraryModel : public QStandardItemModel
-{
- Q_OBJECT
+template <class T>
+class ItemLibrarySortedModel: public QmlListModel {
+public:
+ ItemLibrarySortedModel(QObject *parent = 0);
+ ~ItemLibrarySortedModel();
+
+ void clearElements();
+
+ void addElement(T *element, int libId);
+ void removeElement(int libId);
+
+ bool elementVisible(int libId) const;
+ void setElementVisible(int libId, bool visible);
+
+ const QMap<int, T *> &elements() const;
+
+ T *elementModel(int libId);
+ int findElement(int libId) const;
+
+private:
+ struct order_struct {
+ int libId;
+ bool visible;
+ };
+
+ QMap<int, T *> m_elementModels;
+ QList<struct order_struct> m_elementOrder;
+};
+
+
+class ItemLibraryItemModel: public QScriptValue {
+public:
+ ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName);
+ ~ItemLibraryItemModel();
+
+ int itemLibId() const;
+ QString itemName() const;
+
+ void setItemIcon(const QIcon &itemIcon);
+ void setItemIconSize(const QSize &itemIconSize);
+
+ bool operator<(const ItemLibraryItemModel &other) const;
+
+private:
+ QWeakPointer<QScriptEngine> m_scriptEngine;
+ int m_libId;
+ QString m_name;
+ QIcon m_icon;
+ QSize m_iconSize;
+};
+
+
+class ItemLibrarySectionModel: public QScriptValue {
public:
- explicit ItemLibraryModel(QObject *parent = 0);
- void addItemLibraryInfo(const ItemLibraryInfo &ItemLibraryInfo);
+ ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString &sectionName, QObject *parent = 0);
+
+ QString sectionName() const;
+ void addSectionEntry(ItemLibraryItemModel *sectionEntry);
+ void removeSectionEntry(int itemLibId);
- QStandardItem *findCategoryItem(const QString &category);
+ bool updateSectionVisibility(const QString &searchText);
+ void updateItemIconSize(const QSize &itemIconSize);
- virtual Qt::DropActions supportedDragActions() const;
- virtual Qt::DropActions supportedDropActions() const;
+ bool operator<(const ItemLibrarySectionModel &other) const;
- virtual QStringList mimeTypes() const;
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
+private:
+ QString m_name;
+ ItemLibrarySortedModel<ItemLibraryItemModel> m_sectionEntries;
};
-// ItemLibraryTreeView with Drag implementation
-class ItemLibraryTreeView : public QTreeView {
+
+class ItemLibraryModel: public ItemLibrarySortedModel<ItemLibrarySectionModel> {
Q_OBJECT
- public:
- explicit ItemLibraryTreeView(QWidget *parent = 0);
+ Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged)
- virtual void startDrag(Qt::DropActions supportedActions);
+public:
+ ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent = 0);
+ ~ItemLibraryModel();
+
+ QString searchText() const;
+
+ void update(const MetaInfo &metaInfo);
+
+ QString getTypeName(int libId);
+ QMimeData *getMimeData(int libId);
+ QIcon getIcon(int libId);
- void setRealModel(QStandardItemModel *model) { m_model = model; }
+public slots:
+ void setSearchText(const QString &searchText);
+ void setItemIconSize(const QSize &itemIconSize);
signals:
- void itemActivated(const QString &itemName);
-private slots:
- void activateItem( const QModelIndex & index);
+ void qmlModelChanged();
+ void searchTextChanged();
+ void visibilityUpdated();
private:
- QPixmap m_smallImage, m_bigImage;
- QStandardItemModel *m_model;
-};
+ void updateVisibility();
+ QList<ItemLibraryInfo> itemLibraryRepresentations(const QString &type);
+ QWeakPointer<QScriptEngine> m_scriptEngine;
+ MetaInfo *m_metaInfo;
+ QMap<int, ItemLibraryInfo> m_itemInfos;
+ QString m_searchText;
+ QSize m_itemIconSize;
+ int m_nextLibId;
+};
} // namespace Internal
} // namespace QmlDesigner
+
#endif // ITEMLIBRARYMODEL_H
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp
new file mode 100644
index 0000000000..141c27f2b4
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp
@@ -0,0 +1,109 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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 are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "itemlibrarytreeview.h"
+#include "itemlibrary.h"
+#include "customdraganddrop.h"
+
+#include <QtCore/QMimeData>
+#include <QtCore/QDebug>
+
+#include <QtGui/QImage>
+#include <QtGui/QPixmap>
+#include <QtGui/QDrag>
+#include <QPainter>
+#include <QLabel>
+#include <itemlibraryinfo.h>
+#include <QDirModel>
+
+
+enum { debug = 0 };
+
+
+namespace QmlDesigner {
+
+namespace Internal {
+
+
+ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) :
+ QTreeView(parent)
+{
+ setDragEnabled(true);
+ setDragDropMode(QAbstractItemView::DragOnly);
+ setUniformRowHeights(true);
+ connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &)));
+}
+
+// We need to implement startDrag ourselves since we cannot
+// otherwise influence drag pixmap and hotspot in the standard
+// implementation.
+void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */)
+{
+ if (debug)
+ qDebug() << Q_FUNC_INFO;
+ QMimeData *mimeData = model()->mimeData(selectedIndexes());
+ if (!mimeData)
+ return;
+
+ QDirModel *dirModel = qobject_cast<QDirModel*>(model());
+ Q_ASSERT(dirModel);
+ QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front());
+ QPixmap pixmap(fileInfo.absoluteFilePath());
+ if (!pixmap.isNull()) {
+ CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this);
+ drag->setPreview(pixmap);
+ drag->setPixmap(QIcon(pixmap).pixmap(128, 128));
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setData("application/vnd.bauhaus.libraryresource", fileInfo.absoluteFilePath().toLatin1());
+ drag->setMimeData(mimeData);
+ drag->exec();
+ }
+}
+
+void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/)
+{
+ QMimeData *mimeData = model()->mimeData(selectedIndexes());
+ if (!mimeData)
+ return;
+
+ QString name;
+ QDirModel *dirModel = qobject_cast<QDirModel*>(model());
+ Q_ASSERT(dirModel);
+ QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front());
+ QPixmap pixmap(fileInfo.absoluteFilePath());
+ if (!pixmap.isNull()) {
+ name = "image^" + fileInfo.absoluteFilePath();
+ emit itemActivated(name);
+ }
+}
+
+} // namespace Internal
+
+} // namespace QmlDesigner
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h
new file mode 100644
index 0000000000..61edc0367c
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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 are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef ITEMLIBRARYTREEVIEW_H
+#define ITEMLIBRARYTREEVIEW_H
+
+#include <QtGui/QTreeView>
+#include <QtGui/QStandardItemModel>
+#include <QDrag>
+#include <QDebug>
+#include <QTimeLine>
+
+class QLabel;
+
+namespace QmlDesigner {
+
+namespace Internal {
+
+// ItemLibraryTreeView with Drag implementation
+class ItemLibraryTreeView : public QTreeView {
+ Q_OBJECT
+public:
+ explicit ItemLibraryTreeView(QWidget *parent = 0);
+
+ virtual void startDrag(Qt::DropActions supportedActions);
+
+signals:
+ void itemActivated(const QString &itemName);
+
+private slots:
+ void activateItem( const QModelIndex &index);
+};
+
+
+} // namespace Internal
+
+} // namespace QmlDesigner
+
+#endif // ITEMLIBRARYTREEVIEW_H
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml
new file mode 100644
index 0000000000..2b507cd97f
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml
@@ -0,0 +1,87 @@
+import Qt 4.6
+
+Item {
+ id: itemView
+
+ property var style
+
+ width: GridView.view.cellWidth
+ height: style.cellHeight
+
+ signal itemClicked()
+ signal itemDragged()
+
+ Rectangle {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 1
+ color: style.gridLineColor
+ }
+ Rectangle {
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: -1
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 1
+ color: style.gridLineColor
+ }
+ Rectangle {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ width: 1
+ color: style.gridLineColor
+ }
+ Rectangle {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: -1
+ anchors.right: parent.right
+ anchors.rightMargin: -1
+ width: 1
+ color: style.gridLineColor
+ }
+
+ Image {
+ id: itemIcon
+
+ anchors.top: parent.top
+ anchors.topMargin: style.cellMargin
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ width: itemLibraryIconWidth
+ height: itemLibraryIconHeight
+ pixmap: itemPixmap
+ }
+
+ Text {
+ id: text
+
+ anchors.top: itemIcon.bottom
+ anchors.topMargin: itemView.style.cellSpacing
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: style.textWidth
+ height: style.textHeight
+
+ verticalAlignment: "AlignVCenter"
+ horizontalAlignment: "AlignHCenter"
+ text: itemName
+ // workaround: text color not updated when 'style' var finally assigned
+ color: style.itemNameTextColor
+ Component.onCompleted: text.color = style.itemNameTextColor
+ }
+
+ MouseRegion {
+ id: mouseRegion
+ anchors.fill: parent
+
+ onPositionChanged: {
+ itemDragged();
+ }
+ onClicked: {
+ itemClicked();
+ }
+ }
+}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml
new file mode 100644
index 0000000000..6b38d94d78
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml
@@ -0,0 +1,144 @@
+import Qt 4.6
+
+/*
+ ListModel {
+ id: libraryModel
+ ListElement {
+ sectionTitle: "Section 1"
+ sectionEntries: [
+ ListElement { itemLibId: 0; itemName: "Comp"; itemIconPath: "../images/default-icon.png" },
+ ...
+ ]
+ }
+ ...
+ }
+*/
+
+/* workaround: ListView reports bogus viewportHeight
+
+ListView {
+ id: itemsView
+
+ property string name: "itemsFlickable"
+ anchors.fill: parent
+
+ interactive: false
+
+ model: itemsView.model
+ delegate: sectionDelegate
+}
+*/
+
+
+Rectangle {
+ id: itemsView
+
+ signal itemSelected(int itemLibId)
+ signal itemDragged(int itemLibId)
+
+ function expandAll() {
+ expandAllEntries();
+ scrollbar.handleBar.y = 0;
+ }
+
+ signal expandAllEntries()
+
+ property int entriesPerRow: Math.max(1, Math.floor((itemsFlickable.width - 2) / style.cellWidth))
+ property int cellWidth: Math.floor((itemsFlickable.width - 2) / entriesPerRow)
+ property int cellHeight: style.cellHeight
+
+ property var style
+ style: ItemsViewStyle {}
+
+ color: style.backgroundColor
+
+ /* workaround: without this, a completed drag and drop operation would
+ result in the drag being continued when QmlView re-gains
+ focus */
+ signal stopDragAndDrop
+ MouseRegion {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: if (!pressed) itemsView.stopDragAndDrop
+ }
+
+ Component {
+ id: sectionDelegate
+
+ SectionView {
+ id: section
+ style: itemsView.style
+
+ entriesPerRow: itemsView.entriesPerRow
+ cellWidth: itemsView.cellWidth
+ cellHeight: itemsView.cellHeight
+
+ width: itemsFlickable.width
+ itemHighlight: selector
+
+ onItemSelected: itemsView.itemSelected(itemLibId)
+ onItemDragged: itemsView.itemDragged(itemLibId)
+
+ function focusSelection() {
+ itemSelection.focusSelection()
+ }
+
+ Connection {
+ sender: itemsView
+ signal: "expandAllEntries()"
+ script: section.expand()
+ }
+ }
+ }
+
+ Flickable {
+ id: itemsFlickable
+
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: scrollbar.left
+ anchors.rightMargin: 6
+ clip: true
+
+ interactive: false
+ viewportHeight: col.height
+
+ onViewportHeightChanged: scrollbar.limitHandle()
+
+ Column {
+ id: col
+
+ Repeater {
+ model: itemLibraryModel
+ delegate: sectionDelegate
+ }
+ }
+
+ Selector {
+ id: selector
+ z: -1
+ style: itemsView.style
+ scrollFlickable: itemsFlickable
+
+ onMoveScrollbarHandle: scrollbar.moveHandle(viewportPos)
+
+ width: itemsView.cellWidth
+ height: itemsView.cellHeight
+ }
+ }
+
+ Scrollbar {
+ id: scrollbar
+
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.left: parent.right
+ anchors.leftMargin: -10
+ anchors.right: parent.right
+
+ scrollFlickable: itemsFlickable
+ style: itemsView.style
+ }
+}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml
new file mode 100644
index 0000000000..b31e8c5803
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml
@@ -0,0 +1,34 @@
+import Qt 4.6
+
+Item {
+ property string backgroundColor: "#707070"
+ property string raisedBackgroundColor: "#e0e0e0"
+
+ property string scrollbarBackgroundColor: "#505050"
+ property string scrollbarHandleColor: "#303030"
+
+ property string itemNameTextColor: "#c0c0c0"
+
+ property string sectionTitleTextColor: "#f0f0f0"
+ property string sectionTitleBackgroundColor: "#909090"
+
+ property string gridLineColor: "#a0a0a0"
+
+ property int sectionTitleHeight: 20
+ property int sectionTitleSpacing: 2
+
+ property int selectionSectionOffset: sectionTitleHeight + sectionTitleSpacing
+
+ property int iconWidth: 32
+ property int iconHeight: 32
+
+ property int textWidth: 80
+ property int textHeight: 15
+
+ property int cellSpacing: 7
+ property int cellMargin: 10
+
+ property int cellWidth: textWidth + 2*cellMargin
+ property int cellHeight: itemLibraryIconHeight + textHeight + 2*cellMargin + cellSpacing
+}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml
new file mode 100644
index 0000000000..cff81189a1
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml
@@ -0,0 +1,151 @@
+import Qt 4.6
+
+Item {
+ id: bar
+
+ property var handleBar: handle
+
+ property var scrollFlickable
+ property var style
+
+ property bool scrolling: (scrollFlickable.viewportHeight > scrollFlickable.height)
+ property int scrollHeight: height - handle.height
+
+ Binding {
+ target: scrollFlickable
+ property: "viewportY"
+ value: Math.max(0, scrollFlickable.viewportHeight - scrollFlickable.height) *
+ handle.y / scrollHeight
+ }
+
+ Rectangle {
+ anchors.fill: parent;
+ anchors.rightMargin: 1
+ anchors.bottomMargin: 1
+ color: "transparent"
+ border.width: 1;
+ border.color: "#8F8F8F";
+ }
+
+ function moveHandle(viewportPos) {
+ var pos;
+
+ if (bar.scrollFlickable) {//.visibleArea.yPosition) {
+ pos = bar.scrollHeight * viewportPos / (bar.scrollFlickable.viewportHeight - bar.scrollFlickable.height);
+ } else
+ pos = 0;
+
+// handleMoveAnimation.to = Math.min(bar.scrollHeight, pos)
+// handleMoveAnimation.start();
+ handle.y = Math.min(bar.scrollHeight, pos)
+ }
+
+ function limitHandle() {
+ // the following "if" is needed to get around NaN when starting up
+ if (scrollFlickable)
+ handle.y = Math.min(handle.height * scrollFlickable.visibleArea.yPosition,
+ scrollHeight);
+ else
+ handle.y = 0;
+ }
+/*
+ NumberAnimation {
+ id: handleResetAnimation
+ target: handle
+ property: "y"
+ from: handle.y
+ to: 0
+ duration: 500
+ }
+*/
+ Connection {
+ sender: scrollFlickable
+ signal: "heightChanged"
+ script: {
+ /* since binding loops prevent setting the handle properly,
+ let's animate it to 0 */
+ if (scrollFlickable.viewportY > (scrollFlickable.viewportHeight - scrollFlickable.height))
+// handleResetAnimation.start()
+ handle.y = 0
+ }
+ }
+
+ onScrollFlickableChanged: handle.y = 0
+
+/*
+ Rectangle {
+ anchors.fill: parent
+ anchors.leftMargin: 3
+ anchors.rightMargin: 3
+ anchors.topMargin: 2
+ anchors.bottomMargin: 2
+ radius: width / 2
+ color: style.scrollbarBackgroundColor
+ }
+*/
+ MouseRegion {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: handle.top
+ onClicked: {
+// handleMoveAnimation.to = Math.max(0, handle.y - 40)
+// handleMoveAnimation.start();
+ handle.y = Math.max(0, handle.y - 40)
+ }
+ }
+
+ Item {
+ id: handle
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: Math.max(width, bar.height * Math.min(1, scrollFlickable.visibleArea.heightRatio))
+
+// radius: width / 2
+// color: style.scrollbarHandleColor
+
+ Rectangle {
+ width: parent.height
+ height: parent.width
+ y: parent.height
+
+ rotation: -90
+ transformOrigin: Item.TopLeft
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#C6C6C6" }
+ GradientStop { position: 1.0; color: "#7E7E7E" }
+ }
+ }
+
+ MouseRegion {
+ anchors.fill: parent
+ drag.target: parent
+ drag.axis: "YAxis"
+ drag.minimumY: 0
+ drag.maximumY: scrollHeight
+ }
+ }
+
+ MouseRegion {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: handle.bottom
+ anchors.bottom: parent.bottom
+ onClicked: {
+// handleMoveAnimation.to = Math.min(scrollHeight, handle.y + 40)
+// handleMoveAnimation.start();
+ handle.y = Math.min(scrollHeight, handle.y + 40)
+ }
+ }
+/*
+ NumberAnimation {
+ id: handleMoveAnimation
+ target: handle
+ property: "y"
+ duration: 200
+ }
+*/
+}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml
new file mode 100644
index 0000000000..792ee33297
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml
@@ -0,0 +1,151 @@
+import Qt 4.6
+
+Column {
+ id: sectionView
+
+ property var style
+ property var itemHighlight
+
+ property int entriesPerRow
+ property int cellWidth
+ property int cellHeight
+
+ signal itemSelected(int itemLibId)
+ signal itemDragged(int itemLibId)
+
+ function expand() {
+ gridFrame.state = "";
+ }
+
+ Component {
+ id: itemDelegate
+
+ ItemView {
+ id: item
+ style: sectionView.style
+
+ function selectItem() {
+ itemHighlight.select(sectionView, item, gridFrame.x, -gridView.viewportY);
+ sectionView.itemSelected(itemLibId);
+ }
+
+ onItemClicked: selectItem()
+ onItemDragged: {
+ selectItem();
+ sectionView.itemDragged(itemLibId);
+ }
+ }
+ }
+
+ Rectangle {
+ width: parent.width
+ height: style.sectionTitleHeight
+
+ color: style.sectionTitleBackgroundColor
+ radius: 2
+
+ Item {
+ id: arrow
+
+ Rectangle { y: 0; x: 0; height: 1; width: 9; color: "#aeaeae" }
+ Rectangle { y: 1; x: 1; height: 1; width: 7; color: "#aeaeae" }
+ Rectangle { y: 2; x: 2; height: 1; width: 5; color: "#aeaeae" }
+ Rectangle { y: 3; x: 3; height: 1; width: 3; color: "#aeaeae" }
+ Rectangle { y: 4; x: 4; height: 1; width: 1; color: "#aeaeae" }
+
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ width: 9
+ height: 5
+
+ transformOrigin: Item.Center
+ }
+ Text {
+ id: text
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: arrow.right
+ anchors.leftMargin: 5
+
+ text: sectionName
+ color: style.sectionTitleTextColor
+ Component.onCompleted: text.color = style.sectionTitleTextColor
+ }
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: {
+ if (itemHighlight.visible &&
+ (itemHighlight.section == sectionView)) {
+ itemHighlight.unselect();
+ sectionView.itemSelected(-1);
+ }
+ gridFrame.toggleVisibility()
+ }
+ }
+ }
+
+ Item { height: 2; width: 1 }
+
+ Item {
+ id: gridFrame
+
+ function toggleVisibility() {
+ state = ((state == "hidden")? "":"hidden")
+ }
+
+ clip: true
+ width: sectionView.entriesPerRow * sectionView.cellWidth + 1
+ height: Math.ceil(sectionEntries.count / sectionView.entriesPerRow) * sectionView.cellHeight + 1
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ GridView {
+ id: gridView
+
+ Connection {
+ sender: itemLibraryModel
+ signal: "visibilityUpdated()"
+ script: gridView.positionViewAtIndex(0)
+ }
+
+ anchors.fill: parent
+ anchors.rightMargin: 1
+ anchors.bottomMargin: 1
+
+ cellWidth: sectionView.cellWidth
+ cellHeight: sectionView.cellHeight
+ model: sectionEntries
+ delegate: itemDelegate
+ interactive: false
+ highlightFollowsCurrentItem: false
+ }
+
+ states: [
+ State {
+ name: "hidden"
+ PropertyChanges {
+ target: gridFrame
+ height: 0
+ opacity: 0
+ }
+ PropertyChanges {
+ target: arrow
+ rotation: -90
+ }
+ }
+ ]
+/*
+ transitions: [
+ Transition {
+ NumberAnimation {
+ matchProperties: "x,y,width,height,opacity,rotation"
+ duration: 200
+ }
+ }
+ ]
+*/
+ }
+
+ Item { height: 4; width: 1 }
+}
+
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml
new file mode 100644
index 0000000000..3de5a29a52
--- /dev/null
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml
@@ -0,0 +1,140 @@
+import Qt 4.6
+
+Item {
+ id: selector
+
+ property var style
+ property var scrollFlickable
+
+ signal moveScrollbarHandle(int viewportPos)
+
+ visible: false
+
+ property var section: null
+ property var item: null
+ property int sectionXOffset: 0
+ property int sectionYOffset: 0
+
+ property real staticX: (section && item)? (section.x + item.x + sectionXOffset):0;
+ property real staticY: (section && item)? (section.y + style.selectionSectionOffset + item.y + sectionYOffset):0;
+
+ property bool animateMove: true
+
+ Connection {
+ sender: itemLibraryModel
+ signal: "visibilityUpdated()"
+ script: selector.unselectNow()
+ }
+
+ function select(section, item, sectionXOffset, sectionYOffset) {
+
+ if (!selector.visible) {
+ selector.animateMove = false
+ }
+
+ selector.item = item
+ selector.section = section
+ selector.sectionXOffset = sectionXOffset
+ selector.sectionYOffset = sectionYOffset
+
+ if (!selector.visible) {
+// print("no prev selection");
+
+// selector.opacity = 0
+ selector.visible = true
+// selectAnimation.start();
+ }
+
+ focusSelection();
+ }
+
+ function focusSelection() {
+ var pos = -1;
+
+ if (selector.staticY < scrollFlickable.viewportY)
+ pos = selector.staticY
+ else if ((selector.staticY + selector.height) >
+ (scrollFlickable.viewportY + scrollFlickable.height - 1))
+ pos = selector.staticY + selector.height - scrollFlickable.height + 1
+
+ if (pos >= 0) {
+/*
+ followSelectionAnimation.to = pos
+ followSelectionAnimation.start()
+*/
+ scrollFlickable.viewportY = pos;
+ selector.moveScrollbarHandle(pos)
+ }
+ }
+
+ function unselect() {
+// unselectAnimation.start();
+ unselectNow();
+ }
+
+ function unselectNow() {
+ selector.section = null
+ selector.item = null
+ selector.sectionXOffset = 0
+ selector.sectionYOffset = 0
+ selector.visible = false
+ selector.opacity = 1
+ }
+/*
+ NumberAnimation {
+ id: selectAnimation
+ target: selector
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 200
+ onRunningChanged: {
+ if (!running)
+ selector.animateMove = true
+ }
+ }
+
+ NumberAnimation {
+ id: unselectAnimation
+ target: selector
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: 150
+ onRunningChanged: {
+ if (!running)
+ selector.unselectNow();
+ }
+ }
+
+ NumberAnimation {
+ id: followSelectionAnimation
+ target: scrollFlickable
+ property: "viewportY"
+ duration: 200
+ }
+
+ x: SpringFollow {
+ source: selector.staticX;
+ spring: selector.animateMove? 3.0:0.0;
+ damping: 0.35
+ epsilon: 0.25
+ }
+
+ y: SpringFollow {
+ source: selector.staticY;
+ spring: selector.animateMove? 3.0:0.0;
+ damping: 0.35
+ epsilon: 0.25
+ }
+*/
+
+ x: selector.staticX
+ y: selector.staticY
+
+ Rectangle {
+ anchors.fill: parent
+ color: "steelblue"
+ }
+}
+