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