From f7e0366d65f5f96788b80b9e1255debcd904d601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Schummer?= <ext-jorg.2.schummer@nokia.com> Date: Wed, 10 Mar 2010 12:45:49 +0200 Subject: [PATCH] QmlDesigner.ItemLibrary: various updates - clearing search input focus when clicking clear icon - re-set updated sections' models - using GridView-based item selection - C++ code cleanup - Manhattan-length used for drag & drop initiation - integrated QtCreator's filter text input - replaced QToolButtons with a QTabBar - fix: eliding text & corrected selector offset - styled resources view - updated Qml syntax --- .../components/itemlibrary/itemlibrary.cpp | 178 ++++++------- .../components/itemlibrary/itemlibrary.h | 14 +- .../components/itemlibrary/itemlibrary.pri | 2 - .../components/itemlibrary/itemlibrary.ui | 243 ------------------ .../itemlibrary/itemlibrarymodel.cpp | 108 ++++++-- .../components/itemlibrary/itemlibrarymodel.h | 16 +- .../itemlibrary/itemlibrarywidgets.cpp | 106 +++++++- .../itemlibrary/itemlibrarywidgets.h | 27 +- .../components/itemlibrary/qml/ItemView.qml | 30 ++- .../components/itemlibrary/qml/ItemsView.qml | 146 ++++++++--- .../itemlibrary/qml/ItemsViewStyle.qml | 10 +- .../components/itemlibrary/qml/Scrollbar.qml | 38 +-- .../itemlibrary/qml/SectionView.qml | 81 ++++-- .../components/itemlibrary/qml/Selector.qml | 58 +---- 14 files changed, 533 insertions(+), 524 deletions(-) delete mode 100644 src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp index fd8ee938280..e62a4962804 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp @@ -29,30 +29,19 @@ #include "itemlibrary.h" +#include <utils/filterlineedit.h> +#include "itemlibrarywidgets.h" #include "itemlibrarymodel.h" #include "customdraganddrop.h" -#include "ui_itemlibrary.h" -#include <metainfo.h> -#include <itemlibraryinfo.h> -#include <formeditorscene.h> - -#include <QtCore/QDebug> -#include <QtGui/QContextMenuEvent> -#include <QtGui/QMenu> -#include <QtGui/QAction> -#include <QtGui/QGraphicsView> -#include <QtGui/QGraphicsScene> -#include <QtGui/QGraphicsItem> -#include <QtGui/QPixmap> -#include <QSortFilterProxyModel> -#include <QLabel> -#include <QMainWindow> -#include <QMenuBar> -#include <QFile> -#include <QDirModel> +#include <QFileInfo> #include <QFileIconProvider> +#include <QDirModel> +#include <QStackedWidget> +#include <QGridLayout> +#include <QTabBar> #include <QImageReader> +#include <QMimeData> #include <QDeclarativeView> #include <QDeclarativeItem> @@ -104,23 +93,29 @@ class ItemLibraryPrivate { public: ItemLibraryPrivate(QObject *object); - Ui::ItemLibrary m_ui; Internal::ItemLibraryModel *m_itemLibraryModel; - QDeclarativeView *m_itemsView; QDirModel *m_resourcesDirModel; - QString m_resourcePath; + + QStackedWidget *m_stackedWidget; + Utils::FilterLineEdit *m_lineEdit; + QDeclarativeView *m_itemsView; + Internal::ItemLibraryTreeView *m_resourcesView; + QSize m_itemIconSize, m_resIconSize; MyFileIconProvider m_iconProvider; }; ItemLibraryPrivate::ItemLibraryPrivate(QObject *object) : m_itemLibraryModel(0), + m_resourcesDirModel(0), + m_stackedWidget(0), + m_lineEdit(0), m_itemsView(0), + m_resourcesView(0), m_itemIconSize(22, 22), m_resIconSize(22, 22), m_iconProvider(m_resIconSize) { - m_resourcePath = QDir::currentPath(); Q_UNUSED(object); } @@ -128,78 +123,90 @@ ItemLibrary::ItemLibrary(QWidget *parent) : QFrame(parent), m_d(new ItemLibraryPrivate(this)) { - m_d->m_ui.setupUi(this); - layout()->setContentsMargins(2, 2, 2, 0); - layout()->setSpacing(2); - - m_d->m_resourcesDirModel = new QDirModel(this); - - 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->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_d->m_ui.ItemLibraryTreeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_d->m_ui.ItemLibraryTreeView->setAttribute(Qt::WA_MacShowFocusRect, false); - m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath)); + setWindowTitle(tr("Library", "Title of library view")); + /* create Items view and its model */ m_d->m_itemsView = new QDeclarativeView(this); + m_d->m_itemsView->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml")); 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->setResizeMode(QDeclarativeView::SizeRootObjectToView); - m_d->m_ui.ItemLibraryGridLayout->addWidget(m_d->m_itemsView, 0, 0); - m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::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->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml")); + QDeclarativeContext *rootContext = m_d->m_itemsView->rootContext(); + rootContext->setContextProperty(QLatin1String("itemLibraryModel"), m_d->m_itemLibraryModel); + rootContext->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_d->m_itemIconSize.width()); + rootContext->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_d->m_itemIconSize.height()); QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_d->m_itemsView->rootObject()); connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int))); connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int))); - connect(this, SIGNAL(expandAllItems()), rootItem, SLOT(expandAll())); - - connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setSearchFilter(QString))); - m_d->m_ui.lineEdit->setDragEnabled(false); - - 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(""); + connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView())); + /* create Resources view and its model */ + m_d->m_resourcesDirModel = new QDirModel(this); m_d->m_resourcesDirModel->setIconProvider(&m_d->m_iconProvider); - - setWindowTitle(tr("Library", "Title of library view")); - + m_d->m_resourcesView = new Internal::ItemLibraryTreeView(this); + m_d->m_resourcesView->setModel(m_d->m_resourcesDirModel); + m_d->m_resourcesView->setIconSize(m_d->m_resIconSize); + + /* other widgets */ + QTabBar *tabBar = new QTabBar(this); + tabBar->addTab(tr("Items", "Title of library items view")); + tabBar->addTab(tr("Resources", "Title of library resources view")); + tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + m_d->m_lineEdit = new Utils::FilterLineEdit(this); + m_d->m_lineEdit->setObjectName(QLatin1String("itemLibrarySearchInput")); + m_d->m_lineEdit->setHintText(tr("<Filter>", "Library search input hint text")); + m_d->m_lineEdit->setDragEnabled(false); + m_d->m_lineEdit->setMinimumWidth(75); + m_d->m_lineEdit->setTextMargins(0, 0, 0, 0); + QWidget *lineEditFrame = new QWidget(this); + lineEditFrame->setObjectName(QLatin1String("itemLibrarySearchInputFrame")); + QGridLayout *lineEditLayout = new QGridLayout(lineEditFrame); + lineEditLayout->setMargin(2); + lineEditLayout->setSpacing(0); + lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0); + lineEditLayout->addWidget(m_d->m_lineEdit, 0, 1, 1, 1); + lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 2); + connect(m_d->m_lineEdit, SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString))); + connect(m_d->m_lineEdit, SIGNAL(buttonClicked()), this, SLOT(clearLineEditFocus())); + + m_d->m_stackedWidget = new QStackedWidget(this); + m_d->m_stackedWidget->addWidget(m_d->m_itemsView); + m_d->m_stackedWidget->addWidget(m_d->m_resourcesView); + connect(tabBar, SIGNAL(currentChanged(int)), + m_d->m_stackedWidget, SLOT(setCurrentIndex(int))); + connect(tabBar, SIGNAL(currentChanged(int)), + this, SLOT(updateSearch())); + + QGridLayout *layout = new QGridLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addWidget(tabBar, 0, 0, 1, 1); + layout->addWidget(lineEditFrame, 1, 0, 1, 1); + layout->addWidget(m_d->m_stackedWidget, 2, 0, 1, 1); + + setResourcePath(QDir::currentPath()); + setSearchFilter(QString()); + + /* style sheets */ { QFile file(":/qmldesigner/stylesheet.css"); file.open(QFile::ReadOnly); QString styleSheet = QLatin1String(file.readAll()); setStyleSheet(styleSheet); - - QFile fileTool(":/qmldesigner/toolbutton.css"); - fileTool.open(QFile::ReadOnly); - styleSheet = QLatin1String(fileTool.readAll()); - m_d->m_ui.buttonItems->setStyleSheet(styleSheet); - m_d->m_ui.buttonResources->setStyleSheet(styleSheet); } { QFile file(":/qmldesigner/scrollbar.css"); file.open(QFile::ReadOnly); QString styleSheet = QLatin1String(file.readAll()); - m_d->m_ui.ItemLibraryTreeView->setStyleSheet(styleSheet); + m_d->m_resourcesView->setStyleSheet(styleSheet); } } @@ -208,12 +215,17 @@ ItemLibrary::~ItemLibrary() delete m_d; } +void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo) +{ + m_d->m_itemLibraryModel->update(metaInfo); +} + void ItemLibrary::setSearchFilter(const QString &searchFilter) { - if (m_d->m_ui.buttonItems->isChecked()) { + if (m_d->m_stackedWidget->currentIndex() == 0) { m_d->m_itemLibraryModel->setSearchText(searchFilter); + emit resetItemsView(); m_d->m_itemsView->update(); - emit expandAllItems(); } else { QStringList nameFilterList; if (searchFilter.contains('.')) { @@ -226,29 +238,25 @@ void ItemLibrary::setSearchFilter(const QString &searchFilter) 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); + m_d->m_resourcesView->expandToDepth(1); + m_d->m_resourcesView->scrollToTop(); } } -void ItemLibrary::itemLibraryButtonToggled() +void ItemLibrary::updateSearch() { - m_d->m_ui.LibraryStackedWidget->setCurrentIndex(0); - m_d->m_ui.buttonResources->setChecked(false); - setSearchFilter(m_d->m_ui.lineEdit->text()); + setSearchFilter(m_d->m_lineEdit->typedText()); } -void ItemLibrary::resourcesButtonToggled() +void ItemLibrary::clearLineEditFocus() { - m_d->m_ui.LibraryStackedWidget->setCurrentIndex(1); - m_d->m_ui.buttonItems->setChecked(false); - setSearchFilter(m_d->m_ui.lineEdit->text()); + m_d->m_lineEdit->clearFocus(); } void ItemLibrary::setResourcePath(const QString &resourcePath) { - m_d->m_resourcePath = resourcePath; + if (m_d->m_resourcesView->model() == m_d->m_resourcesDirModel) + m_d->m_resourcesView->setRootIndex(m_d->m_resourcesDirModel->index(resourcePath)); } void ItemLibrary::startDragAndDrop(int itemLibId) @@ -272,10 +280,4 @@ void ItemLibrary::showItemInfo(int /*itemLibId*/) // qDebug() << "showing item info about id" << itemLibId; } -void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo) -{ - 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 adb19233742..e5803f01148 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h @@ -32,12 +32,6 @@ #include <QtGui/QFrame> -QT_BEGIN_NAMESPACE -class QGraphicsItem; -class QPixmap; -class QMimeData; -QT_END_NAMESPACE - namespace QmlDesigner { class ItemLibraryPrivate; @@ -57,10 +51,10 @@ public: void setMetaInfo(const MetaInfo &metaInfo); public Q_SLOTS: - void itemLibraryButtonToggled(); - void resourcesButtonToggled(); + void setSearchFilter(const QString &searchFilter); + void updateSearch(); + void clearLineEditFocus(); - void setSearchFilter(const QString &nameFilter); void setResourcePath(const QString &resourcePath); void startDragAndDrop(int itemLibId); @@ -68,7 +62,7 @@ public Q_SLOTS: signals: void itemActivated(const QString& itemName); - void expandAllItems(); + void resetItemsView(); private: ItemLibraryPrivate *m_d; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri index 2cd17cb5c55..f15e463c666 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri @@ -7,7 +7,5 @@ INCLUDEPATH += $$PWD # Input HEADERS += itemlibrary.h customdraganddrop.h itemlibrarymodel.h itemlibrarywidgets.h -FORMS += itemlibrary.ui SOURCES += itemlibrary.cpp customdraganddrop.cpp itemlibrarymodel.cpp itemlibrarywidgets.cpp RESOURCES += itemlibrary.qrc - diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui deleted file mode 100644 index fdea444759a..00000000000 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui +++ /dev/null @@ -1,243 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>QmlDesigner::ItemLibrary</class> - <widget class="QFrame" name="QmlDesigner::ItemLibrary"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>497</width> - <height>635</height> - </rect> - </property> - <property name="windowTitle"> - <string>ItemLibrary</string> - </property> - <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="QmlDesigner::Internal::ItemLibraryButton" 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="QmlDesigner::Internal::ItemLibraryButton" 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> - </widget> - </item> - <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> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <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> - </widget> - <layoutdefault spacing="0" margin="0"/> - <customwidgets> - <customwidget> - <class>QmlDesigner::Internal::ItemLibraryTreeView</class> - <extends>QTreeView</extends> - <header>itemlibrarywidgets.h</header> - </customwidget> - <customwidget> - <class>QmlDesigner::Internal::ItemLibraryButton</class> - <extends>QToolButton</extends> - <header>itemlibrarywidgets.h</header> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index c35564e1dc9..76ad7efaa1a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -107,27 +107,20 @@ bool ItemLibrarySortedModel<T>::elementVisible(int libId) const template <class T> -void ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible) +bool ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible) { - int pos = findElement(libId), - offset = 0; - + int pos = findElement(libId); 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; - } + return false; + int visiblePos = visibleElementPosition(libId); if (visible) - insert(pos - offset, *(m_elementModels.value(libId))); + insert(visiblePos, *(m_elementModels.value(libId))); else - remove(pos - offset); + remove(visiblePos); m_elementOrder[pos].visible = visible; + return true; } @@ -160,6 +153,22 @@ int ItemLibrarySortedModel<T>::findElement(int libId) const return -1; } +template <class T> +int ItemLibrarySortedModel<T>::visibleElementPosition(int libId) const +{ + int i = 0; + QListIterator<struct order_struct> it(m_elementOrder); + + while (it.hasNext()) { + struct order_struct order = it.next(); + if (order.libId == libId) + return i; + if (order.visible) + ++i; + } + + return -1; +} @@ -252,14 +261,32 @@ void ItemLibrarySectionModel::removeSectionEntry(int itemLibId) } -bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText) +int ItemLibrarySectionModel::visibleItemIndex(int itemLibId) +{ + return m_sectionEntries.visibleElementPosition(itemLibId); +} + + +bool ItemLibrarySectionModel::isItemVisible(int itemLibId) +{ + return m_sectionEntries.elementVisible(itemLibId); +} + + +bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText, bool *changed) { bool haveVisibleItems = false; + + *changed = false; + QMap<int, ItemLibraryItemModel *>::const_iterator itemIt = m_sectionEntries.elements().constBegin(); while (itemIt != m_sectionEntries.elements().constEnd()) { - bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText); - m_sectionEntries.setElementVisible(itemIt.key(), itemVisible); + bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText), + itemChanged = false; + itemChanged = m_sectionEntries.setElementVisible(itemIt.key(), itemVisible); + + *changed |= itemChanged; if (itemVisible) haveVisibleItems = true; @@ -334,12 +361,42 @@ void ItemLibraryModel::setItemIconSize(const QSize &itemIconSize) } +int ItemLibraryModel::getItemSectionIndex(int itemLibId) +{ + if (m_sections.contains(itemLibId)) + return elementModel(m_sections.value(itemLibId))->visibleItemIndex(itemLibId); + else + return -1; +} + + +int ItemLibraryModel::getSectionLibId(int itemLibId) +{ + return m_sections.value(itemLibId); +} + + +bool ItemLibraryModel::isItemVisible(int itemLibId) +{ + if (!m_sections.contains(itemLibId)) + return false; + + int sectionLibId = m_sections.value(itemLibId); + if (!elementVisible(sectionLibId)) + return false; + + return elementModel(sectionLibId)->isItemVisible(itemLibId); +} + + void ItemLibraryModel::update(const MetaInfo &metaInfo) { QMap<QString, int> sections; clearElements(); m_itemInfos.clear(); + m_sections.clear(); + m_nextLibId = 0; if (!m_metaInfo) { m_metaInfo = new MetaInfo(metaInfo); @@ -371,6 +428,7 @@ void ItemLibraryModel::update(const MetaInfo &metaInfo) itemModel->setItemIcon(itemLibraryRepresentation.icon()); itemModel->setItemIconSize(m_itemIconSize); sectionModel->addSectionEntry(itemModel); + m_sections.insert(itemId, sectionId); } } @@ -414,6 +472,8 @@ QIcon ItemLibraryModel::getIcon(int libId) void ItemLibraryModel::updateVisibility() { + bool changed = false; + QMap<int, ItemLibrarySectionModel *>::const_iterator sectionIt = elements().constBegin(); while (sectionIt != elements().constEnd()) { @@ -423,13 +483,21 @@ void ItemLibraryModel::updateVisibility() if (sectionModel->sectionName().toLower().contains(m_searchText)) sectionSearchText = ""; - bool sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText); - setElementVisible(sectionIt.key(), sectionVisibility); + bool sectionChanged = false, + sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText, + §ionChanged); + if (sectionChanged) { + changed = true; + if (sectionVisibility) + emit sectionVisibilityChanged(sectionIt.key()); + } + changed |= setElementVisible(sectionIt.key(), sectionVisibility); ++sectionIt; } - emit visibilityUpdated(); + if (changed) + emit visibilityChanged(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index e819f6b7899..5391d0d83a6 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -57,12 +57,13 @@ public: void removeElement(int libId); bool elementVisible(int libId) const; - void setElementVisible(int libId, bool visible); + bool setElementVisible(int libId, bool visible); const QMap<int, T *> &elements() const; T *elementModel(int libId); int findElement(int libId) const; + int visibleElementPosition(int libId) const; private: struct order_struct { @@ -106,7 +107,10 @@ public: void addSectionEntry(ItemLibraryItemModel *sectionEntry); void removeSectionEntry(int itemLibId); - bool updateSectionVisibility(const QString &searchText); + int visibleItemIndex(int itemLibId); + bool isItemVisible(int itemLibId); + + bool updateSectionVisibility(const QString &searchText, bool *changed); void updateItemIconSize(const QSize &itemIconSize); bool operator<(const ItemLibrarySectionModel &other) const; @@ -137,10 +141,15 @@ public slots: void setSearchText(const QString &searchText); void setItemIconSize(const QSize &itemIconSize); + int getItemSectionIndex(int itemLibId); + int getSectionLibId(int itemLibId); + bool isItemVisible(int itemLibId); + signals: void qmlModelChanged(); void searchTextChanged(); - void visibilityUpdated(); + void visibilityChanged(); + void sectionVisibilityChanged(int changedSectionLibId); private: void updateVisibility(); @@ -149,6 +158,7 @@ private: QWeakPointer<QScriptEngine> m_scriptEngine; MetaInfo *m_metaInfo; QMap<int, ItemLibraryInfo> m_itemInfos; + QMap<int, int> m_sections; QString m_searchText; QSize m_itemIconSize; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp index 390961156cc..8d2ba7df2bb 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp @@ -41,15 +41,59 @@ #include <QLabel> #include <itemlibraryinfo.h> #include <QDirModel> - +#include <QProxyStyle> enum { debug = 0 }; - namespace QmlDesigner { namespace Internal { +static void drawSelectionBackground(QPainter *painter, const QStyleOption &option) +{ + painter->save(); + QLinearGradient gradient; + QColor highlight = option.palette.highlight().color(); + gradient.setColorAt(0, highlight.lighter(130)); + gradient.setColorAt(1, highlight.darker(130)); + gradient.setStart(option.rect.topLeft()); + gradient.setFinalStop(option.rect.bottomLeft()); + painter->fillRect(option.rect, gradient); + painter->setPen(highlight.lighter()); + painter->drawLine(option.rect.topLeft(),option.rect.topRight()); + painter->setPen(highlight.darker()); + painter->drawLine(option.rect.bottomLeft(),option.rect.bottomRight()); + painter->restore(); +} + +// This style basically allows us to span the entire row +// including the arrow indicators which would otherwise not be +// drawn by the delegate +class TreeViewStyle : public QProxyStyle +{ +public: + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget * = 0) const + { + if (element == QStyle::PE_PanelItemViewRow) { + if (option->state & QStyle::State_Selected) { + drawSelectionBackground(painter, *option); + } else { + painter->save(); + painter->setPen(QColor(255, 255, 255, 15)); + painter->drawLine(option->rect.topLeft(), option->rect.topRight()); + painter->setPen(QColor(0, 0, 0, 25)); + painter->drawLine(option->rect.bottomLeft(),option->rect.bottomRight()); + painter->restore(); + } + } + } + int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const { + if (hint == SH_ItemView_ShowDecorationSelected) + return 0; + else + return QProxyStyle::styleHint(hint, option, widget, returnData); + } +}; ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) : QTreeView(parent) @@ -58,6 +102,17 @@ ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) : setDragDropMode(QAbstractItemView::DragOnly); setUniformRowHeights(true); connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &))); + setHeaderHidden(true); + setIndentation(20); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setAttribute(Qt::WA_MacShowFocusRect, false); + + TreeViewStyle *style = new TreeViewStyle; + setStyle(style); + style->setParent(this); + m_delegate = new ResourceItemDelegate(this); + setItemDelegateForColumn(0, m_delegate); } // We need to implement startDrag ourselves since we cannot @@ -86,6 +141,19 @@ void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */) } } +void ItemLibraryTreeView::setModel(QAbstractItemModel *model) +{ + QDirModel *dirModel = dynamic_cast<QDirModel *>(model); + if (dirModel) { + QTreeView::setModel(model); + m_delegate->setModel(dirModel); + setColumnHidden(1, true); + setColumnHidden(2, true); + setColumnHidden(3, true); + setSortingEnabled(true); + } +} + void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/) { QMimeData *mimeData = model()->mimeData(selectedIndexes()); @@ -103,15 +171,39 @@ void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/) } } -ItemLibraryButton::ItemLibraryButton(QWidget *parent) -: QToolButton(parent) +void ResourceItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (option.state & QStyle::State_Selected) + drawSelectionBackground(painter, option); + + painter->save(); + + QIcon icon(m_model->fileIcon(index)); + QPixmap pixmap(icon.pixmap(icon.availableSizes().front())); + painter->drawPixmap(option.rect.x(),option.rect.y()+2,pixmap); + QString myString(m_model->fileName(index)); + + // Check text length does not exceed available space + int extraSpace=12+pixmap.width(); + QFontMetrics fm(option.font); + myString = fm.elidedText(myString,Qt::ElideMiddle,option.rect.width()-extraSpace); + + painter->drawText(option.rect.bottomLeft()+QPoint(3+pixmap.width(),-8),myString); + + painter->restore(); +} + +QSize ResourceItemDelegate::sizeHint(const QStyleOptionViewItem &/*option*/, + const QModelIndex &index) const { + QIcon icon(m_model->fileIcon(index)); + return icon.availableSizes().front() + QSize(25, 4); } -void ItemLibraryButton::mousePressEvent(QMouseEvent *event) +void ResourceItemDelegate::setModel(QDirModel *model) { - if (!isChecked()) - QToolButton::mousePressEvent(event); + m_model = model; } } // namespace Internal diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h index 88f987c1123..c5aa644a7bd 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h @@ -36,6 +36,9 @@ #include <QDebug> #include <QTimeLine> #include <QToolButton> +#include <QStyledItemDelegate> + +class QDirModel; QT_FORWARD_DECLARE_CLASS(QLabel); @@ -43,6 +46,8 @@ namespace QmlDesigner { namespace Internal { +class ResourceItemDelegate; + // ItemLibraryTreeView with Drag implementation class ItemLibraryTreeView : public QTreeView { Q_OBJECT @@ -50,20 +55,34 @@ public: explicit ItemLibraryTreeView(QWidget *parent = 0); virtual void startDrag(Qt::DropActions supportedActions); + virtual void setModel(QAbstractItemModel *model); signals: void itemActivated(const QString &itemName); private slots: void activateItem( const QModelIndex &index); + +private: + ResourceItemDelegate *m_delegate; }; -class ItemLibraryButton : public QToolButton { +class ResourceItemDelegate : public QStyledItemDelegate +{ public: - ItemLibraryButton(QWidget *parent = 0); + explicit ResourceItemDelegate(QObject *parent=0) : + QStyledItemDelegate(parent),m_model(0) {} + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setModel(QDirModel *model); -protected: - void mousePressEvent(QMouseEvent *event); +private: + QDirModel *m_model; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml index 939b4cc9c84..2be2d56c640 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml @@ -29,18 +29,21 @@ import Qt 4.6 +// view displaying an item library grid item + Item { id: itemView // public - + signal itemPressed() signal itemDragged() // internal ItemsViewStyle { id: style } - + + // frame Rectangle { anchors.top: parent.top anchors.left: parent.left @@ -91,28 +94,31 @@ Item { anchors.topMargin: style.cellVerticalMargin anchors.horizontalCenter: parent.horizontalCenter - width: itemLibraryIconWidth - height: itemLibraryIconHeight - pixmap: itemPixmap + width: itemLibraryIconWidth // to be set in Qml context + height: itemLibraryIconHeight // to be set in Qml context + pixmap: itemPixmap // to be set by model } Text { id: text - elide: Qt.ElideMiddle + elide: ElideMiddle anchors.top: itemIcon.bottom anchors.topMargin: style.cellVerticalSpacing - anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + anchors.leftMargin: style.cellHorizontalMargin + anchors.right: parent.right + anchors.rightMargin: style.cellHorizontalMargin width: style.textWidth height: style.textHeight verticalAlignment: "AlignVCenter" horizontalAlignment: "AlignHCenter" - text: itemName + text: itemName // to be set by model color: style.itemNameTextColor } MouseArea { - id: mouseArea + id: mouseRegion anchors.fill: parent property bool reallyPressed: false @@ -127,10 +133,10 @@ Item { } onPositionChanged: { if (reallyPressed && - (Math.abs(mouse.x - pressedX) > 2 || - Math.abs(mouse.y - pressedY) > 2)) { + (Math.abs(mouse.x - pressedX) + + Math.abs(mouse.y - pressedY)) > 3) { itemDragged() - reallyPressed = false; + reallyPressed = false } } onReleased: reallyPressed = false diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml index ce54230d247..f78a3028d52 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml @@ -29,14 +29,40 @@ import Qt 4.6 +/* The view displaying the item grid. + + The following Qml context properties have to be set: + - listmodel itemLibraryModel + - int itemLibraryIconWidth + - int itemLibraryIconHeight + + itemLibraryModel has to have the following structure: + + ListModel { + ListElement { + int sectionLibId + string sectionName + list sectionEntries: [ + ListElement { + int itemLibId + string itemName + pixmap itemPixmap + }, + ... + ] + } + ... + } +*/ + Rectangle { id: itemsView // public - - function expandAll() { - expandAllEntries(); - scrollbar.moveHandle(0, true) + + function resetView() { + expandAllEntries() + scrollbar.reset() } signal itemSelected(int itemLibId) @@ -45,15 +71,11 @@ Rectangle { signal stopDragAndDrop // internal - + signal expandAllEntries ItemsViewStyle { id: style } - 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 - color: style.backgroundColor /* workaround: without this, a completed drag and drop operation would @@ -62,9 +84,45 @@ Rectangle { MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: if (!pressed) itemsView.stopDragAndDrop + 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 @@ -78,13 +136,41 @@ Rectangle { width: itemsFlickable.width itemHighlight: selector - onItemSelected: itemsView.itemSelected(itemLibId) - onItemDragged: itemsView.itemDragged(itemLibId) + 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(); - } + 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 + } + } } } @@ -92,34 +178,37 @@ Rectangle { id: itemsFlickable anchors.top: parent.top - anchors.topMargin: 2 + anchors.topMargin: 3 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: scrollbar.left - anchors.rightMargin: 2 - clip: true + overShoot: false interactive: false contentHeight: col.height + /* 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() + Column { id: col Repeater { - model: itemLibraryModel + model: itemLibraryModel // to be set in Qml context delegate: sectionDelegate } } - - Selector { - id: selector - - z: -1 - flickable: itemsFlickable - - width: itemsView.cellWidth - height: itemsView.cellHeight - } } Scrollbar { @@ -136,4 +225,3 @@ Rectangle { flickable: itemsFlickable } } - diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml index 6516c663465..a2ba71393a2 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml @@ -29,6 +29,8 @@ import Qt 4.6 +// the style used the items view + Item { property string backgroundColor: "#707070" property string raisedBackgroundColor: "#e0e0e0" @@ -50,20 +52,18 @@ Item { property int sectionTitleHeight: 20 property int sectionTitleSpacing: 2 - // the selector's offset from the start of the section - property int selectionSectionOffset: sectionTitleHeight + sectionTitleSpacing - property int iconWidth: 32 property int iconHeight: 32 - property int textWidth: 90 + property int textWidth: 95 property int textHeight: 15 + property int cellHorizontalMargin: 5 property int cellVerticalSpacing: 7 property int cellVerticalMargin: 10 // the following depend on the actual shape of the item delegate - property int cellWidth: textWidth + property int cellWidth: textWidth + 2 * cellHorizontalMargin property int cellHeight: itemLibraryIconHeight + textHeight + 2 * cellVerticalMargin + cellVerticalSpacing } diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml index 99784a7da37..ec8705c3237 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml @@ -29,17 +29,25 @@ import Qt 4.6 +// scrollbar for the items view + Item { id: bar // public - + property var flickable + function reset() { + handle.y = 0 + } + // internal ItemsViewStyle { id: style } - + + onFlickableChanged: reset() + property int scrollHeight: height - handle.height Rectangle { @@ -47,32 +55,28 @@ Item { anchors.rightMargin: 1 anchors.bottomMargin: 1 color: "transparent" - border.width: 1; - border.color: style.scrollbarBorderColor; + border.width: 1 + border.color: style.scrollbarBorderColor } - function moveHandle(contentPos, updateFlickable) { - handle.updateFlickable = updateFlickable + function updateHandle() { + handle.updateFlickable = false if (flickable) handle.y = scrollHeight * Math.min( - contentPos / (flickable.contentHeight - flickable.height), - 1); + flickable.contentY / (flickable.contentHeight - flickable.height), + 1) else - handle.y = 0; + handle.y = 0 handle.updateFlickable = true } - function updateHandle() { - moveHandle(flickable.contentY, false); - } - - onFlickableChanged: moveHandle(0, true) + onHeightChanged: updateHandle() Connections { target: flickable - onHeightChanged: moveHandle(0, true) + onHeightChanged: updateHandle() } Connections { @@ -85,8 +89,6 @@ Item { onContentYChanged: updateHandle() } - onHeightChanged: updateHandle() - MouseArea { anchors.left: parent.left anchors.right: parent.right @@ -105,7 +107,7 @@ Item { height: Math.max(width, bar.height * Math.min(1, flickable.height / flickable.contentHeight)) property bool updateFlickable: true - + onYChanged: { if (updateFlickable) flickable.contentY = Math.max(0, flickable.contentHeight * y / bar.height) diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml index 3f15e559eba..7edfd62c6db 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml @@ -29,28 +29,64 @@ import Qt 4.6 +// view displaying one item library section including its grid + Column { id: sectionView // public - + property var itemHighlight property int entriesPerRow property int cellWidth property int cellHeight + property var currentItem: gridView.currentItem + function expand() { - gridFrame.state = ""; + gridFrame.state = "" } signal itemSelected(int itemLibId) signal itemDragged(int itemLibId) + function setSelection(itemSectionIndex) + { + gridView.currentIndex = itemSectionIndex + } + + function unsetSelection() + { + gridView.currentIndex = -1 + } + + function focusSelection(flickable) { + var pos = -1; + + if (!gridView.currentItem) + return; + + 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 + + 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) + + if (pos >= 0) + flickable.contentY = pos + } + // internal ItemsViewStyle { id: style } - + Component { id: itemDelegate @@ -60,25 +96,17 @@ Column { width: cellWidth height: cellHeight - function selectItem() { - itemHighlight.select(sectionView, item, gridFrame.x, -gridView.viewportY); - sectionView.itemSelected(itemLibId); - } - - onItemPressed: selectItem() - onItemDragged: { - selectItem(); - sectionView.itemDragged(itemLibId); - } + onItemPressed: sectionView.itemSelected(itemLibId) + onItemDragged: sectionView.itemDragged(itemLibId) } } + // clickable header bar Rectangle { width: parent.width height: style.sectionTitleHeight color: style.sectionTitleBackgroundColor - radius: 2 Item { id: arrow @@ -104,19 +132,13 @@ Column { anchors.left: arrow.right anchors.leftMargin: 5 - text: sectionName + text: sectionName // to be set by model color: style.sectionTitleTextColor + elide: Text.ElideMiddle } MouseArea { anchors.fill: parent - onClicked: { - if (itemHighlight.visible && - (itemHighlight.section == sectionView)) { - itemHighlight.unselect(); - sectionView.itemSelected(-1); - } - gridFrame.toggleExpanded() - } + onClicked: gridFrame.toggleExpanded() } } @@ -137,10 +159,14 @@ Column { GridView { id: gridView - // workaround Connections { - target: itemLibraryModel - onVisibilityUpdated: gridView.positionViewAtIndex(0); + target: itemLibraryModel // to be set in Qml context + onSectionVisibilityChanged: { + /* workaround: reset model in order to get the grid view + updated properly under all conditions */ + if (changedSectionLibId == sectionLibId) + gridView.model = sectionEntries + } } anchors.fill: parent @@ -149,8 +175,9 @@ Column { cellWidth: sectionView.cellWidth cellHeight: sectionView.cellHeight - model: sectionEntries + model: sectionEntries // to be set by model delegate: itemDelegate + highlight: itemHighlight interactive: false highlightFollowsCurrentItem: false } diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml index 8581fbb08ca..badb21fa31a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml @@ -29,66 +29,12 @@ import Qt 4.6 +// the coloured selector of the items view + Item { id: selector - // public - - property var flickable - - // internal - ItemsViewStyle { id: style } - - visible: false - - property var section: null - property var item: null - property int sectionXOffset: 0 - property int sectionYOffset: 0 - - x: (section && item)? (section.x + item.x + sectionXOffset):0; - y: (section && item)? (section.y + style.selectionSectionOffset + item.y + sectionYOffset):0; - - Connections { - target: itemLibraryModel - onVisibilityUpdated: unselect() - } - - function select(section, item, sectionXOffset, sectionYOffset) { - - selector.item = item - selector.section = section - selector.sectionXOffset = sectionXOffset - selector.sectionYOffset = sectionYOffset - - visible = true - focusSelection(); - } - - function unselect() { - section = null - item = null - sectionXOffset = 0 - sectionYOffset = 0 - visible = false - } - - function focusSelection() { - var pos = -1; - - if (y < flickable.viewportY) - pos = Math.max(0, y) - - else if ((y + height) > - (flickable.viewportY + flickable.height - 1)) - pos = Math.min(Math.max(0, flickable.viewportHeight - flickable.height), - y + height - flickable.height + 1) - - if (pos >= 0) - flickable.viewportY = pos; - } - SystemPalette { id:systemPalette } Rectangle { -- GitLab