Pārlūkot izejas kodu

处理节点编辑事件;
处理节点图拖拽事件

chengxr 1 gadu atpakaļ
vecāks
revīzija
d6c0decf61

+ 43 - 5
QFD/CCanvas/CMindView.cpp

@@ -15,6 +15,8 @@ CMindView::CMindView(QWidget *parent) : QGraphicsView(new QGraphicsScene(), pare
 {
     setRenderHints(QPainter::Antialiasing);  // 抗锯齿
 
+    //    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+
     m_mind  = new CMind(this);
     m_group = new QGraphicsItemGroup();
     m_group->setFlags(QGraphicsItem::ItemIsMovable);
@@ -66,6 +68,7 @@ void CMindView::addNode(CNodeData n)
     connect(item, &CNodeItem::sigAddSubItem, this, &CMindView::slotAddSubNode);
     connect(item, &CNodeItem::sigRemoveItem, this, &CMindView::slotRemoveNode);
     connect(item, &CNodeItem::sigTextChanged, this, &CMindView::slotTextChanged);
+    connect(item, &CNodeItem::sigWillBeginEditing, this, &CMindView::slotWillBeginEditing);
 
     if (m_root == nullptr) {
         m_root = item;
@@ -95,14 +98,15 @@ void CMindView::refreshItems()
     }
     m_items.clear();
 
+    qDebug() << __FUNCTION__ << __LINE__ << m_group->boundingRect() << m_group->pos() << endl;
+
     refreshNodeGeometry(m_root);
     collectItems(m_root);
     for (QGraphicsItem *item : m_items) {
         m_group->addToGroup(item);
     }
 
-    QRectF r = m_group->childrenBoundingRect();
-    setSceneRect(QRectF(QPointF(), r.size()));
+    moveToCenter();
 }
 
 void CMindView::collectItems(CNodeItem *node)
@@ -192,13 +196,41 @@ void CMindView::mousePressEvent(QMouseEvent *event)
 {
     QGraphicsItem *item = itemAt(event->pos());
     CTextItem *text     = dynamic_cast<CTextItem *>(item);
-    if (text == nullptr && m_root != nullptr && m_root->isEditing()) {
+    if (text == nullptr && m_root != nullptr && m_root->editingNode() != nullptr) {
         m_root->endEditing();
-        refreshItems();
     }
+
+    if (isCloseToEdge()) {
+        moveToCenter();
+    }
+
     QGraphicsView::mousePressEvent(event);
 }
 
+void CMindView::mouseMoveEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseMoveEvent(event);
+}
+
+bool CMindView::isCloseToEdge()
+{
+    qreal left        = m_group->pos().x();
+    qreal right       = m_group->pos().x() + m_group->boundingRect().width();
+    qreal top         = m_group->pos().y();
+    qreal bottom      = m_group->pos().y() + m_group->boundingRect().height();
+    qreal allowedArea = 0.8;
+
+    return left > width() * allowedArea || right < width() * (1 - allowedArea) || top > height() * allowedArea
+            || bottom < height() * (1 - allowedArea);
+}
+
+void CMindView::moveToCenter()
+{
+    m_group->setPos(QPointF());
+    QRectF r = m_group->childrenBoundingRect();
+    setSceneRect(QRectF(QPointF(), r.size()));
+}
+
 void CMindView::testData()
 {
     int num[19]  = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };
@@ -234,6 +266,12 @@ void CMindView::slotRemoveNode(int number)
 void CMindView::slotTextChanged()
 {
     CNodeItem *item = (CNodeItem *)sender();
-    qDebug() << __FUNCTION__ << __LINE__ << item->data().name << endl;
     refreshItems();
+    qDebug() << __FUNCTION__ << __LINE__ << item->data().name << endl;
+}
+
+void CMindView::slotWillBeginEditing()
+{
+    m_root->endEditing();
+    //    refreshItems();
 }

+ 8 - 0
QFD/CCanvas/CMindView.h

@@ -42,6 +42,12 @@ public:
 
     void mousePressEvent(QMouseEvent *event) override;
 
+    void mouseMoveEvent(QMouseEvent *event) override;
+
+    bool isCloseToEdge();
+
+    void moveToCenter();
+
     void testData();
 
 public slots:
@@ -51,6 +57,8 @@ public slots:
 
     void slotTextChanged();  // 编辑节点
 
+    void slotWillBeginEditing();
+
 signals:
     void sigAddSubNode(int pNumber);
 

+ 21 - 15
QFD/CCanvas/CNodeItem.cpp

@@ -136,8 +136,8 @@ void CNodeItem::connectSignalsAndSlots()
     connect(m_rectItem->selectAction(), &QAction::triggered, this, &CNodeItem::slotSelect);
     connect(m_rectItem->subNodeAction(), &QAction::triggered, this, &CNodeItem::slotSubNode);
     connect(m_rectItem->removeAction(), &QAction::triggered, this, &CNodeItem::slotRemove);
+    connect(m_textItem, &CTextItem::sigWillBeginEditing, this, &CNodeItem::slotWillBeginEditing);
     connect(m_textItem, &CTextItem::sigTextChanged, this, &CNodeItem::slotTextChanged);
-    connect(m_textItem->document(), &QTextDocument::contentsChanged, this, &CNodeItem::slotTextChanged);
 }
 
 void CNodeItem::updateItemsGeometry()
@@ -272,27 +272,28 @@ void CNodeItem::beginEditing()
 
 void CNodeItem::endEditing()
 {
-    m_textItem->endEditing();
-    for (QObject *obj : children()) {
-        CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
-        item->endEditing();
+    CNodeItem *item = editingNode();
+    if (item != nullptr) {
+        item->textItem()->endEditing();
     }
 }
 
-bool CNodeItem::isEditing() const
+CNodeItem *CNodeItem::editingNode()
 {
-    bool e = m_textItem->isEditing();
+    CNodeItem *node = nullptr;
+    if (m_textItem->isEditing()) {
+        return this;
+    }
 
-    if (e == false) {
-        for (QObject *obj : children()) {
-            CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
-            if (item->isEditing()) {
-                e = true;
-            }
+    for (QObject *obj : children()) {
+        CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
+        node            = item->editingNode();
+        if (node != nullptr) {
+            return node;
         }
     }
 
-    return e;
+    return node;
 }
 
 void CNodeItem::slotSelect()
@@ -312,6 +313,11 @@ void CNodeItem::slotRemove()
 
 void CNodeItem::slotTextChanged()
 {
-    data().name = m_textItem->toPlainText();
+    m_data.name = m_textItem->toPlainText();
     emit sigTextChanged();
 }
+
+void CNodeItem::slotWillBeginEditing()
+{
+    emit sigWillBeginEditing();
+}

+ 3 - 1
QFD/CCanvas/CNodeItem.h

@@ -84,18 +84,20 @@ public:
 
     void endEditing();
 
-    bool isEditing() const;
+    CNodeItem *editingNode();
 
 signals:
     void sigAddSubItem(int pNumber);
     void sigRemoveItem(int number);
     void sigTextChanged();
+    void sigWillBeginEditing();
 
 public slots:
     void slotSelect();
     void slotSubNode();
     void slotRemove();
     void slotTextChanged();
+    void slotWillBeginEditing();
 
 private:
     CNodeData m_data;

+ 15 - 2
QFD/CCanvas/CTextItem.cpp

@@ -12,12 +12,14 @@ CTextItem::CTextItem(const QString &text, QGraphicsItem *parent) : QGraphicsText
 {
     setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsSelectable);
     setTextInteractionFlags(Qt::TextEditorInteraction);
+    connect(document(), &QTextDocument::contentsChanged, this, &CTextItem::slotTextChanged);
 }
 
 void CTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton) {  //左键双击进入可编辑状态并打开焦点
         if (allowEdit()) {
+            emit sigWillBeginEditing();
             beginEditing();
         }
         QGraphicsTextItem::mouseDoubleClickEvent(event);
@@ -29,7 +31,6 @@ void CTextItem::keyPressEvent(QKeyEvent *event)
     switch (event->key()) {
     case Qt::Key_Return: {
         endEditing();
-        emit sigTextChanged();
     }
     }
 
@@ -47,6 +48,11 @@ void CTextItem::endEditing()
     setTextInteractionFlags(Qt::NoTextInteraction);
     setSelected(false);
     clearFocus();
+
+    if (m_textChanged) {
+        emit sigTextChanged();
+        m_textChanged = false;
+    }
 }
 
 bool CTextItem::isEditing() const
@@ -62,7 +68,9 @@ bool CTextItem::allowEdit() const
 void CTextItem::setAllowEdit(bool a)
 {
     m_allowEdit = a;
-    endEditing();
+    if (a == false) {
+        endEditing();
+    }
 }
 
 QSizeF CTextItem::textSize(const QString t, qreal width)
@@ -78,3 +86,8 @@ QSizeF CTextItem::textSize(const QString t, qreal width)
 
     return i->document()->size();
 }
+
+void CTextItem::slotTextChanged()
+{
+    m_textChanged = true;
+}

+ 6 - 1
QFD/CCanvas/CTextItem.h

@@ -27,11 +27,16 @@ public:
 
     static QSizeF textSize(const QString t, qreal width = -1);
 
+public slots:
+    void slotTextChanged();
+
 signals:
+    void sigWillBeginEditing();
     void sigTextChanged();
 
 private:
-    bool m_allowEdit = true;
+    bool m_allowEdit   = true;
+    bool m_textChanged = false;
 };
 
 #endif  // CTEXTITEM_H