从源头看Dust3d | (八)materialListWidget

从源头看Dust3d | (八)materialListWidget,第1张

从源头看Dust3d | (八)materialListWidget

2021SC@SDUSC 

一、materialListWidget类 (一)materialListWidget.h
class MaterialListWidget : public QTreeWidget
{
    Q_OBJECT
signals:
    void removeMaterial(QUuid materialId);
    void modifyMaterial(QUuid materialId);
    void cornerButtonClicked(QUuid materialId);
    void currentSelectedMaterialChanged(QUuid materialId);
public:
    MaterialListWidget(const document *document, QWidget *parent=nullptr);
    bool isMaterialSelected(QUuid materialId);
    void enableMultipleSelection(bool enabled);
public slots:
    void reload();
    void removeAllContent();
    void materialRemoved(QUuid materialId);
    void showContextMenu(const QPoint &pos);
    void selectMaterial(QUuid materialId, bool multiple=false);
    void copy();
    void setCornerButtonVisible(bool visible);
    void setHasContextMenu(bool hasContextMenu);
protected:
    void resizeEvent(QResizeEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
private:
    int calculateColumnCount();
    void updateMaterialSelectState(QUuid materialId, bool selected);
    const document *m_document = nullptr;
    std::map> m_itemMap;
    std::set m_selectedMaterialIds;
    QUuid m_currentSelectedMaterialId;
    QUuid m_shiftStartMaterialId;
    bool m_cornerButtonVisible = false;
    bool m_hasContextMenu = true;
    bool m_multipleSelectionEnabled = true;
};
(二)materialListWidget.cpp

1.构造函数

MaterialListWidget::MaterialListWidget(const document *document, QWidget *parent) :
    QTreeWidget(parent),
    m_document(document)
{
    setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    setFocusPolicy(Qt::NoFocus);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    setAutoScroll(false);

    setHeaderHidden(true);

    QPalette palette = this->palette();
    palette.setColor(QPalette::Window, Qt::transparent);
    palette.setColor(QPalette::base, Qt::transparent);
    setPalette(palette);

    setStyleSheet("QTreeView {qproperty-indentation: 0;}");

    setContentsMargins(0, 0, 0, 0);

    connect(document, &document::materialListChanged, this, &MaterialListWidget::reload);
    connect(document, &document::cleanup, this, &MaterialListWidget::removeAllContent);

    connect(this, &MaterialListWidget::removeMaterial, document, &document::removeMaterial);

    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &QTreeWidget::customContextMenuRequested, this, &MaterialListWidget::showContextMenu);

    reload();
}

2.enableMultipleSelection

void MaterialListWidget::enableMultipleSelection(bool enabled)
{
    m_multipleSelectionEnabled = enabled;
}

3.materialRemoved

void MaterialListWidget::materialRemoved(QUuid materialId)
{
    if (m_currentSelectedMaterialId == materialId)
        m_currentSelectedMaterialId = QUuid();
    m_selectedMaterialIds.erase(materialId);
    m_itemMap.erase(materialId);
}

4.updateMaterialSelectState

void MaterialListWidget::updateMaterialSelectState(QUuid materialId, bool selected)
{
    auto findItemResult = m_itemMap.find(materialId);
    if (findItemResult == m_itemMap.end()) {
        qDebug() << "Find material item failed:" << materialId;
        return;
    }
    MaterialWidget *materialWidget = (MaterialWidget *)itemWidget(findItemResult->second.first, findItemResult->second.second);
    materialWidget->updateCheckedState(selected);
    if (m_cornerButtonVisible) {
        materialWidget->setCornerButtonVisible(selected);
    }
}

5.selectMaterial

void MaterialListWidget::selectMaterial(QUuid materialId, bool multiple)
{
    if (multiple) {
        if (!m_currentSelectedMaterialId.isNull()) {
            m_selectedMaterialIds.insert(m_currentSelectedMaterialId);
            m_currentSelectedMaterialId = QUuid();
        }
        if (m_selectedMaterialIds.find(materialId) != m_selectedMaterialIds.end()) {
            updateMaterialSelectState(materialId, false);
            m_selectedMaterialIds.erase(materialId);
        } else {
            if (m_multipleSelectionEnabled || m_selectedMaterialIds.empty()) {
                updateMaterialSelectState(materialId, true);
                m_selectedMaterialIds.insert(materialId);
            }
        }
        if (m_selectedMaterialIds.size() > 1) {
            return;
        }
        if (m_selectedMaterialIds.size() == 1)
            materialId = *m_selectedMaterialIds.begin();
        else {
            materialId = QUuid();
            emit currentSelectedMaterialChanged(materialId);
        }
    }
    if (!m_selectedMaterialIds.empty()) {
        for (const auto &id: m_selectedMaterialIds) {
            updateMaterialSelectState(id, false);
        }
        m_selectedMaterialIds.clear();
    }
    if (m_currentSelectedMaterialId != materialId) {
        if (!m_currentSelectedMaterialId.isNull()) {
            updateMaterialSelectState(m_currentSelectedMaterialId, false);
        }
        m_currentSelectedMaterialId = materialId;
        if (!m_currentSelectedMaterialId.isNull()) {
            updateMaterialSelectState(m_currentSelectedMaterialId, true);
        }
        emit currentSelectedMaterialChanged(m_currentSelectedMaterialId);
    }
}

6.mousePressEvent

void MaterialListWidget::mousePressEvent(QMouseEvent *event)
{
    QModelIndex itemIndex = indexAt(event->pos());
    QTreeView::mousePressEvent(event);
    if (event->button() == Qt::LeftButton) {
        bool multiple = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier);
        if (itemIndex.isValid()) {
            QTreeWidgetItem *item = itemFromIndex(itemIndex);
            auto materialId = QUuid(item->data(itemIndex.column(), Qt::UserRole).toString());
            if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
                bool startAdd = false;
                bool stopAdd = false;
                std::vector waitQueue;
                for (const auto &childId: m_document->materialIdList) {
                    if (m_shiftStartMaterialId == childId || materialId == childId) {
                        if (startAdd) {
                            stopAdd = true;
                        } else {
                            startAdd = true;
                        }
                    }
                    if (startAdd)
                        waitQueue.push_back(childId);
                    if (stopAdd)
                        break;
                }
                if (stopAdd && !waitQueue.empty()) {
                    if (!m_selectedMaterialIds.empty()) {
                        for (const auto &id: m_selectedMaterialIds) {
                            updateMaterialSelectState(id, false);
                        }
                        m_selectedMaterialIds.clear();
                    }
                    if (!m_currentSelectedMaterialId.isNull()) {
                        m_currentSelectedMaterialId = QUuid();
                    }
                    for (const auto &waitId: waitQueue) {
                        selectMaterial(waitId, true);
                    }
                }
                return;
            } else {
                m_shiftStartMaterialId = materialId;
            }
            selectMaterial(materialId, multiple);
            return;
        }
        if (!multiple)
            selectMaterial(QUuid());
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5638359.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存