Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fwl / src / core / fwl_gridimp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "include/fwl_targetimp.h"\r
9 #include "include/fwl_threadimp.h"\r
10 #include "include/fwl_noteimp.h"\r
11 #include "include/fwl_widgetimp.h"\r
12 #include "include/fwl_contentimp.h"\r
13 #include "include/fwl_gridimp.h"\r
14 IFWL_Grid* IFWL_Grid::Create()\r
15 {\r
16     return new IFWL_Grid;\r
17 }\r
18 FWL_ERR IFWL_Grid::Initialize()\r
19 {\r
20     m_pData = FX_NEW CFWL_GridImp;\r
21     ((CFWL_GridImp*)m_pData)->SetInterface(this);\r
22     return ((CFWL_GridImp*)m_pData)->Initialize();\r
23 }\r
24 FWL_ERR IFWL_Grid::Initialize(CFWL_WidgetImpProperties &properties)\r
25 {\r
26     m_pData = FX_NEW CFWL_GridImp(properties);\r
27     ((CFWL_GridImp*)m_pData)->SetInterface(this);\r
28     return ((CFWL_GridImp*)m_pData)->Initialize();\r
29 }\r
30 FWL_HGRIDCOLROW IFWL_Grid::InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex )\r
31 {\r
32     return ((CFWL_GridImp*)m_pData)->InsertColRow(bColumn, nIndex);\r
33 }\r
34 FX_INT32 IFWL_Grid::CountColRows(FX_BOOL bColumn)\r
35 {\r
36     return ((CFWL_GridImp*)m_pData)->CountColRows(bColumn);\r
37 }\r
38 FWL_HGRIDCOLROW IFWL_Grid::GetColRow(FX_BOOL bColumn, FX_INT32 nIndex)\r
39 {\r
40     return ((CFWL_GridImp*)m_pData)->GetColRow(bColumn, nIndex);\r
41 }\r
42 FX_INT32 IFWL_Grid::GetIndex(FWL_HGRIDCOLROW hColRow)\r
43 {\r
44     return ((CFWL_GridImp*)m_pData)->GetIndex(hColRow);\r
45 }\r
46 FX_FLOAT IFWL_Grid::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
47 {\r
48     return ((CFWL_GridImp*)m_pData)->GetSize(hColRow, eUnit);\r
49 }\r
50 FWL_ERR IFWL_Grid::SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
51 {\r
52     return ((CFWL_GridImp*)m_pData)->SetSize(hColRow, fSize, eUnit);\r
53 }\r
54 FX_FLOAT IFWL_Grid::GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
55 {\r
56     return ((CFWL_GridImp*)m_pData)->GetMinSize(hColRow, eUnit);\r
57 }\r
58 FWL_ERR IFWL_Grid::SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
59 {\r
60     return ((CFWL_GridImp*)m_pData)->SetMinSize(hColRow, fSize, eUnit);\r
61 }\r
62 FX_FLOAT IFWL_Grid::GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
63 {\r
64     return ((CFWL_GridImp*)m_pData)->GetMaxSize(hColRow, eUnit);\r
65 }\r
66 FWL_ERR IFWL_Grid::SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
67 {\r
68     return ((CFWL_GridImp*)m_pData)->SetMaxSize(hColRow, fSize, eUnit);\r
69 }\r
70 FX_BOOL IFWL_Grid::DeleteColRow(FWL_HGRIDCOLROW hColRow)\r
71 {\r
72     return ((CFWL_GridImp*)m_pData)->DeleteColRow(hColRow);\r
73 }\r
74 FX_BOOL IFWL_Grid::IsColumn(FWL_HGRIDCOLROW hColRow)\r
75 {\r
76     return ((CFWL_GridImp*)m_pData)->IsColumn(hColRow);\r
77 }\r
78 FX_INT32 IFWL_Grid::GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn)\r
79 {\r
80     return ((CFWL_GridImp*)m_pData)->GetWidgetPos(pWidget, bColumn);\r
81 }\r
82 FWL_ERR IFWL_Grid::SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn)\r
83 {\r
84     return ((CFWL_GridImp*)m_pData)->SetWidgetPos(pWidget, iPos, bColumn);\r
85 }\r
86 FX_INT32 IFWL_Grid::GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn)\r
87 {\r
88     return ((CFWL_GridImp*)m_pData)->GetWidgetSpan(pWidget, bColumn);\r
89 }\r
90 FWL_ERR IFWL_Grid::SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn)\r
91 {\r
92     return ((CFWL_GridImp*)m_pData)->SetWidgetSpan(pWidget, iSpan , bColumn);\r
93 }\r
94 FX_FLOAT IFWL_Grid::GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)\r
95 {\r
96     return ((CFWL_GridImp*)m_pData)->GetWidgetSize(pWidget, eSize, eUnit);\r
97 }\r
98 FWL_ERR IFWL_Grid::SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)\r
99 {\r
100     return ((CFWL_GridImp*)m_pData)->SetWidgetSize(pWidget, eSize, fSize, eUit);\r
101 }\r
102 FX_BOOL IFWL_Grid::GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin)\r
103 {\r
104     return ((CFWL_GridImp*)m_pData)->GetWidgetMargin(pWidget, eMargin, fMargin);\r
105 }\r
106 FWL_ERR IFWL_Grid::SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin)\r
107 {\r
108     return ((CFWL_GridImp*)m_pData)->SetWidgetMargin(pWidget, eMargin, fMargin);\r
109 }\r
110 FWL_ERR IFWL_Grid::RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin)\r
111 {\r
112     return ((CFWL_GridImp*)m_pData)->RemoveWidgetMargin(pWidget, eMargin);\r
113 }\r
114 FX_FLOAT IFWL_Grid::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)\r
115 {\r
116     return ((CFWL_GridImp*)m_pData)->GetGridSize(eSize, eUnit);\r
117 }\r
118 FWL_ERR IFWL_Grid::SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)\r
119 {\r
120     return ((CFWL_GridImp*)m_pData)->SetGridSize(eSize, fSize, eUit);\r
121 }\r
122 IFWL_Grid::IFWL_Grid()\r
123 {\r
124     m_pData = NULL;\r
125 }\r
126 IFWL_Grid::~IFWL_Grid()\r
127 {\r
128     if (m_pData) {\r
129         delete (CFWL_GridImp*)m_pData;\r
130         m_pData = NULL;\r
131     }\r
132 }\r
133 CFWL_GridImp::CFWL_GridImp()\r
134 {\r
135     m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto;\r
136     m_Size[FWL_GRIDSIZE_Width].fLength = 0;\r
137     m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto;\r
138     m_Size[FWL_GRIDSIZE_Height].fLength = 0;\r
139     m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed;\r
140     m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0;\r
141     m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity;\r
142     m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0;\r
143     m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed;\r
144     m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0;\r
145     m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity;\r
146     m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0;\r
147 }\r
148 CFWL_GridImp::CFWL_GridImp(const CFWL_WidgetImpProperties &properties)\r
149     : CFWL_ContentImp(properties)\r
150 {\r
151     m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto;\r
152     m_Size[FWL_GRIDSIZE_Width].fLength = 0;\r
153     m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto;\r
154     m_Size[FWL_GRIDSIZE_Height].fLength = 0;\r
155     m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed;\r
156     m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0;\r
157     m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity;\r
158     m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0;\r
159     m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed;\r
160     m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0;\r
161     m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity;\r
162     m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0;\r
163 }\r
164 CFWL_GridImp::~CFWL_GridImp()\r
165 {\r
166     FX_INT32 iCount = m_Columns.GetSize();\r
167     for (FX_INT32 i = 0; i < iCount; i++) {\r
168         delete (CFWL_GridColRow *) m_Columns[i];\r
169     }\r
170     m_Columns.RemoveAll();\r
171     iCount = m_Rows.GetSize();\r
172     for (FX_INT32 j = 0; j < iCount; j++) {\r
173         delete (CFWL_GridColRow*) m_Rows[j];\r
174     }\r
175     m_Rows.RemoveAll();\r
176     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
177     while (ps) {\r
178         IFWL_Widget *pWidget;\r
179         CFWL_GridWidgetInfo *pInfo;\r
180         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
181         delete pInfo;\r
182     }\r
183     m_mapWidgetInfo.RemoveAll();\r
184     if (m_pDelegate) {\r
185         delete (CFWL_GridDelegate*)m_pDelegate;\r
186         m_pDelegate = NULL;\r
187     }\r
188 }\r
189 FWL_ERR CFWL_GridImp::GetClassName(CFX_WideString &wsClass) const\r
190 {\r
191     wsClass = FWL_CLASS_Grid;\r
192     return FWL_ERR_Succeeded;\r
193 }\r
194 FX_DWORD CFWL_GridImp::GetClassID() const\r
195 {\r
196     return FWL_CLASSHASH_Grid;\r
197 }\r
198 FWL_ERR CFWL_GridImp::Initialize()\r
199 {\r
200     _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_ContentImp::Initialize(), FWL_ERR_Indefinite);\r
201     m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_GridDelegate(this);\r
202     return FWL_ERR_Succeeded;\r
203 }\r
204 FWL_ERR CFWL_GridImp::Finalize()\r
205 {\r
206     _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_ContentImp::Finalize(), FWL_ERR_Indefinite);\r
207     if (m_pDelegate) {\r
208         delete (CFWL_GridDelegate*)m_pDelegate;\r
209         m_pDelegate = NULL;\r
210     }\r
211     return FWL_ERR_Succeeded;\r
212 }\r
213 FWL_ERR CFWL_GridImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )\r
214 {\r
215     if (bAutoSize) {\r
216         rect.left = 0;\r
217         rect.top = 0;\r
218         rect.width = ProcessUnCertainColumns();\r
219         rect.height = ProcessUnCertainRows();\r
220     } else {\r
221         rect = m_pProperties->m_rtWidget;\r
222     }\r
223     return FWL_ERR_Succeeded;\r
224 }\r
225 FWL_ERR CFWL_GridImp::SetWidgetRect(const CFX_RectF &rect)\r
226 {\r
227     CFWL_WidgetImp::SetWidgetRect(rect);\r
228     return FWL_ERR_Succeeded;\r
229 }\r
230 FWL_ERR CFWL_GridImp::Update()\r
231 {\r
232     if (IsLocked()) {\r
233         return FWL_ERR_Indefinite;\r
234     }\r
235     ProcessColumns(m_pProperties->m_rtWidget.width);\r
236     ProcessRows(m_pProperties->m_rtWidget.height);\r
237     SetAllWidgetsRect();\r
238     return FWL_ERR_Succeeded;\r
239 }\r
240 FWL_ERR CFWL_GridImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
241 {\r
242     _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);\r
243     if ((m_pProperties->m_dwStyleExes & FWL_GRIDSTYLEEXT_ShowGridLines) == 0) {\r
244         return FWL_ERR_Succeeded;\r
245     }\r
246     pGraphics->SaveGraphState();\r
247     if (pMatrix) {\r
248         pGraphics->ConcatMatrix((CFX_Matrix*)pMatrix);\r
249     }\r
250     {\r
251         FX_BOOL bDrawLine = FALSE;\r
252         CFX_Path path;\r
253         path.Create();\r
254         FX_INT32 iColumns = m_Columns.GetSize();\r
255         for (FX_INT32 i = 1; i < iColumns; i++) {\r
256             CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];\r
257             if (!pColRow) {\r
258                 continue;\r
259             }\r
260             if (!bDrawLine) {\r
261                 bDrawLine = TRUE;\r
262             }\r
263             path.AddLine(pColRow->m_fActualPos,\r
264                          0,\r
265                          pColRow->m_fActualPos,\r
266                          m_pProperties->m_rtWidget.height);\r
267         }\r
268         FX_INT32 iRows = m_Rows.GetSize();\r
269         for (FX_INT32 j = 1; j < iRows; j++) {\r
270             CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[j];\r
271             if (!pColRow) {\r
272                 continue;\r
273             }\r
274             if (!bDrawLine) {\r
275                 bDrawLine = TRUE;\r
276             }\r
277             path.AddLine(0,\r
278                          pColRow->m_fActualPos,\r
279                          m_pProperties->m_rtWidget.width,\r
280                          pColRow->m_fActualPos);\r
281         }\r
282         if (bDrawLine) {\r
283             CFX_Color cr(0xFFFF0000);\r
284             pGraphics->SetStrokeColor(&cr);\r
285             pGraphics->StrokePath(&path);\r
286         }\r
287     }\r
288     pGraphics->RestoreGraphState();\r
289     return FWL_ERR_Succeeded;\r
290 }\r
291 FWL_ERR CFWL_GridImp::InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex )\r
292 {\r
293     _FWL_RETURN_VALUE_IF_FAIL(pChild, FWL_ERR_Indefinite);\r
294     CFWL_ContentImp::InsertWidget(pChild, nIndex);\r
295     if (!m_mapWidgetInfo.GetValueAt(pChild)) {\r
296         CFWL_GridWidgetInfo *pInfo = FX_NEW CFWL_GridWidgetInfo;\r
297         m_mapWidgetInfo.SetAt(pChild, pInfo);\r
298         m_Widgets.Add(pChild);\r
299     }\r
300     return FWL_ERR_Succeeded;\r
301 }\r
302 FWL_ERR CFWL_GridImp::RemoveWidget(IFWL_Widget* pWidget)\r
303 {\r
304     _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);\r
305     CFWL_ContentImp::RemoveWidget(pWidget);\r
306     if (CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)m_mapWidgetInfo.GetValueAt(pWidget)) {\r
307         m_mapWidgetInfo.RemoveKey(pWidget);\r
308         delete pInfo;\r
309         FX_INT32 nIndex = m_Widgets.Find(pWidget);\r
310         m_Widgets.RemoveAt(nIndex, 1);\r
311     }\r
312     return FWL_ERR_Succeeded;\r
313 }\r
314 FWL_HGRIDCOLROW CFWL_GridImp::InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex )\r
315 {\r
316     if (bColumn) {\r
317         if (nIndex < 0 || nIndex > m_Columns.GetSize()) {\r
318             nIndex = m_Columns.GetSize();\r
319         }\r
320         CFWL_GridColRow *pColumn = FX_NEW CFWL_GridColRow;\r
321         m_Columns.InsertAt(nIndex, pColumn, 1);\r
322         return (FWL_HGRIDCOLROW)pColumn;\r
323     }\r
324     if (nIndex < 0 || nIndex > m_Rows.GetSize()) {\r
325         nIndex = m_Rows.GetSize();\r
326     }\r
327     CFWL_GridColRow *pRow = FX_NEW CFWL_GridColRow;\r
328     m_Rows.InsertAt(nIndex, pRow, 1);\r
329     return (FWL_HGRIDCOLROW)pRow;\r
330 }\r
331 FX_INT32 CFWL_GridImp::CountColRows(FX_BOOL bColumn)\r
332 {\r
333     if (bColumn) {\r
334         return m_Columns.GetSize();\r
335     }\r
336     return m_Rows.GetSize();\r
337 }\r
338 FWL_HGRIDCOLROW CFWL_GridImp::GetColRow(FX_BOOL bColumn, FX_INT32 nIndex)\r
339 {\r
340     if (bColumn) {\r
341         if (nIndex < 0 || nIndex >= m_Columns.GetSize()) {\r
342             return NULL;\r
343         }\r
344         return (FWL_HGRIDCOLROW)m_Columns[nIndex];\r
345     }\r
346     if (nIndex < 0 || nIndex >= m_Rows.GetSize()) {\r
347         return NULL;\r
348     }\r
349     return (FWL_HGRIDCOLROW)m_Rows[nIndex];\r
350 }\r
351 FX_INT32 CFWL_GridImp::GetIndex(FWL_HGRIDCOLROW hColRow)\r
352 {\r
353     if (IsColumn(hColRow)) {\r
354         return m_Columns.Find(hColRow);\r
355     }\r
356     return m_Rows.Find(hColRow);\r
357 }\r
358 FX_FLOAT CFWL_GridImp::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
359 {\r
360     _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);\r
361     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
362     eUnit = pColRow->m_Size.eUnit;\r
363     return pColRow->m_Size.fLength;\r
364 }\r
365 FWL_ERR CFWL_GridImp::SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
366 {\r
367     _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);\r
368     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
369     pColRow->m_Size.eUnit = eUnit;\r
370     pColRow->m_Size.fLength = fSize;\r
371     return FWL_ERR_Succeeded;\r
372 }\r
373 FX_FLOAT CFWL_GridImp::GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
374 {\r
375     _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);\r
376     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
377     eUnit = pColRow->m_MinSize.eUnit;\r
378     return pColRow->m_MinSize.fLength;\r
379 }\r
380 FWL_ERR CFWL_GridImp::SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
381 {\r
382     _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);\r
383     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
384     pColRow->m_MinSize.eUnit = eUnit;\r
385     pColRow->m_MinSize.fLength = fSize;\r
386     return FWL_ERR_Succeeded;\r
387 }\r
388 FX_FLOAT CFWL_GridImp::GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)\r
389 {\r
390     _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);\r
391     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
392     eUnit = pColRow->m_MaxSize.eUnit;\r
393     return pColRow->m_MaxSize.fLength;\r
394 }\r
395 FWL_ERR CFWL_GridImp::SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)\r
396 {\r
397     _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);\r
398     CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;\r
399     pColRow->m_MaxSize.eUnit = eUnit;\r
400     pColRow->m_MaxSize.fLength = fSize;\r
401     return FWL_ERR_Succeeded;\r
402 }\r
403 FX_BOOL CFWL_GridImp::DeleteColRow(FWL_HGRIDCOLROW hColRow)\r
404 {\r
405     FX_INT32 nIndex = m_Columns.Find(hColRow);\r
406     if (nIndex >= 0) {\r
407         m_Columns.RemoveAt(nIndex);\r
408         delete (CFWL_GridColRow*)hColRow;\r
409         return TRUE;\r
410     }\r
411     nIndex = m_Rows.Find(hColRow);\r
412     if (nIndex >= 0) {\r
413         delete (CFWL_GridColRow*)hColRow;\r
414         m_Rows.RemoveAt(nIndex);\r
415         return TRUE;\r
416     }\r
417     return FALSE;\r
418 }\r
419 FX_BOOL CFWL_GridImp::IsColumn(FWL_HGRIDCOLROW hColRow)\r
420 {\r
421     return m_Columns.Find(hColRow) != -1;\r
422 }\r
423 FX_INT32 CFWL_GridImp::GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn)\r
424 {\r
425     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
426     if (pInfo) {\r
427         return bColumn ? pInfo->m_iColumn : pInfo->m_iRow;\r
428     }\r
429     return -1;\r
430 }\r
431 FWL_ERR CFWL_GridImp::SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn)\r
432 {\r
433     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
434     if (pInfo) {\r
435         bColumn ? pInfo->m_iColumn = iPos : pInfo->m_iRow = iPos;\r
436     }\r
437     return FWL_ERR_Succeeded;\r
438 }\r
439 FX_INT32 CFWL_GridImp::GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn)\r
440 {\r
441     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
442     if (pInfo) {\r
443         return bColumn ? pInfo->m_iColumnSpan : pInfo->m_iRowSpan;\r
444     }\r
445     return 0;\r
446 }\r
447 FWL_ERR CFWL_GridImp::SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn)\r
448 {\r
449     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
450     if (pInfo) {\r
451         bColumn ? pInfo->m_iColumnSpan = iSpan : pInfo->m_iRowSpan = iSpan;\r
452     }\r
453     return FWL_ERR_Succeeded;\r
454 }\r
455 FX_FLOAT CFWL_GridImp::GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)\r
456 {\r
457     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
458     if (pInfo) {\r
459         eUnit = pInfo->m_Size[eSize].eUnit;\r
460         return pInfo->m_Size[eSize].fLength;\r
461     }\r
462     return 0;\r
463 }\r
464 FWL_ERR CFWL_GridImp::SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)\r
465 {\r
466     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
467     if (pInfo) {\r
468         pInfo->m_Size[eSize].fLength = fSize;\r
469         pInfo->m_Size[eSize].eUnit = eUit;\r
470     }\r
471     return FWL_ERR_Succeeded;\r
472 }\r
473 FX_BOOL CFWL_GridImp::GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin)\r
474 {\r
475     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
476     if (pInfo) {\r
477         fMargin = pInfo->m_Margin[eMargin];\r
478         return (pInfo->m_dwMarginFlag & (1 << eMargin)) != 0;\r
479     }\r
480     return FALSE;\r
481 }\r
482 FWL_ERR CFWL_GridImp::SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin)\r
483 {\r
484     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
485     if (pInfo) {\r
486         pInfo->m_Margin[eMargin] = fMargin;\r
487         pInfo->m_dwMarginFlag |= (1 << eMargin);\r
488     }\r
489     return FWL_ERR_Succeeded;\r
490 }\r
491 FWL_ERR CFWL_GridImp::RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin)\r
492 {\r
493     CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);\r
494     if (pInfo) {\r
495         pInfo->m_dwMarginFlag &= ~(1 << eMargin);\r
496     }\r
497     return FWL_ERR_Succeeded;\r
498 }\r
499 FX_FLOAT CFWL_GridImp::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)\r
500 {\r
501     eUnit = m_Size[eSize].eUnit;\r
502     return m_Size[eSize].fLength;\r
503 }\r
504 FWL_ERR CFWL_GridImp::SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)\r
505 {\r
506     m_Size[eSize].fLength = fSize;\r
507     m_Size[eSize].eUnit = eUit;\r
508     return FWL_ERR_Succeeded;\r
509 }\r
510 CFWL_GridWidgetInfo* CFWL_GridImp::GetWidgetInfo(IFWL_Widget* pWidget)\r
511 {\r
512     return (CFWL_GridWidgetInfo*)m_mapWidgetInfo.GetValueAt(pWidget);\r
513 }\r
514 void CFWL_GridImp::ProcFixedColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn)\r
515 {\r
516     pColRow->m_fActualSize = fColRowSize;\r
517     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
518     while (ps) {\r
519         IFWL_Widget *pWidget = NULL;\r
520         CFWL_GridWidgetInfo *pInfo = NULL;\r
521         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
522         if (bColumn) {\r
523             if (pInfo->m_iColumn == nIndex && pInfo->m_iColumnSpan == 1) {\r
524                 CalcWidgetWidth(pWidget, pInfo, pColRow->m_fActualSize);\r
525             }\r
526         } else {\r
527             if (pInfo->m_iRow == nIndex && pInfo->m_iRowSpan == 1) {\r
528                 CalcWidgetHeigt(pWidget, pInfo, pColRow->m_fActualSize);\r
529             }\r
530         }\r
531     }\r
532 }\r
533 void CFWL_GridImp::ProcAutoColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_BOOL bColumn)\r
534 {\r
535     _FWL_RETURN_IF_FAIL(pColRow);\r
536     FX_FLOAT fMaxSize = 0, fWidgetSize = 0;\r
537     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
538     while (ps) {\r
539         IFWL_Widget*pWidget = NULL;\r
540         CFWL_GridWidgetInfo *pInfo = NULL;\r
541         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
542         if (!pWidget || !pInfo) {\r
543             continue;\r
544         }\r
545         if (bColumn) {\r
546             if (pInfo->m_iColumn != nIndex || pInfo->m_iColumnSpan != 1) {\r
547                 continue;\r
548             }\r
549             fWidgetSize = CalcAutoColumnWidgetWidth(pWidget, pInfo);\r
550             if (fMaxSize < fWidgetSize) {\r
551                 fMaxSize = fWidgetSize;\r
552             }\r
553         } else {\r
554             if (pInfo->m_iRow != nIndex || pInfo->m_iRowSpan != 1) {\r
555                 continue;\r
556             }\r
557             fWidgetSize = CalcAutoColumnWidgetHeight(pWidget, pInfo);\r
558             if (fMaxSize < fWidgetSize) {\r
559                 fMaxSize = fWidgetSize;\r
560             }\r
561         }\r
562     }\r
563     SetColRowActualSize(pColRow, fMaxSize);\r
564 }\r
565 void CFWL_GridImp::ProcScaledColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn)\r
566 {\r
567     if (fColRowSize > 0) {\r
568         ProcFixedColRow(pColRow, nIndex, fColRowSize, bColumn);\r
569     }\r
570 }\r
571 void CFWL_GridImp::CalcWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo, FX_FLOAT fColunmWidth)\r
572 {\r
573     if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {\r
574         SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);\r
575     } else {\r
576         FX_FLOAT fWidth = 0;\r
577         FX_FLOAT fLeftMargin = 0, fRightMargin = 0;\r
578         FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);\r
579         FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);\r
580         if (bLeftMargin && bRightMargin) {\r
581             fWidth = fColunmWidth - fLeftMargin - fRightMargin;\r
582         } else {\r
583             CFX_RectF rtAuto;\r
584             pWidget->GetWidgetRect(rtAuto, TRUE);\r
585             fWidth = rtAuto.Width();\r
586         }\r
587         SetWidgetActualWidth(pInfo, fWidth);\r
588     }\r
589 }\r
590 void CFWL_GridImp::CalcWidgetHeigt(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo, FX_FLOAT fRowHeigt)\r
591 {\r
592     if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {\r
593         SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);\r
594     } else {\r
595         FX_FLOAT fHeight = 0;\r
596         FX_FLOAT fTopMargin = 0, fBottomMargin = 0;\r
597         FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);\r
598         FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);\r
599         if (bTopMargin && bBottomMargin) {\r
600             fHeight = fRowHeigt - fTopMargin - fBottomMargin;\r
601         } else {\r
602             CFX_RectF rtAuto;\r
603             pWidget->GetWidgetRect(rtAuto, TRUE);\r
604             fHeight = rtAuto.Height();\r
605         }\r
606         SetWidgetActualHeight(pInfo, fHeight);\r
607     }\r
608 }\r
609 FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo)\r
610 {\r
611     FX_FLOAT fLeftMargin = 0, fRightMargin = 0;\r
612     FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);\r
613     FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);\r
614     if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {\r
615         SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);\r
616     } else {\r
617         CFX_RectF rtAuto;\r
618         pWidget->GetWidgetRect(rtAuto, TRUE);\r
619         FX_FLOAT fWidth = rtAuto.width;\r
620         SetWidgetActualWidth(pInfo, fWidth);\r
621     }\r
622     FX_FLOAT fTotal = pInfo->m_fActualWidth;\r
623     if (bLeftMargin) {\r
624         fTotal += fLeftMargin;\r
625     }\r
626     if (bRightMargin) {\r
627         fTotal += fRightMargin;\r
628     }\r
629     return fTotal;\r
630 }\r
631 FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetHeight(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo)\r
632 {\r
633     FX_FLOAT fTopMargin = 0, fBottomMargin = 0;\r
634     FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);\r
635     FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);\r
636     if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {\r
637         SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);\r
638     } else {\r
639         CFX_RectF rtAuto;\r
640         pWidget->GetWidgetRect(rtAuto, TRUE);\r
641         FX_FLOAT fHeight = rtAuto.height;\r
642         SetWidgetActualHeight(pInfo, fHeight);\r
643     }\r
644     FX_FLOAT fTotal = pInfo->m_fActualHeight;\r
645     if (bTopMargin) {\r
646         fTotal += fTopMargin;\r
647     }\r
648     if (bBottomMargin) {\r
649         fTotal += fBottomMargin;\r
650     }\r
651     return fTotal;\r
652 }\r
653 FX_FLOAT CFWL_GridImp::ProcessColumns(FX_FLOAT fWidth)\r
654 {\r
655     if (fWidth <= 0) {\r
656         return ProcessUnCertainColumns();\r
657     }\r
658     FX_INT32 iColumns = m_Columns.GetSize();\r
659     if (iColumns < 1) {\r
660         return fWidth;\r
661     }\r
662     FX_FLOAT fFixedWidth = 0;\r
663     FX_FLOAT fAutoWidth = 0;\r
664     CFX_PtrArray autoColumns;\r
665     CFX_PtrArray scaledColumns;\r
666     FX_FLOAT fScaledColumnNum = 0;\r
667     for (FX_INT32 i = 0; i < iColumns; i++) {\r
668         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];\r
669         if (!pColRow) {\r
670             continue;\r
671         }\r
672         switch(pColRow->m_Size.eUnit) {\r
673             case FWL_GRIDUNIT_Fixed: {\r
674                     SetColRowActualSize(pColRow, pColRow->m_Size.fLength);\r
675                     fFixedWidth += pColRow->m_fActualSize;\r
676                     break;\r
677                 }\r
678             case FWL_GRIDUNIT_Auto: {\r
679                     ProcAutoColRow(pColRow, i, TRUE);\r
680                     autoColumns.Add(pColRow);\r
681                     break;\r
682                 }\r
683             case FWL_GRIDUNIT_Scaled:\r
684             default: {\r
685                     fScaledColumnNum += pColRow->m_Size.fLength;\r
686                     scaledColumns.Add(pColRow);\r
687                     SetColRowActualSize(pColRow, 0);\r
688                 }\r
689         }\r
690     }\r
691     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
692     while (ps) {\r
693         IFWL_Widget *pWidget = NULL;\r
694         CFWL_GridWidgetInfo *pInfo = NULL;\r
695         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
696         if (!pInfo || pInfo->m_iColumnSpan < 2) {\r
697             continue;\r
698         }\r
699         CFX_PtrArray spanAutoColumns;\r
700         FX_FLOAT fSpanSize = 0;\r
701         FX_INT32 iAutoColRows = 0;\r
702         FX_INT32 iScaledColRows = 0;\r
703         for (FX_INT32 i = 0; i < pInfo->m_iColumnSpan; i++) {\r
704             CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + i);\r
705             if (!pColumn) {\r
706                 break;\r
707             }\r
708             fSpanSize += pColumn->m_fActualSize;\r
709             if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) {\r
710                 iAutoColRows++;\r
711                 spanAutoColumns.Add(pColumn);\r
712             } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {\r
713                 iScaledColRows++;\r
714             }\r
715         }\r
716         if (iAutoColRows < 1) {\r
717             continue;\r
718         }\r
719         FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo);\r
720         if (fWidgetWidth > fSpanSize) {\r
721             if (iScaledColRows > 0) {\r
722             } else {\r
723                 SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize);\r
724             }\r
725         }\r
726     }\r
727     FX_INT32 iAutoCols = autoColumns.GetSize();\r
728     for (FX_INT32 k = 0; k < iAutoCols; k++) {\r
729         fAutoWidth += ((CFWL_GridColRow*)autoColumns[k])->m_fActualSize;\r
730     }\r
731     FX_FLOAT fScaledWidth = fWidth - fFixedWidth - fAutoWidth;\r
732     if (fScaledWidth > 0 && fScaledColumnNum > 0) {\r
733         SetScaledColRowsSize(scaledColumns, fScaledWidth, fScaledColumnNum);\r
734     }\r
735     return fWidth;\r
736 }\r
737 FX_FLOAT CFWL_GridImp::ProcessRows(FX_FLOAT fHeight)\r
738 {\r
739     if (fHeight <= 0) {\r
740         return ProcessUnCertainRows();\r
741     }\r
742     FX_INT32 iRows = m_Rows.GetSize();\r
743     if (iRows < 1) {\r
744         return fHeight;\r
745     }\r
746     FX_FLOAT fFixedHeight = 0;\r
747     FX_FLOAT fAutoHeigt = 0;\r
748     CFX_PtrArray autoRows;\r
749     CFX_PtrArray scaledRows;\r
750     FX_FLOAT fScaledRowNum = 0;\r
751     for (FX_INT32 i = 0; i < iRows; i++) {\r
752         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[i];\r
753         if (!pColRow) {\r
754             continue;\r
755         }\r
756         switch(pColRow->m_Size.eUnit) {\r
757             case FWL_GRIDUNIT_Fixed: {\r
758                     SetColRowActualSize(pColRow, pColRow->m_Size.fLength);\r
759                     fFixedHeight += pColRow->m_fActualSize;\r
760                     break;\r
761                 }\r
762             case FWL_GRIDUNIT_Auto: {\r
763                     ProcAutoColRow(pColRow, i, FALSE);\r
764                     autoRows.Add(pColRow);\r
765                     break;\r
766                 }\r
767             case FWL_GRIDUNIT_Scaled:\r
768             default: {\r
769                     fScaledRowNum += pColRow->m_Size.fLength;\r
770                     scaledRows.Add(pColRow);\r
771                     SetColRowActualSize(pColRow, 0);\r
772                     break;\r
773                 }\r
774         }\r
775     }\r
776     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
777     while (ps) {\r
778         IFWL_Widget *pWidget = NULL;\r
779         CFWL_GridWidgetInfo *pInfo = NULL;\r
780         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
781         if (!pInfo || pInfo->m_iRowSpan < 2) {\r
782             continue;\r
783         }\r
784         CFX_PtrArray spanAutoRows;\r
785         FX_FLOAT fSpanSize = 0;\r
786         FX_INT32 iAutoColRows = 0;\r
787         FX_INT32 iScaledColRows = 0;\r
788         for (FX_INT32 i = 0; i < pInfo->m_iRowSpan; i++) {\r
789             CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + i);\r
790             if (!pRow) {\r
791                 break;\r
792             }\r
793             fSpanSize += pRow->m_fActualSize;\r
794             if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) {\r
795                 iAutoColRows++;\r
796                 spanAutoRows.Add(pRow);\r
797             } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {\r
798                 iScaledColRows++;\r
799             }\r
800         }\r
801         if (iAutoColRows < 1) {\r
802             continue;\r
803         }\r
804         FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo);\r
805         if (fWidgetHeight > fSpanSize) {\r
806             if (iScaledColRows > 0) {\r
807             } else {\r
808                 SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize);\r
809             }\r
810         }\r
811     }\r
812     FX_INT32 iAutoRows = autoRows.GetSize();\r
813     for (FX_INT32 k = 0; k < iAutoRows; k++) {\r
814         fAutoHeigt += ((CFWL_GridColRow*)autoRows[k])->m_fActualSize;\r
815     }\r
816     FX_FLOAT fScaledHeight = fHeight - fFixedHeight - fAutoHeigt;\r
817     if (fScaledHeight > 0 && fScaledRowNum > 0) {\r
818         SetScaledColRowsSize(scaledRows, fScaledHeight, fScaledRowNum);\r
819     }\r
820     return fHeight;\r
821 }\r
822 FX_FLOAT CFWL_GridImp::ProcessUnCertainColumns()\r
823 {\r
824     FX_INT32 iColumns = m_Columns.GetSize();\r
825     if (iColumns < 1) {\r
826         CFWL_GridColRow *pColRow = new CFWL_GridColRow;\r
827         pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto;\r
828         ProcAutoColRow(pColRow, 0, TRUE);\r
829         FX_FLOAT fWidth = pColRow->m_fActualSize;\r
830         delete pColRow;\r
831         return fWidth;\r
832     }\r
833     FX_FLOAT fFixedWidth = 0;\r
834     CFX_PtrArray autoColumns;\r
835     CFX_PtrArray scaledColumns;\r
836     FX_FLOAT fScaledColumnNum = 0;\r
837     FX_FLOAT fScaledMaxPerWidth = 0;\r
838     for (FX_INT32 i = 0; i < iColumns; i++) {\r
839         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];\r
840         if (!pColRow) {\r
841             continue;\r
842         }\r
843         switch(pColRow->m_Size.eUnit) {\r
844             case FWL_GRIDUNIT_Fixed: {\r
845                     SetColRowActualSize(pColRow, pColRow->m_Size.fLength);\r
846                     fFixedWidth += pColRow->m_fActualSize;\r
847                     break;\r
848                 }\r
849             case FWL_GRIDUNIT_Auto: {\r
850                     ProcAutoColRow(pColRow, i, TRUE);\r
851                     autoColumns.Add(pColRow);\r
852                     break;\r
853                 }\r
854             case FWL_GRIDUNIT_Scaled:\r
855             default: {\r
856                     ProcAutoColRow(pColRow, i, TRUE);\r
857                     fScaledColumnNum += pColRow->m_Size.fLength;\r
858                     scaledColumns.Add(pColRow);\r
859                     if (pColRow->m_Size.fLength <= 0) {\r
860                         break;\r
861                     }\r
862                     FX_FLOAT fPerWidth = pColRow->m_fActualSize / pColRow->m_Size.fLength;\r
863                     if (fPerWidth > fScaledMaxPerWidth) {\r
864                         fScaledMaxPerWidth = fPerWidth;\r
865                     }\r
866                 }\r
867         }\r
868     }\r
869     iColumns = scaledColumns.GetSize();\r
870     for (FX_INT32 j = 0; j < iColumns; j++) {\r
871         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)scaledColumns[j];\r
872         if (!pColRow) {\r
873             continue;\r
874         }\r
875         SetColRowActualSize(pColRow, fScaledMaxPerWidth * pColRow->m_Size.fLength);\r
876     }\r
877     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
878     while (ps) {\r
879         IFWL_Widget *pWidget = NULL;\r
880         CFWL_GridWidgetInfo *pInfo = NULL;\r
881         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
882         if (!pInfo || pInfo->m_iColumnSpan < 2) {\r
883             continue;\r
884         }\r
885         CFX_PtrArray spanAutoColumns;\r
886         CFX_PtrArray spanScaledColumns;\r
887         FX_FLOAT fSpanSize = 0;\r
888         FX_FLOAT fScaledSum = 0;\r
889         FX_INT32 iAutoColRows = 0;\r
890         FX_INT32 iScaledColRows = 0;\r
891         for (FX_INT32 i = 0; i < pInfo->m_iColumnSpan; i++) {\r
892             CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + i);\r
893             if (!pColumn) {\r
894                 break;\r
895             }\r
896             fSpanSize += pColumn->m_fActualSize;\r
897             if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) {\r
898                 iAutoColRows++;\r
899                 spanAutoColumns.Add(pColumn);\r
900             } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {\r
901                 iScaledColRows++;\r
902                 fScaledSum += pColumn->m_Size.fLength;\r
903                 spanScaledColumns.Add(pColumn);\r
904             }\r
905         }\r
906         if (iAutoColRows < 1 && iScaledColRows < 1) {\r
907             continue;\r
908         }\r
909         FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo);\r
910         if (fWidgetWidth > fSpanSize) {\r
911             if (iScaledColRows > 0 ) {\r
912                 if (fScaledSum <= 0) {\r
913                     continue;\r
914                 }\r
915                 SetSpanScaledColRowSize(spanScaledColumns, fWidgetWidth - fSpanSize, fScaledSum);\r
916             } else {\r
917                 SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize);\r
918             }\r
919         }\r
920     }\r
921     FX_FLOAT fAutoWidth = 0;\r
922     FX_INT32 iAutoCols = autoColumns.GetSize();\r
923     for (FX_INT32 m = 0; m < iAutoCols; m++) {\r
924         fAutoWidth += ((CFWL_GridColRow*)autoColumns[m])->m_fActualSize;\r
925     }\r
926     FX_FLOAT fScaledWidth = 0;\r
927     iColumns = scaledColumns.GetSize();\r
928     for (FX_INT32 n = 0; n < iColumns; n++) {\r
929         fScaledWidth += ((CFWL_GridColRow*)scaledColumns[n])->m_fActualSize;\r
930     }\r
931     return fFixedWidth + fAutoWidth + fScaledWidth;\r
932 }\r
933 FX_FLOAT CFWL_GridImp::ProcessUnCertainRows()\r
934 {\r
935     FX_INT32 iRows = m_Rows.GetSize();\r
936     if (iRows < 1) {\r
937         CFWL_GridColRow *pColRow = new CFWL_GridColRow;\r
938         pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto;\r
939         ProcAutoColRow(pColRow, 0, FALSE);\r
940         FX_FLOAT fWidth = pColRow->m_fActualSize;\r
941         delete pColRow;\r
942         return fWidth;\r
943     }\r
944     FX_FLOAT fFixedHeight = 0;\r
945     CFX_PtrArray autoRows;\r
946     CFX_PtrArray scaledRows;\r
947     FX_FLOAT fScaledRowNum = 0;\r
948     FX_FLOAT fScaledMaxPerHeight = 0;\r
949     for (FX_INT32 i = 0; i < iRows; i++) {\r
950         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[i];\r
951         if (!pColRow) {\r
952             continue;\r
953         }\r
954         switch(pColRow->m_Size.eUnit) {\r
955             case FWL_GRIDUNIT_Fixed: {\r
956                     SetColRowActualSize(pColRow, pColRow->m_Size.fLength);\r
957                     fFixedHeight += pColRow->m_fActualSize;\r
958                     break;\r
959                 }\r
960             case FWL_GRIDUNIT_Auto: {\r
961                     ProcAutoColRow(pColRow, i, FALSE);\r
962                     autoRows.Add(pColRow);\r
963                     break;\r
964                 }\r
965             case FWL_GRIDUNIT_Scaled:\r
966             default: {\r
967                     ProcAutoColRow(pColRow, i, FALSE);\r
968                     fScaledRowNum += pColRow->m_Size.fLength;\r
969                     scaledRows.Add(pColRow);\r
970                     if (pColRow->m_Size.fLength > 0) {\r
971                         FX_FLOAT fPerHeight = pColRow->m_fActualSize / pColRow->m_Size.fLength;\r
972                         if (fPerHeight > fScaledMaxPerHeight) {\r
973                             fScaledMaxPerHeight = fPerHeight;\r
974                         }\r
975                     }\r
976                     break;\r
977                 }\r
978         }\r
979     }\r
980     iRows = scaledRows.GetSize();\r
981     for (FX_INT32 j = 0; j < iRows; j++) {\r
982         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)scaledRows[j];\r
983         if (!pColRow) {\r
984             continue;\r
985         }\r
986         SetColRowActualSize(pColRow, fScaledMaxPerHeight * pColRow->m_Size.fLength);\r
987     }\r
988     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
989     while (ps) {\r
990         IFWL_Widget *pWidget = NULL;\r
991         CFWL_GridWidgetInfo *pInfo = NULL;\r
992         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
993         if (pInfo->m_iRowSpan < 2) {\r
994             continue;\r
995         }\r
996         CFX_PtrArray spanAutoRows;\r
997         CFX_PtrArray spanScaledRows;\r
998         FX_FLOAT fSpanSize = 0;\r
999         FX_FLOAT fScaledSum = 0;\r
1000         FX_INT32 iAutoColRows = 0;\r
1001         FX_INT32 iScaledColRows = 0;\r
1002         for (FX_INT32 i = 0; i < pInfo->m_iRowSpan; i++) {\r
1003             CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + i);\r
1004             if (!pRow) {\r
1005                 break;\r
1006             }\r
1007             fSpanSize += pRow->m_fActualSize;\r
1008             if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) {\r
1009                 iAutoColRows++;\r
1010                 spanAutoRows.Add(pRow);\r
1011             } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {\r
1012                 iScaledColRows++;\r
1013                 fScaledSum += pRow->m_Size.fLength;\r
1014                 spanScaledRows.Add(pRow);\r
1015             }\r
1016         }\r
1017         if (iAutoColRows < 1 && iScaledColRows < 1) {\r
1018             continue;\r
1019         }\r
1020         FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo);\r
1021         if (fWidgetHeight > fSpanSize) {\r
1022             if (iScaledColRows > 0) {\r
1023                 if (fScaledSum <= 0) {\r
1024                     continue;\r
1025                 }\r
1026                 SetSpanScaledColRowSize(spanScaledRows, fWidgetHeight - fSpanSize, fScaledSum);\r
1027             } else {\r
1028                 SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize);\r
1029             }\r
1030         }\r
1031     }\r
1032     FX_FLOAT fAutoHeigt = 0;\r
1033     FX_INT32 iAutoRows = autoRows.GetSize();\r
1034     for (FX_INT32 m = 0; m < iAutoRows; m++) {\r
1035         fAutoHeigt += ((CFWL_GridColRow*)autoRows[m])->m_fActualSize;\r
1036     }\r
1037     FX_FLOAT fScaledHeight = 0;\r
1038     iRows = scaledRows.GetSize();\r
1039     for (FX_INT32 n = 0; n < iRows; n++) {\r
1040         fScaledHeight += ((CFWL_GridColRow*)scaledRows[n])->m_fActualSize;\r
1041     }\r
1042     return fFixedHeight + fAutoHeigt + fScaledHeight;\r
1043 }\r
1044 FX_BOOL CFWL_GridImp::SetColRowActualSize(CFWL_GridColRow* pColRow, FX_FLOAT fSize, FX_BOOL bSetBeyond )\r
1045 {\r
1046     if (pColRow->m_MinSize.eUnit == FWL_GRIDUNIT_Fixed && fSize < pColRow->m_MinSize.fLength) {\r
1047         pColRow->m_fActualSize = pColRow->m_MinSize.fLength;\r
1048         return FALSE;\r
1049     }\r
1050     if (pColRow->m_MaxSize.eUnit == FWL_GRIDUNIT_Fixed && fSize > pColRow->m_MaxSize.fLength) {\r
1051         pColRow->m_fActualSize = pColRow->m_MaxSize.fLength;\r
1052         return FALSE;\r
1053     }\r
1054     if (bSetBeyond) {\r
1055         return TRUE;\r
1056     }\r
1057     pColRow->m_fActualSize = fSize;\r
1058     return TRUE;\r
1059 }\r
1060 FX_FLOAT CFWL_GridImp::SetWidgetActualWidth(CFWL_GridWidgetInfo* pInfo, FX_FLOAT fWidth)\r
1061 {\r
1062     if (pInfo->m_Size[FWL_GRIDSIZE_MinWidth].eUnit == FWL_GRIDUNIT_Fixed &&\r
1063             fWidth < pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength) {\r
1064         fWidth = pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength;\r
1065     }\r
1066     if (pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].eUnit == FWL_GRIDUNIT_Fixed &&\r
1067             fWidth > pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength) {\r
1068         fWidth = pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength;\r
1069     }\r
1070     pInfo->m_fActualWidth = fWidth;\r
1071     return fWidth;\r
1072 }\r
1073 FX_FLOAT CFWL_GridImp::SetWidgetActualHeight(CFWL_GridWidgetInfo* pInfo, FX_FLOAT fHeight)\r
1074 {\r
1075     if (pInfo->m_Size[FWL_GRIDSIZE_MinHeight].eUnit == FWL_GRIDUNIT_Fixed &&\r
1076             fHeight < pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength) {\r
1077         fHeight = pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength;\r
1078     }\r
1079     if (pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].eUnit == FWL_GRIDUNIT_Fixed &&\r
1080             fHeight > pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength) {\r
1081         fHeight = pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength;\r
1082     }\r
1083     pInfo->m_fActualHeight = fHeight;\r
1084     return fHeight;\r
1085 }\r
1086 void CFWL_GridImp::SetAllWidgetsRect()\r
1087 {\r
1088     FX_FLOAT fStartLeft = 0;\r
1089     FX_INT32 iColumns = m_Columns.GetSize();\r
1090     for (FX_INT32 i = 0; i < iColumns; i++) {\r
1091         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];\r
1092         if (!pColRow) {\r
1093             continue;\r
1094         }\r
1095         pColRow->m_fActualPos = fStartLeft;\r
1096         fStartLeft += pColRow->m_fActualSize;\r
1097     }\r
1098     FX_FLOAT fStartTop = 0;\r
1099     FX_INT32 iRows = m_Rows.GetSize();\r
1100     for (FX_INT32 j = 0; j < iRows; j++) {\r
1101         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[j];\r
1102         if (!pColRow) {\r
1103             continue;\r
1104         }\r
1105         pColRow->m_fActualPos = fStartTop;\r
1106         fStartTop += pColRow->m_fActualSize;\r
1107     }\r
1108     FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();\r
1109     while (ps) {\r
1110         IFWL_Widget *pWidget = NULL;\r
1111         CFWL_GridWidgetInfo *pInfo = NULL;\r
1112         m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);\r
1113         if (!pWidget || !pInfo) {\r
1114             continue;\r
1115         }\r
1116         FX_FLOAT fColumnStart = 0;\r
1117         CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn);\r
1118         if (pColumn) {\r
1119             fColumnStart = pColumn->m_fActualPos;\r
1120         }\r
1121         FX_FLOAT fRowStart = 0;\r
1122         CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow);\r
1123         if (pRow) {\r
1124             fRowStart = pRow->m_fActualPos;\r
1125         }\r
1126         FX_FLOAT fColumnWidth = 0;\r
1127         if (iColumns > 0) {\r
1128             for (FX_INT32 j = 0; j < pInfo->m_iColumnSpan; j++) {\r
1129                 CFWL_GridColRow *pCol = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + j);\r
1130                 if (!pCol) {\r
1131                     break;\r
1132                 }\r
1133                 fColumnWidth += pCol->m_fActualSize;\r
1134             }\r
1135         } else {\r
1136             fColumnWidth = m_pProperties->m_rtWidget.width;\r
1137         }\r
1138         FX_FLOAT fRowHeight = 0;\r
1139         if (iRows > 0) {\r
1140             for (FX_INT32 k = 0; k < pInfo->m_iRowSpan; k++) {\r
1141                 CFWL_GridColRow *pR = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + k);\r
1142                 if (!pR) {\r
1143                     break;\r
1144                 }\r
1145                 fRowHeight += pR->m_fActualSize;\r
1146             }\r
1147         } else {\r
1148             fRowHeight = m_pProperties->m_rtWidget.height;\r
1149         }\r
1150         FX_FLOAT fLeftMargin = 0, fRightMargin = 0;\r
1151         FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);\r
1152         FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);\r
1153         FX_FLOAT fTopMargin = 0, fBottomMargin = 0;\r
1154         FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);\r
1155         FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);\r
1156         FWL_LAYOUTDATA ltd;\r
1157         ltd.fWidth = 0;\r
1158         ltd.fHeight = 0;\r
1159         if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {\r
1160             SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);\r
1161             ltd.fWidth = pInfo->m_fActualWidth;\r
1162         } else {\r
1163             if (bLeftMargin && bRightMargin) {\r
1164                 SetWidgetActualWidth(pInfo, fColumnWidth - fLeftMargin - fRightMargin);\r
1165                 ltd.fWidth = pInfo->m_fActualWidth;\r
1166             } else {\r
1167                 CFX_RectF rtAuto;\r
1168                 pWidget->GetWidgetRect(rtAuto, TRUE);\r
1169                 SetWidgetActualWidth(pInfo,  rtAuto.width);\r
1170             }\r
1171         }\r
1172         if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {\r
1173             SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);\r
1174             ltd.fHeight = pInfo->m_fActualHeight;\r
1175         } else {\r
1176             if (bTopMargin && bBottomMargin) {\r
1177                 SetWidgetActualHeight(pInfo, fRowHeight - fTopMargin - fBottomMargin);\r
1178                 ltd.fHeight = pInfo->m_fActualHeight;\r
1179             } else {\r
1180                 CFX_RectF rtAuto;\r
1181                 pWidget->GetWidgetRect(rtAuto, TRUE);\r
1182                 SetWidgetActualHeight(pInfo, rtAuto.height);\r
1183             }\r
1184         }\r
1185         if (bLeftMargin && bRightMargin && pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {\r
1186             fLeftMargin = fColumnStart + fLeftMargin + (fColumnWidth - fLeftMargin - fRightMargin - pInfo->m_fActualWidth) / 2;\r
1187         } else if (bLeftMargin) {\r
1188             fLeftMargin = fColumnStart + fLeftMargin;\r
1189         } else if (bRightMargin) {\r
1190             fLeftMargin = fColumnStart + fColumnWidth  - fRightMargin - pInfo->m_fActualWidth;\r
1191         } else {\r
1192             fLeftMargin = fColumnStart;\r
1193         }\r
1194         if (bTopMargin && bBottomMargin && pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {\r
1195             fTopMargin = fRowStart + fTopMargin + (fRowHeight - fTopMargin - fBottomMargin - pInfo->m_fActualHeight) / 2;\r
1196         } else if (bTopMargin) {\r
1197             fTopMargin = fRowStart + fTopMargin;\r
1198         } else if (bBottomMargin) {\r
1199             fTopMargin = fRowStart + fRowHeight - fBottomMargin - pInfo->m_fActualHeight;\r
1200         } else {\r
1201             fTopMargin = fRowStart;\r
1202         }\r
1203         CFX_RectF rtWidget, rtOld;\r
1204         rtWidget.Set(fLeftMargin, fTopMargin, pInfo->m_fActualWidth, pInfo->m_fActualHeight);\r
1205         pWidget->GetWidgetRect(rtOld);\r
1206         if (rtWidget == rtOld) {\r
1207             continue;\r
1208         }\r
1209         pWidget->SetWidgetRect(rtWidget);\r
1210         if (rtWidget.width == rtOld.width && rtWidget.height == rtOld.height) {\r
1211             continue;\r
1212         }\r
1213         pWidget->Update();\r
1214     }\r
1215 }\r
1216 FX_BOOL CFWL_GridImp::IsGrid(IFWL_Widget* pWidget)\r
1217 {\r
1218     _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);\r
1219     return pWidget->GetClassID() == FWL_CLASSHASH_Grid;\r
1220 }\r
1221 void CFWL_GridImp::SetSpanAutoColRowSize(const CFX_PtrArray &spanAutos, FX_FLOAT fTotalSize)\r
1222 {\r
1223     FX_INT32 iAutoColRows = spanAutos.GetSize();\r
1224     if (iAutoColRows < 1) {\r
1225         return;\r
1226     }\r
1227     CFX_PtrArray autoNoMinMaxs;\r
1228     FX_FLOAT fAutoPer = fTotalSize / iAutoColRows;\r
1229     for (FX_INT32 j = 0; j < iAutoColRows; j++) {\r
1230         CFWL_GridColRow *pColumn = (CFWL_GridColRow*)spanAutos[j];\r
1231         FX_FLOAT fOrgSize = pColumn->m_fActualSize;\r
1232         if (SetColRowActualSize(pColumn, pColumn->m_fActualSize + fAutoPer, TRUE)) {\r
1233             autoNoMinMaxs.Add(pColumn);\r
1234         } else {\r
1235             fTotalSize -= pColumn->m_fActualSize - fOrgSize;\r
1236             FX_INT32 iNoMinMax = iAutoColRows - (j + 1 - autoNoMinMaxs.GetSize());\r
1237             if (iNoMinMax > 0 && fTotalSize > 0) {\r
1238                 fAutoPer = fTotalSize / iNoMinMax;\r
1239             } else {\r
1240                 break;\r
1241             }\r
1242         }\r
1243     }\r
1244     FX_INT32 iNormals = autoNoMinMaxs.GetSize();\r
1245     if (fTotalSize > 0) {\r
1246         if (iNormals == iAutoColRows) {\r
1247             fAutoPer = fTotalSize / iNormals;\r
1248             for (FX_INT32 k = 0; k < iNormals; k++) {\r
1249                 CFWL_GridColRow *pColumn = (CFWL_GridColRow*)autoNoMinMaxs[k];\r
1250                 pColumn->m_fActualSize += fAutoPer;\r
1251             }\r
1252         } else {\r
1253             SetSpanAutoColRowSize(autoNoMinMaxs, fTotalSize);\r
1254         }\r
1255     } else {\r
1256     }\r
1257 }\r
1258 void CFWL_GridImp::SetSpanScaledColRowSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum)\r
1259 {\r
1260     FX_INT32 iScaledColRows = spanScaleds.GetSize();\r
1261     if (iScaledColRows < 1) {\r
1262         return;\r
1263     }\r
1264     CFX_PtrArray autoNoMinMaxs;\r
1265     FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum;\r
1266     for (FX_INT32 i = 0; i < iScaledColRows; i++) {\r
1267         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)spanScaleds[i];\r
1268         if (SetColRowActualSize(pColRow, pColRow->m_fActualSize + fPerSize * pColRow->m_Size.fLength, TRUE)) {\r
1269             autoNoMinMaxs.Add(pColRow);\r
1270         } else {\r
1271             fTotalSize -= pColRow->m_fActualSize;\r
1272             fTotalScaledNum -= pColRow->m_Size.fLength;\r
1273             FX_INT32 iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize());\r
1274             if (iNoMinMax > 0 && fTotalSize > 0) {\r
1275                 fPerSize = fTotalSize / fTotalScaledNum;\r
1276             } else {\r
1277                 break;\r
1278             }\r
1279         }\r
1280     }\r
1281     FX_INT32 iNormals = autoNoMinMaxs.GetSize();\r
1282     if (fTotalSize > 0) {\r
1283         if (iNormals == iScaledColRows) {\r
1284             fPerSize = fTotalSize / fTotalScaledNum;\r
1285             for (FX_INT32 j = 0; j < iNormals; j++) {\r
1286                 CFWL_GridColRow *pColumn = (CFWL_GridColRow*)autoNoMinMaxs[j];\r
1287                 pColumn->m_fActualSize += fPerSize * pColumn->m_Size.fLength;\r
1288             }\r
1289         } else {\r
1290             SetSpanScaledColRowSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum);\r
1291         }\r
1292     } else {\r
1293     }\r
1294 }\r
1295 void CFWL_GridImp::SetScaledColRowsSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum)\r
1296 {\r
1297     FX_INT32 iScaledColRows = spanScaleds.GetSize();\r
1298     if (iScaledColRows < 1) {\r
1299         return;\r
1300     }\r
1301     CFX_PtrArray autoNoMinMaxs;\r
1302     FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum;\r
1303     for (FX_INT32 i = 0; i < iScaledColRows; i++) {\r
1304         CFWL_GridColRow *pColRow = (CFWL_GridColRow*)spanScaleds[i];\r
1305         if (!pColRow) {\r
1306             continue;\r
1307         }\r
1308         FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength;\r
1309         FX_FLOAT fOrgSize = pColRow->m_fActualSize;\r
1310         if (SetColRowActualSize(pColRow, fSize, TRUE)) {\r
1311             autoNoMinMaxs.Add(pColRow);\r
1312         } else {\r
1313             fTotalSize -= pColRow->m_fActualSize - fOrgSize;\r
1314             fTotalScaledNum -= pColRow->m_Size.fLength;\r
1315             FX_INT32 iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize());\r
1316             if (iNoMinMax > 0 && fTotalSize > 0) {\r
1317                 fPerSize = fTotalSize / fTotalScaledNum;\r
1318             } else {\r
1319                 break;\r
1320             }\r
1321         }\r
1322     }\r
1323     FX_INT32 iNormals = autoNoMinMaxs.GetSize();\r
1324     if (fTotalSize > 0) {\r
1325         if (iNormals == iScaledColRows) {\r
1326             fPerSize = fTotalSize / fTotalScaledNum;\r
1327             for (FX_INT32 i = 0; i < iNormals; i++) {\r
1328                 CFWL_GridColRow *pColRow = (CFWL_GridColRow*)autoNoMinMaxs[i];\r
1329                 if (!pColRow) {\r
1330                     continue;\r
1331                 }\r
1332                 FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength;\r
1333                 pColRow->m_fActualSize = fSize;\r
1334             }\r
1335         } else {\r
1336             SetScaledColRowsSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum);\r
1337         }\r
1338     } else {\r
1339     }\r
1340 }\r
1341 CFWL_GridDelegate::CFWL_GridDelegate(CFWL_GridImp *pOwner)\r
1342     : m_pOwner(pOwner)\r
1343 {\r
1344 }\r
1345 FX_INT32 CFWL_GridDelegate::OnProcessMessage(CFWL_Message *pMessage)\r
1346 {\r
1347     if (pMessage->GetClassID() != FWL_MSGHASH_Mouse) {\r
1348         return 0;\r
1349     }\r
1350     CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;\r
1351     if (pMsg->m_dwCmd != FWL_MSGMOUSECMD_LButtonDown) {\r
1352         return 0;\r
1353     }\r
1354     return 1;\r
1355 }\r
1356 FWL_ERR CFWL_GridDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
1357 {\r
1358     return m_pOwner->DrawWidget(pGraphics, pMatrix);\r
1359 }\r