📄 qlayoutengine.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 "qlayout.h"#include "private/qlayoutengine_p.h"#include "qvector.h"#include "qwidget.h"#include <qlist.h>#include <qalgorithms.h>#include <qdebug.h>//#define QLAYOUT_EXTRA_DEBUGtypedef qint64 Fixed;static inline Fixed toFixed(int i) { return (Fixed)i * 256; }static inline int fRound(Fixed i) { return (i % 256 < 128) ? i / 256 : 1 + i / 256;}/* This is the main workhorse of the QGridLayout. It portions out available space to the chain's children. The calculation is done in fixed point: "fixed" variables are scaled by a factor of 256. If the layout runs "backwards" (i.e. RightToLeft or Up) the layout is computed mirror-reversed, and it's the caller's responsibility do reverse the values before use. chain contains input and output parameters describing the geometry. count is the count of items in the chain; pos and space give the interval (relative to parentWidget topLeft).*/void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count, int pos, int space, int spacer){ int cHint = 0; int cMin = 0; int cMax = 0; int sumStretch = 0; int sumSpacing = 0; bool wannaGrow = false; // anyone who really wants to grow? // bool canShrink = false; // anyone who could be persuaded to shrink? bool allEmptyNonstretch = true; int pendingSpacing = -1; int spacerCount = 0; int i; for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; data->done = false; cHint += data->smartSizeHint(); cMin += data->minimumSize; cMax += data->maximumSize; sumStretch += data->stretch; if (!data->empty) { /* Using pendingSpacing, we ensure that the spacing for the last (non-empty) item is ignored. */ if (pendingSpacing >= 0) { sumSpacing += pendingSpacing; ++spacerCount; } pendingSpacing = data->effectiveSpacer(spacer); } wannaGrow = wannaGrow || data->expansive || data->stretch > 0; allEmptyNonstretch = allEmptyNonstretch && !wannaGrow && data->empty; } int extraspace = 0; if (space < cMin + sumSpacing) { /* Less space than minimumSize; take from the biggest first */ int minSize = cMin + sumSpacing; // shrink the spacers proportionally if (spacer >= 0) { spacer = minSize > 0 ? spacer * space / minSize : 0; sumSpacing = spacer * spacerCount; } QList<int> list; for (i = start; i < start + count; i++) list << chain.at(i).minimumSize; qSort(list); int space_left = space - sumSpacing; int sum = 0; int idx = 0; int space_used=0; int current = 0; while (idx < count && space_used < space_left) { current = list.at(idx); space_used = sum + current * (count - idx); sum += current; ++idx; } --idx; int deficit = space_used - space_left; int items = count - idx; /* * If we truncate all items to "current", we would get "deficit" too many pixels. Therefore, we have to remove * deficit/items from each item bigger than maxval. The actual value to remove is deficitPerItem + remainder/items * "rest" is the accumulated error from using integer arithmetic. */ int deficitPerItem = deficit/items; int remainder = deficit % items; int maxval = current - deficitPerItem; int rest = 0; for (i = start; i < start + count; i++) { int maxv = maxval; rest += remainder; if (rest >= items) { maxv--; rest-=items; } QLayoutStruct *data = &chain[i]; data->size = qMin(data->minimumSize, maxv); data->done = true; } } else if (space < cHint + sumSpacing) { /* Less space than smartSizeHint(), but more than minimumSize. Currently take space equally from each, as in Qt 2.x. Commented-out lines will give more space to stretchier items. */ int n = count; int space_left = space - sumSpacing; int overdraft = cHint - space_left; // first give to the fixed ones: for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; if (!data->done && data->minimumSize >= data->smartSizeHint()) { data->size = data->smartSizeHint(); data->done = true; space_left -= data->smartSizeHint(); // sumStretch -= data->stretch; n--; } } bool finished = n == 0; while (!finished) { finished = true; Fixed fp_over = toFixed(overdraft); Fixed fp_w = 0; for (i = start; i < start+count; i++) { QLayoutStruct *data = &chain[i]; if (data->done) continue; // if (sumStretch <= 0) fp_w += fp_over / n; // else // fp_w += (fp_over * data->stretch) / sumStretch; int w = fRound(fp_w); data->size = data->smartSizeHint() - w; fp_w -= toFixed(w); // give the difference to the next if (data->size < data->minimumSize) { data->done = true; data->size = data->minimumSize; finished = false; overdraft -= data->smartSizeHint() - data->minimumSize; // sumStretch -= data->stretch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -