⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgridlayout.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 "qlayoutengine_p.h"#include "qlayout_p.h"/*  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;    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) const;    QSize minimumSize(int) const;    QSize maximumSize(int) const;    Qt::Orientations expandingDirections(int spacing) const;    void distribute(QRect, int);    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[r]; }    inline int colStretch(int c) const { return cStretch[c]; }    inline void setRowSpacing(int r, int s)        { expand(r + 1, 0); rSpacing[r] = s; setDirty(); }    inline void setColSpacing(int c, int s)        { expand(0, c + 1); cSpacing[c] = s; setDirty(); }    inline int rowSpacing(int r) const { return rSpacing[r]; }    inline int colSpacing(int c) const { return cSpacing[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 space);    int heightForWidth(int, int, int);    int minimumHeightForWidth(int, int, int);    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 < 0 ? rr-1 : b->torow;            int toCol = b->tocol  < 0 ? cc-1 : b->tocol;            *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, int s);    void addHfwData(QGridBox *box, int width);    void init();    QSize findSize(int QLayoutStruct::*, int) const;    void addData(QGridBox *b, bool r = true, bool c = true);    void setSize(int rows, int cols);    void setupLayoutData(int space);    void setupHfwLayoutData(int space);    int rr;    int cc;    QVector<QLayoutStruct> rowData;    QVector<QLayoutStruct> colData;    QVector<QLayoutStruct> *hfwData;    QVector<int> rStretch;    QVector<int> cStretch;    QVector<int> rSpacing;    QVector<int> cSpacing;    QList<QGridBox *> things;    int hfw_width;    int hfw_height;    int hfw_minheight;    int nextR;    int nextC;    uint hReversed        : 1;    uint vReversed        : 1;    uint needRecalc        : 1;    uint has_hfw        : 1;    uint addVertical        : 1;};QGridLayoutPrivate::QGridLayoutPrivate(){    addVertical = false;    setDirty();    rr = cc = 0;    nextR = nextC = 0;    hfwData = 0;    hReversed = false;    vReversed = false;}#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 spacing){    setupLayoutData(spacing);    return has_hfw;}/*  Assumes that setupLayoutData() has been called, and that  qGeomCalc() has filled in colData with appropriate values.*/void QGridLayoutPrivate::recalcHFW(int w, int spacing){    /*      Go through all children, using colData and heightForWidth()      and put the results in hfwData.    */    if (!hfwData)        hfwData = new QVector<QLayoutStruct>(rr);    setupHfwLayoutData(spacing);    QVector<QLayoutStruct> &rData = *hfwData;    int h = 0;    int mh = 0;    int n = 0;    for (int r = 0; r < rr; r++) {        if (!rData[r].empty) {            h += rData[r].sizeHint;            mh += rData[r].minimumSize;            n++;        }    }    if (n) {        h += (n - 1) * spacing;        mh += (n - 1) * spacing;    }    hfw_width = w;    hfw_height = qMin(QLAYOUTSIZE_MAX, h);    hfw_minheight = qMin(QLAYOUTSIZE_MAX, mh);}int QGridLayoutPrivate::heightForWidth(int w, int margin, int spacing){    setupLayoutData(spacing);    if (!has_hfw)        return -1;    if (w + 2*margin != hfw_width) {        qGeomCalc(colData, 0, cc, 0, w+2*margin, spacing);        recalcHFW(w+2*margin, spacing);    }    return hfw_height + 2*margin;}int QGridLayoutPrivate::minimumHeightForWidth(int w, int margin, int spacing){    (void) heightForWidth(w, margin, spacing);    return has_hfw ? (hfw_minheight + 2*margin) : -1;}QSize QGridLayoutPrivate::findSize(int QLayoutStruct::*size, int spacer) const{    QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this);    that->setupLayoutData(spacer);    int w = 0;    int h = 0;    int n = 0;    for (int r = 0; r < rr; r++)        if (!rowData[r].empty) {            h = h + rowData[r].*size;            n++;        }    if (n)        h += (n - 1) * spacer;    n = 0;    for (int c = 0; c < cc; c++)        if (!colData[c].empty) {            w = w + colData[c].*size;            n++;        }    if (n)        w += (n - 1) * spacer;    w = qMin(QLAYOUTSIZE_MAX, w);    h = qMin(QLAYOUTSIZE_MAX, h);    return QSize(w, h);}Qt::Orientations QGridLayoutPrivate::expandingDirections(int spacing) const{    QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this);    that->setupLayoutData(spacing);    Qt::Orientations ret;    for (int r = 0; r < rr; r++) {        if (rowData[r].expansive) {            ret |= Qt::Vertical;            break;        }    }    for (int c = 0; c < cc; c++) {        if (colData[c].expansive) {            ret |= Qt::Horizontal;            break;        }    }    return ret;}QSize QGridLayoutPrivate::sizeHint(int spacer) const{    return findSize(&QLayoutStruct::sizeHint, spacer);}QSize QGridLayoutPrivate::maximumSize(int spacer) const{    return findSize(&QLayoutStruct::maximumSize, spacer);}QSize QGridLayoutPrivate::minimumSize(int spacer) const{    return findSize(&QLayoutStruct::minimumSize, spacer);}void QGridLayoutPrivate::setSize(int r, int c){    if ((int)rowData.size() < r) {        int newR = qMax(r, rr * 2);        rowData.resize(newR);        rStretch.resize(newR);        rSpacing.resize(newR);        for (int i = rr; i < newR; i++) {            rowData[i].init();            rStretch[i] = 0;            rSpacing[i] = 0;        }    }    if ((int)colData.size() < c) {        int newC = qMax(c, cc * 2);        colData.resize(newC);        cStretch.resize(newC);        cSpacing.resize(newC);        for (int i = cc; i < newC; i++) {            colData[i].init();            cStretch[i] = 0;            cSpacing[i] = 0;        }    }    if (hfwData && (int)hfwData->size() < r) {        delete hfwData;        hfwData = 0;        hfw_width = -1;    }    rr = r;    cc = c;}void QGridLayoutPrivate::setNextPosAfter(int row, int col){    if (addVertical) {        if (col > nextC || col == nextC && row >= nextR) {            nextR = row + 1;            nextC = col;            if (nextR >= rr) {                nextR = 0;                nextC++;            }        }    } else {        if (row > nextR || row == nextR && col >= nextC) {            nextR = row;            nextC = col + 1;            if (nextC >= cc) {                nextC = 0;                nextR++;            }        }    }}void QGridLayoutPrivate::add(QGridBox *box, int row, int col){    expand(row+1, col+1);    box->row = box->torow = row;    box->col = box->tocol = col;    things.append(box);    setDirty();    setNextPosAfter(row, col);}void QGridLayoutPrivate::add(QGridBox *box, int row1, int row2, int col1,                           int col2 ){    if (row2 >= 0 && row2 < row1)        qWarning("QGridLayout: Multi-cell fromRow greater than toRow");    if (col2 >= 0 && col2 < col1)        qWarning("QGridLayout: Multi-cell fromCol greater than toCol");    if (row1 == row2 && col1 == col2) {        add(box, row1, col1);        return;    }    expand(row2+1, col2+1);    box->row = row1;    box->col = col1;    box->torow = row2;    box->tocol = col2;    things.append(box);    setDirty();    if (col2 < 0)        col2 = cc - 1;    setNextPosAfter(row2, col2);}void QGridLayoutPrivate::addData(QGridBox *box, bool r, bool c){    QSize hint = box->sizeHint();    QSize minS = box->minimumSize();    QSize maxS = box->maximumSize();    const QWidget *widget = box->item()->widget();    if (box->isEmpty() && widget)        return;    if (c) {        if (!cStretch[box->col])            colData[box->col].stretch = qMax(colData[box->col].stretch,                                              box->hStretch());        colData[box->col].sizeHint = qMax(hint.width(),                                           colData[box->col].sizeHint);        colData[box->col].minimumSize = qMax(minS.width(),                                              colData[box->col].minimumSize);        qMaxExpCalc(colData[box->col].maximumSize, colData[box->col].expansive,                     maxS.width(),                     box->expandingDirections() & Qt::Horizontal);    }    if (r) {        if (!rStretch[box->row])            rowData[box->row].stretch = qMax(rowData[box->row].stretch,                                              box->vStretch());        rowData[box->row].sizeHint = qMax(hint.height(),                                           rowData[box->row].sizeHint);        rowData[box->row].minimumSize = qMax(minS.height(),                                              rowData[box->row].minimumSize);        qMaxExpCalc(rowData[box->row].maximumSize, rowData[box->row].expansive,                     maxS.height(),                     box->expandingDirections() & Qt::Vertical);    }    if (!box->isEmpty()) {        // Empty boxes (i.e. spacers) do not get borders. This is        // hacky, but compatible.        if (c)            colData[box->col].empty = false;        if (r)            rowData[box->row].empty = false;    }}static void distributeMultiBox(QVector<QLayoutStruct> &chain, int spacing, int start, int end,                               int minSize, int sizeHint, QVector<int> &stretchArray, int stretch){    int i;    int w = 0;    int wh = 0;    int max = 0;    for (i = start; i <= end; i++) {        w += chain[i].minimumSize;        wh += chain[i].sizeHint;        max += chain[i].maximumSize;        chain[i].empty = false;        if (stretchArray[i] == 0)            chain[i].stretch = qMax(chain[i].stretch,stretch);    }    w += spacing * (end - start);    wh += spacing * (end - start);    max += spacing * (end - start);    if (max < minSize) { // implies w < minSize        /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -