/* Calculates and stores the preferred height given the width \a w. */ void QBoxLayoutPrivate::calcHfw(int w) { QVector<QLayoutStruct> &a = geomArray; int n = a.count(); int h = 0; int mh = 0; Q_ASSERT(n == list.size()); if (horz(dir)) { qGeomCalc(a, 0, n, 0, w); for (int i = 0; i < n; i++) { QBoxLayoutItem *box = list.at(i); h = qMax(h, box->hfw(a.at(i).size)); mh = qMax(mh, box->mhfw(a.at(i).size)); } } else { for (int i = 0; i < n; ++i) { QBoxLayoutItem *box = list.at(i); int spacing = a.at(i).spacing; h += box->hfw(w); mh += box->mhfw(w); h += spacing; mh += spacing; } } hfwWidth = w; hfwHeight = h; hfwMinHeight = mh; }
/*! Sets the direction of this layout to \a direction. */ void QBoxLayout::setDirection(Direction direction) { Q_D(QBoxLayout); if (d->dir == direction) return; if (horz(d->dir) != horz(direction)) { //swap around the spacers (the "magic" bits) //#### a bit yucky, knows too much. //#### probably best to add access functions to spacerItem //#### or even a QSpacerItem::flip() for (int i = 0; i < d->list.size(); ++i) { QBoxLayoutItem *box = d->list.at(i); if (box->magic) { QSpacerItem *sp = box->item->spacerItem(); if (sp) { if (sp->expandingDirections() == Qt::Orientations(0) /*No Direction*/) { //spacing or strut QSize s = sp->sizeHint(); sp->changeSize(s.height(), s.width(), horz(direction) ? QSizePolicy::Fixed:QSizePolicy::Minimum, horz(direction) ? QSizePolicy::Minimum:QSizePolicy::Fixed); } else { //stretch if (horz(direction)) sp->changeSize(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); else sp->changeSize(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); } } } } } d->dir = direction; invalidate(); }
/*! Limits the perpendicular dimension of the box (e.g. height if the box is \l LeftToRight) to a minimum of \a size. Other constraints may increase the limit. \sa addItem() */ void QBoxLayout::addStrut(int size) { Q_D(QBoxLayout); QLayoutItem *b; if (horz(d->dir)) b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Fixed, QSizePolicy::Minimum); else b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Minimum, QSizePolicy::Fixed); QBoxLayoutItem *it = new QBoxLayoutItem(b); it->magic = true; d->list.append(it); invalidate(); }
/*! Inserts a stretchable space (a QSpacerItem) at position \a index, with zero minimum size and stretch factor \a stretch. If \a index is negative the space is added at the end. \sa addStretch(), insertItem(), QSpacerItem */ void QBoxLayout::insertStretch(int index, int stretch) { Q_D(QBoxLayout); if (index < 0) // append index = d->list.count(); QLayoutItem *b; if (horz(d->dir)) b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); else b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); QBoxLayoutItem *it = new QBoxLayoutItem(b, stretch); it->magic = true; d->list.insert(index, it); invalidate(); }
/*! Inserts a non-stretchable space (a QSpacerItem) at position \a index, with size \a size. If \a index is negative the space is added at the end. The box layout has default margin and spacing. This function adds additional space. \sa addSpacing(), insertItem(), QSpacerItem */ void QBoxLayout::insertSpacing(int index, int size) { Q_D(QBoxLayout); if (index < 0) // append index = d->list.count(); QLayoutItem *b; if (horz(d->dir)) b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum); else b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Minimum, QSizePolicy::Fixed); QBoxLayoutItem *it = new QBoxLayoutItem(b); it->magic = true; d->list.insert(index, it); invalidate(); }
int main(int argc, char **argv) { if (argc != 3) { std::cout << "Usage: XO_tester <program1> <program2>\n"; return 1; } const char *program1 = argv[1]; const char *program2 = argv[2]; //initLog(program1, program2); // save field and score before the first move saveField(); ExecutionResult result = ER_OK; for (int move = 0 ; move < size * size ; ++move) { bool first = move % 2 == 0; std::ostringstream outs; outs << !first + 1 << "\n"; for (int i = 0 ; i < size ; ++i) { for (int j = 0 ; j < size ; ++j) { outs << field[i][j] << " "; } outs << "\n"; } std::string output; result = runProcess(first ? program1 : program2, outs.str(), output, 1000, 64000); if (result == ER_OK) { std::istringstream ins(output); int x, y; ins >> y >> x; if (x >= 1 && x <= size && y >= 1 && y <= size && !field[y-1][x-1]) { printLog(first, result, output); int xo = first ? 1 : 2; field[y-1][x-1] = xo; saveField(); // check win if (diag1(xo) || diag2(xo) || horz(xo, y - 1) || vert(xo, x - 1)) { result = ER_WIN; printLog(first, result, output); break; } } else { result = ER_IM; printLog(first, result, output); break; } } else {
int main(int argc, char **argv) { if (argc != 3) { std::cout << "Usage: tester <program1> <program2>\n"; return 1; } const char *program1 = argv[1]; const char *program2 = argv[2]; ExecutionResult result = ER_OK; for (int move = 0 ; move < size * size ; ++move) { bool first = move % 2 == 0; std::ostringstream outs; outs << !first + 1 << "\n"; for (int i = 0 ; i < size ; ++i) { for (int j = 0 ; j < size ; ++j) { outs << field[i][j] << " "; } outs << "\n"; } std::string output; result = runProcess(first ? program1 : program2, outs.str(), output, 1000, 64000); if (result == ER_OK) { std::istringstream ins(output); int x, y; ins >> y >> x; if (x >= 1 && x <= size && y >= 1 && y <= size && !field[y-1][x-1]) { printLog(first, result, output); int xo = first ? 1 : 2; field[y-1][x-1] = xo; score[0] = score[1] = 0; for (int i = 0 ; i < size ; ++i) { for (int j = 0 ; j < size ; ++j) { horz(i, j); vert(i, j); diag1(i, j); diag2(i, j); } } std::ostringstream outs; for (int i = 0 ; i < size ; ++i) { for (int j = 0 ; j < size ; ++j) outs << field[i][j] << " "; outs << "\n"; } outs << score[0] << " " << score[1] << "\n"; printField(outs.str()); } else { result = ER_IM; printLog(first, result, output); break; } } else {
/*! \reimp */ void QBoxLayout::setGeometry(const QRect &r) { Q_D(QBoxLayout); if (d->dirty || r != geometry()) { QRect oldRect = geometry(); QLayout::setGeometry(r); if (d->dirty) d->setupGeom(); QRect cr = alignment() ? alignmentRect(r) : r; int left, top, right, bottom; d->effectiveMargins(&left, &top, &right, &bottom); QRect s(cr.x() + left, cr.y() + top, cr.width() - (left + right), cr.height() - (top + bottom)); QVector<QLayoutStruct> a = d->geomArray; int pos = horz(d->dir) ? s.x() : s.y(); int space = horz(d->dir) ? s.width() : s.height(); int n = a.count(); if (d->hasHfw && !horz(d->dir)) { for (int i = 0; i < n; i++) { QBoxLayoutItem *box = d->list.at(i); if (box->item->hasHeightForWidth()) { int width = qBound(box->item->minimumSize().width(), s.width(), box->item->maximumSize().width()); a[i].sizeHint = a[i].minimumSize = box->item->heightForWidth(width); } } } Direction visualDir = d->dir; QWidget *parent = parentWidget(); if (parent && parent->isRightToLeft()) { if (d->dir == LeftToRight) visualDir = RightToLeft; else if (d->dir == RightToLeft) visualDir = LeftToRight; } qGeomCalc(a, 0, n, pos, space); bool reverse = (horz(visualDir) ? ((r.right() > oldRect.right()) != (visualDir == RightToLeft)) : r.bottom() > oldRect.bottom()); for (int j = 0; j < n; j++) { int i = reverse ? n-j-1 : j; QBoxLayoutItem *box = d->list.at(i); switch (visualDir) { case LeftToRight: box->item->setGeometry(QRect(a.at(i).pos, s.y(), a.at(i).size, s.height())); break; case RightToLeft: box->item->setGeometry(QRect(s.left() + s.right() - a.at(i).pos - a.at(i).size + 1, s.y(), a.at(i).size, s.height())); break; case TopToBottom: box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size)); break; case BottomToTop: box->item->setGeometry(QRect(s.x(), s.top() + s.bottom() - a.at(i).pos - a.at(i).size + 1, s.width(), a.at(i).size)); } } } }
/* Initializes the data structure needed by qGeomCalc and recalculates max/min and size hint. */ void QBoxLayoutPrivate::setupGeom() { if (!dirty) return; Q_Q(QBoxLayout); int maxw = horz(dir) ? 0 : QLAYOUTSIZE_MAX; int maxh = horz(dir) ? QLAYOUTSIZE_MAX : 0; int minw = 0; int minh = 0; int hintw = 0; int hinth = 0; bool horexp = false; bool verexp = false; hasHfw = false; int n = list.count(); geomArray.clear(); QVector<QLayoutStruct> a(n); QSizePolicy::ControlTypes controlTypes1; QSizePolicy::ControlTypes controlTypes2; int fixedSpacing = q->spacing(); int previousNonEmptyIndex = -1; QStyle *style = 0; if (fixedSpacing < 0) { if (QWidget *parentWidget = q->parentWidget()) style = parentWidget->style(); } for (int i = 0; i < n; i++) { QBoxLayoutItem *box = list.at(i); QSize max = box->item->maximumSize(); QSize min = box->item->minimumSize(); QSize hint = box->item->sizeHint(); Qt::Orientations exp = box->item->expandingDirections(); bool empty = box->item->isEmpty(); int spacing = 0; if (!empty) { if (fixedSpacing >= 0) { spacing = (previousNonEmptyIndex >= 0) ? fixedSpacing : 0; #ifdef Q_WS_MAC if (!horz(dir) && previousNonEmptyIndex >= 0) { QBoxLayoutItem *sibling = (dir == QBoxLayout::TopToBottom ? box : list.at(previousNonEmptyIndex)); if (sibling) { QWidget *wid = sibling->item->widget(); if (wid) spacing = qMax(spacing, sibling->item->geometry().top() - wid->geometry().top()); } } #endif } else { controlTypes1 = controlTypes2; controlTypes2 = box->item->controlTypes(); if (previousNonEmptyIndex >= 0) { QSizePolicy::ControlTypes actual1 = controlTypes1; QSizePolicy::ControlTypes actual2 = controlTypes2; if (dir == QBoxLayout::RightToLeft || dir == QBoxLayout::BottomToTop) qSwap(actual1, actual2); if (style) { spacing = style->combinedLayoutSpacing(actual1, actual2, horz(dir) ? Qt::Horizontal : Qt::Vertical, 0, q->parentWidget()); if (spacing < 0) spacing = 0; } } } if (previousNonEmptyIndex >= 0) a[previousNonEmptyIndex].spacing = spacing; previousNonEmptyIndex = i; } bool ignore = empty && box->item->widget(); // ignore hidden widgets bool dummy = true; if (horz(dir)) { bool expand = (exp & Qt::Horizontal || box->stretch > 0); horexp = horexp || expand; maxw += spacing + max.width(); minw += spacing + min.width(); hintw += spacing + hint.width(); if (!ignore) qMaxExpCalc(maxh, verexp, dummy, max.height(), exp & Qt::Vertical, box->item->isEmpty()); minh = qMax(minh, min.height()); hinth = qMax(hinth, hint.height()); a[i].sizeHint = hint.width(); a[i].maximumSize = max.width(); a[i].minimumSize = min.width(); a[i].expansive = expand; a[i].stretch = box->stretch ? box->stretch : box->hStretch(); } else { bool expand = (exp & Qt::Vertical || box->stretch > 0); verexp = verexp || expand; maxh += spacing + max.height(); minh += spacing + min.height(); hinth += spacing + hint.height(); if (!ignore) qMaxExpCalc(maxw, horexp, dummy, max.width(), exp & Qt::Horizontal, box->item->isEmpty()); minw = qMax(minw, min.width()); hintw = qMax(hintw, hint.width()); a[i].sizeHint = hint.height(); a[i].maximumSize = max.height(); a[i].minimumSize = min.height(); a[i].expansive = expand; a[i].stretch = box->stretch ? box->stretch : box->vStretch(); } a[i].empty = empty; a[i].spacing = 0; // might be be initialized with a non-zero value in a later iteration hasHfw = hasHfw || box->item->hasHeightForWidth(); } geomArray = a; expanding = (Qt::Orientations) ((horexp ? Qt::Horizontal : 0) | (verexp ? Qt::Vertical : 0)); minSize = QSize(minw, minh); maxSize = QSize(maxw, maxh).expandedTo(minSize); sizeHint = QSize(hintw, hinth).expandedTo(minSize).boundedTo(maxSize); q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); int left, top, right, bottom; effectiveMargins(&left, &top, &right, &bottom); QSize extra(left + right, top + bottom); minSize += extra; maxSize += extra; sizeHint += extra; dirty = false; }
/** * The purpose of this function is to make sure that widgets are not laid out outside its layout. * E.g. the layoutItemRect margins are only meant to take of the surrounding margins/spacings. * However, if the margin is 0, it can easily cover the area of a widget above it. */ void QBoxLayoutPrivate::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 Q_Q(const QBoxLayout); if (horz(dir)) { QBoxLayoutItem *leftBox = 0; QBoxLayoutItem *rightBox = 0; if (left || right) { leftBox = list.value(0); rightBox = list.value(list.count() - 1); if (dir == QBoxLayout::RightToLeft) qSwap(leftBox, rightBox); int leftDelta = 0; int rightDelta = 0; if (leftBox) { QLayoutItem *itm = leftBox->item; if (QWidget *w = itm->widget()) leftDelta = itm->geometry().left() - w->geometry().left(); } if (rightBox) { QLayoutItem *itm = rightBox->item; if (QWidget *w = itm->widget()) rightDelta = w->geometry().right() - itm->geometry().right(); } QWidget *w = q->parentWidget(); Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QApplication::layoutDirection(); if (layoutDirection == Qt::RightToLeft) qSwap(leftDelta, rightDelta); l = qMax(l, leftDelta); r = qMax(r, rightDelta); } int count = top || bottom ? list.count() : 0; for (int i = 0; i < count; ++i) { QBoxLayoutItem *box = list.at(i); QLayoutItem *itm = box->item; QWidget *w = itm->widget(); if (w) { QRect lir = itm->geometry(); QRect wr = w->geometry(); if (top) t = qMax(t, lir.top() - wr.top()); if (bottom) b = qMax(b, wr.bottom() - lir.bottom()); } } } else { // vertical layout QBoxLayoutItem *topBox = 0; QBoxLayoutItem *bottomBox = 0; if (top || bottom) { topBox = list.value(0); bottomBox = list.value(list.count() - 1); if (dir == QBoxLayout::BottomToTop) { qSwap(topBox, bottomBox); } if (top && topBox) { QLayoutItem *itm = topBox->item; QWidget *w = itm->widget(); if (w) t = qMax(t, itm->geometry().top() - w->geometry().top()); } if (bottom && bottomBox) { QLayoutItem *itm = bottomBox->item; QWidget *w = itm->widget(); if (w) b = qMax(b, w->geometry().bottom() - itm->geometry().bottom()); } } int count = left || right ? list.count() : 0; for (int i = 0; i < count; ++i) { QBoxLayoutItem *box = list.at(i); QLayoutItem *itm = box->item; QWidget *w = itm->widget(); if (w) { QRect lir = itm->geometry(); QRect wr = w->geometry(); if (left) l = qMax(l, lir.left() - wr.left()); if (right) r = qMax(r, wr.right() - lir.right()); } } } #endif if (left) *left = l; if (top) *top = t; if (right) *right = r; if (bottom) *bottom = b; }