diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 04a53773010..27933db2627 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -33,11 +33,16 @@ #include #include +#include #include #include #include #include +static bool inline registerItemLibrarySortedModel() { + qmlRegisterType(); + return true; +} namespace QmlDesigner { @@ -45,31 +50,59 @@ namespace Internal { static QHash collapsedStateHash; - -template -ItemLibrarySortedModel::ItemLibrarySortedModel(QObject *parent) : - QDeclarativeListModel(parent) +ItemLibrarySortedModel::ItemLibrarySortedModel(QObject *parent) : + QAbstractListModel(parent) { } - -template -ItemLibrarySortedModel::~ItemLibrarySortedModel() +ItemLibrarySortedModel::~ItemLibrarySortedModel() { clearElements(); } - -template -void ItemLibrarySortedModel::clearElements() +int ItemLibrarySortedModel::rowCount(const QModelIndex &) const { - while (m_elementOrder.count() > 0) - removeElement(m_elementOrder.at(0).libId); + return m_privList.count(); } +QVariant ItemLibrarySortedModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row()+1 > m_privList.count()) { + qDebug() << Q_FUNC_INFO << "invalid index requested"; + return QVariant(); + } -template -void ItemLibrarySortedModel::addElement(T *element, int libId) + if (m_roleNames.contains(role)) { + QVariant value = m_privList.at(index.row())->property(m_roleNames.value(role)); + + if (ItemLibrarySortedModel* model = qobject_cast(value.value())) { + return QVariant::fromValue(model); + } + + return m_privList.at(index.row())->property(m_roleNames.value(role)); + } + + qWarning() << Q_FUNC_INFO << "invalid role requested"; + + return QVariant(); +} + +void ItemLibrarySortedModel::clearElements() +{ + beginResetModel(); + while (m_elementOrder.count() > 0) + removeElement(m_elementOrder.at(0).libId); + endResetModel(); +} + +static bool compareFunction(QObject *first, QObject *second) +{ + static const char sortRoleName[] = "sortingRole"; + + return first->property(sortRoleName).toString() < second->property(sortRoleName).toString(); +} + +void ItemLibrarySortedModel::addElement(QObject *element, int libId) { struct order_struct orderEntry; orderEntry.libId = libId; @@ -77,7 +110,7 @@ void ItemLibrarySortedModel::addElement(T *element, int libId) int pos = 0; while ((pos < m_elementOrder.count()) && - (*(m_elementModels.value(m_elementOrder.at(pos).libId)) < *element)) + compareFunction(m_elementModels.value(m_elementOrder.at(pos).libId), element)) ++pos; m_elementModels.insert(libId, element); @@ -86,10 +119,9 @@ void ItemLibrarySortedModel::addElement(T *element, int libId) setElementVisible(libId, true); } -template -void ItemLibrarySortedModel::removeElement(int libId) +void ItemLibrarySortedModel::removeElement(int libId) { - T *element = m_elementModels.value(libId); + QObject *element = m_elementModels.value(libId); int pos = findElement(libId); setElementVisible(libId, false); @@ -100,49 +132,77 @@ void ItemLibrarySortedModel::removeElement(int libId) delete element; } - -template -bool ItemLibrarySortedModel::elementVisible(int libId) const +bool ItemLibrarySortedModel::elementVisible(int libId) const { int pos = findElement(libId); return m_elementOrder.at(pos).visible; } - -template -bool ItemLibrarySortedModel::setElementVisible(int libId, bool visible) +bool ItemLibrarySortedModel::setElementVisible(int libId, bool visible) { int pos = findElement(libId); if (m_elementOrder.at(pos).visible == visible) return false; int visiblePos = visibleElementPosition(libId); - if (visible) - insert(visiblePos, *(m_elementModels.value(libId))); - else - remove(visiblePos); + if (visible) { + privateInsert(visiblePos, (m_elementModels.value(libId))); + } else { + privateRemove(visiblePos); + } m_elementOrder[pos].visible = visible; return true; } +void ItemLibrarySortedModel::privateInsert(int pos, QObject *element) +{ + QObject *object = element; -template -const QMap &ItemLibrarySortedModel::elements() const + for (int i = 0; i < object->metaObject()->propertyCount(); ++i) { + QMetaProperty property = object->metaObject()->property(i); + addRoleName(property.name()); + } + + m_privList.insert(pos, element); +} + +void ItemLibrarySortedModel::privateRemove(int pos) +{ + m_privList.removeAt(pos); +} + +const QMap &ItemLibrarySortedModel::elements() const { return m_elementModels; } +template +const QList ItemLibrarySortedModel::elementsByType() const +{ + QList objectList; -template -T *ItemLibrarySortedModel::elementModel(int libId) + foreach (QObject *item, elements()) { + T object = qobject_cast(item); + if (object) + objectList.append(object); + } + + return objectList; +} + +QObject *ItemLibrarySortedModel::element(int libId) { return m_elementModels.value(libId); } +template +T ItemLibrarySortedModel::elementByType(int libId) +{ + return qobject_cast(element(libId)); +} -template -int ItemLibrarySortedModel::findElement(int libId) const +int ItemLibrarySortedModel::findElement(int libId) const { int i = 0; QListIterator it(m_elementOrder); @@ -156,8 +216,7 @@ int ItemLibrarySortedModel::findElement(int libId) const return -1; } -template -int ItemLibrarySortedModel::visibleElementPosition(int libId) const +int ItemLibrarySortedModel::visibleElementPosition(int libId) const { int i = 0; QListIterator it(m_elementOrder); @@ -173,26 +232,36 @@ int ItemLibrarySortedModel::visibleElementPosition(int libId) const return -1; } +void ItemLibrarySortedModel::resetModel() +{ + beginResetModel(); + endResetModel(); +} +void ItemLibrarySortedModel::addRoleName(const QByteArray &roleName) +{ + if (m_roleNames.values().contains(roleName)) { + return; + } -ItemLibraryItemModel::ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName) - : QScriptValue(scriptEngine->newObject()), - m_scriptEngine(scriptEngine), + int key = m_roleNames.count(); + m_roleNames.insert(key, roleName); + setRoleNames(m_roleNames); +} + +ItemLibraryItemModel::ItemLibraryItemModel(int itemLibId, const QString &itemName, QObject *parent) + : QObject(parent), m_libId(itemLibId), m_name(itemName), m_iconSize(64, 64) { - QScriptValue pixmapScriptValue(m_scriptEngine->newVariant(QPixmap())); - setProperty(QLatin1String("itemLibId"), itemLibId); - setProperty(QLatin1String("itemName"), itemName); - setProperty(QLatin1String("itemPixmap"), pixmapScriptValue); } ItemLibraryItemModel::~ItemLibraryItemModel() { - setProperty(QLatin1String("itemPixmap"), QVariant::Invalid); + } @@ -207,45 +276,37 @@ QString ItemLibraryItemModel::itemName() const return m_name; } +QString ItemLibraryItemModel::itemLibraryIconPath() const +{ + //Prepend image provider prefix + return QLatin1String("image://qmldesigner_itemlibrary/")+ m_iconPath; +} + +QVariant ItemLibraryItemModel::sortingRole() const +{ + return itemName(); +} + void ItemLibraryItemModel::setItemIconPath(const QString &iconPath) { m_iconPath = iconPath; - - setProperty(QLatin1String("itemLibraryIconPath"), - QString(QLatin1String("image://qmldesigner_itemlibrary/") + iconPath)); } void ItemLibraryItemModel::setItemIconSize(const QSize &itemIconSize) { m_iconSize = itemIconSize; -// qDebug() << "set icon size" << itemIconSize; setItemIconPath(m_iconPath); } - -bool ItemLibraryItemModel::operator<(const ItemLibraryItemModel &other) const -{ - return itemName() < other.itemName(); -} - - - - -ItemLibrarySectionModel::ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString §ionName, QObject *parent) - : QScriptValue(scriptEngine->newObject()), +ItemLibrarySectionModel::ItemLibrarySectionModel(int sectionLibId, const QString §ionName, QObject *parent) + : QObject(parent), m_name(sectionName), + m_sectionLibId(sectionLibId), + m_sectionExpanded(true), m_sectionEntries(parent) { - QScriptValue::setProperty(QLatin1String("sectionLibId"), sectionLibId); - QScriptValue::setProperty(QLatin1String("sectionName"), sectionName); - QScriptValue::setProperty(QLatin1String("sectionEntries"), - scriptEngine->newVariant(QVariant::fromValue(static_cast(&m_sectionEntries)))); - - if (collapsedStateHash.contains(sectionName)) { - QScriptValue::setProperty(QLatin1String("sectionExpanded"), collapsedStateHash.value(sectionName)); - } else { - QScriptValue::setProperty(QLatin1String("sectionExpanded"), true); - } + if (collapsedStateHash.contains(sectionName)) + m_sectionExpanded= collapsedStateHash.value(sectionName); } @@ -254,6 +315,24 @@ QString ItemLibrarySectionModel::sectionName() const return m_name; } +int ItemLibrarySectionModel::sectionLibId() const +{ + return m_sectionLibId; +} + +bool ItemLibrarySectionModel::sectionExpanded() const +{ + return m_sectionExpanded; +} + +QVariant ItemLibrarySectionModel::sortingRole() const +{ + + if (sectionName() == QLatin1String("QML Components")) //Qml Components always come first + return QVariant(QLatin1String("AA.this_comes_first")); + + return sectionName(); +} void ItemLibrarySectionModel::addSectionEntry(ItemLibraryItemModel *sectionEntry) { @@ -266,6 +345,10 @@ void ItemLibrarySectionModel::removeSectionEntry(int itemLibId) m_sectionEntries.removeElement(itemLibId); } +QObject *ItemLibrarySectionModel::sectionEntries() +{ + return &m_sectionEntries; +} int ItemLibrarySectionModel::visibleItemIndex(int itemLibId) { @@ -285,11 +368,13 @@ bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText, *changed = false; - QMap::const_iterator itemIt = m_sectionEntries.elements().constBegin(); + QMap::const_iterator itemIt = m_sectionEntries.elements().constBegin(); while (itemIt != m_sectionEntries.elements().constEnd()) { - bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText), - itemChanged = false; + bool itemVisible = m_sectionEntries.elementByType( + itemIt.key())->itemName().toLower().contains(searchText); + + bool itemChanged = false; itemChanged = m_sectionEntries.setElementVisible(itemIt.key(), itemVisible); *changed |= itemChanged; @@ -300,24 +385,21 @@ bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText, ++itemIt; } + m_sectionEntries.resetModel(); + + emit sectionEntriesChanged(); + return haveVisibleItems; } void ItemLibrarySectionModel::updateItemIconSize(const QSize &itemIconSize) { - foreach (ItemLibraryItemModel *item, m_sectionEntries.elements()) { - item->setItemIconSize(itemIconSize); + foreach (ItemLibraryItemModel* itemLibraryItemModel, m_sectionEntries.elementsByType()) { + itemLibraryItemModel->setItemIconSize(itemIconSize); } } -bool ItemLibrarySectionModel::operator<(const ItemLibrarySectionModel &other) const -{ - if (sectionName() == QLatin1String("QML Components")) //Qml Components always come first - return true; - return sectionName() < other.sectionName(); -} - void ItemLibraryModel::setExpanded(bool expanded, const QString §ion) { if (collapsedStateHash.contains(section)) @@ -327,9 +409,8 @@ void ItemLibraryModel::setExpanded(bool expanded, const QString §ion) collapsedStateHash.insert(section, expanded); } -ItemLibraryModel::ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent) - : ItemLibrarySortedModel(parent), - m_scriptEngine(scriptEngine), +ItemLibraryModel::ItemLibraryModel(QObject *parent) + : ItemLibrarySortedModel(parent), m_searchText(""), m_itemIconSize(64, 64), m_nextLibId(0) @@ -365,15 +446,16 @@ void ItemLibraryModel::setItemIconSize(const QSize &itemIconSize) { m_itemIconSize = itemIconSize; - foreach (ItemLibrarySectionModel *section, elements().values()) - section->updateItemIconSize(itemIconSize); + foreach (ItemLibrarySectionModel* itemLibrarySectionModel, sections()) { + itemLibrarySectionModel->updateItemIconSize(itemIconSize); + } } int ItemLibraryModel::getItemSectionIndex(int itemLibId) { if (m_sections.contains(itemLibId)) - return elementModel(m_sections.value(itemLibId))->visibleItemIndex(itemLibId); + return section(m_sections.value(itemLibId))->visibleItemIndex(itemLibId); else return -1; } @@ -394,7 +476,7 @@ bool ItemLibraryModel::isItemVisible(int itemLibId) if (!elementVisible(sectionLibId)) return false; - return elementModel(sectionLibId)->isItemVisible(itemLibId); + return section(sectionLibId)->isItemVisible(itemLibId); } Import entryToImport(const ItemLibraryEntry &entry) @@ -439,17 +521,17 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) if (sections.contains(itemSectionName)) { sectionId = sections.value(itemSectionName); - sectionModel = elementModel(sectionId); + sectionModel = section(sectionId); } else { sectionId = m_nextLibId++; - sectionModel = new ItemLibrarySectionModel(m_scriptEngine.data(), sectionId, itemSectionName, this); + sectionModel = new ItemLibrarySectionModel(sectionId, itemSectionName, this); addElement(sectionModel, sectionId); sections.insert(itemSectionName, sectionId); } m_itemInfos.insert(itemId, entry); - itemModel = new ItemLibraryItemModel(m_scriptEngine.data(), itemId, entry.name()); + itemModel = new ItemLibraryItemModel(itemId, entry.name(), sectionModel); // delayed creation of (default) icons if (entry.iconPath().isEmpty()) @@ -501,15 +583,26 @@ QIcon ItemLibraryModel::getIcon(int libId) return m_itemInfos.value(libId).icon(); } +ItemLibrarySectionModel *ItemLibraryModel::section(int libId) +{ + return elementByType(libId); +} + +QList ItemLibraryModel::sections() const +{ + return elementsByType(); +} void ItemLibraryModel::updateVisibility() { + beginResetModel(); + endResetModel(); bool changed = false; - QMap::const_iterator sectionIt = elements().constBegin(); + QMap::const_iterator sectionIt = elements().constBegin(); while (sectionIt != elements().constEnd()) { + ItemLibrarySectionModel *sectionModel = section(sectionIt.key()); - ItemLibrarySectionModel *sectionModel = sectionIt.value(); QString sectionSearchText = m_searchText; if (sectionModel->sectionName().toLower().contains(m_searchText)) @@ -564,6 +657,11 @@ QPixmap ItemLibraryModel::createDragPixmap(int , int ) return QPixmap::fromImage(dragImage); } +void registerQmlTypes() +{ + registerItemLibrarySortedModel(); +} + } // namespace Internal } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index 1aacaa63888..cae9d2fbab5 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -32,8 +32,8 @@ #include #include -#include -#include +#include +#include QT_FORWARD_DECLARE_CLASS(QMimeData) @@ -45,52 +45,82 @@ class Model; namespace Internal { -template -class ItemLibrarySortedModel: public QDeclarativeListModel { +void registerQmlTypes(); + +class ItemLibrarySortedModel: public QAbstractListModel { + + Q_OBJECT + public: ItemLibrarySortedModel(QObject *parent = 0); ~ItemLibrarySortedModel(); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + void clearElements(); - void addElement(T *element, int libId); + void addElement(QObject *element, int libId); void removeElement(int libId); bool elementVisible(int libId) const; bool setElementVisible(int libId, bool visible); - const QMap &elements() const; + void privateInsert(int pos, QObject *element); + void privateRemove(int pos); + + const QMap &elements() const; + + template + const QList elementsByType() const; + + QObject *element(int libId); + + template + T elementByType(int libId); - T *elementModel(int libId); int findElement(int libId) const; int visibleElementPosition(int libId) const; + void resetModel(); + private: + void addRoleName(const QByteArray &roleName); + struct order_struct { int libId; bool visible; }; - QMap m_elementModels; + QMap m_elementModels; QList m_elementOrder; + + QList m_privList; + QHash m_roleNames; }; +class ItemLibraryItemModel: public QObject { + + Q_OBJECT + + Q_PROPERTY(int itemLibId READ itemLibId FINAL) + Q_PROPERTY(QString itemName READ itemName FINAL) + Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL) + Q_PROPERTY(QVariant sortingRole READ sortingRole FINAL) -class ItemLibraryItemModel: public QScriptValue { public: - ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName); + ItemLibraryItemModel(int itemLibId, const QString &itemName, QObject *parent); ~ItemLibraryItemModel(); int itemLibId() const; QString itemName() const; + QString itemLibraryIconPath() const; + QVariant sortingRole() const; void setItemIconPath(const QString &iconPath); void setItemIconSize(const QSize &itemIconSize); - bool operator<(const ItemLibraryItemModel &other) const; - private: - QWeakPointer m_scriptEngine; int m_libId; QString m_name; QString m_iconPath; @@ -98,14 +128,27 @@ private: }; -class ItemLibrarySectionModel: public QScriptValue { +class ItemLibrarySectionModel: public QObject { + + Q_OBJECT + + Q_PROPERTY(QObject* sectionEntries READ sectionEntries NOTIFY sectionEntriesChanged FINAL) + Q_PROPERTY(int sectionLibId READ sectionLibId FINAL) + Q_PROPERTY(QString sectionName READ sectionName FINAL) + Q_PROPERTY(bool sectionExpanded READ sectionExpanded FINAL) + Q_PROPERTY(QVariant sortingRole READ sortingRole FINAL) + public: - ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString §ionName, QObject *parent = 0); + ItemLibrarySectionModel(int sectionLibId, const QString §ionName, QObject *parent = 0); QString sectionName() const; + int sectionLibId() const; + bool sectionExpanded() const; + QVariant sortingRole() const; void addSectionEntry(ItemLibraryItemModel *sectionEntry); void removeSectionEntry(int itemLibId); + QObject *sectionEntries(); int visibleItemIndex(int itemLibId); bool isItemVisible(int itemLibId); @@ -113,20 +156,24 @@ public: bool updateSectionVisibility(const QString &searchText, bool *changed); void updateItemIconSize(const QSize &itemIconSize); - bool operator<(const ItemLibrarySectionModel &other) const; +signals: + void sectionEntriesChanged(); private: QString m_name; - ItemLibrarySortedModel m_sectionEntries; + int m_sectionLibId; + bool m_sectionExpanded; + ItemLibrarySortedModel m_sectionEntries; }; -class ItemLibraryModel: public ItemLibrarySortedModel { +class ItemLibraryModel: public ItemLibrarySortedModel { + Q_OBJECT Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged) public: - explicit ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent = 0); + explicit ItemLibraryModel(QObject *parent = 0); ~ItemLibraryModel(); QString searchText() const; @@ -137,6 +184,9 @@ public: QMimeData *getMimeData(int libId); QIcon getIcon(int libId); + ItemLibrarySectionModel* section(int libId); + QList sections() const; + public slots: void setSearchText(const QString &searchText); void setItemIconSize(const QSize &itemIconSize); @@ -159,7 +209,6 @@ private: int getHeight(const ItemLibraryEntry &entry); QPixmap createDragPixmap(int width, int height); - QWeakPointer m_scriptEngine; QMap m_itemInfos; QMap m_sections; @@ -171,5 +220,7 @@ private: } // namespace Internal } // namespace QmlDesigner +QML_DECLARE_TYPE(QmlDesigner::Internal::ItemLibrarySortedModel) + #endif // ITEMLIBRARYMODEL_H diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 9888a566e69..0f976beb5bf 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -67,6 +67,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_resourcesView(new Internal::ItemLibraryTreeView(this)), m_filterFlag(QtBasic) { + Internal::registerQmlTypes(); + setWindowTitle(tr("Library", "Title of library view")); /* create Items view and its model */ @@ -75,7 +77,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_itemsView->setAcceptDrops(false); m_itemsView->setFocusPolicy(Qt::ClickFocus); m_itemsView->setResizeMode(QDeclarativeView::SizeRootObjectToView); - m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::getScriptEngine(m_itemsView->engine()), this); + m_itemLibraryModel = new Internal::ItemLibraryModel(this); m_itemLibraryModel->setItemIconSize(m_itemIconSize); QDeclarativeContext *rootContext = m_itemsView->rootContext(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml index 20ecae2ce49..b81f405258a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml @@ -90,146 +90,147 @@ focus */ onEntered: { if (!pressed) stopDragAndDrop() + } + } + + signal selectionUpdated(int itemSectionIndex) + + property int selectedItemLibId: -1 + property int selectionSectionLibId: -1 + + function setSelection(itemLibId) { + selectedItemLibId = itemLibId + selectionSectionLibId = itemLibraryModel.getSectionLibId(itemLibId) + selectionUpdated(itemLibraryModel.getItemSectionIndex(itemLibId)) + } + + function unsetSelection() { + selectedItemLibId = -1 + selectionSectionLibId = -1 + selectionUpdated(-1) + } + + Connections { + target: itemLibraryModel + onVisibilityChanged: { + if (itemLibraryModel.isItemVisible(selectedItemLibId)) + setSelection(selectedItemLibId) + else + unsetSelection() + } + } + + /* the following 3 properties are calculated here for performance + reasons and then passed to the section views */ + 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 + + Component { + id: sectionDelegate + + SectionView { + id: section + + entriesPerRow: itemsView.entriesPerRow + cellWidth: itemsView.cellWidth + cellHeight: itemsView.cellHeight + + width: itemsFlickable.width + itemHighlight: selector + + property bool containsSelection: (selectionSectionLibId == sectionLibId) + + onItemSelected: { + itemsView.setSelection(itemLibId) + itemsView.itemSelected(itemLibId) } + onItemDragged: { + section.itemSelected(itemLibId) + itemsView.itemDragged(itemLibId) } - signal selectionUpdated(int itemSectionIndex) - - property int selectedItemLibId: -1 - property int selectionSectionLibId: -1 - - function setSelection(itemLibId) { - selectedItemLibId = itemLibId - selectionSectionLibId = itemLibraryModel.getSectionLibId(itemLibId) - selectionUpdated(itemLibraryModel.getItemSectionIndex(itemLibId)) + Connections { + target: itemsView + onExpandAllEntries: section.expand() + onSelectionUpdated: { + if (containsSelection) { + section.setSelection(itemSectionIndex) + section.focusSelection(itemsFlickable) + } else + section.unsetSelection() } + } - function unsetSelection() { - selectedItemLibId = -1 - selectionSectionLibId = -1 - selectionUpdated(-1) + Component { + id: selector + + Selector { + x: containsSelection? section.currentItem.x:0 + y: containsSelection? section.currentItem.y:0 + width: itemsView.cellWidth + height: itemsView.cellHeight + + visible: containsSelection } + } + } + } - Connections { - target: itemLibraryModel - onVisibilityChanged: { - if (itemLibraryModel.isItemVisible(selectedItemLibId)) - setSelection(selectedItemLibId) - else - unsetSelection() - } - } + Flickable { + id: itemsFlickable - /* the following 3 properties are calculated here for performance -reasons and then passed to the section views */ - 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 + anchors.top: parent.top + anchors.topMargin: 3 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: scrollbarFrame.left + boundsBehavior: Flickable.DragOverBounds - Component { - id: sectionDelegate + interactive: false + contentHeight: col.height - SectionView { - id: section - - entriesPerRow: itemsView.entriesPerRow - cellWidth: itemsView.cellWidth - cellHeight: itemsView.cellHeight - - width: itemsFlickable.width - itemHighlight: selector - - property bool containsSelection: (selectionSectionLibId == sectionLibId) - - onItemSelected: { - itemsView.setSelection(itemLibId) - itemsView.itemSelected(itemLibId) - } - onItemDragged: { - section.itemSelected(itemLibId) - itemsView.itemDragged(itemLibId) - } - - Connections { - target: itemsView - onExpandAllEntries: section.expand() - onSelectionUpdated: { - if (containsSelection) { - section.setSelection(itemSectionIndex) - section.focusSelection(itemsFlickable) - } else - section.unsetSelection() - } - } - - Component { - id: selector - - Selector { - x: containsSelection? section.currentItem.x:0 - y: containsSelection? section.currentItem.y:0 - width: itemsView.cellWidth - height: itemsView.cellHeight - - visible: containsSelection - } - } - } - } - - Flickable { - id: itemsFlickable - - anchors.top: parent.top - anchors.topMargin: 3 - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: scrollbarFrame.left - boundsBehavior: Flickable.DragOverBounds - - interactive: false - contentHeight: col.height - - /* Limit the content position. Without this, resizing would get the + /* Limit the content position. Without this, resizing would get the content position out of scope regarding the scrollbar. */ - function limitContentPos() { - if (contentY < 0) { - contentY = 0; - } else { - var maxContentY = Math.max(0, contentHeight - height) - if (contentY > maxContentY) - contentY = maxContentY; - } - } - onHeightChanged: limitContentPos() - onContentHeightChanged: limitContentPos() + function limitContentPos() { + if (contentY < 0) { + contentY = 0; + } else { + var maxContentY = Math.max(0, contentHeight - height) + if (contentY > maxContentY) + contentY = maxContentY; + } + } + onHeightChanged: limitContentPos() + onContentHeightChanged: limitContentPos() - Column { - id: col + Column { + id: col - Repeater { - model: itemLibraryModel // to be set in Qml context - delegate: sectionDelegate - } - } - } + Repeater { + model: itemLibraryModel // to be set in Qml context + delegate: sectionDelegate + } + } + } - Item { - id: scrollbarFrame + Item { + id: scrollbarFrame - anchors.top: parent.top - anchors.topMargin: 2 - anchors.bottom: parent.bottom - anchors.bottomMargin: 1 - anchors.right: parent.right - width: (itemsFlickable.contentHeight > itemsFlickable.height)? 11:0 + anchors.top: parent.top + anchors.topMargin: 2 + anchors.bottom: parent.bottom + anchors.bottomMargin: 1 + anchors.right: parent.right + width: (itemsFlickable.contentHeight > itemsFlickable.height)? 11:0 - Scrollbar { - id: scrollbar - anchors.fill: parent - anchors.leftMargin: 1 + Scrollbar { + id: scrollbar + anchors.fill: parent + anchors.leftMargin: 1 - flickable: itemsFlickable - } - } - } + flickable: itemsFlickable + } + } +} diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml index a29cf8997da..9f582f5baaa 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml @@ -77,18 +77,18 @@ Column { var currentItemX = sectionView.x + gridFrame.x + gridView.x + gridView.currentItem.x; var currentItemY = sectionView.y + gridFrame.y + gridView.y + gridView.currentItem.y - - gridView.contentY; // workaround: GridView reports wrong contentY + - gridView.contentY; // workaround: GridView reports wrong contentY if (currentItemY < flickable.contentY) pos = Math.max(0, currentItemY) - else if ((currentItemY + gridView.currentItem.height) > - (flickable.contentY + flickable.height - 1)) - pos = Math.min(Math.max(0, flickable.contentHeight - flickable.height), - currentItemY + gridView.currentItem.height - flickable.height + 1) + else if ((currentItemY + gridView.currentItem.height) > + (flickable.contentY + flickable.height - 1)) + pos = Math.min(Math.max(0, flickable.contentHeight - flickable.height), + currentItemY + gridView.currentItem.height - flickable.height + 1) - if (pos >= 0) - flickable.contentY = pos + if (pos >= 0) + flickable.contentY = pos } // internal @@ -168,7 +168,8 @@ Column { clip: true width: entriesPerRow * cellWidth + 1 - height: Math.ceil(sectionEntries.count / entriesPerRow) * cellHeight + 1 + height: gridView.model !== undefined ? Math.ceil(gridView.count / sectionView.entriesPerRow) * cellHeight + 1 : 0 + anchors.horizontalCenter: parent.horizontalCenter GridView { @@ -198,18 +199,18 @@ updated properly under all conditions */ } states: [ - State { - name: "shrunk" - PropertyChanges { - target: gridFrame - height: 0 - opacity: 0 + State { + name: "shrunk" + PropertyChanges { + target: gridFrame + height: 0 + opacity: 0 + } + PropertyChanges { + target: arrow + rotation: -90 + } } - PropertyChanges { - target: arrow - rotation: -90 - } - } ] }