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