📄 qgridlayout.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qgridlayout.h"#include "qapplication.h"#include "qwidget.h"#include "qlist.h"#include "qsizepolicy.h"#include "qvector.h"#include "qvarlengtharray.h"#include "qlayoutengine_p.h"#include "qlayout_p.h"struct QGridLayoutSizeTriple{ QSize minS; QSize hint; QSize maxS;};/* Three internal classes related to QGridLayout: (1) QGridBox is a QLayoutItem with (row, column) information and (torow, tocolumn) information; (3) QGridLayoutData is the internal representation of a QGridLayout.*/class QGridBox{public: QGridBox(QLayoutItem *lit) { item_ = lit; } QGridBox(QWidget *wid) { item_ = new QWidgetItem(wid); } ~QGridBox() { delete item_; } QSize sizeHint() const { return item_->sizeHint(); } QSize minimumSize() const { return item_->minimumSize(); } QSize maximumSize() const { return item_->maximumSize(); } Qt::Orientations expandingDirections() const { return item_->expandingDirections(); } bool isEmpty() const { return item_->isEmpty(); } bool hasHeightForWidth() const { return item_->hasHeightForWidth(); } int heightForWidth(int w) const { return item_->heightForWidth(w); } void setAlignment(Qt::Alignment a) { item_->setAlignment(a); } void setGeometry(const QRect &r) { item_->setGeometry(r); } Qt::Alignment alignment() const { return item_->alignment(); } QLayoutItem *item() { return item_; } QLayoutItem *takeItem() { QLayoutItem *i = item_; item_ = 0; return i; } int hStretch() { return item_->widget() ? item_->widget()->sizePolicy().horizontalStretch() : 0; } int vStretch() { return item_->widget() ? item_->widget()->sizePolicy().verticalStretch() : 0; }private: friend class QGridLayoutPrivate; inline int toRow(int rr) const { return torow >= 0 ? torow : rr - 1; } inline int toCol(int cc) const { return tocol >= 0 ? tocol : cc - 1; } QLayoutItem *item_; int row, col; int torow, tocol;};class QGridLayoutPrivate : public QLayoutPrivate{ Q_DECLARE_PUBLIC(QGridLayout)public: QGridLayoutPrivate(); void add(QGridBox*, int row, int col); void add(QGridBox*, int row1, int row2, int col1, int col2); QSize sizeHint(int hSpacing, int vSpacing) const; QSize minimumSize(int hSpacing, int vSpacing) const; QSize maximumSize(int hSpacing, int vSpacing) const; Qt::Orientations expandingDirections(int hSpacing, int vSpacing) const; void distribute(QRect rect, int hSpacing, int vSpacing); inline int numRows() const { return rr; } inline int numCols() const { return cc; } inline void expand(int rows, int cols) { setSize(qMax(rows, rr), qMax(cols, cc)); } inline void setRowStretch(int r, int s) { expand(r + 1, 0); rStretch[r] = s; setDirty(); } inline void setColStretch(int c, int s) { expand(0, c + 1); cStretch[c] = s; setDirty(); } inline int rowStretch(int r) const { return rStretch.at(r); } inline int colStretch(int c) const { return cStretch.at(c); } inline void setRowMinimumHeight(int r, int s) { expand(r + 1, 0); rMinHeights[r] = s; setDirty(); } inline void setColumnMinimumWidth(int c, int s) { expand(0, c + 1); cMinWidths[c] = s; setDirty(); } inline int rowSpacing(int r) const { return rMinHeights.at(r); } inline int colSpacing(int c) const { return cMinWidths.at(c); } inline void setReversed(bool r, bool c) { hReversed = c; vReversed = r; } inline bool horReversed() const { return hReversed; } inline bool verReversed() const { return vReversed; } inline void setDirty() { needRecalc = true; hfw_width = -1; } inline bool isDirty() const { return needRecalc; } bool hasHeightForWidth(int hSpacing, int vSpacing); int heightForWidth(int width, int hSpacing, int vSpacing); int minimumHeightForWidth(int width, int hSpacing, int vSpacing); inline void getNextPos(int &row, int &col) { row = nextR; col = nextC; } inline int count() const { return things.count(); } QRect cellRect(int row, int col) const; inline QLayoutItem *itemAt(int index) const { if (index < things.count()) return things.at(index)->item(); else return 0; } inline QLayoutItem *takeAt(int index) { QLayoutItem *item = 0; if (index < things.count()) { QGridBox *b = things.takeAt(index); if (b) { item = b->takeItem(); delete b; } } return item; } void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) { if (index < things.count()) { QGridBox *b = things.at(index); int toRow = b->toRow(rr); int toCol = b->toCol(cc); *row = b->row; *column = b->col; *rowSpan = toRow - *row + 1; *columnSpan = toCol - *column +1; } } void deleteAll();private: void setNextPosAfter(int r, int c); void recalcHFW(int w); void addHfwData(QGridBox *box, int width); void init(); QSize findSize(int QLayoutStruct::*, int hSpacing, int vSpacing) const; void addData(QGridBox *b, const QGridLayoutSizeTriple &sizes, bool r, bool c); void setSize(int rows, int cols); void setupSpacings(QVector<QLayoutStruct> &chain, QGridBox *grid[], int fixedSpacing, Qt::Orientation orientation); void setupLayoutData(int hSpacing, int vSpacing); void setupHfwLayoutData(); void effectiveMargins(int *left, int *top, int *right, int *bottom) const; int rr; int cc; QVector<QLayoutStruct> rowData; QVector<QLayoutStruct> colData; QVector<QLayoutStruct> *hfwData; QVector<int> rStretch; QVector<int> cStretch; QVector<int> rMinHeights; QVector<int> cMinWidths; QList<QGridBox *> things; int hfw_width; int hfw_height; int hfw_minheight; int nextR; int nextC; int horizontalSpacing; int verticalSpacing; int leftMargin; int topMargin; int rightMargin; int bottomMargin; uint hReversed : 1; uint vReversed : 1; uint needRecalc : 1; uint has_hfw : 1; uint addVertical : 1;};void QGridLayoutPrivate::effectiveMargins(int *left, int *top, int *right, int *bottom) const{ int l = leftMargin; int t = topMargin; int r = rightMargin; int b = bottomMargin;#ifdef Q_WS_MAC int leftMost = INT_MAX; int topMost = INT_MAX; int rightMost = 0; int bottomMost = 0; QWidget *w = 0; const int n = things.count(); for (int i = 0; i < n; ++i) { QGridBox *box = things.at(i); QLayoutItem *itm = box->item(); w = itm->widget(); if (w) { bool visualHReversed = hReversed != (w->layoutDirection() == Qt::RightToLeft); QRect lir = itm->geometry(); QRect wr = w->geometry(); if (box->col <= leftMost) { if (box->col < leftMost) { // we found an item even closer to the margin, discard. leftMost = box->col; if (visualHReversed) r = rightMargin; else l = leftMargin; } if (visualHReversed) { r = qMax(r, wr.right() - lir.right()); } else { l = qMax(l, lir.left() - wr.left()); } } if (box->row <= topMost) { if (box->row < topMost) { // we found an item even closer to the margin, discard. topMost = box->row; if (vReversed) b = bottomMargin; else t = topMargin; } if (vReversed) b = qMax(b, wr.bottom() - lir.bottom()); else t = qMax(t, lir.top() - wr.top()); } if (box->toCol(cc) >= rightMost) { if (box->toCol(cc) > rightMost) { // we found an item even closer to the margin, discard. rightMost = box->toCol(cc); if (visualHReversed) l = leftMargin; else r = rightMargin; } if (visualHReversed) { l = qMax(l, lir.left() - wr.left()); } else { r = qMax(r, wr.right() - lir.right()); } } if (box->toRow(rr) >= bottomMost) { if (box->toRow(rr) > bottomMost) { // we found an item even closer to the margin, discard. bottomMost = box->toRow(rr); if (vReversed) t = topMargin; else b = bottomMargin; } if (vReversed) t = qMax(t, lir.top() - wr.top()); else b = qMax(b, wr.bottom() - lir.bottom()); } } }#endif if (left) *left = l; if (top) *top = t; if (right) *right = r; if (bottom) *bottom = b;}QGridLayoutPrivate::QGridLayoutPrivate(){ addVertical = false; setDirty(); rr = cc = 0; nextR = nextC = 0; hfwData = 0; hReversed = false; vReversed = false; horizontalSpacing = -1; verticalSpacing = -1;}#if 0QGridLayoutPrivate::QGridLayoutPrivate(int nRows, int nCols) : rowData(0), colData(0){ init(); if (nRows < 0) { nRows = 1; addVertical = false; } if (nCols < 0) { nCols = 1; addVertical = true; } setSize(nRows, nCols);}#endifvoid QGridLayoutPrivate::deleteAll(){ while (!things.isEmpty()) delete things.takeFirst(); delete hfwData;}bool QGridLayoutPrivate::hasHeightForWidth(int hSpacing, int vSpacing){ setupLayoutData(hSpacing, vSpacing); return has_hfw;}/* Assumes that setupLayoutData() has been called, and that qGeomCalc() has filled in colData with appropriate values.*/void QGridLayoutPrivate::recalcHFW(int w){ /* Go through all children, using colData and heightForWidth() and put the results in hfwData. */ if (!hfwData) hfwData = new QVector<QLayoutStruct>(rr); setupHfwLayoutData(); QVector<QLayoutStruct> &rData = *hfwData; int h = 0; int mh = 0; for (int r = 0; r < rr; r++) { int spacing = rData.at(r).spacing; h += rData.at(r).sizeHint + spacing; mh += rData.at(r).minimumSize + spacing; } hfw_width = w; hfw_height = qMin(QLAYOUTSIZE_MAX, h); hfw_minheight = qMin(QLAYOUTSIZE_MAX, mh);}int QGridLayoutPrivate::heightForWidth(int w, int hSpacing, int vSpacing){ setupLayoutData(hSpacing, vSpacing); if (!has_hfw) return -1; int left, top, right, bottom; effectiveMargins(&left, &top, &right, &bottom); int hMargins = left + right; if (w - hMargins != hfw_width) { qGeomCalc(colData, 0, cc, 0, w - hMargins); recalcHFW(w - hMargins); } return hfw_height + top + bottom;}int QGridLayoutPrivate::minimumHeightForWidth(int w, int hSpacing, int vSpacing){ (void)heightForWidth(w, hSpacing, vSpacing); if (!has_hfw) return -1; int top, bottom; effectiveMargins(0, &top, 0, &bottom); return hfw_minheight + top + bottom;}QSize QGridLayoutPrivate::findSize(int QLayoutStruct::*size, int hSpacing, int vSpacing) const{ QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this); that->setupLayoutData(hSpacing, vSpacing); int w = 0; int h = 0; for (int r = 0; r < rr; r++) h += rowData.at(r).*size + rowData.at(r).spacing; for (int c = 0; c < cc; c++) w += colData.at(c).*size + colData.at(c).spacing; w = qMin(QLAYOUTSIZE_MAX, w); h = qMin(QLAYOUTSIZE_MAX, h); return QSize(w, h);}Qt::Orientations QGridLayoutPrivate::expandingDirections(int hSpacing, int vSpacing) const{ QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this); that->setupLayoutData(hSpacing, vSpacing); Qt::Orientations ret; for (int r = 0; r < rr; r++) { if (rowData.at(r).expansive) { ret |= Qt::Vertical; break; } } for (int c = 0; c < cc; c++) { if (colData.at(c).expansive) { ret |= Qt::Horizontal; break; } } return ret;}QSize QGridLayoutPrivate::sizeHint(int hSpacing, int vSpacing) const{ return findSize(&QLayoutStruct::sizeHint, hSpacing, vSpacing);}QSize QGridLayoutPrivate::maximumSize(int hSpacing, int vSpacing) const{ return findSize(&QLayoutStruct::maximumSize, hSpacing, vSpacing);}QSize QGridLayoutPrivate::minimumSize(int hSpacing, int vSpacing) const{ return findSize(&QLayoutStruct::minimumSize, hSpacing, vSpacing);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -