| // Copyright 2014 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #include "xfa/src/foxitlib.h" |
| #include "xfa/src/fwl/src/core/include/fwl_targetimp.h" |
| #include "xfa/src/fwl/src/core/include/fwl_threadimp.h" |
| #include "xfa/src/fwl/src/core/include/fwl_noteimp.h" |
| #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h" |
| #include "xfa/src/fwl/src/core/include/fwl_contentimp.h" |
| #include "xfa/src/fwl/src/core/include/fwl_gridimp.h" |
| |
| // static |
| IFWL_Grid* IFWL_Grid::Create(const CFWL_WidgetImpProperties& properties) { |
| IFWL_Grid* pGrid = new IFWL_Grid; |
| CFWL_GridImp* pGridImpl = new CFWL_GridImp(properties, nullptr); |
| pGrid->SetImpl(pGridImpl); |
| pGridImpl->SetInterface(pGrid); |
| return pGrid; |
| } |
| IFWL_Grid::IFWL_Grid() {} |
| FWL_HGRIDCOLROW IFWL_Grid::InsertColRow(FX_BOOL bColumn, int32_t nIndex) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->InsertColRow(bColumn, nIndex); |
| } |
| int32_t IFWL_Grid::CountColRows(FX_BOOL bColumn) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->CountColRows(bColumn); |
| } |
| FWL_HGRIDCOLROW IFWL_Grid::GetColRow(FX_BOOL bColumn, int32_t nIndex) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetColRow(bColumn, nIndex); |
| } |
| int32_t IFWL_Grid::GetIndex(FWL_HGRIDCOLROW hColRow) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetIndex(hColRow); |
| } |
| FX_FLOAT IFWL_Grid::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT& eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetSize(hColRow, eUnit); |
| } |
| FWL_ERR IFWL_Grid::SetSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->SetSize(hColRow, fSize, eUnit); |
| } |
| FX_FLOAT IFWL_Grid::GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT& eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetMinSize(hColRow, eUnit); |
| } |
| FWL_ERR IFWL_Grid::SetMinSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetMinSize(hColRow, fSize, eUnit); |
| } |
| FX_FLOAT IFWL_Grid::GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT& eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetMaxSize(hColRow, eUnit); |
| } |
| FWL_ERR IFWL_Grid::SetMaxSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetMaxSize(hColRow, fSize, eUnit); |
| } |
| FX_BOOL IFWL_Grid::DeleteColRow(FWL_HGRIDCOLROW hColRow) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->DeleteColRow(hColRow); |
| } |
| FX_BOOL IFWL_Grid::IsColumn(FWL_HGRIDCOLROW hColRow) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->IsColumn(hColRow); |
| } |
| int32_t IFWL_Grid::GetWidgetPos(IFWL_Widget* pWidget, FX_BOOL bColumn) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetWidgetPos(pWidget, bColumn); |
| } |
| FWL_ERR IFWL_Grid::SetWidgetPos(IFWL_Widget* pWidget, |
| int32_t iPos, |
| FX_BOOL bColumn) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetWidgetPos(pWidget, iPos, bColumn); |
| } |
| int32_t IFWL_Grid::GetWidgetSpan(IFWL_Widget* pWidget, FX_BOOL bColumn) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetWidgetSpan(pWidget, bColumn); |
| } |
| FWL_ERR IFWL_Grid::SetWidgetSpan(IFWL_Widget* pWidget, |
| int32_t iSpan, |
| FX_BOOL bColumn) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetWidgetSpan(pWidget, iSpan, bColumn); |
| } |
| FX_FLOAT IFWL_Grid::GetWidgetSize(IFWL_Widget* pWidget, |
| FWL_GRIDSIZE eSize, |
| FWL_GRIDUNIT& eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->GetWidgetSize(pWidget, eSize, eUnit); |
| } |
| FWL_ERR IFWL_Grid::SetWidgetSize(IFWL_Widget* pWidget, |
| FWL_GRIDSIZE eSize, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUit) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetWidgetSize(pWidget, eSize, fSize, eUit); |
| } |
| FX_BOOL IFWL_Grid::GetWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin, |
| FX_FLOAT& fMargin) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->GetWidgetMargin(pWidget, eMargin, fMargin); |
| } |
| FWL_ERR IFWL_Grid::SetWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin, |
| FX_FLOAT fMargin) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->SetWidgetMargin(pWidget, eMargin, fMargin); |
| } |
| FWL_ERR IFWL_Grid::RemoveWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin) { |
| return static_cast<CFWL_GridImp*>(GetImpl()) |
| ->RemoveWidgetMargin(pWidget, eMargin); |
| } |
| FX_FLOAT IFWL_Grid::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT& eUnit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->GetGridSize(eSize, eUnit); |
| } |
| FWL_ERR IFWL_Grid::SetGridSize(FWL_GRIDSIZE eSize, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUit) { |
| return static_cast<CFWL_GridImp*>(GetImpl())->SetGridSize(eSize, fSize, eUit); |
| } |
| |
| CFWL_GridImp::CFWL_GridImp(const CFWL_WidgetImpProperties& properties, |
| IFWL_Widget* pOuter) |
| : CFWL_ContentImp(properties, pOuter) { |
| m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto; |
| m_Size[FWL_GRIDSIZE_Width].fLength = 0; |
| m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto; |
| m_Size[FWL_GRIDSIZE_Height].fLength = 0; |
| m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed; |
| m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0; |
| m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity; |
| m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0; |
| m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed; |
| m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0; |
| m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity; |
| m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0; |
| } |
| CFWL_GridImp::~CFWL_GridImp() { |
| int32_t iCount = m_Columns.GetSize(); |
| for (int32_t i = 0; i < iCount; i++) { |
| delete static_cast<CFWL_GridColRow*>(m_Columns[i]); |
| } |
| m_Columns.RemoveAll(); |
| iCount = m_Rows.GetSize(); |
| for (int32_t j = 0; j < iCount; j++) { |
| delete static_cast<CFWL_GridColRow*>(m_Rows[j]); |
| } |
| m_Rows.RemoveAll(); |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget; |
| CFWL_GridWidgetInfo* pInfo; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| delete pInfo; |
| } |
| m_mapWidgetInfo.RemoveAll(); |
| delete m_pDelegate; |
| m_pDelegate = nullptr; |
| } |
| FWL_ERR CFWL_GridImp::GetClassName(CFX_WideString& wsClass) const { |
| wsClass = FWL_CLASS_Grid; |
| return FWL_ERR_Succeeded; |
| } |
| FX_DWORD CFWL_GridImp::GetClassID() const { |
| return FWL_CLASSHASH_Grid; |
| } |
| FWL_ERR CFWL_GridImp::Initialize() { |
| if (CFWL_ContentImp::Initialize() != FWL_ERR_Succeeded) |
| return FWL_ERR_Indefinite; |
| m_pDelegate = new CFWL_GridImpDelegate(this); |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::Finalize() { |
| if (CFWL_ContentImp::Finalize() != FWL_ERR_Succeeded) |
| return FWL_ERR_Indefinite; |
| delete m_pDelegate; |
| m_pDelegate = nullptr; |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) { |
| if (bAutoSize) { |
| rect.left = 0; |
| rect.top = 0; |
| rect.width = ProcessUnCertainColumns(); |
| rect.height = ProcessUnCertainRows(); |
| } else { |
| rect = m_pProperties->m_rtWidget; |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::SetWidgetRect(const CFX_RectF& rect) { |
| CFWL_WidgetImp::SetWidgetRect(rect); |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::Update() { |
| if (IsLocked()) { |
| return FWL_ERR_Indefinite; |
| } |
| ProcessColumns(m_pProperties->m_rtWidget.width); |
| ProcessRows(m_pProperties->m_rtWidget.height); |
| SetAllWidgetsRect(); |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::DrawWidget(CFX_Graphics* pGraphics, |
| const CFX_Matrix* pMatrix) { |
| if (!pGraphics) |
| return FWL_ERR_Indefinite; |
| if ((m_pProperties->m_dwStyleExes & FWL_GRIDSTYLEEXT_ShowGridLines) == 0) { |
| return FWL_ERR_Succeeded; |
| } |
| pGraphics->SaveGraphState(); |
| if (pMatrix) { |
| pGraphics->ConcatMatrix(pMatrix); |
| } |
| { |
| FX_BOOL bDrawLine = FALSE; |
| CFX_Path path; |
| path.Create(); |
| int32_t iColumns = m_Columns.GetSize(); |
| for (int32_t i = 1; i < iColumns; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Columns[i]); |
| if (!pColRow) { |
| continue; |
| } |
| bDrawLine = TRUE; |
| path.AddLine(pColRow->m_fActualPos, 0, pColRow->m_fActualPos, |
| m_pProperties->m_rtWidget.height); |
| } |
| int32_t iRows = m_Rows.GetSize(); |
| for (int32_t j = 1; j < iRows; j++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Rows[j]); |
| if (!pColRow) { |
| continue; |
| } |
| bDrawLine = TRUE; |
| path.AddLine(0, pColRow->m_fActualPos, m_pProperties->m_rtWidget.width, |
| pColRow->m_fActualPos); |
| } |
| if (bDrawLine) { |
| CFX_Color cr(0xFFFF0000); |
| pGraphics->SetStrokeColor(&cr); |
| pGraphics->StrokePath(&path); |
| } |
| } |
| pGraphics->RestoreGraphState(); |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::InsertWidget(IFWL_Widget* pChild, int32_t nIndex) { |
| if (!pChild) |
| return FWL_ERR_Indefinite; |
| CFWL_ContentImp::InsertWidget(pChild, nIndex); |
| if (!m_mapWidgetInfo.GetValueAt(pChild)) { |
| CFWL_GridWidgetInfo* pInfo = new CFWL_GridWidgetInfo; |
| m_mapWidgetInfo.SetAt(pChild, pInfo); |
| m_Widgets.Add(pChild); |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::RemoveWidget(IFWL_Widget* pWidget) { |
| if (!pWidget) |
| return FWL_ERR_Indefinite; |
| CFWL_ContentImp::RemoveWidget(pWidget); |
| if (CFWL_GridWidgetInfo* pInfo = static_cast<CFWL_GridWidgetInfo*>( |
| m_mapWidgetInfo.GetValueAt(pWidget))) { |
| m_mapWidgetInfo.RemoveKey(pWidget); |
| delete pInfo; |
| int32_t nIndex = m_Widgets.Find(pWidget); |
| m_Widgets.RemoveAt(nIndex, 1); |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FWL_HGRIDCOLROW CFWL_GridImp::InsertColRow(FX_BOOL bColumn, int32_t nIndex) { |
| if (bColumn) { |
| if (nIndex < 0 || nIndex > m_Columns.GetSize()) { |
| nIndex = m_Columns.GetSize(); |
| } |
| CFWL_GridColRow* pColumn = new CFWL_GridColRow; |
| m_Columns.InsertAt(nIndex, pColumn, 1); |
| return (FWL_HGRIDCOLROW)pColumn; |
| } |
| if (nIndex < 0 || nIndex > m_Rows.GetSize()) { |
| nIndex = m_Rows.GetSize(); |
| } |
| CFWL_GridColRow* pRow = new CFWL_GridColRow; |
| m_Rows.InsertAt(nIndex, pRow, 1); |
| return (FWL_HGRIDCOLROW)pRow; |
| } |
| int32_t CFWL_GridImp::CountColRows(FX_BOOL bColumn) { |
| if (bColumn) { |
| return m_Columns.GetSize(); |
| } |
| return m_Rows.GetSize(); |
| } |
| FWL_HGRIDCOLROW CFWL_GridImp::GetColRow(FX_BOOL bColumn, int32_t nIndex) { |
| if (bColumn) { |
| if (nIndex < 0 || nIndex >= m_Columns.GetSize()) { |
| return NULL; |
| } |
| return (FWL_HGRIDCOLROW)m_Columns[nIndex]; |
| } |
| if (nIndex < 0 || nIndex >= m_Rows.GetSize()) { |
| return NULL; |
| } |
| return (FWL_HGRIDCOLROW)m_Rows[nIndex]; |
| } |
| int32_t CFWL_GridImp::GetIndex(FWL_HGRIDCOLROW hColRow) { |
| if (IsColumn(hColRow)) { |
| return m_Columns.Find(hColRow); |
| } |
| return m_Rows.Find(hColRow); |
| } |
| FX_FLOAT CFWL_GridImp::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT& eUnit) { |
| if (!hColRow) |
| return -1; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| eUnit = pColRow->m_Size.eUnit; |
| return pColRow->m_Size.fLength; |
| } |
| FWL_ERR CFWL_GridImp::SetSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| if (!hColRow) |
| return FWL_ERR_Indefinite; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| pColRow->m_Size.eUnit = eUnit; |
| pColRow->m_Size.fLength = fSize; |
| return FWL_ERR_Succeeded; |
| } |
| FX_FLOAT CFWL_GridImp::GetMinSize(FWL_HGRIDCOLROW hColRow, |
| FWL_GRIDUNIT& eUnit) { |
| if (!hColRow) |
| return -1; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| eUnit = pColRow->m_MinSize.eUnit; |
| return pColRow->m_MinSize.fLength; |
| } |
| FWL_ERR CFWL_GridImp::SetMinSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| if (!hColRow) |
| return FWL_ERR_Indefinite; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| pColRow->m_MinSize.eUnit = eUnit; |
| pColRow->m_MinSize.fLength = fSize; |
| return FWL_ERR_Succeeded; |
| } |
| FX_FLOAT CFWL_GridImp::GetMaxSize(FWL_HGRIDCOLROW hColRow, |
| FWL_GRIDUNIT& eUnit) { |
| if (!hColRow) |
| return -1; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| eUnit = pColRow->m_MaxSize.eUnit; |
| return pColRow->m_MaxSize.fLength; |
| } |
| FWL_ERR CFWL_GridImp::SetMaxSize(FWL_HGRIDCOLROW hColRow, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUnit) { |
| if (!hColRow) |
| return FWL_ERR_Indefinite; |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| pColRow->m_MaxSize.eUnit = eUnit; |
| pColRow->m_MaxSize.fLength = fSize; |
| return FWL_ERR_Succeeded; |
| } |
| FX_BOOL CFWL_GridImp::DeleteColRow(FWL_HGRIDCOLROW hColRow) { |
| int32_t nIndex = m_Columns.Find(hColRow); |
| if (nIndex >= 0) { |
| m_Columns.RemoveAt(nIndex); |
| delete reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| return TRUE; |
| } |
| nIndex = m_Rows.Find(hColRow); |
| if (nIndex >= 0) { |
| delete reinterpret_cast<CFWL_GridColRow*>(hColRow); |
| m_Rows.RemoveAt(nIndex); |
| return TRUE; |
| } |
| return FALSE; |
| } |
| FX_BOOL CFWL_GridImp::IsColumn(FWL_HGRIDCOLROW hColRow) { |
| return m_Columns.Find(hColRow) != -1; |
| } |
| int32_t CFWL_GridImp::GetWidgetPos(IFWL_Widget* pWidget, FX_BOOL bColumn) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| return bColumn ? pInfo->m_iColumn : pInfo->m_iRow; |
| } |
| return -1; |
| } |
| FWL_ERR CFWL_GridImp::SetWidgetPos(IFWL_Widget* pWidget, |
| int32_t iPos, |
| FX_BOOL bColumn) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| bColumn ? pInfo->m_iColumn = iPos : pInfo->m_iRow = iPos; |
| } |
| return FWL_ERR_Succeeded; |
| } |
| int32_t CFWL_GridImp::GetWidgetSpan(IFWL_Widget* pWidget, FX_BOOL bColumn) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| return bColumn ? pInfo->m_iColumnSpan : pInfo->m_iRowSpan; |
| } |
| return 0; |
| } |
| FWL_ERR CFWL_GridImp::SetWidgetSpan(IFWL_Widget* pWidget, |
| int32_t iSpan, |
| FX_BOOL bColumn) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| bColumn ? pInfo->m_iColumnSpan = iSpan : pInfo->m_iRowSpan = iSpan; |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FX_FLOAT CFWL_GridImp::GetWidgetSize(IFWL_Widget* pWidget, |
| FWL_GRIDSIZE eSize, |
| FWL_GRIDUNIT& eUnit) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| eUnit = pInfo->m_Size[eSize].eUnit; |
| return pInfo->m_Size[eSize].fLength; |
| } |
| return 0; |
| } |
| FWL_ERR CFWL_GridImp::SetWidgetSize(IFWL_Widget* pWidget, |
| FWL_GRIDSIZE eSize, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUit) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| pInfo->m_Size[eSize].fLength = fSize; |
| pInfo->m_Size[eSize].eUnit = eUit; |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FX_BOOL CFWL_GridImp::GetWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin, |
| FX_FLOAT& fMargin) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| fMargin = pInfo->m_Margin[eMargin]; |
| return (pInfo->m_dwMarginFlag & (1 << eMargin)) != 0; |
| } |
| return FALSE; |
| } |
| FWL_ERR CFWL_GridImp::SetWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin, |
| FX_FLOAT fMargin) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| pInfo->m_Margin[eMargin] = fMargin; |
| pInfo->m_dwMarginFlag |= (1 << eMargin); |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FWL_ERR CFWL_GridImp::RemoveWidgetMargin(IFWL_Widget* pWidget, |
| FWL_GRIDMARGIN eMargin) { |
| CFWL_GridWidgetInfo* pInfo = |
| static_cast<CFWL_GridWidgetInfo*>(GetWidgetInfo(pWidget)); |
| if (pInfo) { |
| pInfo->m_dwMarginFlag &= ~(1 << eMargin); |
| } |
| return FWL_ERR_Succeeded; |
| } |
| FX_FLOAT CFWL_GridImp::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT& eUnit) { |
| eUnit = m_Size[eSize].eUnit; |
| return m_Size[eSize].fLength; |
| } |
| FWL_ERR CFWL_GridImp::SetGridSize(FWL_GRIDSIZE eSize, |
| FX_FLOAT fSize, |
| FWL_GRIDUNIT eUit) { |
| m_Size[eSize].fLength = fSize; |
| m_Size[eSize].eUnit = eUit; |
| return FWL_ERR_Succeeded; |
| } |
| CFWL_GridWidgetInfo* CFWL_GridImp::GetWidgetInfo(IFWL_Widget* pWidget) { |
| return static_cast<CFWL_GridWidgetInfo*>(m_mapWidgetInfo.GetValueAt(pWidget)); |
| } |
| void CFWL_GridImp::ProcFixedColRow(CFWL_GridColRow* pColRow, |
| int32_t nIndex, |
| FX_FLOAT fColRowSize, |
| FX_BOOL bColumn) { |
| pColRow->m_fActualSize = fColRowSize; |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| void* key = nullptr; |
| void* value = nullptr; |
| m_mapWidgetInfo.GetNextAssoc(ps, key, value); |
| IFWL_Widget* pWidget = static_cast<IFWL_Widget*>(key); |
| CFWL_GridWidgetInfo* pInfo = static_cast<CFWL_GridWidgetInfo*>(value); |
| if (bColumn) { |
| if (pInfo->m_iColumn == nIndex && pInfo->m_iColumnSpan == 1) { |
| CalcWidgetWidth(pWidget, pInfo, pColRow->m_fActualSize); |
| } |
| } else { |
| if (pInfo->m_iRow == nIndex && pInfo->m_iRowSpan == 1) { |
| CalcWidgetHeigt(pWidget, pInfo, pColRow->m_fActualSize); |
| } |
| } |
| } |
| } |
| void CFWL_GridImp::ProcAutoColRow(CFWL_GridColRow* pColRow, |
| int32_t nIndex, |
| FX_BOOL bColumn) { |
| if (!pColRow) |
| return; |
| FX_FLOAT fMaxSize = 0, fWidgetSize = 0; |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget = NULL; |
| CFWL_GridWidgetInfo* pInfo = NULL; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| if (!pWidget || !pInfo) { |
| continue; |
| } |
| if (bColumn) { |
| if (pInfo->m_iColumn != nIndex || pInfo->m_iColumnSpan != 1) { |
| continue; |
| } |
| fWidgetSize = CalcAutoColumnWidgetWidth(pWidget, pInfo); |
| if (fMaxSize < fWidgetSize) { |
| fMaxSize = fWidgetSize; |
| } |
| } else { |
| if (pInfo->m_iRow != nIndex || pInfo->m_iRowSpan != 1) { |
| continue; |
| } |
| fWidgetSize = CalcAutoColumnWidgetHeight(pWidget, pInfo); |
| if (fMaxSize < fWidgetSize) { |
| fMaxSize = fWidgetSize; |
| } |
| } |
| } |
| SetColRowActualSize(pColRow, fMaxSize); |
| } |
| void CFWL_GridImp::ProcScaledColRow(CFWL_GridColRow* pColRow, |
| int32_t nIndex, |
| FX_FLOAT fColRowSize, |
| FX_BOOL bColumn) { |
| if (fColRowSize > 0) { |
| ProcFixedColRow(pColRow, nIndex, fColRowSize, bColumn); |
| } |
| } |
| void CFWL_GridImp::CalcWidgetWidth(IFWL_Widget* pWidget, |
| CFWL_GridWidgetInfo* pInfo, |
| FX_FLOAT fColunmWidth) { |
| if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength); |
| } else { |
| FX_FLOAT fWidth = 0; |
| FX_FLOAT fLeftMargin = 0, fRightMargin = 0; |
| FX_BOOL bLeftMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin); |
| FX_BOOL bRightMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin); |
| if (bLeftMargin && bRightMargin) { |
| fWidth = fColunmWidth - fLeftMargin - fRightMargin; |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| fWidth = rtAuto.Width(); |
| } |
| SetWidgetActualWidth(pInfo, fWidth); |
| } |
| } |
| void CFWL_GridImp::CalcWidgetHeigt(IFWL_Widget* pWidget, |
| CFWL_GridWidgetInfo* pInfo, |
| FX_FLOAT fRowHeigt) { |
| if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength); |
| } else { |
| FX_FLOAT fHeight = 0; |
| FX_FLOAT fTopMargin = 0, fBottomMargin = 0; |
| FX_BOOL bTopMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin); |
| FX_BOOL bBottomMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin); |
| if (bTopMargin && bBottomMargin) { |
| fHeight = fRowHeigt - fTopMargin - fBottomMargin; |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| fHeight = rtAuto.Height(); |
| } |
| SetWidgetActualHeight(pInfo, fHeight); |
| } |
| } |
| FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetWidth(IFWL_Widget* pWidget, |
| CFWL_GridWidgetInfo* pInfo) { |
| FX_FLOAT fLeftMargin = 0, fRightMargin = 0; |
| FX_BOOL bLeftMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin); |
| FX_BOOL bRightMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin); |
| if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength); |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| FX_FLOAT fWidth = rtAuto.width; |
| SetWidgetActualWidth(pInfo, fWidth); |
| } |
| FX_FLOAT fTotal = pInfo->m_fActualWidth; |
| if (bLeftMargin) { |
| fTotal += fLeftMargin; |
| } |
| if (bRightMargin) { |
| fTotal += fRightMargin; |
| } |
| return fTotal; |
| } |
| FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetHeight(IFWL_Widget* pWidget, |
| CFWL_GridWidgetInfo* pInfo) { |
| FX_FLOAT fTopMargin = 0, fBottomMargin = 0; |
| FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin); |
| FX_BOOL bBottomMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin); |
| if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength); |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| FX_FLOAT fHeight = rtAuto.height; |
| SetWidgetActualHeight(pInfo, fHeight); |
| } |
| FX_FLOAT fTotal = pInfo->m_fActualHeight; |
| if (bTopMargin) { |
| fTotal += fTopMargin; |
| } |
| if (bBottomMargin) { |
| fTotal += fBottomMargin; |
| } |
| return fTotal; |
| } |
| FX_FLOAT CFWL_GridImp::ProcessColumns(FX_FLOAT fWidth) { |
| if (fWidth <= 0) { |
| return ProcessUnCertainColumns(); |
| } |
| int32_t iColumns = m_Columns.GetSize(); |
| if (iColumns < 1) { |
| return fWidth; |
| } |
| FX_FLOAT fFixedWidth = 0; |
| FX_FLOAT fAutoWidth = 0; |
| CFX_PtrArray autoColumns; |
| CFX_PtrArray scaledColumns; |
| FX_FLOAT fScaledColumnNum = 0; |
| for (int32_t i = 0; i < iColumns; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Columns[i]); |
| if (!pColRow) { |
| continue; |
| } |
| switch (pColRow->m_Size.eUnit) { |
| case FWL_GRIDUNIT_Fixed: { |
| SetColRowActualSize(pColRow, pColRow->m_Size.fLength); |
| fFixedWidth += pColRow->m_fActualSize; |
| break; |
| } |
| case FWL_GRIDUNIT_Auto: { |
| ProcAutoColRow(pColRow, i, TRUE); |
| autoColumns.Add(pColRow); |
| break; |
| } |
| case FWL_GRIDUNIT_Scaled: |
| default: { |
| fScaledColumnNum += pColRow->m_Size.fLength; |
| scaledColumns.Add(pColRow); |
| SetColRowActualSize(pColRow, 0); |
| } |
| } |
| } |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget = NULL; |
| CFWL_GridWidgetInfo* pInfo = NULL; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| if (!pInfo || pInfo->m_iColumnSpan < 2) { |
| continue; |
| } |
| CFX_PtrArray spanAutoColumns; |
| FX_FLOAT fSpanSize = 0; |
| int32_t iAutoColRows = 0; |
| int32_t iScaledColRows = 0; |
| for (int32_t i = 0; i < pInfo->m_iColumnSpan; i++) { |
| CFWL_GridColRow* pColumn = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(TRUE, pInfo->m_iColumn + i)); |
| if (!pColumn) { |
| break; |
| } |
| fSpanSize += pColumn->m_fActualSize; |
| if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) { |
| iAutoColRows++; |
| spanAutoColumns.Add(pColumn); |
| } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) { |
| iScaledColRows++; |
| } |
| } |
| if (iAutoColRows < 1) { |
| continue; |
| } |
| FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo); |
| if (fWidgetWidth > fSpanSize) { |
| if (iScaledColRows > 0) { |
| } else { |
| SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize); |
| } |
| } |
| } |
| int32_t iAutoCols = autoColumns.GetSize(); |
| for (int32_t k = 0; k < iAutoCols; k++) { |
| fAutoWidth += static_cast<CFWL_GridColRow*>(autoColumns[k])->m_fActualSize; |
| } |
| FX_FLOAT fScaledWidth = fWidth - fFixedWidth - fAutoWidth; |
| if (fScaledWidth > 0 && fScaledColumnNum > 0) { |
| SetScaledColRowsSize(scaledColumns, fScaledWidth, fScaledColumnNum); |
| } |
| return fWidth; |
| } |
| FX_FLOAT CFWL_GridImp::ProcessRows(FX_FLOAT fHeight) { |
| if (fHeight <= 0) { |
| return ProcessUnCertainRows(); |
| } |
| int32_t iRows = m_Rows.GetSize(); |
| if (iRows < 1) { |
| return fHeight; |
| } |
| FX_FLOAT fFixedHeight = 0; |
| FX_FLOAT fAutoHeigt = 0; |
| CFX_PtrArray autoRows; |
| CFX_PtrArray scaledRows; |
| FX_FLOAT fScaledRowNum = 0; |
| for (int32_t i = 0; i < iRows; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Rows[i]); |
| if (!pColRow) { |
| continue; |
| } |
| switch (pColRow->m_Size.eUnit) { |
| case FWL_GRIDUNIT_Fixed: { |
| SetColRowActualSize(pColRow, pColRow->m_Size.fLength); |
| fFixedHeight += pColRow->m_fActualSize; |
| break; |
| } |
| case FWL_GRIDUNIT_Auto: { |
| ProcAutoColRow(pColRow, i, FALSE); |
| autoRows.Add(pColRow); |
| break; |
| } |
| case FWL_GRIDUNIT_Scaled: |
| default: { |
| fScaledRowNum += pColRow->m_Size.fLength; |
| scaledRows.Add(pColRow); |
| SetColRowActualSize(pColRow, 0); |
| break; |
| } |
| } |
| } |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget = NULL; |
| CFWL_GridWidgetInfo* pInfo = NULL; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| if (!pInfo || pInfo->m_iRowSpan < 2) { |
| continue; |
| } |
| CFX_PtrArray spanAutoRows; |
| FX_FLOAT fSpanSize = 0; |
| int32_t iAutoColRows = 0; |
| int32_t iScaledColRows = 0; |
| for (int32_t i = 0; i < pInfo->m_iRowSpan; i++) { |
| CFWL_GridColRow* pRow = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(FALSE, pInfo->m_iRow + i)); |
| if (!pRow) { |
| break; |
| } |
| fSpanSize += pRow->m_fActualSize; |
| if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) { |
| iAutoColRows++; |
| spanAutoRows.Add(pRow); |
| } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) { |
| iScaledColRows++; |
| } |
| } |
| if (iAutoColRows < 1) { |
| continue; |
| } |
| FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo); |
| if (fWidgetHeight > fSpanSize) { |
| if (iScaledColRows > 0) { |
| } else { |
| SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize); |
| } |
| } |
| } |
| int32_t iAutoRows = autoRows.GetSize(); |
| for (int32_t k = 0; k < iAutoRows; k++) { |
| fAutoHeigt += |
| reinterpret_cast<CFWL_GridColRow*>(autoRows[k])->m_fActualSize; |
| } |
| FX_FLOAT fScaledHeight = fHeight - fFixedHeight - fAutoHeigt; |
| if (fScaledHeight > 0 && fScaledRowNum > 0) { |
| SetScaledColRowsSize(scaledRows, fScaledHeight, fScaledRowNum); |
| } |
| return fHeight; |
| } |
| FX_FLOAT CFWL_GridImp::ProcessUnCertainColumns() { |
| int32_t iColumns = m_Columns.GetSize(); |
| if (iColumns < 1) { |
| CFWL_GridColRow* pColRow = new CFWL_GridColRow; |
| pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto; |
| ProcAutoColRow(pColRow, 0, TRUE); |
| FX_FLOAT fWidth = pColRow->m_fActualSize; |
| delete pColRow; |
| return fWidth; |
| } |
| FX_FLOAT fFixedWidth = 0; |
| CFX_PtrArray autoColumns; |
| CFX_PtrArray scaledColumns; |
| FX_FLOAT fScaledColumnNum = 0; |
| FX_FLOAT fScaledMaxPerWidth = 0; |
| for (int32_t i = 0; i < iColumns; i++) { |
| CFWL_GridColRow* pColRow = reinterpret_cast<CFWL_GridColRow*>(m_Columns[i]); |
| if (!pColRow) { |
| continue; |
| } |
| switch (pColRow->m_Size.eUnit) { |
| case FWL_GRIDUNIT_Fixed: { |
| SetColRowActualSize(pColRow, pColRow->m_Size.fLength); |
| fFixedWidth += pColRow->m_fActualSize; |
| break; |
| } |
| case FWL_GRIDUNIT_Auto: { |
| ProcAutoColRow(pColRow, i, TRUE); |
| autoColumns.Add(pColRow); |
| break; |
| } |
| case FWL_GRIDUNIT_Scaled: |
| default: { |
| ProcAutoColRow(pColRow, i, TRUE); |
| fScaledColumnNum += pColRow->m_Size.fLength; |
| scaledColumns.Add(pColRow); |
| if (pColRow->m_Size.fLength <= 0) { |
| break; |
| } |
| FX_FLOAT fPerWidth = pColRow->m_fActualSize / pColRow->m_Size.fLength; |
| if (fPerWidth > fScaledMaxPerWidth) { |
| fScaledMaxPerWidth = fPerWidth; |
| } |
| } |
| } |
| } |
| iColumns = scaledColumns.GetSize(); |
| for (int32_t j = 0; j < iColumns; j++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(scaledColumns[j]); |
| if (!pColRow) { |
| continue; |
| } |
| SetColRowActualSize(pColRow, fScaledMaxPerWidth * pColRow->m_Size.fLength); |
| } |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget = NULL; |
| CFWL_GridWidgetInfo* pInfo = NULL; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| if (!pInfo || pInfo->m_iColumnSpan < 2) { |
| continue; |
| } |
| CFX_PtrArray spanAutoColumns; |
| CFX_PtrArray spanScaledColumns; |
| FX_FLOAT fSpanSize = 0; |
| FX_FLOAT fScaledSum = 0; |
| int32_t iAutoColRows = 0; |
| int32_t iScaledColRows = 0; |
| for (int32_t i = 0; i < pInfo->m_iColumnSpan; i++) { |
| CFWL_GridColRow* pColumn = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(TRUE, pInfo->m_iColumn + i)); |
| if (!pColumn) { |
| break; |
| } |
| fSpanSize += pColumn->m_fActualSize; |
| if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) { |
| iAutoColRows++; |
| spanAutoColumns.Add(pColumn); |
| } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) { |
| iScaledColRows++; |
| fScaledSum += pColumn->m_Size.fLength; |
| spanScaledColumns.Add(pColumn); |
| } |
| } |
| if (iAutoColRows < 1 && iScaledColRows < 1) { |
| continue; |
| } |
| FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo); |
| if (fWidgetWidth > fSpanSize) { |
| if (iScaledColRows > 0) { |
| if (fScaledSum <= 0) { |
| continue; |
| } |
| SetSpanScaledColRowSize(spanScaledColumns, fWidgetWidth - fSpanSize, |
| fScaledSum); |
| } else { |
| SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize); |
| } |
| } |
| } |
| FX_FLOAT fAutoWidth = 0; |
| int32_t iAutoCols = autoColumns.GetSize(); |
| for (int32_t m = 0; m < iAutoCols; m++) { |
| fAutoWidth += static_cast<CFWL_GridColRow*>(autoColumns[m])->m_fActualSize; |
| } |
| FX_FLOAT fScaledWidth = 0; |
| iColumns = scaledColumns.GetSize(); |
| for (int32_t n = 0; n < iColumns; n++) { |
| fScaledWidth += |
| static_cast<CFWL_GridColRow*>(scaledColumns[n])->m_fActualSize; |
| } |
| return fFixedWidth + fAutoWidth + fScaledWidth; |
| } |
| FX_FLOAT CFWL_GridImp::ProcessUnCertainRows() { |
| int32_t iRows = m_Rows.GetSize(); |
| if (iRows < 1) { |
| CFWL_GridColRow* pColRow = new CFWL_GridColRow; |
| pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto; |
| ProcAutoColRow(pColRow, 0, FALSE); |
| FX_FLOAT fWidth = pColRow->m_fActualSize; |
| delete pColRow; |
| return fWidth; |
| } |
| FX_FLOAT fFixedHeight = 0; |
| CFX_PtrArray autoRows; |
| CFX_PtrArray scaledRows; |
| FX_FLOAT fScaledRowNum = 0; |
| FX_FLOAT fScaledMaxPerHeight = 0; |
| for (int32_t i = 0; i < iRows; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Rows[i]); |
| if (!pColRow) { |
| continue; |
| } |
| switch (pColRow->m_Size.eUnit) { |
| case FWL_GRIDUNIT_Fixed: { |
| SetColRowActualSize(pColRow, pColRow->m_Size.fLength); |
| fFixedHeight += pColRow->m_fActualSize; |
| break; |
| } |
| case FWL_GRIDUNIT_Auto: { |
| ProcAutoColRow(pColRow, i, FALSE); |
| autoRows.Add(pColRow); |
| break; |
| } |
| case FWL_GRIDUNIT_Scaled: |
| default: { |
| ProcAutoColRow(pColRow, i, FALSE); |
| fScaledRowNum += pColRow->m_Size.fLength; |
| scaledRows.Add(pColRow); |
| if (pColRow->m_Size.fLength > 0) { |
| FX_FLOAT fPerHeight = |
| pColRow->m_fActualSize / pColRow->m_Size.fLength; |
| if (fPerHeight > fScaledMaxPerHeight) { |
| fScaledMaxPerHeight = fPerHeight; |
| } |
| } |
| break; |
| } |
| } |
| } |
| iRows = scaledRows.GetSize(); |
| for (int32_t j = 0; j < iRows; j++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(scaledRows[j]); |
| if (!pColRow) { |
| continue; |
| } |
| SetColRowActualSize(pColRow, fScaledMaxPerHeight * pColRow->m_Size.fLength); |
| } |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| void* key = nullptr; |
| void* value = nullptr; |
| m_mapWidgetInfo.GetNextAssoc(ps, key, value); |
| IFWL_Widget* pWidget = static_cast<IFWL_Widget*>(key); |
| CFWL_GridWidgetInfo* pInfo = static_cast<CFWL_GridWidgetInfo*>(value); |
| if (pInfo->m_iRowSpan < 2) { |
| continue; |
| } |
| CFX_PtrArray spanAutoRows; |
| CFX_PtrArray spanScaledRows; |
| FX_FLOAT fSpanSize = 0; |
| FX_FLOAT fScaledSum = 0; |
| int32_t iAutoColRows = 0; |
| int32_t iScaledColRows = 0; |
| for (int32_t i = 0; i < pInfo->m_iRowSpan; i++) { |
| CFWL_GridColRow* pRow = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(FALSE, pInfo->m_iRow + i)); |
| if (!pRow) { |
| break; |
| } |
| fSpanSize += pRow->m_fActualSize; |
| if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) { |
| iAutoColRows++; |
| spanAutoRows.Add(pRow); |
| } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) { |
| iScaledColRows++; |
| fScaledSum += pRow->m_Size.fLength; |
| spanScaledRows.Add(pRow); |
| } |
| } |
| if (iAutoColRows < 1 && iScaledColRows < 1) { |
| continue; |
| } |
| FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo); |
| if (fWidgetHeight > fSpanSize) { |
| if (iScaledColRows > 0) { |
| if (fScaledSum <= 0) { |
| continue; |
| } |
| SetSpanScaledColRowSize(spanScaledRows, fWidgetHeight - fSpanSize, |
| fScaledSum); |
| } else { |
| SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize); |
| } |
| } |
| } |
| FX_FLOAT fAutoHeigt = 0; |
| int32_t iAutoRows = autoRows.GetSize(); |
| for (int32_t m = 0; m < iAutoRows; m++) { |
| fAutoHeigt += static_cast<CFWL_GridColRow*>(autoRows[m])->m_fActualSize; |
| } |
| FX_FLOAT fScaledHeight = 0; |
| iRows = scaledRows.GetSize(); |
| for (int32_t n = 0; n < iRows; n++) { |
| fScaledHeight += |
| static_cast<CFWL_GridColRow*>(scaledRows[n])->m_fActualSize; |
| } |
| return fFixedHeight + fAutoHeigt + fScaledHeight; |
| } |
| FX_BOOL CFWL_GridImp::SetColRowActualSize(CFWL_GridColRow* pColRow, |
| FX_FLOAT fSize, |
| FX_BOOL bSetBeyond) { |
| if (pColRow->m_MinSize.eUnit == FWL_GRIDUNIT_Fixed && |
| fSize < pColRow->m_MinSize.fLength) { |
| pColRow->m_fActualSize = pColRow->m_MinSize.fLength; |
| return FALSE; |
| } |
| if (pColRow->m_MaxSize.eUnit == FWL_GRIDUNIT_Fixed && |
| fSize > pColRow->m_MaxSize.fLength) { |
| pColRow->m_fActualSize = pColRow->m_MaxSize.fLength; |
| return FALSE; |
| } |
| if (bSetBeyond) { |
| return TRUE; |
| } |
| pColRow->m_fActualSize = fSize; |
| return TRUE; |
| } |
| FX_FLOAT CFWL_GridImp::SetWidgetActualWidth(CFWL_GridWidgetInfo* pInfo, |
| FX_FLOAT fWidth) { |
| if (pInfo->m_Size[FWL_GRIDSIZE_MinWidth].eUnit == FWL_GRIDUNIT_Fixed && |
| fWidth < pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength) { |
| fWidth = pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength; |
| } |
| if (pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].eUnit == FWL_GRIDUNIT_Fixed && |
| fWidth > pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength) { |
| fWidth = pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength; |
| } |
| pInfo->m_fActualWidth = fWidth; |
| return fWidth; |
| } |
| FX_FLOAT CFWL_GridImp::SetWidgetActualHeight(CFWL_GridWidgetInfo* pInfo, |
| FX_FLOAT fHeight) { |
| if (pInfo->m_Size[FWL_GRIDSIZE_MinHeight].eUnit == FWL_GRIDUNIT_Fixed && |
| fHeight < pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength) { |
| fHeight = pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength; |
| } |
| if (pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].eUnit == FWL_GRIDUNIT_Fixed && |
| fHeight > pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength) { |
| fHeight = pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength; |
| } |
| pInfo->m_fActualHeight = fHeight; |
| return fHeight; |
| } |
| void CFWL_GridImp::SetAllWidgetsRect() { |
| FX_FLOAT fStartLeft = 0; |
| int32_t iColumns = m_Columns.GetSize(); |
| for (int32_t i = 0; i < iColumns; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Columns[i]); |
| if (!pColRow) { |
| continue; |
| } |
| pColRow->m_fActualPos = fStartLeft; |
| fStartLeft += pColRow->m_fActualSize; |
| } |
| FX_FLOAT fStartTop = 0; |
| int32_t iRows = m_Rows.GetSize(); |
| for (int32_t j = 0; j < iRows; j++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(m_Rows[j]); |
| if (!pColRow) { |
| continue; |
| } |
| pColRow->m_fActualPos = fStartTop; |
| fStartTop += pColRow->m_fActualSize; |
| } |
| FX_POSITION ps = m_mapWidgetInfo.GetStartPosition(); |
| while (ps) { |
| IFWL_Widget* pWidget = NULL; |
| CFWL_GridWidgetInfo* pInfo = NULL; |
| m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo); |
| if (!pWidget || !pInfo) { |
| continue; |
| } |
| FX_FLOAT fColumnStart = 0; |
| CFWL_GridColRow* pColumn = |
| reinterpret_cast<CFWL_GridColRow*>(GetColRow(TRUE, pInfo->m_iColumn)); |
| if (pColumn) { |
| fColumnStart = pColumn->m_fActualPos; |
| } |
| FX_FLOAT fRowStart = 0; |
| CFWL_GridColRow* pRow = |
| reinterpret_cast<CFWL_GridColRow*>(GetColRow(FALSE, pInfo->m_iRow)); |
| if (pRow) { |
| fRowStart = pRow->m_fActualPos; |
| } |
| FX_FLOAT fColumnWidth = 0; |
| if (iColumns > 0) { |
| for (int32_t j = 0; j < pInfo->m_iColumnSpan; j++) { |
| CFWL_GridColRow* pCol = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(TRUE, pInfo->m_iColumn + j)); |
| if (!pCol) { |
| break; |
| } |
| fColumnWidth += pCol->m_fActualSize; |
| } |
| } else { |
| fColumnWidth = m_pProperties->m_rtWidget.width; |
| } |
| FX_FLOAT fRowHeight = 0; |
| if (iRows > 0) { |
| for (int32_t k = 0; k < pInfo->m_iRowSpan; k++) { |
| CFWL_GridColRow* pR = reinterpret_cast<CFWL_GridColRow*>( |
| GetColRow(FALSE, pInfo->m_iRow + k)); |
| if (!pR) { |
| break; |
| } |
| fRowHeight += pR->m_fActualSize; |
| } |
| } else { |
| fRowHeight = m_pProperties->m_rtWidget.height; |
| } |
| FX_FLOAT fLeftMargin = 0, fRightMargin = 0; |
| FX_BOOL bLeftMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin); |
| FX_BOOL bRightMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin); |
| FX_FLOAT fTopMargin = 0, fBottomMargin = 0; |
| FX_BOOL bTopMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin); |
| FX_BOOL bBottomMargin = |
| GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin); |
| FWL_LAYOUTDATA ltd; |
| ltd.fWidth = 0; |
| ltd.fHeight = 0; |
| if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength); |
| ltd.fWidth = pInfo->m_fActualWidth; |
| } else { |
| if (bLeftMargin && bRightMargin) { |
| SetWidgetActualWidth(pInfo, fColumnWidth - fLeftMargin - fRightMargin); |
| ltd.fWidth = pInfo->m_fActualWidth; |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| SetWidgetActualWidth(pInfo, rtAuto.width); |
| } |
| } |
| if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) { |
| SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength); |
| ltd.fHeight = pInfo->m_fActualHeight; |
| } else { |
| if (bTopMargin && bBottomMargin) { |
| SetWidgetActualHeight(pInfo, fRowHeight - fTopMargin - fBottomMargin); |
| ltd.fHeight = pInfo->m_fActualHeight; |
| } else { |
| CFX_RectF rtAuto; |
| pWidget->GetWidgetRect(rtAuto, TRUE); |
| SetWidgetActualHeight(pInfo, rtAuto.height); |
| } |
| } |
| if (bLeftMargin && bRightMargin && |
| pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) { |
| fLeftMargin = |
| fColumnStart + fLeftMargin + |
| (fColumnWidth - fLeftMargin - fRightMargin - pInfo->m_fActualWidth) / |
| 2; |
| } else if (bLeftMargin) { |
| fLeftMargin = fColumnStart + fLeftMargin; |
| } else if (bRightMargin) { |
| fLeftMargin = |
| fColumnStart + fColumnWidth - fRightMargin - pInfo->m_fActualWidth; |
| } else { |
| fLeftMargin = fColumnStart; |
| } |
| if (bTopMargin && bBottomMargin && |
| pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) { |
| fTopMargin = |
| fRowStart + fTopMargin + |
| (fRowHeight - fTopMargin - fBottomMargin - pInfo->m_fActualHeight) / |
| 2; |
| } else if (bTopMargin) { |
| fTopMargin = fRowStart + fTopMargin; |
| } else if (bBottomMargin) { |
| fTopMargin = |
| fRowStart + fRowHeight - fBottomMargin - pInfo->m_fActualHeight; |
| } else { |
| fTopMargin = fRowStart; |
| } |
| CFX_RectF rtWidget, rtOld; |
| rtWidget.Set(fLeftMargin, fTopMargin, pInfo->m_fActualWidth, |
| pInfo->m_fActualHeight); |
| pWidget->GetWidgetRect(rtOld); |
| if (rtWidget == rtOld) { |
| continue; |
| } |
| pWidget->SetWidgetRect(rtWidget); |
| if (rtWidget.width == rtOld.width && rtWidget.height == rtOld.height) { |
| continue; |
| } |
| pWidget->Update(); |
| } |
| } |
| FX_BOOL CFWL_GridImp::IsGrid(IFWL_Widget* pWidget) { |
| if (!pWidget) |
| return FALSE; |
| return pWidget->GetClassID() == FWL_CLASSHASH_Grid; |
| } |
| void CFWL_GridImp::SetSpanAutoColRowSize(const CFX_PtrArray& spanAutos, |
| FX_FLOAT fTotalSize) { |
| int32_t iAutoColRows = spanAutos.GetSize(); |
| if (iAutoColRows < 1) { |
| return; |
| } |
| CFX_PtrArray autoNoMinMaxs; |
| FX_FLOAT fAutoPer = fTotalSize / iAutoColRows; |
| for (int32_t j = 0; j < iAutoColRows; j++) { |
| CFWL_GridColRow* pColumn = static_cast<CFWL_GridColRow*>(spanAutos[j]); |
| FX_FLOAT fOrgSize = pColumn->m_fActualSize; |
| if (SetColRowActualSize(pColumn, pColumn->m_fActualSize + fAutoPer, TRUE)) { |
| autoNoMinMaxs.Add(pColumn); |
| } else { |
| fTotalSize -= pColumn->m_fActualSize - fOrgSize; |
| int32_t iNoMinMax = iAutoColRows - (j + 1 - autoNoMinMaxs.GetSize()); |
| if (iNoMinMax > 0 && fTotalSize > 0) { |
| fAutoPer = fTotalSize / iNoMinMax; |
| } else { |
| break; |
| } |
| } |
| } |
| int32_t iNormals = autoNoMinMaxs.GetSize(); |
| if (fTotalSize > 0) { |
| if (iNormals == iAutoColRows) { |
| fAutoPer = fTotalSize / iNormals; |
| for (int32_t k = 0; k < iNormals; k++) { |
| CFWL_GridColRow* pColumn = |
| static_cast<CFWL_GridColRow*>(autoNoMinMaxs[k]); |
| pColumn->m_fActualSize += fAutoPer; |
| } |
| } else { |
| SetSpanAutoColRowSize(autoNoMinMaxs, fTotalSize); |
| } |
| } else { |
| } |
| } |
| void CFWL_GridImp::SetSpanScaledColRowSize(const CFX_PtrArray& spanScaleds, |
| FX_FLOAT fTotalSize, |
| FX_FLOAT fTotalScaledNum) { |
| int32_t iScaledColRows = spanScaleds.GetSize(); |
| if (iScaledColRows < 1) { |
| return; |
| } |
| CFX_PtrArray autoNoMinMaxs; |
| FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum; |
| for (int32_t i = 0; i < iScaledColRows; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(spanScaleds[i]); |
| if (SetColRowActualSize(pColRow, pColRow->m_fActualSize + |
| fPerSize * pColRow->m_Size.fLength, |
| TRUE)) { |
| autoNoMinMaxs.Add(pColRow); |
| } else { |
| fTotalSize -= pColRow->m_fActualSize; |
| fTotalScaledNum -= pColRow->m_Size.fLength; |
| int32_t iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize()); |
| if (iNoMinMax > 0 && fTotalSize > 0) { |
| fPerSize = fTotalSize / fTotalScaledNum; |
| } else { |
| break; |
| } |
| } |
| } |
| int32_t iNormals = autoNoMinMaxs.GetSize(); |
| if (fTotalSize > 0) { |
| if (iNormals == iScaledColRows) { |
| fPerSize = fTotalSize / fTotalScaledNum; |
| for (int32_t j = 0; j < iNormals; j++) { |
| CFWL_GridColRow* pColumn = |
| static_cast<CFWL_GridColRow*>(autoNoMinMaxs[j]); |
| pColumn->m_fActualSize += fPerSize * pColumn->m_Size.fLength; |
| } |
| } else { |
| SetSpanScaledColRowSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum); |
| } |
| } else { |
| } |
| } |
| void CFWL_GridImp::SetScaledColRowsSize(const CFX_PtrArray& spanScaleds, |
| FX_FLOAT fTotalSize, |
| FX_FLOAT fTotalScaledNum) { |
| int32_t iScaledColRows = spanScaleds.GetSize(); |
| if (iScaledColRows < 1) { |
| return; |
| } |
| CFX_PtrArray autoNoMinMaxs; |
| FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum; |
| for (int32_t i = 0; i < iScaledColRows; i++) { |
| CFWL_GridColRow* pColRow = static_cast<CFWL_GridColRow*>(spanScaleds[i]); |
| if (!pColRow) { |
| continue; |
| } |
| FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength; |
| FX_FLOAT fOrgSize = pColRow->m_fActualSize; |
| if (SetColRowActualSize(pColRow, fSize, TRUE)) { |
| autoNoMinMaxs.Add(pColRow); |
| } else { |
| fTotalSize -= pColRow->m_fActualSize - fOrgSize; |
| fTotalScaledNum -= pColRow->m_Size.fLength; |
| int32_t iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize()); |
| if (iNoMinMax > 0 && fTotalSize > 0) { |
| fPerSize = fTotalSize / fTotalScaledNum; |
| } else { |
| break; |
| } |
| } |
| } |
| int32_t iNormals = autoNoMinMaxs.GetSize(); |
| if (fTotalSize > 0) { |
| if (iNormals == iScaledColRows) { |
| fPerSize = fTotalSize / fTotalScaledNum; |
| for (int32_t i = 0; i < iNormals; i++) { |
| CFWL_GridColRow* pColRow = |
| static_cast<CFWL_GridColRow*>(autoNoMinMaxs[i]); |
| if (!pColRow) { |
| continue; |
| } |
| FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength; |
| pColRow->m_fActualSize = fSize; |
| } |
| } else { |
| SetScaledColRowsSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum); |
| } |
| } else { |
| } |
| } |
| CFWL_GridImpDelegate::CFWL_GridImpDelegate(CFWL_GridImp* pOwner) |
| : m_pOwner(pOwner) { |
| } |
| int32_t CFWL_GridImpDelegate::OnProcessMessage(CFWL_Message* pMessage) { |
| if (pMessage->GetClassID() != FWL_MSGHASH_Mouse) { |
| return 0; |
| } |
| CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); |
| if (pMsg->m_dwCmd != FWL_MSGMOUSECMD_LButtonDown) { |
| return 0; |
| } |
| return 1; |
| } |
| FWL_ERR CFWL_GridImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, |
| const CFX_Matrix* pMatrix) { |
| return m_pOwner->DrawWidget(pGraphics, pMatrix); |
| } |