File indexing completed on 2024-04-28 05:38:13
0001 /*************************************************************************** 0002 * Copyright (C) 2010 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * rolisteam 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 0021 #include <QtWidgets> 0022 0023 #include "flowlayout.h" 0024 FlowLayout::FlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) 0025 : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) 0026 { 0027 setContentsMargins(margin, margin, margin, margin); 0028 } 0029 0030 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) : m_hSpace(hSpacing), m_vSpace(vSpacing) 0031 { 0032 setContentsMargins(margin, margin, margin, margin); 0033 } 0034 0035 FlowLayout::~FlowLayout() 0036 { 0037 QLayoutItem* item; 0038 while((item= takeAt(0))) 0039 delete item; 0040 } 0041 0042 void FlowLayout::addItem(QLayoutItem* item) 0043 { 0044 itemList.append(item); 0045 } 0046 0047 int FlowLayout::horizontalSpacing() const 0048 { 0049 if(m_hSpace >= 0) 0050 { 0051 return m_hSpace; 0052 } 0053 else 0054 { 0055 return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); 0056 } 0057 } 0058 0059 int FlowLayout::verticalSpacing() const 0060 { 0061 if(m_vSpace >= 0) 0062 { 0063 return m_vSpace; 0064 } 0065 else 0066 { 0067 return smartSpacing(QStyle::PM_LayoutVerticalSpacing); 0068 } 0069 } 0070 0071 int FlowLayout::count() const 0072 { 0073 return itemList.size(); 0074 } 0075 0076 QLayoutItem* FlowLayout::itemAt(int index) const 0077 { 0078 return itemList.value(index); 0079 } 0080 0081 QLayoutItem* FlowLayout::takeAt(int index) 0082 { 0083 if(index >= 0 && index < itemList.size()) 0084 return itemList.takeAt(index); 0085 else 0086 return 0; 0087 } 0088 0089 Qt::Orientations FlowLayout::expandingDirections() const 0090 { 0091 return Qt::Horizontal; 0092 } 0093 0094 bool FlowLayout::hasHeightForWidth() const 0095 { 0096 return true; 0097 } 0098 0099 int FlowLayout::heightForWidth(int width) const 0100 { 0101 int height= doLayout(QRect(0, 0, width, 0), true); 0102 return height; 0103 } 0104 0105 void FlowLayout::setGeometry(const QRect& rect) 0106 { 0107 QLayout::setGeometry(rect); 0108 doLayout(rect, false); 0109 } 0110 0111 QSize FlowLayout::sizeHint() const 0112 { 0113 return minimumSize(); 0114 } 0115 0116 QSize FlowLayout::minimumSize() const 0117 { 0118 QSize size; 0119 for(auto item : itemList) 0120 size= size.expandedTo(item->minimumSize()); 0121 size+= QSize(contentsMargins().left() + contentsMargins().right(), 0122 contentsMargins().top() + contentsMargins().bottom()); 0123 return size; 0124 } 0125 0126 int FlowLayout::doLayout(const QRect& rect, bool testOnly) const 0127 { 0128 int left, top, right, bottom; 0129 getContentsMargins(&left, &top, &right, &bottom); 0130 QRect effectiveRect= rect.adjusted(+left, +top, -right, -bottom); 0131 int x= effectiveRect.x(); 0132 int y= effectiveRect.y(); 0133 int lineHeight= 0; 0134 0135 for(auto item : itemList) 0136 { 0137 QWidget* wid= item->widget(); 0138 int spaceX= horizontalSpacing(); 0139 if(spaceX == -1) 0140 spaceX= wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); 0141 int spaceY= verticalSpacing(); 0142 if(spaceY == -1) 0143 spaceY= wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); 0144 int nextX= x + item->sizeHint().width() + spaceX; 0145 if(nextX - spaceX > effectiveRect.right() && lineHeight > 0) 0146 { 0147 x= effectiveRect.x(); 0148 y= y + lineHeight + spaceY; 0149 nextX= x + item->sizeHint().width() + spaceX; 0150 lineHeight= 0; 0151 } 0152 0153 if(!testOnly) 0154 item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); 0155 0156 x= nextX; 0157 lineHeight= qMax(lineHeight, item->sizeHint().height()); 0158 } 0159 return y + lineHeight - rect.y() + bottom; 0160 } 0161 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const 0162 { 0163 QObject* parent= this->parent(); 0164 if(!parent) 0165 { 0166 return -1; 0167 } 0168 else if(parent->isWidgetType()) 0169 { 0170 QWidget* pw= static_cast<QWidget*>(parent); 0171 return pw->style()->pixelMetric(pm, 0, pw); 0172 } 0173 else 0174 { 0175 return static_cast<QLayout*>(parent)->spacing(); 0176 } 0177 }