CMindView.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "CMindView.h"
  2. #include "CRectItem.h"
  3. #include "CLineItem.h"
  4. #include "CTextItem.h"
  5. #include "CMind.h"
  6. #include "CNodeItem.h"
  7. #include <QMenu>
  8. #include <QContextMenuEvent>
  9. #include <QDebug>
  10. CMindView::CMindView(QWidget *parent) : QGraphicsView(new QGraphicsScene(), parent)
  11. {
  12. setRenderHints(QPainter::Antialiasing); // 抗锯齿
  13. m_mind = new CMind(this);
  14. m_group = new QGraphicsItemGroup();
  15. m_group->setFlags(QGraphicsItem::ItemIsMovable);
  16. m_group->setHandlesChildEvents(false);
  17. scene()->addItem(m_group);
  18. setStyleSheet("QGraphicsView {border: 1px solid rgba(0, 0, 0, 0.073);background: rgb(244, 244, "
  19. "255);}");
  20. }
  21. CMind *CMindView::mind() const
  22. {
  23. return m_mind;
  24. }
  25. void CMindView::setNodeList(QList<CNodeData> list)
  26. {
  27. clear();
  28. m_mind->setNodeList(list);
  29. m_root = new CNodeItem(m_mind->root());
  30. refreshItems();
  31. }
  32. void CMindView::addNode(CNodeData n)
  33. {
  34. m_mind->addNode(n);
  35. CNodeItem *item = new CNodeItem(n);
  36. connect(item, &CNodeItem::sigAddSubItem, this, &CMindView::slotAddSubNode);
  37. connect(item, &CNodeItem::sigRemoveItem, this, &CMindView::slotRemoveNode);
  38. connect(item, &CNodeItem::sigTextChanged, this, &CMindView::slotTextChanged);
  39. if (m_root == nullptr) {
  40. m_root = item;
  41. } else {
  42. m_root->endEditing();
  43. m_root->addSubNode(item);
  44. }
  45. item->textItem()->beginEditing();
  46. refreshItems();
  47. }
  48. void CMindView::clear()
  49. {
  50. m_mind->nodeList().clear();
  51. delete m_root;
  52. m_root = nullptr;
  53. refreshItems();
  54. }
  55. void CMindView::refreshItems()
  56. {
  57. for (QGraphicsItem *item : m_items) {
  58. scene()->removeItem(item);
  59. }
  60. m_items.clear();
  61. refreshNodeGeometry(m_root);
  62. collectItems(m_root);
  63. for (QGraphicsItem *item : m_items) {
  64. m_group->addToGroup(item);
  65. }
  66. QRectF r = m_group->childrenBoundingRect();
  67. setSceneRect(QRectF(QPointF(), r.size()));
  68. }
  69. void CMindView::collectItems(CNodeItem *node)
  70. {
  71. if (node == nullptr) {
  72. return;
  73. }
  74. m_items.append(node->rectItem());
  75. for (QObject *o : node->children()) {
  76. CNodeItem *n = dynamic_cast<CNodeItem *>(o);
  77. collectItems(n);
  78. }
  79. }
  80. qreal CMindView::hNodeSpace() const
  81. {
  82. return m_hNodeSpace;
  83. }
  84. void CMindView::setHNodeSpace(qreal h)
  85. {
  86. m_hNodeSpace = h;
  87. }
  88. qreal CMindView::vNodeSpace() const
  89. {
  90. return m_vNodeSpace;
  91. }
  92. void CMindView::setVNodeSpace(qreal v)
  93. {
  94. m_vNodeSpace = v;
  95. }
  96. void CMindView::setALignment(CMindView::Alignment align)
  97. {
  98. m_align = align;
  99. }
  100. CNodeItem *CMindView::root() const
  101. {
  102. return m_root;
  103. }
  104. void CMindView::refreshNodeGeometry(CNodeItem *node, QPointF topLeft)
  105. {
  106. /// 边框
  107. if (node == nullptr) {
  108. return;
  109. }
  110. QRect borderRect = QRect(topLeft.x(), topLeft.y() + (node->treeHeight() - node->borderHeight()) / 2,
  111. node->borderWidth(), node->borderHeight());
  112. node->rectItem()->setRect(borderRect);
  113. /// 文本
  114. QPointF textPos = QPointF(borderRect.left() + node->xMargin(),
  115. borderRect.top() + (node->borderHeight() - node->textHeight()) / 2);
  116. node->textItem()->setPos(textPos);
  117. node->textItem()->setTextWidth(borderRect.width() - node->xMargin() * 2);
  118. node->rectItem()->setPos(QPoint(0, 0));
  119. /// 子节点
  120. int x = borderRect.right() + m_hNodeSpace;
  121. if (m_align) {
  122. x = borderRect.left() + m_root->maxBorderWidthOfLevel(node->depth()) + m_hNodeSpace;
  123. }
  124. int y = topLeft.y();
  125. if (node->borderHeight() > node->childrenHeight()) {
  126. y += (node->borderHeight() - node->childrenHeight()) / 2;
  127. }
  128. for (QObject *obj : node->children()) {
  129. CNodeItem *subNode = dynamic_cast<CNodeItem *>(obj);
  130. refreshNodeGeometry(subNode, QPointF(x, y));
  131. y += subNode->treeHeight() + m_vNodeSpace;
  132. subNode->lineItem()->setStartPos(node->rectItem()->centerRight());
  133. subNode->lineItem()->setEndPos(subNode->rectItem()->centerLeft());
  134. }
  135. }
  136. void CMindView::mousePressEvent(QMouseEvent *event)
  137. {
  138. QGraphicsItem *item = itemAt(event->pos());
  139. CTextItem *text = dynamic_cast<CTextItem *>(item);
  140. if (text == nullptr && m_root != nullptr && m_root->isEditing()) {
  141. m_root->endEditing();
  142. refreshItems();
  143. }
  144. QGraphicsView::mousePressEvent(event);
  145. }
  146. void CMindView::slotAddSubNode(int pNumber)
  147. {
  148. if (pNumber < 0) {
  149. return;
  150. }
  151. CNodeData data = root()->data();
  152. CNodeData n = CNodeData(data.projectId, data.evalType, m_mind->maxNumber() + 1, pNumber);
  153. addNode(n);
  154. }
  155. void CMindView::slotRemoveNode(int number)
  156. {
  157. m_mind->removeNode(number);
  158. if (number == m_root->data().number) {
  159. clear();
  160. } else {
  161. m_root->removeNode(number);
  162. }
  163. refreshItems();
  164. }
  165. void CMindView::slotTextChanged()
  166. {
  167. refreshItems();
  168. }