238 nRows = (nCells + nCols - 1) / nCols;
239 else if (nCols == -1)
240 nCols = (nCells + nRows - 1) / nRows;
242 int cells = nCols * nRows;
243 CSize *pCellsSize =
new CSize[cells];
244 bool *pCellsOccupy =
new bool[cells];
246 for (
int i = 0; i < cells; i++)
248 pCellsOccupy[i] =
false;
251 int iRow = 0, iCol = 0;
252 const IWindow *pCell = pParent->GetNextLayoutIChild(NULL);
256 SASSERT(pLayoutParam);
258 int colSpan = pLayoutParam->nColSpan;
259 int rowSpan = pLayoutParam->nRowSpan;
261 colSpan = smin(colSpan, nCols - iCol);
262 rowSpan = smin(rowSpan, nRows - iRow);
263 SASSERT(colSpan >= 1);
264 SASSERT(rowSpan >= 1);
265 SASSERT(pCellsOccupy[iRow * nCols + iCol] ==
false);
267 for (
int y = 0; y < rowSpan; y++)
268 for (
int x = 0; x < colSpan; x++)
270 int iCell = (iRow + y) * nCols + iCol + x;
271 if (pCellsOccupy[iCell])
282 ((IWindow *)pCell)->GetDesiredSize(&szCell, SIZE_WRAP_CONTENT, SIZE_WRAP_CONTENT);
284 szCell.cx /= colSpan;
285 szCell.cy /= rowSpan;
286 for (
int y = 0; y < rowSpan; y++)
287 for (
int x = 0; x < colSpan; x++)
289 int iCell = (iRow + y) * nCols + iCol + x;
290 pCellsOccupy[iCell] =
true;
291 pCellsSize[iCell] = szCell;
296 for (
int x = iCol + 1; x < nCols; x++)
298 if (!pCellsOccupy[iRow * nCols + x])
305 for (
int y = iRow + 1; y < nRows && !bFind; y++)
306 for (
int x = 0; x < nCols; x++)
308 if (!pCellsOccupy[y * nCols + x])
318 pCell = pParent->GetNextLayoutIChild(pCell);
323 for (
int x = 0; x < nCols; x++)
326 for (
int y = 0; y < nRows; y++)
328 int iCell = y * nCols + x;
329 maxWid = smax(pCellsSize[iCell].cx, maxWid);
334 for (
int y = 0; y < nRows; y++)
337 for (
int x = 0; x < nCols; x++)
339 int iCell = y * nCols + x;
340 maxHei = smax(pCellsSize[iCell].cy, maxHei);
346 delete[] pCellsOccupy;
348 int xInter =
m_xInterval.toPixelSize(pParent->GetScale());
349 int yInter =
m_yInterval.toPixelSize(pParent->GetScale());
354 szRet.cx += xInter * (nCols - 1);
355 szRet.cy += yInter * (nRows - 1);
369 nRows = (nCells + nCols - 1) / nCols;
370 else if (nCols == -1)
371 nCols = (nCells + nRows - 1) / nRows;
374 pParent->GetChildrenLayoutRect(&rcParent);
377 int cells = nCols * nRows;
378 CSize *pCellsSize =
new CSize[cells];
379 bool *pCellsOccupy =
new bool[cells];
380 float *pCellsColWeight =
new float[cells];
381 float *pCellsRowWeight =
new float[cells];
382 IWindow **pCellsChild =
new IWindow *[cells];
383 CPoint *pCellsSpan =
new CPoint[cells];
384 bool *pCellsSpanFlagX =
new bool[cells];
385 bool *pCellsSpanFlagY =
new bool[cells];
387 for (
int i = 0; i < cells; i++)
389 pCellsOccupy[i] =
false;
390 pCellsChild[i] = NULL;
393 int iRow = 0, iCol = 0;
394 IWindow *pCell = pParent->GetNextLayoutIChild(NULL);
397 pCellsChild[iRow * nCols + iCol] = pCell;
399 SASSERT(pLayoutParam);
401 int colSpan = pLayoutParam->nColSpan;
402 int rowSpan = pLayoutParam->nRowSpan;
404 colSpan = smin(colSpan, nCols - iCol);
405 rowSpan = smin(rowSpan, nRows - iRow);
406 SASSERT(colSpan >= 1);
407 SASSERT(rowSpan >= 1);
408 SASSERT(pCellsOccupy[iRow * nCols + iCol] ==
false);
410 for (
int y = 0; y < rowSpan; y++)
411 for (
int x = 0; x < colSpan; x++)
413 int iCell = (iRow + y) * nCols + iCol + x;
414 if (pCellsOccupy[iCell])
425 pCell->GetDesiredSize(&szCell, SIZE_WRAP_CONTENT, SIZE_WRAP_CONTENT);
427 szCell.cx /= colSpan;
428 szCell.cy /= rowSpan;
430 float colWeight = pLayoutParam->fColWeight / colSpan;
431 float rowWeight = pLayoutParam->fRowWeight / rowSpan;
432 for (
int y = 0; y < rowSpan; y++)
433 for (
int x = 0; x < colSpan; x++)
435 int iCell = (iRow + y) * nCols + iCol + x;
436 pCellsOccupy[iCell] =
true;
437 pCellsSize[iCell] = szCell;
438 pCellsColWeight[iCell] = colWeight;
439 pCellsRowWeight[iCell] = rowWeight;
440 pCellsSpan[iCell].x = 0;
441 pCellsSpan[iCell].y = 0;
442 pCellsSpanFlagX[iCell] = colSpan > 1;
443 pCellsSpanFlagY[iCell] = rowSpan > 1;
445 pCellsSpan[iRow * nCols + iCol] = CPoint(colSpan, rowSpan);
449 for (
int x = iCol + 1; x < nCols; x++)
451 if (!pCellsOccupy[iRow * nCols + x])
458 for (
int y = iRow + 1; y < nRows && !bFind; y++)
459 for (
int x = 0; x < nCols; x++)
461 if (!pCellsOccupy[y * nCols + x])
471 pCell = pParent->GetNextLayoutIChild(pCell);
474 int *pCellsWidth =
new int[nCols];
476 float *pColsWeight =
new float[nCols];
477 float totalColsWeight = 0.0f;
479 for (
int x = 0; x < nCols; x++)
482 float maxWeight = 0.0f;
483 for (
int y = 0; y < nRows; y++)
485 int iCell = y * nCols + x;
486 if (pCellsSpanFlagX[iCell])
488 maxWid = smax(pCellsSize[iCell].cx, maxWid);
489 maxWeight = smax(pCellsColWeight[iCell], maxWeight);
491 pCellsWidth[x] = maxWid;
492 nTotalWidth += maxWid;
493 pColsWeight[x] = maxWeight;
494 totalColsWeight += maxWeight;
497 int *pCellsHeight =
new int[nRows];
498 int nTotalHeight = 0;
499 float *pRowsWeight =
new float[nRows];
500 float totalRowsWeight = 0.0f;
501 for (
int y = 0; y < nRows; y++)
504 float maxWeight = 0.0f;
505 for (
int x = 0; x < nCols; x++)
507 int iCell = y * nCols + x;
508 if (pCellsSpanFlagY[iCell])
510 maxHei = smax(pCellsSize[iCell].cy, maxHei);
511 maxWeight = smax(pCellsRowWeight[iCell], maxWeight);
513 pCellsHeight[y] = maxHei;
514 nTotalHeight += maxHei;
515 pRowsWeight[y] = maxWeight;
516 totalRowsWeight += maxWeight;
519 delete[] pCellsOccupy;
521 delete[] pCellsColWeight;
522 delete[] pCellsRowWeight;
523 delete[] pCellsSpanFlagY;
524 delete[] pCellsSpanFlagX;
526 int xInter =
m_xInterval.toPixelSize(pParent->GetScale());
527 int yInter =
m_yInterval.toPixelSize(pParent->GetScale());
529 if (totalColsWeight > 0.0f)
531 int netParentWid = rcParent.Width() - (nCols - 1) * (xInter > 0 ? xInter : 0);
532 if (nTotalWidth < netParentWid)
534 int nRemain = netParentWid - nTotalWidth;
535 for (
int i = 0; i < nCols; i++)
539 int extra = int(nRemain * pColsWeight[i] / totalColsWeight + 0.5f);
540 pCellsWidth[i] += extra;
542 totalColsWeight -= pColsWeight[i];
548 int nRemain = rcParent.Width() - nTotalWidth;
549 if (xInter == SIZE_WRAP_CONTENT && nCols > 1)
550 xInter = nRemain / (nCols - 1);
551 else if (xInter == SIZE_MATCH_PARENT)
553 xInter = nRemain / (nCols + 1);
554 rcParent.DeflateRect(xInter, 0, xInter, 0);
559 if (totalRowsWeight > 0.0f)
561 int netParentHei = rcParent.Height() - (nRows - 1) * (yInter > 0 ? yInter : 0);
562 if (nTotalHeight < netParentHei)
564 int nRemain = netParentHei - nTotalHeight;
565 for (
int i = 0; i < nRows; i++)
569 int extra = int(nRemain * pRowsWeight[i] / totalRowsWeight + 0.5f);
570 pCellsHeight[i] += extra;
572 totalRowsWeight -= pRowsWeight[i];
578 int nRemain = rcParent.Height() - nTotalHeight;
579 if (yInter == SIZE_WRAP_CONTENT && nRows > 1)
580 yInter = nRemain / (nRows - 1);
581 else if (yInter == SIZE_MATCH_PARENT)
583 yInter = nRemain / (nRows + 1);
584 rcParent.DeflateRect(0, yInter, 0, yInter);
590 delete[] pColsWeight;
591 delete[] pRowsWeight;
594 CPoint pt = rcParent.TopLeft();
595 for (
int y = 0; y < nRows; y++)
597 for (
int x = 0; x < nCols; x++)
599 int iCell = y * nCols + x;
600 if (pCellsSpan[iCell].x == 0 || pCellsSpan[iCell].y == 0)
602 pt.x += pCellsWidth[x] + xInter;
612 for (
int xx = 0; xx < pCellsSpan[iCell].x; xx++)
613 szCell.cx += pCellsWidth[x + xx];
614 for (
int yy = 0; yy < pCellsSpan[iCell].y; yy++)
615 szCell.cy += pCellsHeight[y + yy];
616 szCell.cx += xInter * (pCellsSpan[iCell].x - 1);
617 szCell.cy += yInter * (pCellsSpan[iCell].y - 1);
619 CSize szDesired = pCellsSize[iCell];
620 szDesired.cx *= pCellsSpan[iCell].x;
621 szDesired.cy *= pCellsSpan[iCell].y;
624 GridGravity gx = pLayoutParam->layoutGravityX;
633 pt2.x += (szCell.cx - szDesired.cx) / 2;
636 pt2.x += (szCell.cx - szDesired.cx);
639 szDesired.cx = szCell.cx;
642 GridGravity gy = pLayoutParam->layoutGravityY;
651 pt2.y += (szCell.cy - szDesired.cy) / 2;
654 pt2.y += (szCell.cy - szDesired.cy);
657 szDesired.cy = szCell.cy;
660 CRect rcCell(pt2, szDesired);
663 pt.x += pCellsWidth[x] + xInter;
665 pt.x = rcParent.left;
666 pt.y += pCellsHeight[y] + yInter;
670 delete[] pCellsWidth;
671 delete[] pCellsHeight;
673 delete[] pCellsChild;