123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- #include "CNodeItem.h"
- #include "CRectItem.h"
- #include "CTextItem.h"
- #include "CLineItem.h"
- #include <QAction>
- #include <QTextDocument>
- #include <QDebug>
- CNodeItem::CNodeItem(const CNodeData data, CNodeItem *parent) : QObject(parent), m_data(data)
- {
- m_rectItem = new CRectItem();
- m_rectItem->setToolTip(data.remark);
- m_textItem = new CTextItem(data.name, m_rectItem);
- m_lineItem = new CLineItem(m_rectItem);
- updateItemsGeometry();
- connectSignalsAndSlots();
- // m_textItem->setDefaultTextColor(Qt::white);
- m_rectItem->setNormalFillColor(QColor("#ddddff"));
- m_lineItem->setNormalLineColor(QColor("#ddddff"));
- m_lineItem->setLineWidth(2);
- m_lineItem->setBrush(Qt::NoBrush);
- }
- CNodeData CNodeItem::data() const
- {
- return m_data;
- }
- void CNodeItem::setData(CNodeData data)
- {
- m_data = data;
- m_textItem->setPlainText(data.name);
- m_rectItem->setToolTip(data.remark);
- }
- void CNodeItem::addSubNode(CNodeItem *n)
- {
- if (n == nullptr) {
- return;
- }
- if (n->data().pNumber == data().number) {
- n->setParent(this);
- } else {
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- item->addSubNode(n);
- }
- }
- }
- void CNodeItem::removeNode(int number)
- {
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- if (item->data().number == number) {
- item->setParent(nullptr);
- delete item;
- } else {
- item->removeNode(number);
- }
- }
- }
- CNodeItem *CNodeItem::subNode(int number)
- {
- if (data().number == number) {
- return this;
- }
- for (QObject *obj : children()) {
- CNodeItem *t = dynamic_cast<CNodeItem *>(obj);
- CNodeItem *sub = t->subNode(number);
- if (sub != nullptr) {
- return sub;
- }
- }
- return nullptr;
- }
- CRectItem *CNodeItem::rectItem() const
- {
- return m_rectItem;
- }
- CTextItem *CNodeItem::textItem() const
- {
- return m_textItem;
- }
- CLineItem *CNodeItem::lineItem() const
- {
- return m_lineItem;
- }
- QPointF CNodeItem::pos() const
- {
- return m_pos;
- }
- void CNodeItem::setPos(const QPointF pos)
- {
- m_pos = pos;
- updateItemsGeometry();
- }
- qreal CNodeItem::xMargin() const
- {
- return m_xMargin;
- }
- void CNodeItem::setXMargin(qreal x)
- {
- m_xMargin = x;
- updateItemsGeometry();
- }
- qreal CNodeItem::yMargin() const
- {
- return m_yMargin;
- }
- void CNodeItem::setYMargin(qreal y)
- {
- m_yMargin = y;
- updateItemsGeometry();
- }
- qreal CNodeItem::minWidth() const
- {
- return m_minWidth;
- }
- void CNodeItem::setMinWidth(qreal w)
- {
- m_minWidth = w;
- updateItemsGeometry();
- }
- qreal CNodeItem::maxWidth() const
- {
- return m_maxWidth;
- }
- void CNodeItem::setMaxWidth(qreal w)
- {
- m_maxWidth = w;
- }
- qreal CNodeItem::minHeight() const
- {
- return m_minHeight;
- }
- void CNodeItem::setMinHeight(qreal h)
- {
- m_minHeight = h;
- updateItemsGeometry();
- }
- void CNodeItem::connectSignalsAndSlots()
- {
- connect(m_rectItem->editAction(), &QAction::triggered, this, &CNodeItem::slotEditNode);
- 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);
- }
- void CNodeItem::updateItemsGeometry()
- {
- QRectF tr = m_textItem->boundingRect();
- qreal w = std::max(tr.width() + m_xMargin * 2, m_minWidth);
- qreal h = std::max(tr.height() + m_yMargin * 2, m_minHeight);
- m_rectItem->setRect(QRectF(m_pos, QSizeF(w, h)));
- m_textItem->setPos(m_pos + QPointF(m_xMargin, (h - tr.height()) / 2));
- }
- int CNodeItem::height() const
- {
- int h = 1;
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- h = std::max(h, item->height() + 1);
- }
- return h;
- }
- int CNodeItem::depth() const
- {
- int d = 1;
- const CNodeItem *node = this;
- while (node->parent() != nullptr) {
- d++;
- node = dynamic_cast<CNodeItem *>(node->parent());
- }
- return d;
- }
- int CNodeItem::leafs() const
- {
- int d = 1;
- if (children().count() > 0) {
- int d = 0;
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- d += item->leafs();
- }
- }
- return d;
- }
- int CNodeItem::sizeOfLevel(int lev) const
- {
- if (lev < 1) {
- return 0;
- }
- if (lev == 1) {
- return 1;
- }
- int size = 0;
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- size += item->sizeOfLevel(lev - 1);
- }
- return size;
- }
- qreal CNodeItem::textWidth() const
- {
- return m_textItem->boundingRect().width();
- }
- qreal CNodeItem::textHeight() const
- {
- return m_textItem->boundingRect().height();
- }
- qreal CNodeItem::borderWidth() const
- {
- return m_minWidth;
- QFont font = m_textItem->font();
- QFontMetrics fm(font);
- int w = fm.width(m_textItem->toPlainText());
- return std::max(w + m_xMargin * 2, m_minWidth);
- }
- qreal CNodeItem::borderHeight() const
- {
- return std::max(textHeight() + m_yMargin * 2, m_minHeight);
- }
- qreal CNodeItem::hNodeSpace() const
- {
- return m_hNodeSpace;
- }
- void CNodeItem::setHNodeSpace(qreal h)
- {
- m_hNodeSpace = h;
- }
- qreal CNodeItem::vNodeSpace() const
- {
- return m_vNodeSpace;
- }
- void CNodeItem::setVNodeSpace(qreal v)
- {
- m_vNodeSpace = v;
- }
- qreal CNodeItem::childrenHeight() const
- {
- qreal h = vNodeSpace() * (children().count() - 1); // 子节点竖直方向上总间隔
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- h += item->treeHeight(); // 加上各子节点高度
- }
- return std::max(h, h - h);
- }
- qreal CNodeItem::treeHeight() const
- {
- return std::max(borderHeight(), childrenHeight());
- }
- qreal CNodeItem::maxBorderWidthOfLevel(int lev) const
- {
- if (lev < 1) {
- return 0;
- }
- if (lev == 1) {
- return borderWidth();
- }
- qreal w = 0;
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- w = std::max(w, item->maxBorderWidthOfLevel(lev - 1));
- }
- return w;
- }
- void CNodeItem::beginEditing()
- {
- m_textItem->beginEditing();
- }
- void CNodeItem::endEditing()
- {
- CNodeItem *item = editingNode();
- if (item != nullptr) {
- item->textItem()->endEditing();
- }
- }
- CNodeItem *CNodeItem::editingNode()
- {
- CNodeItem *node = nullptr;
- if (m_textItem->isEditing()) {
- return this;
- }
- for (QObject *obj : children()) {
- CNodeItem *item = dynamic_cast<CNodeItem *>(obj);
- node = item->editingNode();
- if (node != nullptr) {
- return node;
- }
- }
- return node;
- }
- void CNodeItem::setHighlighted(bool h)
- {
- m_rectItem->setHighlighted(h);
- m_lineItem->setHighlighted(h);
- m_lineItem->setBrush(Qt::NoBrush);
- m_textItem->setDefaultTextColor(h ? QColor("#cccccc") : Qt::black);
- }
- void CNodeItem::slotEditNode()
- {
- emit sigEditNode(data());
- }
- void CNodeItem::slotSelect()
- {
- m_rectItem->setHighlighted(!m_rectItem->highlighted());
- }
- void CNodeItem::slotSubNode()
- {
- emit sigAddSubItem(data().number);
- }
- void CNodeItem::slotRemove()
- {
- emit sigRemoveItem(data().number);
- }
- void CNodeItem::slotTextChanged()
- {
- m_data.name = m_textItem->toPlainText();
- emit sigTextChanged();
- }
- void CNodeItem::slotWillBeginEditing()
- {
- emit sigWillBeginEditing();
- }
|