File indexing completed on 2024-05-12 05:40:25
0001 /*************************************************************************** 0002 * Copyright (C) 2022 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "mindmap/data/packagenode.h" 0021 0022 #include <QDebug> 0023 namespace mindmap 0024 { 0025 PackageNode::PackageNode(QObject* parent) : PositionedItem{MindItem::PackageType, parent}, m_title{tr("Package")} 0026 { 0027 connect(this, &PackageNode::itemDragged, this, [this](const QPointF& motion) { 0028 std::for_each(std::begin(m_internalChildren), std::end(m_internalChildren), [motion](PositionedItem* item) { 0029 if(!item) 0030 return; 0031 auto pos= item->position(); 0032 item->setPosition({pos.x() - motion.x(), pos.y() - motion.y()}); 0033 }); 0034 }); 0035 0036 connect(this, &PackageNode::widthChanged, this, &PackageNode::performLayout); 0037 connect(this, &PackageNode::heightChanged, this, &PackageNode::performLayout); 0038 connect(this, &PackageNode::visibleChanged, this, [this](bool visible) { 0039 std::for_each(std::begin(m_internalChildren), std::end(m_internalChildren), 0040 [visible](PositionedItem* item) { item->setVisible(visible); }); 0041 }); 0042 } 0043 0044 const QString& PackageNode::title() const 0045 { 0046 return m_title; 0047 } 0048 0049 void PackageNode::setTitle(const QString& newTitle) 0050 { 0051 if(m_title == newTitle) 0052 return; 0053 m_title= newTitle; 0054 emit titleChanged(); 0055 } 0056 0057 void PackageNode::addChild(PositionedItem* item) 0058 { 0059 if(m_internalChildren.contains(item) || item == this || item == nullptr) 0060 return; 0061 m_internalChildren.append(item); 0062 performLayout(); 0063 emit childAdded(item->id()); 0064 } 0065 0066 const QList<PositionedItem*>& PackageNode::children() const 0067 { 0068 return m_internalChildren; 0069 } 0070 0071 void PackageNode::performLayout() 0072 { 0073 if(m_internalChildren.isEmpty()) 0074 return; 0075 0076 auto const itemCount= m_internalChildren.size(); 0077 auto const w= width(); 0078 0079 std::vector<int> vec; 0080 std::transform(std::begin(m_internalChildren), std::end(m_internalChildren), std::back_inserter(vec), 0081 [](PositionedItem* item) { return item->width(); }); 0082 auto maxWidth= *std::max_element(std::begin(vec), std::end(vec)); 0083 0084 int itemPerLine= 1; 0085 while(maxWidth < (width() * 0.75) && itemCount > itemPerLine) 0086 { 0087 ++itemPerLine; 0088 int maxW= 0; 0089 std::vector<int> rows; 0090 rows.reserve(itemPerLine); 0091 for(auto w : vec) 0092 { 0093 if(rows.size() < itemPerLine) 0094 { 0095 rows.push_back(w); 0096 } 0097 else 0098 { 0099 maxW= std::max(std::accumulate(std::begin(rows), std::end(rows), 0), maxW); 0100 rows.clear(); 0101 } 0102 } 0103 maxW= std::max(std::accumulate(std::begin(rows), std::end(rows), 0), maxW); 0104 rows.clear(); 0105 maxWidth= maxW; 0106 qDebug() << itemPerLine << " maxwidth:" << maxWidth; 0107 } 0108 0109 if(maxWidth > width()) 0110 { 0111 --itemPerLine; 0112 } 0113 // auto const itemPerLine= std::min(static_cast<int>((w - m_minimumMargin) / (m_sizeItem + m_minimumMargin)), 0114 // static_cast<int>(itemCount)); 0115 0116 auto currentMarge= (w - maxWidth) / (itemPerLine + 1); 0117 0118 auto currentX= itemPerLine == itemCount ? currentMarge : m_minimumMargin; 0119 auto currentY= m_minimumMargin; 0120 0121 int i= 0; 0122 qreal maxH= 0.; 0123 for(auto item : m_internalChildren) 0124 { 0125 auto p= position(); 0126 QPointF a{currentX + p.x(), currentY + p.y()}; 0127 // qDebug() << a; 0128 item->setPosition(a); 0129 0130 currentX+= item->width() + currentMarge; 0131 maxH= std::max(item->height(), maxH); 0132 ++i; 0133 if(i >= itemPerLine) 0134 { 0135 currentY+= maxH + m_minimumMargin; 0136 currentX= m_minimumMargin; 0137 maxH= 0.; 0138 } 0139 } 0140 } 0141 0142 int PackageNode::minimumMargin() const 0143 { 0144 return m_minimumMargin; 0145 } 0146 0147 void PackageNode::setMinimumMargin(int newMinimumMargin) 0148 { 0149 if(m_minimumMargin == newMinimumMargin) 0150 return; 0151 m_minimumMargin= newMinimumMargin; 0152 emit minimumMarginChanged(); 0153 } 0154 0155 QStringList PackageNode::childrenId() const 0156 { 0157 QStringList res; 0158 0159 std::transform(std::begin(m_internalChildren), std::end(m_internalChildren), std::back_inserter(res), 0160 [](PositionedItem* item) { return item->id(); }); 0161 0162 return res; 0163 } 0164 0165 } // namespace mindmap