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

📄 qsplitter.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        ++j;        a[j].init();        if (s->widget->isHidden() || s->collapsed) {            a[j].maximumSize = 0;        } else {            a[j].minimumSize = pick(qSmartMinSize(s->widget));            a[j].maximumSize = pick(s->widget->maximumSize());            a[j].empty = false;            bool stretch = noStretchFactorsSet;            if (!stretch) {                QSizePolicy p = s->widget->sizePolicy();                int sf = orient == Qt::Horizontal ? p.horizontalStretch() : p.verticalStretch();                stretch = (sf != 0);            }            if (stretch) {                a[j].stretch = s->getWidgetSize(orient);                a[j].sizeHint = a[j].minimumSize;                a[j].expansive = true;            } else {                a[j].sizeHint = s->getWidgetSize(orient);            }        }        ++j;    }    qGeomCalc(a, 0, n*2, pick(r.topLeft()), pick(r.size()), 0);#ifdef QSPLITTER_DEBUG    for (i = 0; i < n*2; ++i) {        qDebug("%*s%d: stretch %d, sh %d, minS %d, maxS %d, exp %d, emp %d -> %d, %d",               i, "", i,               a[i].stretch,               a[i].sizeHint,               a[i].minimumSize,               a[i].maximumSize,               a[i].expansive,               a[i].empty,               a[i].pos,               a[i].size);    }#endif    for (i = 0; i < n; ++i) {        QSplitterLayoutStruct *s = list.at(i);        setGeo(s, a[i*2+1].pos, a[i*2+1].size, false);    }}void QSplitterPrivate::storeSizes(){    for (int i = 0; i < list.size(); ++i) {        QSplitterLayoutStruct *sls = list.at(i);        sls->sizer = pick(sls->rect.size());    }}void QSplitterPrivate::addContribution(int index, int *min, int *max, bool mayCollapse) const{    QSplitterLayoutStruct *s = list.at(index);    if (!s->widget->isHidden()) {        if (!s->handle->isHidden()) {            *min += s->getHandleSize(orient);            *max += s->getHandleSize(orient);        }        if (mayCollapse || !s->collapsed)            *min += pick(qSmartMinSize(s->widget));        *max += pick(s->widget->maximumSize());    }}int QSplitterPrivate::findWidgetJustBeforeOrJustAfter(int index, int delta, int &collapsibleSize) const{    if (delta < 0)        index += delta;    do {        QWidget *w = list.at(index)->widget;        if (!w->isHidden()) {            if (collapsible(list.at(index)))                collapsibleSize = pick(qSmartMinSize(w));            return index;        }        index += delta;    } while (index >= 0 && index < list.count());    return -1;}/*  For the splitter handle with index \a index, \a min and \a max give the range without collapsing any widgets,  and \a farMin and farMax give the range with collapsing included.*/void QSplitterPrivate::getRange(int index, int *farMin, int *min, int *max, int *farMax) const{    Q_Q(const QSplitter);    int n = list.count();    if (index <= 0 || index >= n)        return;    int collapsibleSizeBefore = 0;    int idJustBefore = findWidgetJustBeforeOrJustAfter(index, -1, collapsibleSizeBefore);    int collapsibleSizeAfter = 0;    int idJustAfter = findWidgetJustBeforeOrJustAfter(index, +1, collapsibleSizeAfter);    int minBefore = 0;    int minAfter = 0;    int maxBefore = 0;    int maxAfter = 0;    int i;    for (i = 0; i < index; ++i)        addContribution(i, &minBefore, &maxBefore, i == idJustBefore);    for (i = index; i < n; ++i)        addContribution(i, &minAfter, &maxAfter, i == idJustAfter);    QRect r = q->contentsRect();    int farMinVal;    int minVal;    int maxVal;    int farMaxVal;    int smartMinBefore = qMax(minBefore, pick(r.size()) - maxAfter);    int smartMaxBefore = qMin(maxBefore, pick(r.size()) - minAfter);    minVal = pick(r.topLeft()) + smartMinBefore;    maxVal = pick(r.topLeft()) + smartMaxBefore;    farMinVal = minVal;    if (minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter)        farMinVal -= collapsibleSizeBefore;    farMaxVal = maxVal;    if (pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore)        farMaxVal += collapsibleSizeAfter;    if (farMin)        *farMin = farMinVal;    if (min)        *min = minVal;    if (max)        *max = maxVal;    if (farMax)        *farMax = farMaxVal;}int QSplitterPrivate::adjustPos(int pos, int index, int *farMin, int *min, int *max, int *farMax) const{    const int Threshold = 40;    getRange(index, farMin, min, max, farMax);    if (pos >= *min) {        if (pos <= *max) {            return pos;        } else {            int delta = pos - *max;            int width = *farMax - *max;            if (delta > width / 2 && delta >= qMin(Threshold, width)) {                return *farMax;            } else {                return *max;            }        }    } else {        int delta = *min - pos;        int width = *min - *farMin;        if (delta > width / 2 && delta >= qMin(Threshold, width)) {            return *farMin;        } else {            return *min;        }    }}bool QSplitterPrivate::collapsible(QSplitterLayoutStruct *s) const{    if (s->collapsible != Default) {        return (bool)s->collapsible;    } else {        return childrenCollapsible;    }}void QSplitterPrivate::updateHandles(){    Q_Q(QSplitter);    recalc(q->isVisible());}void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool allowCollapse){    Q_Q(QSplitter);    QWidget *w = sls->widget;    QRect r;    QRect contents = q->contentsRect();    if (orient == Qt::Horizontal) {        r.setRect(p, contents.y(), s, contents.height());    } else {        r.setRect(contents.x(), p, contents.width(), s);    }    sls->rect = r;    int minSize = pick(qSmartMinSize(w));    if (orient == Qt::Horizontal && q->isRightToLeft())        r.moveRight(contents.width() - r.left());    if (allowCollapse)        sls->collapsed = s <= 0 && minSize > 0 && !w->isHidden();    //   Hide the child widget, but without calling hide() so that    //   the splitter handle is still shown.    if (sls->collapsed)        r.moveTopLeft(QPoint(-r.width()-1, -r.height()-1));    w->setGeometry(r);    if (!sls->handle->isHidden()) {        QSplitterHandle *h = sls->handle;        QSize hs = h->sizeHint();        if (orient==Qt::Horizontal) {            if (q->isRightToLeft())                p = contents.width() - p + hs.width();            h->setGeometry(p-hs.width(), contents.y(), hs.width(), contents.height());        } else {            h->setGeometry(contents.x(), p-hs.height(), contents.width(), hs.height());        }    }}void QSplitterPrivate::doMove(bool backwards, int hPos, int index, int delta, bool mayCollapse,                              int *positions, int *widths){    if (index < 0 || index >= list.count())        return;#ifdef QSPLITTER_DEBUG    qDebug() << "QSplitterPrivate::doMove" << backwards << hPos << index << delta << mayCollapse;#endif    QSplitterLayoutStruct *s = list.at(index);    QWidget *w = s->widget;    int nextId = backwards ? index - delta : index + delta;    if (w->isHidden()) {        doMove(backwards, hPos, nextId, delta, collapsible(nextId), positions, widths);    } else {        int hs =s->handle->isHidden() ? 0 : s->getHandleSize(orient);        int  ws = backwards ? hPos - pick(s->rect.topLeft())                 : pick(s->rect.bottomRight()) - hPos -hs + 1;        if (ws > 0 || (!s->collapsed && !mayCollapse)) {            ws = qMin(ws, pick(w->maximumSize()));            ws = qMax(ws, pick(qSmartMinSize(w)));        } else {            ws = 0;        }        positions[index] = backwards ? hPos - ws : hPos + hs;        widths[index] = ws;        doMove(backwards, backwards ? hPos - ws - hs : hPos + hs + ws, nextId, delta,               collapsible(nextId), positions, widths);    }}QSplitterLayoutStruct *QSplitterPrivate::findWidget(QWidget *w) const{    for (int i = 0; i < list.size(); ++i) {        if (list.at(i)->widget == w)            return list.at(i);    }    return 0;}#ifdef QT3_SUPPORTstatic void setStretch(QWidget *w, int sf){    QSizePolicy sp = w->sizePolicy();    sp.setHorizontalStretch(sf);    sp.setVerticalStretch(sf);    w->setSizePolicy(sp);}static int getStretch(const QWidget *w){    QSizePolicy sp = w->sizePolicy();    return qMax(sp.horizontalStretch(), sp.verticalStretch());}void QSplitter::setResizeMode(QWidget *w, ResizeMode mode){    /*        Internal comment:        This function tries to simulate the Qt 3.x ResizeMode        behavior using QSizePolicy stretch factors. This isn't easy,        because the default \l ResizeMode was \l Stretch, not \l        KeepSize, whereas the default stetch factor is 0.        So what we do is this: When the user calls setResizeMode()        the first time, we iterate through all the child widgets and        set their stretch factors to 1. Later on, if children are        added (using addWidget()), their stretch factors are also set        to 1.        There is just one problem left: Often, setResizeMode() is        called \e{before} addWidget(), because addWidget() is called        from the event loop. In that case, we use a special value,        243, instead of 0 to prevent 0 from being overwritten with 1        in addWidget(). This is a wicked hack, but fortunately it        only occurs as a result of calling a \c QT3_SUPPORT function.    */    Q_D(QSplitter);    bool metWidget = false;    if (!d->compatMode) {        d->compatMode = true;        for (int i = 0; i < d->list.size(); ++i) {            QSplitterLayoutStruct *s = d->list.at(i);            if (s->widget == w)                metWidget = true;            if (getStretch(s->widget) == 0)                setStretch(s->widget, 1);        }    }    int sf;    if (mode == KeepSize)        sf = metWidget ? 0 : 243;    else        sf = 1;    setStretch(w, sf);}/*!    Use one of the constructors that doesn't take the \a name    argument and then use setObjectName() instead.*/QSplitter::QSplitter(QWidget *parent, const char *name)    : QFrame(*new QSplitterPrivate, parent){    Q_D(QSplitter);    setObjectName(QString::fromAscii(name));    d->orient = Qt::Horizontal;    d->init();}/*!    Use one of the constructors that don't take the \a name argument    and then use setObjectName() instead.*/QSplitter::QSplitter(Qt::Orientation orientation, QWidget *parent, const char *name)    : QFrame(*new QSplitterPrivate, parent){    Q_D(QSplitter);    setObjectName(QString::fromAscii(name));    d->orient = orientation;    d->init();}#endif/*    Inserts the widget \a w at position \a index in the splitter's list of widgets.    If \a w is already in the splitter, it will be moved to the new position.*/QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w){    Q_Q(QSplitter);    QSplitterLayoutStruct *sls = 0;    int i;    int last = list.count();    for (i = 0; i < list.size(); ++i) {        QSplitterLayoutStruct *s = list.at(i);        if (s->widget == w) {            sls = s;            --last;            break;        }    }    if (index < 0 || index > last)        index = last;    if (sls) {        list.move(i,index);    } else {        QSplitterHandle *newHandle = 0;        sls = new QSplitterLayoutStruct;        QString tmp = QLatin1String("qt_splithandle_");        tmp += w->objectName();        newHandle = q->createHandle();        newHandle->setObjectName(tmp);        sls->handle = newHandle;        sls->widget = w;        list.insert(index,sls);        if (newHandle && q->isVisible())            newHandle->show(); // will trigger sending of post events#ifdef QT3_SUPPORT        if (compatMode) {            int sf = getStretch(sls->widget);            if (sf == 243)                setStretch(sls->widget, 0);            else if (sf == 0)                setStretch(sls->widget, 1);        }#endif    }    return sls;}/*!    \class QSplitter    \brief The QSplitter class implements a splitter widget.    \ingroup organizers    \mainclass    A splitter lets the user control the size of child widgets by dragging the    boundary between the children. Any number of widgets may be controlled by a    single splitter. The typical use of a QSplitter is to create several    widgets and add them using insertWidget() or addWidget().    The following example will show a QListView, QTreeView, and    QTextEdit side by side, with two splitter handles:    \quotefromfile snippets/splitter/splitter.cpp    \skipto  QSplitter    \printuntil splitter->addWidget(textedit);    If a widget is already inside a QSplitter when insertWidget() or    addWidget() is called, it will move to the new position. This can be used    to reorder widgets in the splitter later. You can use indexOf(),    widget(), and count() to get access to the widgets inside the splitter.    A default QSplitter lays out its children horizontally (side by side); you    can use setOrientation(Qt::Vertical) to lay its    children out vertically.    By default, all widgets can be as large or as small as the user    wishes, between the \l minimumSizeHint() (or \l minimumSize())    and \l maximumSize() of the widgets.    QSplitter resizes its children dynamically by default. If you    would rather have QSplitter resize the children only at the end of

⌨️ 快捷键说明

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