diff --git a/src/parttreewidget.cpp b/src/parttreewidget.cpp index d35cb1c6..8de2d9b8 100644 --- a/src/parttreewidget.cpp +++ b/src/parttreewidget.cpp @@ -70,7 +70,9 @@ PartTreeWidget::PartTreeWidget(const Document *document, QWidget *parent) : m_firstSelect = true; selectComponent(QUuid()); - connect(this, &QTreeWidget::customContextMenuRequested, this, &PartTreeWidget::showContextMenu); + connect(this, &QTreeWidget::customContextMenuRequested, this, [&](const QPoint &pos) { + showContextMenu(pos); + }); connect(this, &QTreeWidget::itemChanged, this, &PartTreeWidget::groupChanged); connect(this, &QTreeWidget::itemExpanded, this, &PartTreeWidget::groupExpanded); connect(this, &QTreeWidget::itemCollapsed, this, &PartTreeWidget::groupCollapsed); @@ -154,64 +156,104 @@ void PartTreeWidget::updateComponentSelectState(QUuid componentId, bool selected } } -void PartTreeWidget::mousePressEvent(QMouseEvent *event) +void PartTreeWidget::mouseDoubleClickEvent(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 componentId = QUuid(item->data(0, Qt::UserRole).toString()); - if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { - if (!m_shiftStartComponentId.isNull()) { - const Component *parent = m_document->findComponentParent(m_shiftStartComponentId); - if (parent) { - if (!parent->childrenIds.empty()) { - bool startAdd = false; - bool stopAdd = false; - std::vector waitQueue; - for (const auto &childId: parent->childrenIds) { - if (m_shiftStartComponentId == childId || componentId == childId) { - if (startAdd) { - stopAdd = true; - } else { - startAdd = true; - } + delete m_delayedMousePressTimer; + m_delayedMousePressTimer = nullptr; + + QWidget::mouseDoubleClickEvent(event); + auto componentIds = collectSelectedComponentIds(event->pos()); + for (const auto &componentId: componentIds) { + std::vector partIds; + m_document->collectComponentDescendantParts(componentId, partIds); + for (const auto &partId: partIds) { + emit addPartToSelection(partId); + } + } + event->accept(); +} + +void PartTreeWidget::handleSingleClick(const QPoint &pos) +{ + QModelIndex itemIndex = indexAt(pos); + + auto showMenu = [=]() { + delete m_delayedMousePressTimer; + m_delayedMousePressTimer = new QTimer(this); + m_delayedMousePressTimer->setSingleShot(true); + m_delayedMousePressTimer->setInterval(200); + connect(m_delayedMousePressTimer, &QTimer::timeout, this, [=]() { + showContextMenu(pos, true); + }); + m_delayedMousePressTimer->start(); + }; + + bool multiple = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier); + if (itemIndex.isValid()) { + QTreeWidgetItem *item = itemFromIndex(itemIndex); + auto componentId = QUuid(item->data(0, Qt::UserRole).toString()); + if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { + if (!m_shiftStartComponentId.isNull()) { + const Component *parent = m_document->findComponentParent(m_shiftStartComponentId); + if (parent) { + if (!parent->childrenIds.empty()) { + bool startAdd = false; + bool stopAdd = false; + std::vector waitQueue; + for (const auto &childId: parent->childrenIds) { + if (m_shiftStartComponentId == childId || componentId == childId) { + if (startAdd) { + stopAdd = true; + } else { + startAdd = true; } - if (startAdd) - waitQueue.push_back(childId); - if (stopAdd) - break; } - if (stopAdd && !waitQueue.empty()) { - if (!m_selectedComponentIds.empty()) { - for (const auto &id: m_selectedComponentIds) { - updateComponentSelectState(id, false); - } - m_selectedComponentIds.clear(); - } - if (!m_currentSelectedComponentId.isNull()) { - m_currentSelectedComponentId = QUuid(); - emit currentComponentChanged(m_currentSelectedComponentId); - } - for (const auto &waitId: waitQueue) { - selectComponent(waitId, true); + if (startAdd) + waitQueue.push_back(childId); + if (stopAdd) + break; + } + if (stopAdd && !waitQueue.empty()) { + if (!m_selectedComponentIds.empty()) { + for (const auto &id: m_selectedComponentIds) { + updateComponentSelectState(id, false); } + m_selectedComponentIds.clear(); + } + if (!m_currentSelectedComponentId.isNull()) { + m_currentSelectedComponentId = QUuid(); + emit currentComponentChanged(m_currentSelectedComponentId); + } + for (const auto &waitId: waitQueue) { + selectComponent(waitId, true); } } } } - return; - } else { - m_shiftStartComponentId = componentId; } - selectComponent(componentId, multiple); + showMenu(); return; + } else { + m_shiftStartComponentId = componentId; } - if (!multiple) - selectComponent(QUuid()); + selectComponent(componentId, multiple); + showMenu(); + return; } + if (!multiple) + selectComponent(QUuid()); + + showMenu(); +} + +void PartTreeWidget::mousePressEvent(QMouseEvent *event) +{ + QTreeView::mousePressEvent(event); + + if (event->button() != Qt::LeftButton) + return; + + handleSingleClick(event->pos()); } void PartTreeWidget::showClothSettingMenu(const QPoint &pos, const QUuid &componentId) @@ -294,12 +336,8 @@ void PartTreeWidget::showClothSettingMenu(const QPoint &pos, const QUuid &compon popupMenu.exec(mapToGlobal(pos)); } -void PartTreeWidget::showContextMenu(const QPoint &pos) +std::vector PartTreeWidget::collectSelectedComponentIds(const QPoint &pos) { - const Component *component = nullptr; - const SkeletonPart *part = nullptr; - PartWidget *partWidget = nullptr; - std::set unorderedComponentIds = m_selectedComponentIds; if (!m_currentSelectedComponentId.isNull()) unorderedComponentIds.insert(m_currentSelectedComponentId); @@ -320,6 +358,25 @@ void PartTreeWidget::showContextMenu(const QPoint &pos) componentIds.push_back(cand); } + return componentIds; +} + +void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted) +{ + delete m_delayedMousePressTimer; + m_delayedMousePressTimer = nullptr; + + const Component *component = nullptr; + const SkeletonPart *part = nullptr; + PartWidget *partWidget = nullptr; + + std::vector componentIds = collectSelectedComponentIds(pos); + + if (shorted) { + if (componentIds.size() != 1) + return; + } + QMenu contextMenu(this); if (componentIds.size() == 1) { @@ -493,6 +550,13 @@ void PartTreeWidget::showContextMenu(const QPoint &pos) contextMenu.addSeparator(); //} + if (shorted) { + auto globalPos = mapToGlobal(pos); + globalPos.setX(globalPos.x() - contextMenu.sizeHint().width() - pos.x()); + contextMenu.exec(globalPos); + return; + } + QAction showAction(tr("Show"), this); showAction.setIcon(Theme::awesome()->icon(fa::eye)); QAction hideAction(tr("Hide"), this); @@ -758,7 +822,9 @@ void PartTreeWidget::showContextMenu(const QPoint &pos) contextMenu.addAction(&deleteAction); } - contextMenu.exec(mapToGlobal(pos)); + auto globalPos = mapToGlobal(pos); + globalPos.setX(globalPos.x() - contextMenu.sizeHint().width() - pos.x()); + contextMenu.exec(globalPos); for (const auto &action: groupsActions) { delete action; diff --git a/src/parttreewidget.h b/src/parttreewidget.h index bbfa0a81..facbaf8a 100644 --- a/src/parttreewidget.h +++ b/src/parttreewidget.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "document.h" class PartTreeWidget : public QTreeWidget @@ -85,11 +86,12 @@ public slots: void groupExpanded(QTreeWidgetItem *item); void groupCollapsed(QTreeWidgetItem *item); void removeAllContent(); - void showContextMenu(const QPoint &pos); + void showContextMenu(const QPoint &pos, bool shorted=false); void showClothSettingMenu(const QPoint &pos, const QUuid &componentId); protected: QSize sizeHint() const override; void mousePressEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; private: void addComponentChildrenToItem(QUuid componentId, QTreeWidgetItem *parentItem); void deleteItemChildren(QTreeWidgetItem *item); @@ -98,9 +100,12 @@ private: void updateComponentSelectState(QUuid componentId, bool selected); void updateComponentAppearance(QUuid componentId); bool isComponentSelected(QUuid componentId); + std::vector collectSelectedComponentIds(const QPoint &pos); + void handleSingleClick(const QPoint &pos); private: const Document *m_document = nullptr; QTreeWidgetItem *m_rootItem = nullptr; + QTimer *m_delayedMousePressTimer = nullptr; bool m_firstSelect = true; std::map m_partItemMap; std::map m_componentItemMap; diff --git a/src/partwidget.cpp b/src/partwidget.cpp index 618454e3..539959e7 100644 --- a/src/partwidget.cpp +++ b/src/partwidget.cpp @@ -323,11 +323,11 @@ void PartWidget::updateUnnormalState(bool unnormal) updateAllButtons(); } -void PartWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - QWidget::mouseDoubleClickEvent(event); - emit checkPart(m_partId); -} +//void PartWidget::mouseDoubleClickEvent(QMouseEvent *event) +//{ +// QWidget::mouseDoubleClickEvent(event); +// emit checkPart(m_partId); +//} void PartWidget::initToolButtonWithoutFont(QPushButton *button) { diff --git a/src/partwidget.h b/src/partwidget.h index 53c892d6..ebc520d3 100644 --- a/src/partwidget.h +++ b/src/partwidget.h @@ -58,7 +58,7 @@ public: static QSize preferredSize(); ModelWidget *previewWidget(); protected: - void mouseDoubleClickEvent(QMouseEvent *event) override; + //void mouseDoubleClickEvent(QMouseEvent *event) override; public slots: void showDeformSettingPopup(const QPoint &pos); void showCutRotationSettingPopup(const QPoint &pos);