/*! \reimp */ QSize QWidgetItem::minimumSize() const { if (isEmpty()) return QSize(0, 0); return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect) ? toLayoutItemSize(wid->d_func(), qSmartMinSize(this)) : qSmartMinSize(this); }
void QSplitterPrivate::setSizes_helper(const QList<int> &sizes, bool clampNegativeSize) { int j = 0; for (int i = 0; i < list.size(); ++i) { QSplitterLayoutStruct *s = list.at(i); s->collapsed = false; s->sizer = sizes.value(j++); if (clampNegativeSize && s->sizer < 0) s->sizer = 0; int smartMinSize = pick(qSmartMinSize(s->widget)); // Make sure that we reset the collapsed state. if (s->sizer == 0) { if (collapsible(s) && smartMinSize > 0) { s->collapsed = true; } else { s->sizer = smartMinSize; } } else { if (s->sizer < smartMinSize) s->sizer = smartMinSize; } } doResize(); }
QSize QSplitter::minimumSizeHint() const { Q_D(const QSplitter); ensurePolished(); int l = 0; int t = 0; for (int i = 0; i < d->list.size(); ++i) { QSplitterLayoutStruct *s = d->list.at(i); if (!s || !s->widget) continue; if (s->widget->isHidden()) continue; QSize widgetSize = qSmartMinSize(s->widget); if (widgetSize.isValid()) { l += d->pick(widgetSize); t = qMax(t, d->trans(widgetSize)); } if (!s->handle || s->handle->isHidden()) continue; QSize splitterSize = s->handle->sizeHint(); if (splitterSize.isValid()) { l += d->pick(splitterSize); t = qMax(t, d->trans(splitterSize)); } } return orientation() == Qt::Horizontal ? QSize(l, t) : QSize(t, l); }
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); } }
void QScrollAreaPrivate::updateScrollBars() { Q_Q(QScrollArea); if (!widget) return; QSize p = viewport->size(); QSize m = q->maximumViewportSize(); QSize min = qSmartMinSize(widget); QSize max = qSmartMaxSize(widget); if (resizable) { if ((widget->layout() ? widget->layout()->hasHeightForWidth() : widget->sizePolicy().hasHeightForWidth())) { QSize p_hfw = p.expandedTo(min).boundedTo(max); int h = widget->heightForWidth( p_hfw.width() ); min = QSize(p_hfw.width(), qMax(p_hfw.height(), h)); } } if ((resizable && m.expandedTo(min) == m && m.boundedTo(max) == m) || (!resizable && m.expandedTo(widget->size()) == m)) p = m; // no scroll bars needed if (resizable) widget->resize(p.expandedTo(min).boundedTo(max)); QSize v = widget->size(); hbar->setRange(0, v.width() - p.width()); hbar->setPageStep(p.width()); vbar->setRange(0, v.height() - p.height()); vbar->setPageStep(p.height()); updateWidgetPosition(); }
Q_GUI_EXPORT QSize qSmartMinSize(const QWidgetItem *i) { QWidget *w = ((QWidgetItem *)i)->widget(); return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(), w->minimumSize(), w->maximumSize(), w->sizePolicy()); }
/*! Updates the \a editor for the item specified by \a index according to the style \a option given. */ void QStyledItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!editor) return; Q_ASSERT(index.isValid()); const QWidget *widget = QStyledItemDelegatePrivate::widget(option); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // let the editor take up all available space //if the editor is not a QLineEdit //or it is in a QTableView #if QT_CONFIG(tableview) && QT_CONFIG(lineedit) if (qobject_cast<QExpandingLineEdit*>(editor) && !qobject_cast<const QTableView*>(widget)) opt.showDecorationSelected = editor->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, editor); else #endif opt.showDecorationSelected = true; QStyle *style = widget ? widget->style() : QApplication::style(); QRect geom = style->subElementRect(QStyle::SE_ItemViewItemText, &opt, widget); if ( editor->layoutDirection() == Qt::RightToLeft) { const int delta = qSmartMinSize(editor).width() - geom.width(); if (delta > 0) { //we need to widen the geometry geom.adjust(-delta, 0, 0, 0); } } editor->setGeometry(geom); }
Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidgetItem *i) { QWidget *w = const_cast<QWidgetItem *>(i)->widget(); return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(), w->minimumSize(), w->maximumSize(), w->sizePolicy()); }
void QScrollAreaPrivate::updateScrollBars() { Q_Q(QScrollArea); if (!widget) return; QSize p = viewport->size(); QSize m = q->maximumViewportSize(); QSize min = qSmartMinSize(widget); QSize max = qSmartMaxSize(widget); if ((resizable && m.expandedTo(min) == m && m.boundedTo(max) == m) || (!resizable && m.expandedTo(widget->size()) == m)) p = m; // no scroll bars needed if (resizable) widget->resize(p.expandedTo(min).boundedTo(max)); QSize v = widget->size(); hbar->setRange(0, v.width() - p.width()); hbar->setPageStep(p.width()); vbar->setRange(0, v.height() - p.height()); vbar->setPageStep(p.height()); updateWidgetPosition(); }
QSize QWidgetStack::sizeHint() const { constPolish(); QSize size( 0, 0 ); QIntDictIterator<QWidget> it( *dict ); QWidget *w; while ( (w = it.current()) != 0 ) { ++it; QSize sh = w->sizeHint(); if ( w->sizePolicy().horData() == QSizePolicy::Ignored ) sh.rwidth() = 0; if ( w->sizePolicy().verData() == QSizePolicy::Ignored ) sh.rheight() = 0; #ifndef QT_NO_LAYOUT size = size.expandedTo( sh ).expandedTo( qSmartMinSize(w) ); #endif } if ( size.isNull() ) size = QSize( 128, 64 ); size += QSize( 2*frameWidth(), 2*frameWidth() ); return size; }
/*! \reimp */ QSize QStackedLayout::minimumSize() const { Q_D(const QStackedLayout); QSize s(0, 0); int n = d->list.count(); for (int i = 0; i < n; ++i) if (QWidget *widget = d->list.at(i)->widget()) s = s.expandedTo(qSmartMinSize(widget)); return s; }
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()); } }
QT_BEGIN_NAMESPACE static int menuBarHeightForWidth(QWidget *menubar, int w) { if (menubar && !menubar->isHidden() && !menubar->isWindow()) { int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth())); if (result == -1) result = menubar->sizeHint().height(); const int min = qSmartMinSize(menubar).height(); result = qBound(min, result, menubar->maximumSize().height()); if (result != -1) return result; } return 0; }
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; }
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(); int left, top, right, bottom; h->getContentsMargins(&left, &top, &right, &bottom); if (orient==Qt::Horizontal) { if (q->isRightToLeft()) p = contents.width() - p + hs.width(); h->setGeometry(p-hs.width() - left, contents.y(), hs.width() + left + right, contents.height()); } else { h->setGeometry(contents.x(), p-hs.height() - top, contents.width(), hs.height() + top + bottom); } } }
void QSplitterPrivate::doResize() { Q_Q(QSplitter); QRect r = q->contentsRect(); int n = list.count(); QVector<QLayoutStruct> a(n*2); int i; bool noStretchFactorsSet = true; for (i = 0; i < n; ++i) { QSizePolicy p = list.at(i)->widget->sizePolicy(); int sf = orient == Qt::Horizontal ? p.horizontalStretch() : p.verticalStretch(); if (sf != 0) { noStretchFactorsSet = false; break; } } int j=0; for (i = 0; i < n; ++i) { QSplitterLayoutStruct *s = list.at(i); #ifdef QSPLITTER_DEBUG qDebug("widget %d hidden: %d collapsed: %d handle hidden: %d", i, s->widget->isHidden(), s->collapsed, s->handle->isHidden()); #endif a[j].init(); if (s->handle->isHidden()) { a[j].maximumSize = 0; } else { a[j].sizeHint = a[j].minimumSize = a[j].maximumSize = s->getHandleSize(orient); a[j].empty = false; } ++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 = qMax(s->getWidgetSize(orient), a[j].minimumSize); } } ++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); } }
Q_EXPORT QSize qSmartMinSize( QWidget *w ) { QWidgetItem item( w ); return qSmartMinSize( &item ); }
void QWidgetResizeHandler::mouseMoveEvent(QMouseEvent *e) { QPoint pos = widget->mapFromGlobal(e->globalPos()); if (!moveResizeMode && !buttonDown) { if (pos.y() <= range && pos.x() <= range) mode = TopLeft; else if (pos.y() >= widget->height()-range && pos.x() >= widget->width()-range) mode = BottomRight; else if (pos.y() >= widget->height()-range && pos.x() <= range) mode = BottomLeft; else if (pos.y() <= range && pos.x() >= widget->width()-range) mode = TopRight; else if (pos.y() <= range) mode = Top; else if (pos.y() >= widget->height()-range) mode = Bottom; else if (pos.x() <= range) mode = Left; else if ( pos.x() >= widget->width()-range) mode = Right; else if (widget->rect().contains(pos)) mode = Center; else mode = Nowhere; if (widget->isMinimized() || !isActive(Resize)) mode = Center; #ifndef QT_NO_CURSOR setMouseCursor(mode); #endif return; } if (mode == Center && !movingEnabled) return; if (widget->testAttribute(Qt::WA_WState_ConfigPending)) return; QPoint globalPos = (!widget->isWindow() && widget->parentWidget()) ? widget->parentWidget()->mapFromGlobal(e->globalPos()) : e->globalPos(); if (!widget->isWindow() && !widget->parentWidget()->rect().contains(globalPos)) { if (globalPos.x() < 0) globalPos.rx() = 0; if (globalPos.y() < 0) globalPos.ry() = 0; if (sizeprotect && globalPos.x() > widget->parentWidget()->width()) globalPos.rx() = widget->parentWidget()->width(); if (sizeprotect && globalPos.y() > widget->parentWidget()->height()) globalPos.ry() = widget->parentWidget()->height(); } QPoint p = globalPos + invertedMoveOffset; QPoint pp = globalPos - moveOffset; // Workaround for window managers which refuse to move a tool window partially offscreen. if (QGuiApplication::platformName() == QLatin1String("xcb")) { const QRect desktop = QApplication::desktop()->availableGeometry(widget); pp.rx() = qMax(pp.x(), desktop.left()); pp.ry() = qMax(pp.y(), desktop.top()); p.rx() = qMin(p.x(), desktop.right()); p.ry() = qMin(p.y(), desktop.bottom()); } QSize ms = qSmartMinSize(childWidget); int mw = ms.width(); int mh = ms.height(); if (childWidget != widget) { mw += 2 * fw; mh += 2 * fw + extrahei; } QSize maxsize(childWidget->maximumSize()); if (childWidget != widget) maxsize += QSize(2 * fw, 2 * fw + extrahei); QSize mpsize(widget->geometry().right() - pp.x() + 1, widget->geometry().bottom() - pp.y() + 1); mpsize = mpsize.expandedTo(widget->minimumSize()).expandedTo(QSize(mw, mh)) .boundedTo(maxsize); QPoint mp(widget->geometry().right() - mpsize.width() + 1, widget->geometry().bottom() - mpsize.height() + 1); QRect geom = widget->geometry(); switch (mode) { case TopLeft: geom = QRect(mp, widget->geometry().bottomRight()) ; break; case BottomRight: geom = QRect(widget->geometry().topLeft(), p) ; break; case BottomLeft: geom = QRect(QPoint(mp.x(), widget->geometry().y()), QPoint(widget->geometry().right(), p.y())) ; break; case TopRight: geom = QRect(QPoint(widget->geometry().x(), mp.y()), QPoint(p.x(), widget->geometry().bottom())) ; break; case Top: geom = QRect(QPoint(widget->geometry().left(), mp.y()), widget->geometry().bottomRight()) ; break; case Bottom: geom = QRect(widget->geometry().topLeft(), QPoint(widget->geometry().right(), p.y())) ; break; case Left: geom = QRect(QPoint(mp.x(), widget->geometry().top()), widget->geometry().bottomRight()) ; break; case Right: geom = QRect(widget->geometry().topLeft(), QPoint(p.x(), widget->geometry().bottom())) ; break; case Center: geom.moveTopLeft(pp); break; default: break; } geom = QRect(geom.topLeft(), geom.size().expandedTo(widget->minimumSize()) .expandedTo(QSize(mw, mh)) .boundedTo(maxsize)); if (geom != widget->geometry() && (widget->isWindow() || widget->parentWidget()->rect().intersects(geom))) { if (mode == Center) widget->move(geom.topLeft()); else widget->setGeometry(geom); } }
QSize QToolBarAreaLayoutItem::minimumSize() const { if (skip()) return QSize(0, 0); return qSmartMinSize(static_cast<QWidgetItem*>(widgetItem)); }
Q_GUI_EXPORT QSize qSmartMinSize(const QWidget *w) { return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(), w->minimumSize(), w->maximumSize(), w->sizePolicy()); }
void QSplitterPrivate::recalc(bool update) { Q_Q(QSplitter); int n = list.count(); /* Splitter handles before the first visible widget or right before a hidden widget must be hidden. */ bool first = true; for (int i = 0; i < n ; ++i) { QSplitterLayoutStruct *s = list.at(i); s->handle->setHidden(first || s->widget->isHidden()); if (!s->widget->isHidden()) first = false; } int fi = 2 * q->frameWidth(); int maxl = fi; int minl = fi; int maxt = QWIDGETSIZE_MAX; int mint = fi; /* calculate min/max sizes for the whole splitter */ bool empty = true; for (int j = 0; j < n; j++) { QSplitterLayoutStruct *s = list.at(j); if (!s->widget->isHidden()) { empty = false; if (!s->handle->isHidden()) { minl += s->getHandleSize(orient); maxl += s->getHandleSize(orient); } QSize minS = qSmartMinSize(s->widget); minl += pick(minS); maxl += pick(s->widget->maximumSize()); mint = qMax(mint, trans(minS)); int tm = trans(s->widget->maximumSize()); if (tm > 0) maxt = qMin(maxt, tm); } } if (empty) { if (qobject_cast<QSplitter *>(q->parentWidget())) { // nested splitters; be nice maxl = maxt = 0; } else { // QSplitter with no children yet maxl = QWIDGETSIZE_MAX; } } else { maxl = qMin<int>(maxl, QWIDGETSIZE_MAX); } if (maxt < mint) maxt = mint; if (update) { if (orient == Qt::Horizontal) { q->setMaximumSize(maxl, maxt); if (q->isWindow()) q->setMinimumSize(minl,mint); } else { q->setMaximumSize(maxt, maxl); if (q->isWindow()) q->setMinimumSize(mint,minl); } doResize(); q->updateGeometry(); } else { firstShow = true; } }