// 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); | |
} |