forked from qt-creator/qt-creator
QmlDesigner: Update look and feel of navigator
Task-number: QDS-2880 Change-Id: I5e54e6c35afe8bd0149f35486ac308ce0ea0d59a Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
553929f322
commit
fcb3fabd13
@@ -32,7 +32,8 @@
|
|||||||
#include "navigatortreemodel.h"
|
#include "navigatortreemodel.h"
|
||||||
#include "qproxystyle.h"
|
#include "qproxystyle.h"
|
||||||
|
|
||||||
#include "metainfo.h"
|
#include <metainfo.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ IconCheckboxItemDelegate::IconCheckboxItemDelegate(QObject *parent,
|
|||||||
QSize IconCheckboxItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/,
|
QSize IconCheckboxItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/,
|
||||||
const QModelIndex & /*modelIndex*/) const
|
const QModelIndex & /*modelIndex*/) const
|
||||||
{
|
{
|
||||||
return {15, 20};
|
return {15, 20};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isChecked(const QModelIndex &modelIndex)
|
static bool isChecked(const QModelIndex &modelIndex)
|
||||||
@@ -63,9 +64,9 @@ static bool isChecked(const QModelIndex &modelIndex)
|
|||||||
return modelIndex.model()->data(modelIndex, Qt::CheckStateRole) == Qt::Checked;
|
return modelIndex.model()->data(modelIndex, Qt::CheckStateRole) == Qt::Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVisible(const QModelIndex &modelIndex)
|
static bool isThisOrAncestorLocked(const QModelIndex &modelIndex)
|
||||||
{
|
{
|
||||||
return modelIndex.model()->data(modelIndex, ItemIsVisibleRole).toBool();
|
return modelIndex.model()->data(modelIndex, ItemOrAncestorLocked).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModelNode getModelNode(const QModelIndex &modelIndex)
|
static ModelNode getModelNode(const QModelIndex &modelIndex)
|
||||||
@@ -82,6 +83,13 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
|
|||||||
const QStyleOptionViewItem &styleOption,
|
const QStyleOptionViewItem &styleOption,
|
||||||
const QModelIndex &modelIndex) const
|
const QModelIndex &modelIndex) const
|
||||||
{
|
{
|
||||||
|
if (styleOption.state & QStyle::State_MouseOver && !isThisOrAncestorLocked(modelIndex))
|
||||||
|
painter->fillRect(styleOption.rect.adjusted(0, delegateMargin, 0, -delegateMargin),
|
||||||
|
Theme::getColor(Theme::Color::DSsliderHandle));
|
||||||
|
|
||||||
|
if (styleOption.state & QStyle::State_Selected)
|
||||||
|
NavigatorTreeView::drawSelectionBackground(painter, styleOption);
|
||||||
|
|
||||||
bool isVisibilityIcon = modelIndex.column() != NavigatorTreeModel::ColumnType::Visibility;
|
bool isVisibilityIcon = modelIndex.column() != NavigatorTreeModel::ColumnType::Visibility;
|
||||||
// We need to invert the check status if visibility icon
|
// We need to invert the check status if visibility icon
|
||||||
bool checked = isVisibilityIcon ? isChecked(modelIndex) : !isChecked(modelIndex);
|
bool checked = isVisibilityIcon ? isChecked(modelIndex) : !isChecked(modelIndex);
|
||||||
@@ -89,10 +97,7 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (rowIsPropertyRole(modelIndex.model(), modelIndex))
|
if (rowIsPropertyRole(modelIndex.model(), modelIndex))
|
||||||
return; //Do not paint icons for property rows
|
return; // Do not paint icons for property rows
|
||||||
|
|
||||||
if (styleOption.state & QStyle::State_Selected)
|
|
||||||
NavigatorTreeView::drawSelectionBackground(painter, styleOption);
|
|
||||||
|
|
||||||
if (!getModelNode(modelIndex).isRootNode()) {
|
if (!getModelNode(modelIndex).isRootNode()) {
|
||||||
QWindow *window = dynamic_cast<QWidget*>(painter->device())->window()->windowHandle();
|
QWindow *window = dynamic_cast<QWidget*>(painter->device())->window()->windowHandle();
|
||||||
@@ -101,17 +106,15 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
|
|||||||
const QRect iconRect(styleOption.rect.left() + 2, styleOption.rect.top() + 2, 16, 16);
|
const QRect iconRect(styleOption.rect.left() + 2, styleOption.rect.top() + 2, 16, 16);
|
||||||
const QIcon &icon = isChecked(modelIndex) ? m_checkedIcon : m_uncheckedIcon;
|
const QIcon &icon = isChecked(modelIndex) ? m_checkedIcon : m_uncheckedIcon;
|
||||||
const QPixmap iconPixmap = icon.pixmap(window, iconRect.size());
|
const QPixmap iconPixmap = icon.pixmap(window, iconRect.size());
|
||||||
const bool visible = isVisible(modelIndex);
|
|
||||||
|
|
||||||
if (!visible) {
|
painter->save();
|
||||||
painter->save();
|
|
||||||
|
if (isThisOrAncestorLocked(modelIndex))
|
||||||
painter->setOpacity(0.5);
|
painter->setOpacity(0.5);
|
||||||
}
|
|
||||||
|
|
||||||
painter->drawPixmap(iconRect.topLeft(), iconPixmap);
|
painter->drawPixmap(iconRect.topLeft() + QPoint(0, delegateMargin), iconPixmap);
|
||||||
|
|
||||||
if (!visible)
|
painter->restore();
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <modelnodecontextmenu.h>
|
#include <modelnodecontextmenu.h>
|
||||||
#include <qmlobjectnode.h>
|
#include <qmlobjectnode.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -47,6 +48,8 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
int NameItemDelegate::iconOffset = 0;
|
||||||
|
|
||||||
static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
|
static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
|
||||||
{
|
{
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
@@ -111,13 +114,15 @@ NameItemDelegate::NameItemDelegate(QObject *parent)
|
|||||||
|
|
||||||
static int drawIcon(QPainter *painter, const QStyleOptionViewItem &styleOption, const QModelIndex &modelIndex)
|
static int drawIcon(QPainter *painter, const QStyleOptionViewItem &styleOption, const QModelIndex &modelIndex)
|
||||||
{
|
{
|
||||||
QIcon icon = modelIndex.data(Qt::DecorationRole).value<QIcon>();
|
const QIcon icon = modelIndex.data(Qt::DecorationRole).value<QIcon>();
|
||||||
|
int pixmapSize = icon.isNull() ? 4 : 16;
|
||||||
const int pixmapSize = icon.isNull() ? 4 : 16;
|
|
||||||
|
|
||||||
QPixmap pixmap = icon.pixmap(pixmapSize, pixmapSize);
|
QPixmap pixmap = icon.pixmap(pixmapSize, pixmapSize);
|
||||||
|
|
||||||
painter->drawPixmap(styleOption.rect.x() + 1 , styleOption.rect.y() + 2, pixmap);
|
painter->drawPixmap(styleOption.rect.x() + 1 + delegateMargin,
|
||||||
|
styleOption.rect.y() + 2 + delegateMargin,
|
||||||
|
pixmap);
|
||||||
|
|
||||||
|
pixmapSize += delegateMargin;
|
||||||
|
|
||||||
return pixmapSize;
|
return pixmapSize;
|
||||||
}
|
}
|
||||||
@@ -128,19 +133,20 @@ static QRect drawText(QPainter *painter,
|
|||||||
int iconOffset)
|
int iconOffset)
|
||||||
{
|
{
|
||||||
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
||||||
if (displayString.isEmpty())
|
|
||||||
displayString = modelIndex.data(Qt::DisplayRole).toString();
|
|
||||||
QPoint displayStringOffset;
|
QPoint displayStringOffset;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
|
||||||
// Check text length does not exceed available space
|
// Check text length does not exceed available space
|
||||||
int extraSpace = 12 + iconOffset;
|
const int extraSpace = 12 + iconOffset;
|
||||||
|
|
||||||
|
displayString = styleOption.fontMetrics.elidedText(displayString,
|
||||||
|
Qt::ElideMiddle,
|
||||||
|
styleOption.rect.width() - extraSpace);
|
||||||
|
displayStringOffset = QPoint(5 + iconOffset, -5 - delegateMargin);
|
||||||
|
|
||||||
displayString = styleOption.fontMetrics.elidedText(displayString, Qt::ElideMiddle, styleOption.rect.width() - extraSpace);
|
|
||||||
displayStringOffset = QPoint(5 + iconOffset, -5);
|
|
||||||
width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
||||||
|
|
||||||
QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
const QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
||||||
painter->drawText(textPosition, displayString);
|
painter->drawText(textPosition, displayString);
|
||||||
|
|
||||||
QRect textFrame;
|
QRect textFrame;
|
||||||
@@ -150,9 +156,9 @@ static QRect drawText(QPainter *painter,
|
|||||||
return textFrame;
|
return textFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVisible(const QModelIndex &modelIndex)
|
static bool isThisOrAncestorLocked(const QModelIndex &modelIndex)
|
||||||
{
|
{
|
||||||
return modelIndex.model()->data(modelIndex, ItemIsVisibleRole).toBool();
|
return modelIndex.model()->data(modelIndex, ItemOrAncestorLocked).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModelNode getModelNode(const QModelIndex &modelIndex)
|
static ModelNode getModelNode(const QModelIndex &modelIndex)
|
||||||
@@ -175,17 +181,56 @@ static void drawRedWavyUnderLine(QPainter *painter,
|
|||||||
painter->fillRect(textFrame.x(), 0, qCeil(textFrame.width()), qMin(wave.height(), descent), wave);
|
painter->fillRect(textFrame.x(), 0, qCeil(textFrame.width()), qMin(wave.height(), descent), wave);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setId(const QModelIndex &index, const QString &newId)
|
||||||
|
{
|
||||||
|
ModelNode modelNode = getModelNode(index);
|
||||||
|
|
||||||
|
if (!modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (modelNode.id() == newId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!modelNode.isValidId(newId)) {
|
||||||
|
Core::AsynchronousMessageBox::warning(NavigatorTreeView::tr("Invalid Id"),
|
||||||
|
NavigatorTreeView::tr("%1 is an invalid id.").arg(newId));
|
||||||
|
} else if (modelNode.view()->hasId(newId)) {
|
||||||
|
Core::AsynchronousMessageBox::warning(NavigatorTreeView::tr("Invalid Id"),
|
||||||
|
NavigatorTreeView::tr("%1 already exists.").arg(newId));
|
||||||
|
} else {
|
||||||
|
modelNode.setIdWithRefactoring(newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void openContextMenu(const QModelIndex &index, const QPoint &pos)
|
||||||
|
{
|
||||||
|
const ModelNode modelNode = getModelNode(index);
|
||||||
|
QTC_ASSERT(modelNode.isValid(), return);
|
||||||
|
ModelNodeContextMenu::showContextMenu(modelNode.view(), pos, QPoint(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize NameItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/,
|
||||||
|
const QModelIndex & /*modelIndex*/) const
|
||||||
|
{
|
||||||
|
return {15, 20 + (2 * delegateMargin)};
|
||||||
|
}
|
||||||
|
|
||||||
void NameItemDelegate::paint(QPainter *painter,
|
void NameItemDelegate::paint(QPainter *painter,
|
||||||
const QStyleOptionViewItem &styleOption,
|
const QStyleOptionViewItem &styleOption,
|
||||||
const QModelIndex &modelIndex) const
|
const QModelIndex &modelIndex) const
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
|
if (styleOption.state & QStyle::State_MouseOver && !isThisOrAncestorLocked(modelIndex))
|
||||||
|
painter->fillRect(styleOption.rect.adjusted(0, delegateMargin, 0, -delegateMargin),
|
||||||
|
Theme::getColor(Theme::Color::DSsliderHandle));
|
||||||
|
|
||||||
if (styleOption.state & QStyle::State_Selected)
|
if (styleOption.state & QStyle::State_Selected)
|
||||||
NavigatorTreeView::drawSelectionBackground(painter, styleOption);
|
NavigatorTreeView::drawSelectionBackground(painter, styleOption);
|
||||||
|
|
||||||
int iconOffset = drawIcon(painter, styleOption, modelIndex);
|
iconOffset = drawIcon(painter, styleOption, modelIndex);
|
||||||
|
|
||||||
if (!isVisible(modelIndex))
|
if (isThisOrAncestorLocked(modelIndex))
|
||||||
painter->setOpacity(0.5);
|
painter->setOpacity(0.5);
|
||||||
|
|
||||||
QRect textFrame = drawText(painter, styleOption, modelIndex, iconOffset);
|
QRect textFrame = drawText(painter, styleOption, modelIndex, iconOffset);
|
||||||
@@ -196,28 +241,8 @@ void NameItemDelegate::paint(QPainter *painter,
|
|||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openContextMenu(const QModelIndex &index, const QPoint &pos)
|
|
||||||
{
|
|
||||||
const ModelNode modelNode = getModelNode(index);
|
|
||||||
QTC_ASSERT(modelNode.isValid(), return);
|
|
||||||
ModelNodeContextMenu::showContextMenu(modelNode.view(), pos, QPoint(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NameItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *, const QStyleOptionViewItem &, const QModelIndex &index)
|
|
||||||
{
|
|
||||||
if (event->type() == QEvent::MouseButtonRelease) {
|
|
||||||
auto mouseEvent = static_cast<QMouseEvent *>(event);
|
|
||||||
if (mouseEvent->button() == Qt::RightButton) {
|
|
||||||
openContextMenu(index, mouseEvent->globalPos());
|
|
||||||
mouseEvent->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *NameItemDelegate::createEditor(QWidget *parent,
|
QWidget *NameItemDelegate::createEditor(QWidget *parent,
|
||||||
const QStyleOptionViewItem & /*option*/,
|
const QStyleOptionViewItem &/*option*/,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!getModelNode(index).isValid())
|
if (!getModelNode(index).isValid())
|
||||||
@@ -235,42 +260,35 @@ void NameItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
|
|||||||
lineEdit->setText(value);
|
lineEdit->setText(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setId(const QModelIndex &index, const QString &newId)
|
|
||||||
{
|
|
||||||
ModelNode modelNode = getModelNode(index);
|
|
||||||
|
|
||||||
if (!modelNode.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (modelNode.id() == newId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!modelNode.isValidId(newId)) {
|
|
||||||
Core::AsynchronousMessageBox::warning(NavigatorTreeView::tr("Invalid Id"),
|
|
||||||
NavigatorTreeView::tr("%1 is an invalid id.").arg(newId));
|
|
||||||
} else if (modelNode.view()->hasId(newId)) {
|
|
||||||
Core::AsynchronousMessageBox::warning(NavigatorTreeView::tr("Invalid Id"),
|
|
||||||
NavigatorTreeView::tr("%1 already exists.").arg(newId));
|
|
||||||
} else {
|
|
||||||
modelNode.setIdWithRefactoring(newId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NameItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
void NameItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(model)
|
Q_UNUSED(model)
|
||||||
auto lineEdit = static_cast<QLineEdit*>(editor);
|
auto lineEdit = static_cast<QLineEdit*>(editor);
|
||||||
setId(index,lineEdit->text());
|
setId(index, lineEdit->text());
|
||||||
lineEdit->clearFocus();
|
lineEdit->clearFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NameItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *, const QStyleOptionViewItem &, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
if (mouseEvent->button() == Qt::RightButton) {
|
||||||
|
openContextMenu(index, mouseEvent->globalPos());
|
||||||
|
mouseEvent->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NameItemDelegate::updateEditorGeometry(QWidget *editor,
|
void NameItemDelegate::updateEditorGeometry(QWidget *editor,
|
||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
const QModelIndex & /*index*/) const
|
const QModelIndex &/*index*/) const
|
||||||
{
|
{
|
||||||
auto lineEdit = static_cast<QLineEdit*>(editor);
|
auto lineEdit = static_cast<QLineEdit*>(editor);
|
||||||
lineEdit->setGeometry(option.rect);
|
lineEdit->setTextMargins(0, 0, 0, 2);
|
||||||
|
// + 2 is shifting the QLineEdit to the left so it will align with the text when activated
|
||||||
|
lineEdit->setGeometry(option.rect.adjusted(iconOffset + 2, delegateMargin, 0, -delegateMargin));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -34,18 +34,28 @@ class NavigatorTreeModel;
|
|||||||
class NameItemDelegate : public QStyledItemDelegate
|
class NameItemDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static int iconOffset;
|
||||||
|
|
||||||
explicit NameItemDelegate(QObject *parent);
|
explicit NameItemDelegate(QObject *parent);
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &styleOption,
|
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const override;
|
const QModelIndex &index) const override;
|
||||||
|
void paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &styleOption,
|
||||||
|
const QModelIndex &index) const override;
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index ) override;
|
bool editorEvent(QEvent *event,
|
||||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) override;
|
||||||
|
void updateEditorGeometry(QWidget *editor,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -203,6 +203,12 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == ItemIsVisibleRole) // independent of column
|
if (role == ItemIsVisibleRole) // independent of column
|
||||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||||
|
|
||||||
|
if (role == ItemOrAncestorLocked)
|
||||||
|
return ModelNode::isThisOrAncestorLocked(modelNode);
|
||||||
|
|
||||||
|
if (role == ModelNodeRole)
|
||||||
|
return QVariant::fromValue<ModelNode>(modelNode);
|
||||||
|
|
||||||
if (index.column() == ColumnType::Name) {
|
if (index.column() == ColumnType::Name) {
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
return modelNode.displayName();
|
return modelNode.displayName();
|
||||||
@@ -237,8 +243,6 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
auto op = m_actionManager->modelNodePreviewOperation(modelNode);
|
auto op = m_actionManager->modelNodePreviewOperation(modelNode);
|
||||||
if (op)
|
if (op)
|
||||||
return op(modelNode);
|
return op(modelNode);
|
||||||
} else if (role == ModelNodeRole) {
|
|
||||||
return QVariant::fromValue<ModelNode>(modelNode);
|
|
||||||
}
|
}
|
||||||
} else if (index.column() == ColumnType::Alias) { // export
|
} else if (index.column() == ColumnType::Alias) { // export
|
||||||
if (role == Qt::CheckStateRole)
|
if (role == Qt::CheckStateRole)
|
||||||
@@ -268,7 +272,7 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
|||||||
if (index.column() == ColumnType::Alias
|
if (index.column() == ColumnType::Alias
|
||||||
|| index.column() == ColumnType::Visibility
|
|| index.column() == ColumnType::Visibility
|
||||||
|| index.column() == ColumnType::Lock)
|
|| index.column() == ColumnType::Lock)
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren;
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren;
|
||||||
|
|
||||||
const ModelNode modelNode = modelNodeForIndex(index);
|
const ModelNode modelNode = modelNodeForIndex(index);
|
||||||
if (ModelNode::isThisOrAncestorLocked(modelNode))
|
if (ModelNode::isThisOrAncestorLocked(modelNode))
|
||||||
@@ -277,8 +281,7 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
|||||||
if (index.column() == ColumnType::Name)
|
if (index.column() == ColumnType::Name)
|
||||||
return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
|
||||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren;
|
||||||
| Qt::ItemNeverHasChildren;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static appendForcedNodes(const NodeListProperty &property, QList<ModelNode> &list)
|
void static appendForcedNodes(const NodeListProperty &property, QList<ModelNode> &list)
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "previewtooltip.h"
|
#include "previewtooltip.h"
|
||||||
|
|
||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
#include <utils/icon.h>
|
#include <utils/icon.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
@@ -63,32 +64,28 @@ public:
|
|||||||
baseStyle()->setParent(parent);
|
baseStyle()->setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override
|
void drawPrimitive(PrimitiveElement element,
|
||||||
|
const QStyleOption *option,
|
||||||
|
QPainter *painter,
|
||||||
|
const QWidget *widget = nullptr) const override
|
||||||
{
|
{
|
||||||
static QRect mouseOverStateSavedFrameRectangle;
|
static QRect mouseOverStateSavedFrameRectangle;
|
||||||
if (element == QStyle::PE_PanelItemViewRow) {
|
if (element == QStyle::PE_PanelItemViewRow) {
|
||||||
if (option->state & QStyle::State_MouseOver)
|
if (option->state & QStyle::State_MouseOver)
|
||||||
mouseOverStateSavedFrameRectangle = option->rect;
|
mouseOverStateSavedFrameRectangle = option->rect;
|
||||||
|
|
||||||
if (option->state & QStyle::State_Selected)
|
painter->fillRect(option->rect.adjusted(0, delegateMargin, 0, -delegateMargin),
|
||||||
NavigatorTreeView::drawSelectionBackground(painter, *option);
|
Theme::getColor(Theme::Color::QmlDesigner_BorderColor));
|
||||||
|
|
||||||
} else if (element == PE_IndicatorItemViewItemDrop) {
|
} else if (element == PE_IndicatorItemViewItemDrop) {
|
||||||
// between elements and on elements we have a width
|
// between elements and on elements we have a width
|
||||||
if (option->rect.width() > 0) {
|
if (option->rect.width() > 0) {
|
||||||
m_currentTextColor = option->palette.text().color();
|
m_currentTextColor = option->palette.text().color();
|
||||||
QRect frameRectangle = adjustedRectangleToWidgetWidth(option->rect, widget);
|
QRect frameRectangle = adjustedRectangleToWidgetWidth(option->rect, widget);
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
if (option->rect.height() == 0) {
|
if (option->rect.height() == 0) {
|
||||||
bool isNotRootItem = option->rect.top() > 10 && mouseOverStateSavedFrameRectangle.top() > 10;
|
bool isNotRootItem = option->rect.top() > 10 && mouseOverStateSavedFrameRectangle.top() > 10;
|
||||||
if (isNotRootItem) {
|
if (isNotRootItem)
|
||||||
drawIndicatorLine(frameRectangle.topLeft(), frameRectangle.topRight(), painter);
|
drawIndicatorLine(frameRectangle.topLeft(), frameRectangle.topRight(), painter);
|
||||||
// there is only a line in the styleoption object at this moment
|
|
||||||
// so we need to use the last saved rect from the mouse over state
|
|
||||||
frameRectangle = adjustedRectangleToWidgetWidth(mouseOverStateSavedFrameRectangle, widget);
|
|
||||||
drawBackgroundFrame(frameRectangle, painter);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
drawHighlightFrame(frameRectangle, painter);
|
drawHighlightFrame(frameRectangle, painter);
|
||||||
}
|
}
|
||||||
@@ -96,12 +93,72 @@ public:
|
|||||||
}
|
}
|
||||||
} else if (element == PE_FrameFocusRect) {
|
} else if (element == PE_FrameFocusRect) {
|
||||||
// don't draw
|
// don't draw
|
||||||
|
} else if (element == PE_IndicatorBranch) {
|
||||||
|
painter->save();
|
||||||
|
static const int decoration_size = 10;
|
||||||
|
int mid_h = option->rect.x() + option->rect.width() / 2;
|
||||||
|
int mid_v = option->rect.y() + option->rect.height() / 2;
|
||||||
|
int bef_h = mid_h;
|
||||||
|
int bef_v = mid_v;
|
||||||
|
int aft_h = mid_h;
|
||||||
|
int aft_v = mid_v;
|
||||||
|
QBrush brush(Theme::getColor(Theme::Color::DSsliderHandle), Qt::SolidPattern);
|
||||||
|
if (option->state & State_Item) {
|
||||||
|
if (option->direction == Qt::RightToLeft)
|
||||||
|
painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
|
||||||
|
else
|
||||||
|
painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
|
||||||
|
}
|
||||||
|
if (option->state & State_Sibling)
|
||||||
|
painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
|
||||||
|
if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
|
||||||
|
painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
|
||||||
|
if (option->state & State_Children) {
|
||||||
|
int delta = decoration_size / 2;
|
||||||
|
bef_h -= delta;
|
||||||
|
bef_v -= delta;
|
||||||
|
aft_h += delta;
|
||||||
|
aft_v += delta;
|
||||||
|
|
||||||
|
const QRectF rect(bef_h, bef_v, decoration_size + 1, decoration_size + 1);
|
||||||
|
painter->fillRect(rect, QBrush(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate)));
|
||||||
|
|
||||||
|
static const QPointF collapsePoints[3] = {
|
||||||
|
QPointF(0.0, 0.0),
|
||||||
|
QPointF(4.0, 4.0),
|
||||||
|
QPointF(0.0, 8.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QPointF expandPoints[3] = {
|
||||||
|
QPointF(0.0, 0.0),
|
||||||
|
QPointF(8.0, 0.0),
|
||||||
|
QPointF(4.0, 4.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
auto color = Theme::getColor(Theme::Color::IconsBaseColor);
|
||||||
|
painter->setPen(color);
|
||||||
|
painter->setBrush(color);
|
||||||
|
|
||||||
|
if (option->state & QStyle::State_Open) {
|
||||||
|
painter->translate(QPointF(mid_h - 4, mid_v - 2));
|
||||||
|
painter->drawConvexPolygon(expandPoints, 3);
|
||||||
|
} else {
|
||||||
|
painter->translate(QPointF(mid_h - 2, mid_v - 4));
|
||||||
|
painter->drawConvexPolygon(collapsePoints, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override {
|
int styleHint(StyleHint hint,
|
||||||
|
const QStyleOption *option = nullptr,
|
||||||
|
const QWidget *widget = nullptr,
|
||||||
|
QStyleHintReturn *returnData = nullptr) const override
|
||||||
|
{
|
||||||
if (hint == SH_ItemView_ShowDecorationSelected)
|
if (hint == SH_ItemView_ShowDecorationSelected)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
@@ -180,7 +237,8 @@ NavigatorTreeView::NavigatorTreeView(QWidget *parent)
|
|||||||
void NavigatorTreeView::drawSelectionBackground(QPainter *painter, const QStyleOption &option)
|
void NavigatorTreeView::drawSelectionBackground(QPainter *painter, const QStyleOption &option)
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->fillRect(option.rect, option.palette.color(QPalette::Highlight));
|
painter->fillRect(option.rect.adjusted(0, delegateMargin, 0, -delegateMargin),
|
||||||
|
Theme::getColor(Theme::Color::QmlDesigner_HighlightColor));
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,5 +281,4 @@ bool NavigatorTreeView::viewportEvent(QEvent *event)
|
|||||||
return QTreeView::viewportEvent(event);
|
return QTreeView::viewportEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,7 @@ void NavigatorView::modelAttached(Model *model)
|
|||||||
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Visibility, 26);
|
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Visibility, 26);
|
||||||
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Lock, 26);
|
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Lock, 26);
|
||||||
treeView->setIndentation(20);
|
treeView->setIndentation(20);
|
||||||
|
treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
|
||||||
m_currentModelInterface->setFilter(false);
|
m_currentModelInterface->setFilter(false);
|
||||||
|
|
||||||
@@ -493,7 +494,6 @@ void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, con
|
|||||||
QSet<ModelNode> nodeSet;
|
QSet<ModelNode> nodeSet;
|
||||||
|
|
||||||
for (const QModelIndex &index : treeWidget()->selectionModel()->selectedIndexes()) {
|
for (const QModelIndex &index : treeWidget()->selectionModel()->selectedIndexes()) {
|
||||||
|
|
||||||
const ModelNode modelNode = modelNodeForIndex(index);
|
const ModelNode modelNode = modelNodeForIndex(index);
|
||||||
if (modelNode.isValid())
|
if (modelNode.isValid())
|
||||||
nodeSet.insert(modelNode);
|
nodeSet.insert(modelNode);
|
||||||
@@ -539,7 +539,7 @@ void NavigatorView::updateItemSelection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool blocked = blockSelectionChangedSignal(true);
|
bool blocked = blockSelectionChangedSignal(true);
|
||||||
treeWidget()->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect);
|
treeWidget()->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||||
blockSelectionChangedSignal(blocked);
|
blockSelectionChangedSignal(blocked);
|
||||||
|
|
||||||
if (!selectedModelNodes().isEmpty())
|
if (!selectedModelNodes().isEmpty())
|
||||||
@@ -586,7 +586,7 @@ void NavigatorView::reparentAndCatch(NodeAbstractProperty property, const ModelN
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
property.reparentHere(modelNode);
|
property.reparentHere(modelNode);
|
||||||
} catch (Exception &exception) {
|
} catch (Exception &exception) {
|
||||||
exception.showException();
|
exception.showException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,29 +620,29 @@ void NavigatorView::setupWidget()
|
|||||||
const QIcon visibilityOnIcon =
|
const QIcon visibilityOnIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::visibilityOn),
|
Theme::getIconUnicode(Theme::Icon::visibilityOn),
|
||||||
28, 28, QColor(Qt::white));
|
20, 20, QColor(Qt::white));
|
||||||
const QIcon visibilityOffIcon =
|
const QIcon visibilityOffIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::visibilityOff),
|
Theme::getIconUnicode(Theme::Icon::visibilityOff),
|
||||||
28, 28, QColor(Qt::white));
|
20, 20, QColor(Qt::white));
|
||||||
|
|
||||||
const QIcon aliasOnIcon =
|
const QIcon aliasOnIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::idAliasOn),
|
Theme::getIconUnicode(Theme::Icon::idAliasOn),
|
||||||
28, 28, QColor(Qt::red));
|
20, 20, QColor(Qt::red));
|
||||||
const QIcon aliasOffIcon =
|
const QIcon aliasOffIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::idAliasOff),
|
Theme::getIconUnicode(Theme::Icon::idAliasOff),
|
||||||
28, 28, QColor(Qt::white));
|
20, 20, QColor(Qt::white));
|
||||||
|
|
||||||
const QIcon lockOnIcon =
|
const QIcon lockOnIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::lockOn),
|
Theme::getIconUnicode(Theme::Icon::lockOn),
|
||||||
28, 28, QColor(Qt::white));
|
20, 20, QColor(Qt::white));
|
||||||
const QIcon lockOffIcon =
|
const QIcon lockOffIcon =
|
||||||
Utils::StyleHelper::getIconFromIconFont(fontName,
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(Theme::Icon::lockOff),
|
Theme::getIconUnicode(Theme::Icon::lockOff),
|
||||||
28, 28, QColor(Qt::white));
|
20, 20, QColor(Qt::white));
|
||||||
|
|
||||||
auto idDelegate = new NameItemDelegate(this);
|
auto idDelegate = new NameItemDelegate(this);
|
||||||
|
|
||||||
|
@@ -43,6 +43,8 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static int delegateMargin = 2;
|
||||||
|
|
||||||
class NavigatorWidget;
|
class NavigatorWidget;
|
||||||
class NavigatorTreeModel;
|
class NavigatorTreeModel;
|
||||||
|
|
||||||
@@ -50,7 +52,8 @@ enum NavigatorRoles {
|
|||||||
ItemIsVisibleRole = Qt::UserRole,
|
ItemIsVisibleRole = Qt::UserRole,
|
||||||
RowIsPropertyRole = Qt::UserRole + 1,
|
RowIsPropertyRole = Qt::UserRole + 1,
|
||||||
ModelNodeRole = Qt::UserRole + 2,
|
ModelNodeRole = Qt::UserRole + 2,
|
||||||
ToolTipImageRole = Qt::UserRole + 3
|
ToolTipImageRole = Qt::UserRole + 3,
|
||||||
|
ItemOrAncestorLocked = Qt::UserRole + 4
|
||||||
};
|
};
|
||||||
|
|
||||||
class NavigatorView : public AbstractView
|
class NavigatorView : public AbstractView
|
||||||
|
Reference in New Issue
Block a user