soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SGridLayout.cpp
1#include "souistd.h"
2#include "layout/SGridLayout.h"
3#include <core/SWnd.h>
4SNSBEGIN
5GridGravity SGridLayoutParam::parseGridGravity(const SStringW &strValue)
6{
7 struct ValueMap
8 {
9 GridGravity gridGravity;
10 LPCWSTR pszGravity;
11 } map[] = {
12 { gLeft, L"left" }, { gTop, L"top" }, { gCenter, L"center" }, { gRight, L"right" }, { gBottom, L"bottom" }, { gFill, L"fill" },
13 };
14
15 for (int i = 0; i < ARRAYSIZE(map); i++)
16 {
17 if (strValue.CompareNoCase(map[i].pszGravity) == 0)
18 {
19 return map[i].gridGravity;
20 }
21 }
22 return gUndef;
23}
24
25HRESULT SGridLayoutParam::OnAttrSize(const SStringW &strValue, BOOL bLoading)
26{
27 SStringWList szStr;
28 if (2 != SplitString(strValue, L',', szStr))
29 return E_FAIL;
30
31 OnAttrWidth(szStr[0], bLoading);
32 OnAttrHeight(szStr[1], bLoading);
33 return S_OK;
34}
35
36HRESULT SGridLayoutParam::OnAttrWidth(const SStringW &strValue, BOOL bLoading)
37{
38 if (strValue.CompareNoCase(L"matchParent") == 0)
39 width.setMatchParent();
40 else if (strValue.CompareNoCase(L"wrapContent") == 0)
41 width.setWrapContent();
42 else
43 width = GETLAYOUTSIZE(strValue);
44 return S_OK;
45}
46
47HRESULT SGridLayoutParam::OnAttrHeight(const SStringW &strValue, BOOL bLoading)
48{
49 if (strValue.CompareNoCase(L"matchParent") == 0)
50 height.setMatchParent();
51 else if (strValue.CompareNoCase(L"wrapContent") == 0)
52 height.setWrapContent();
53 else
54 height = GETLAYOUTSIZE(strValue);
55 return S_OK;
56}
57
62
64{
65 width.setWrapContent();
66 height.setWrapContent();
67 nColSpan = nRowSpan = 1;
68 layoutGravityX = gUndef;
69 layoutGravityY = gUndef;
70 fColWeight = 0.0f;
71 fRowWeight = 0.0f;
72}
73
74void SGridLayoutParam::SetMatchParent(ORIENTATION orientation)
75{
76 switch (orientation)
77 {
78 case Horz:
79 width.setMatchParent();
80 break;
81 case Vert:
82 height.setMatchParent();
83 break;
84 case Both:
85 width.setMatchParent();
86 height.setMatchParent();
87 break;
88 }
89}
90
91void SGridLayoutParam::SetWrapContent(ORIENTATION orientation)
92{
93 switch (orientation)
94 {
95 case Horz:
96 width.setWrapContent();
97 break;
98 case Vert:
99 height.setWrapContent();
100 break;
101 case Both:
102 width.setWrapContent();
103 height.setWrapContent();
104 break;
105 }
106}
107
108void SGridLayoutParam::SetSpecifiedSize(ORIENTATION orientation, const SLayoutSize &layoutSize)
109{
110 switch (orientation)
111 {
112 case Horz:
113 width = layoutSize;
114 break;
115 case Vert:
116 height = layoutSize;
117 break;
118 case Both:
119 width = height = layoutSize;
120 break;
121 }
122}
123
124BOOL SGridLayoutParam::IsMatchParent(ORIENTATION orientation) const
125{
126 switch (orientation)
127 {
128 case Horz:
129 return width.isMatchParent();
130 case Vert:
131 return height.isMatchParent();
132 case Any:
133 return IsMatchParent(Horz) || IsMatchParent(Vert);
134 case Both:
135 default:
136 return IsMatchParent(Horz) && IsMatchParent(Vert);
137 }
138}
139
140BOOL SGridLayoutParam::IsWrapContent(ORIENTATION orientation) const
141{
142 switch (orientation)
143 {
144 case Horz:
145 return width.isWrapContent();
146 case Vert:
147 return height.isWrapContent();
148 case Any:
149 return IsWrapContent(Horz) || IsWrapContent(Vert);
150 case Both:
151 default:
152 return IsWrapContent(Horz) && IsWrapContent(Vert);
153 }
154}
155
156BOOL SGridLayoutParam::IsSpecifiedSize(ORIENTATION orientation) const
157{
158 switch (orientation)
159 {
160 case Horz:
161 return width.isSpecifiedSize();
162 case Vert:
163 return height.isSpecifiedSize();
164 case Any:
165 return IsSpecifiedSize(Horz) || IsSpecifiedSize(Vert);
166 case Both:
167 default:
168 return IsSpecifiedSize(Horz) && IsSpecifiedSize(Vert);
169 }
170}
171
173{
174 switch (orientation)
175 {
176 case Horz:
177 return width;
178 case Vert:
179 return height;
180 case Any:
181 case Both:
182 default:
183 SASSERT_MSGA(FALSE, "GetSpecifiedSize can only be applied for Horz or Vert");
184 return SLayoutSize();
185 }
186}
187
189{
190 return (SGridLayoutParamStruct *)this;
191}
192
193ILayoutParam *SGridLayoutParam::Clone() const
194{
196 memcpy(pRet->GetRawData(), (SGridLayoutParamStruct *)this, sizeof(SGridLayoutParamStruct));
197 return pRet;
198}
199
200//////////////////////////////////////////////////////////////////////////
202 : m_GravityX(gCenter)
203 , m_GravityY(gCenter)
204 , m_nCols(-1)
205 , m_nRows(-1)
206{
207}
208
212
213BOOL SGridLayout::IsParamAcceptable(const ILayoutParam *pLayoutParam) const
214{
215 return pLayoutParam->IsClass(SGridLayoutParam::GetClassName());
216}
217
219{
220 return new SGridLayoutParam();
221}
222
223/*
224 * MeasureChildren 计算gridlayout的子窗口大小
225 */
226SIZE SGridLayout::MeasureChildren(const IWindow *pParent, int nWidth, int nHeight) const
227{
228 SUNUSED(nWidth);
229 SUNUSED(nHeight);
230 if (m_nCols == -1 && m_nRows == -1)
231 return CSize();
232
233 int nCols = m_nCols;
234 int nRows = m_nRows;
235
236 int nCells = CalcCells(pParent);
237 if (nRows == -1)
238 nRows = (nCells + nCols - 1) / nCols;
239 else if (nCols == -1)
240 nCols = (nCells + nRows - 1) / nRows;
241
242 int cells = nCols * nRows;
243 CSize *pCellsSize = new CSize[cells];
244 bool *pCellsOccupy = new bool[cells];
245
246 for (int i = 0; i < cells; i++)
247 {
248 pCellsOccupy[i] = false;
249 }
250
251 int iRow = 0, iCol = 0;
252 const IWindow *pCell = pParent->GetNextLayoutIChild(NULL);
253 while (pCell)
254 {
255 const SGridLayoutParam *pLayoutParam = (const SGridLayoutParam *)pCell->GetLayoutParam();
256 SASSERT(pLayoutParam);
257 //将当前网络所占用的空间位置清0
258 int colSpan = pLayoutParam->nColSpan;
259 int rowSpan = pLayoutParam->nRowSpan;
260
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); //保证至少有一个空间可用
266 //计算可占用空间
267 for (int y = 0; y < rowSpan; y++)
268 for (int x = 0; x < colSpan; x++)
269 {
270 int iCell = (iRow + y) * nCols + iCol + x;
271 if (pCellsOccupy[iCell])
272 { // colSpan优先
273 rowSpan = y + 1;
274 if (y == 0)
275 colSpan = x + 1;
276 break;
277 }
278 }
279
280 //计算出网络大小
281 CSize szCell;
282 ((IWindow *)pCell)->GetDesiredSize(&szCell, SIZE_WRAP_CONTENT, SIZE_WRAP_CONTENT);
283 //填充网格,把大小平均分散到网格中。
284 szCell.cx /= colSpan;
285 szCell.cy /= rowSpan;
286 for (int y = 0; y < rowSpan; y++)
287 for (int x = 0; x < colSpan; x++)
288 {
289 int iCell = (iRow + y) * nCols + iCol + x;
290 pCellsOccupy[iCell] = true;
291 pCellsSize[iCell] = szCell;
292 }
293
294 //计算下一个网络的排列位置(先在当前行查找,再到下面行从0开始查找)
295 bool bFind = false;
296 for (int x = iCol + 1; x < nCols; x++)
297 {
298 if (!pCellsOccupy[iRow * nCols + x])
299 {
300 bFind = true;
301 iCol = x;
302 break;
303 }
304 }
305 for (int y = iRow + 1; y < nRows && !bFind; y++)
306 for (int x = 0; x < nCols; x++)
307 {
308 if (!pCellsOccupy[y * nCols + x])
309 {
310 iRow = y;
311 iCol = x;
312 bFind = true;
313 break;
314 }
315 }
316 if (!bFind)
317 break;
318 pCell = pParent->GetNextLayoutIChild(pCell);
319 }
320
321 CSize szRet;
322 //计算列宽
323 for (int x = 0; x < nCols; x++)
324 {
325 int maxWid = 0;
326 for (int y = 0; y < nRows; y++)
327 {
328 int iCell = y * nCols + x;
329 maxWid = smax(pCellsSize[iCell].cx, maxWid);
330 }
331 szRet.cx += maxWid;
332 }
333 //计算列高
334 for (int y = 0; y < nRows; y++)
335 {
336 int maxHei = 0;
337 for (int x = 0; x < nCols; x++)
338 {
339 int iCell = y * nCols + x;
340 maxHei = smax(pCellsSize[iCell].cy, maxHei);
341 }
342 szRet.cy += maxHei;
343 }
344
345 delete[] pCellsSize;
346 delete[] pCellsOccupy;
347
348 int xInter = m_xInterval.toPixelSize(pParent->GetScale());
349 int yInter = m_yInterval.toPixelSize(pParent->GetScale());
350 if (xInter < 0)
351 xInter = 0;
352 if (yInter < 0)
353 yInter = 0;
354 szRet.cx += xInter * (nCols - 1);
355 szRet.cy += yInter * (nRows - 1);
356 return szRet;
357}
358
359void SGridLayout::LayoutChildren(IWindow *pParent)
360{
361 if (m_nCols == -1 && m_nRows == -1)
362 return;
363
364 int nCols = m_nCols;
365 int nRows = m_nRows;
366
367 int nCells = CalcCells(pParent);
368 if (nRows == -1)
369 nRows = (nCells + nCols - 1) / nCols;
370 else if (nCols == -1)
371 nCols = (nCells + nRows - 1) / nRows;
372
373 CRect rcParent;
374 pParent->GetChildrenLayoutRect(&rcParent);
375
376 //先计算出每个格子的大小,算法和MeasureChildren一样,后面再考虑如何优化
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];
386
387 for (int i = 0; i < cells; i++)
388 {
389 pCellsOccupy[i] = false;
390 pCellsChild[i] = NULL;
391 }
392
393 int iRow = 0, iCol = 0;
394 IWindow *pCell = pParent->GetNextLayoutIChild(NULL);
395 while (pCell)
396 {
397 pCellsChild[iRow * nCols + iCol] = pCell;
398 SGridLayoutParam *pLayoutParam = (SGridLayoutParam *)pCell->GetLayoutParam();
399 SASSERT(pLayoutParam);
400 //将当前网络所占用的空间位置清0
401 int colSpan = pLayoutParam->nColSpan;
402 int rowSpan = pLayoutParam->nRowSpan;
403
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); //保证至少有一个空间可用
409 //计算可占用空间
410 for (int y = 0; y < rowSpan; y++)
411 for (int x = 0; x < colSpan; x++)
412 {
413 int iCell = (iRow + y) * nCols + iCol + x;
414 if (pCellsOccupy[iCell])
415 { // colSpan优先
416 rowSpan = y + 1;
417 if (y == 0)
418 colSpan = x + 1;
419 break;
420 }
421 }
422
423 //计算出网络大小,强制使用-1,-1代表自适应大小
424 CSize szCell;
425 pCell->GetDesiredSize(&szCell, SIZE_WRAP_CONTENT, SIZE_WRAP_CONTENT);
426 //填充网格,把大小平均分散到网格中。
427 szCell.cx /= colSpan;
428 szCell.cy /= rowSpan;
429
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++)
434 {
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;
444 }
445 pCellsSpan[iRow * nCols + iCol] = CPoint(colSpan, rowSpan);
446
447 //计算下一个网络的排列位置(先在当前行查找,再到下面行从0开始查找)
448 bool bFind = false;
449 for (int x = iCol + 1; x < nCols; x++)
450 {
451 if (!pCellsOccupy[iRow * nCols + x])
452 {
453 bFind = true;
454 iCol = x;
455 break;
456 }
457 }
458 for (int y = iRow + 1; y < nRows && !bFind; y++)
459 for (int x = 0; x < nCols; x++)
460 {
461 if (!pCellsOccupy[y * nCols + x])
462 {
463 iRow = y;
464 iCol = x;
465 bFind = true;
466 break;
467 }
468 }
469 if (!bFind)
470 break;
471 pCell = pParent->GetNextLayoutIChild(pCell);
472 }
473
474 int *pCellsWidth = new int[nCols];
475 int nTotalWidth = 0;
476 float *pColsWeight = new float[nCols];
477 float totalColsWeight = 0.0f;
478 //计算列宽及相应的weight
479 for (int x = 0; x < nCols; x++)
480 {
481 int maxWid = 0;
482 float maxWeight = 0.0f;
483 for (int y = 0; y < nRows; y++)
484 {
485 int iCell = y * nCols + x;
486 if (pCellsSpanFlagX[iCell])
487 continue;
488 maxWid = smax(pCellsSize[iCell].cx, maxWid);
489 maxWeight = smax(pCellsColWeight[iCell], maxWeight);
490 }
491 pCellsWidth[x] = maxWid;
492 nTotalWidth += maxWid;
493 pColsWeight[x] = maxWeight;
494 totalColsWeight += maxWeight;
495 }
496 //计算列高
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++)
502 {
503 int maxHei = 0;
504 float maxWeight = 0.0f;
505 for (int x = 0; x < nCols; x++)
506 {
507 int iCell = y * nCols + x;
508 if (pCellsSpanFlagY[iCell])
509 continue;
510 maxHei = smax(pCellsSize[iCell].cy, maxHei);
511 maxWeight = smax(pCellsRowWeight[iCell], maxWeight);
512 }
513 pCellsHeight[y] = maxHei;
514 nTotalHeight += maxHei;
515 pRowsWeight[y] = maxWeight;
516 totalRowsWeight += maxWeight;
517 }
518
519 delete[] pCellsOccupy;
520
521 delete[] pCellsColWeight;
522 delete[] pCellsRowWeight;
523 delete[] pCellsSpanFlagY;
524 delete[] pCellsSpanFlagX;
525
526 int xInter = m_xInterval.toPixelSize(pParent->GetScale());
527 int yInter = m_yInterval.toPixelSize(pParent->GetScale());
528 //分配weight
529 if (totalColsWeight > 0.0f)
530 {
531 int netParentWid = rcParent.Width() - (nCols - 1) * (xInter > 0 ? xInter : 0);
532 if (nTotalWidth < netParentWid)
533 {
534 int nRemain = netParentWid - nTotalWidth;
535 for (int i = 0; i < nCols; i++)
536 { //采用逐行4舍5入的方式解决不能整除的问题.
537 if (SLayoutSize::fequal(totalColsWeight, 0.0f))
538 break;
539 int extra = int(nRemain * pColsWeight[i] / totalColsWeight + 0.5f);
540 pCellsWidth[i] += extra;
541 nRemain -= extra;
542 totalColsWeight -= pColsWeight[i];
543 }
544 }
545 }
546 else if (xInter < 0)
547 {
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)
552 {
553 xInter = nRemain / (nCols + 1);
554 rcParent.DeflateRect(xInter, 0, xInter, 0);
555 }
556 else
557 xInter = 0;
558 }
559 if (totalRowsWeight > 0.0f)
560 {
561 int netParentHei = rcParent.Height() - (nRows - 1) * (yInter > 0 ? yInter : 0);
562 if (nTotalHeight < netParentHei)
563 {
564 int nRemain = netParentHei - nTotalHeight;
565 for (int i = 0; i < nRows; i++)
566 { //采用逐行4舍5入的方式解决不能整除的问题.
567 if (SLayoutSize::fequal(totalRowsWeight, 0.0f))
568 break;
569 int extra = int(nRemain * pRowsWeight[i] / totalRowsWeight + 0.5f);
570 pCellsHeight[i] += extra;
571 nRemain -= extra;
572 totalRowsWeight -= pRowsWeight[i];
573 }
574 }
575 }
576 else if (yInter < 0)
577 {
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)
582 {
583 yInter = nRemain / (nRows + 1);
584 rcParent.DeflateRect(0, yInter, 0, yInter);
585 }
586 else
587 yInter = 0;
588 }
589
590 delete[] pColsWeight;
591 delete[] pRowsWeight;
592
593 //计算子窗口位置
594 CPoint pt = rcParent.TopLeft();
595 for (int y = 0; y < nRows; y++)
596 {
597 for (int x = 0; x < nCols; x++)
598 {
599 int iCell = y * nCols + x;
600 if (pCellsSpan[iCell].x == 0 || pCellsSpan[iCell].y == 0)
601 {
602 pt.x += pCellsWidth[x] + xInter;
603 continue;
604 }
605 SWindow *pCell = (SWindow *)pCellsChild[iCell];
606 if (!pCell)
607 break;
608
609 SGridLayoutParam *pLayoutParam = (SGridLayoutParam *)pCell->GetLayoutParam();
610
611 CSize szCell;
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);
618
619 CSize szDesired = pCellsSize[iCell];
620 szDesired.cx *= pCellsSpan[iCell].x;
621 szDesired.cy *= pCellsSpan[iCell].y;
622
623 CPoint pt2 = pt;
624 GridGravity gx = pLayoutParam->layoutGravityX;
625 if (gx == gUndef)
626 gx = m_GravityX;
627 switch (gx)
628 {
629 case gUndef:
630 case gLeft:
631 break;
632 case gCenter:
633 pt2.x += (szCell.cx - szDesired.cx) / 2;
634 break;
635 case gRight:
636 pt2.x += (szCell.cx - szDesired.cx);
637 break;
638 case gFill:
639 szDesired.cx = szCell.cx;
640 break;
641 }
642 GridGravity gy = pLayoutParam->layoutGravityY;
643 if (gy == gUndef)
644 gy = m_GravityY;
645 switch (gy)
646 {
647 case gUndef:
648 case gTop:
649 break;
650 case gCenter:
651 pt2.y += (szCell.cy - szDesired.cy) / 2;
652 break;
653 case gBottom:
654 pt2.y += (szCell.cy - szDesired.cy);
655 break;
656 case gFill:
657 szDesired.cy = szCell.cy;
658 break;
659 }
660 CRect rcCell(pt2, szDesired);
661 pCell->OnRelayout(rcCell);
662
663 pt.x += pCellsWidth[x] + xInter;
664 }
665 pt.x = rcParent.left;
666 pt.y += pCellsHeight[y] + yInter;
667 }
668
669 delete[] pCellsSize;
670 delete[] pCellsWidth;
671 delete[] pCellsHeight;
672
673 delete[] pCellsChild;
674 delete[] pCellsSpan;
675}
676
677int SGridLayout::CalcCells(const IWindow *pParent) const
678{
679 int nCells = 0;
680 const IWindow *pCell = pParent->GetNextLayoutIChild(NULL);
681 while (pCell)
682 {
683 const SGridLayoutParam *pParam = (const SGridLayoutParam *)pCell->GetLayoutParam();
684 SASSERT(pParam);
685 int nColSpan = pParam->nColSpan;
686 int nRowSpan = pParam->nRowSpan;
687 nCells += nColSpan * nRowSpan;
688 pCell = pParent->GetNextLayoutIChild(pCell);
689 }
690 return nCells;
691}
692
693SNSEND
SOUI基础DUI窗口模块
BOOL IsParamAcceptable(const ILayoutParam *pLayoutParam) SCONST OVERRIDE
检查布局参数是否可接受
int CalcCells(const IWindow *pParent) const
计算网格单元格数量
ILayoutParam * CreateLayoutParam() SCONST OVERRIDE
创建布局参数对象
SLayoutSize m_yInterval
~SGridLayout(void)
析构函数
GridGravity m_GravityX
SIZE MeasureChildren(const IWindow *pParent, int nWidth, int nHeight) SCONST OVERRIDE
测量子窗口大小
GridGravity m_GravityY
SLayoutSize m_xInterval
SGridLayout(void)
构造函数
void LayoutChildren(IWindow *pParent) OVERRIDE
布局子窗口
网格布局参数类
Definition SGridLayout.h:25
BOOL IsMatchParent(ORIENTATION orientation) SCONST OVERRIDE
检查是否匹配父容器大小
ILayoutParam * Clone() SCONST OVERRIDE
克隆布局参数
BOOL IsWrapContent(ORIENTATION orientation) SCONST OVERRIDE
检查是否包裹内容大小
void SetSpecifiedSize(ORIENTATION orientation, const SLayoutSize &layoutSize) OVERRIDE
设置指定大小
void Clear() OVERRIDE
清除布局参数
HRESULT OnAttrHeight(const SStringW &strValue, BOOL bLoading)
处理高度属性
void SetWrapContent(ORIENTATION orientation) OVERRIDE
设置包裹内容大小
HRESULT OnAttrWidth(const SStringW &strValue, BOOL bLoading)
处理宽度属性
static GridGravity parseGridGravity(const SStringW &strValue)
解析网格对齐方式
void * GetRawData() OVERRIDE
获取原始数据指针
SLayoutSize GetSpecifiedSize(ORIENTATION orientation) SCONST OVERRIDE
获取指定大小
void SetMatchParent(ORIENTATION orientation) OVERRIDE
设置匹配父容器大小
BOOL IsSpecifiedSize(ORIENTATION orientation) SCONST OVERRIDE
检查是否指定大小
SGridLayoutParam()
构造函数
HRESULT OnAttrSize(const SStringW &strValue, BOOL bLoading)
处理大小属性
布局大小类
Definition SLayoutSize.h:10
static bool fequal(float a, float b)
比较两个浮点数是否相等
static LPCWSTR GetClassName()
Definition Sobject.hpp:41
A class representing an ASCII string.
Definition sstringw.h:96
int CompareNoCase(const wchar_t *psz) SCONST
Compares the string with another string, ignoring case.
Definition sstringw.cpp:929
Base class for SOUI DUI windows.
Definition SWnd.h:286
virtual BOOL OnRelayout(const CRect &rcWnd)
Handles window position changes during layout updates.
Definition Swnd.cpp:1587
ILayoutParam * GetLayoutParam() SCONST OVERRIDE
Retrieves the layout parameter object associated with the window.
Definition SWnd.h:405