IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent, FX_FLOAT x, FX_FLOAT y) { if (!parent) return nullptr; FX_FLOAT x1; FX_FLOAT y1; IFWL_Widget* child = GetLastChildWidget(parent); while (child) { if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) { x1 = x; y1 = y; CFX_Matrix matrixOnParent; child->GetMatrix(matrixOnParent); CFX_Matrix m; m.SetIdentity(); m.SetReverse(matrixOnParent); m.TransformPoint(x1, y1); CFX_RectF bounds; child->GetWidgetRect(bounds); if (bounds.Contains(x1, y1)) { x1 -= bounds.left; y1 -= bounds.top; return GetWidgetAtPoint(child, x1, y1); } } child = GetPriorSiblingWidget(child); } return parent; }
FWL_Error CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget, const CFX_RectF* pRect) { if (!m_pAdapter) return FWL_Error::Indefinite; IFWL_Widget* pNative = pWidget; CFX_RectF rect(*pRect); if (IsFormDisabled()) { IFWL_Widget* pOuter = pWidget->GetOuter(); while (pOuter) { CFX_RectF rtTemp; pNative->GetWidgetRect(rtTemp); rect.left += rtTemp.left; rect.top += rtTemp.top; pNative = pOuter; pOuter = pOuter->GetOuter(); } } else if (!IsAbleNative(pWidget)) { pNative = GetSystemFormWidget(pWidget); if (!pNative) return FWL_Error::Indefinite; pWidget->TransformTo(pNative, rect.left, rect.top); } AddRedrawCounts(pNative); return m_pAdapter->RepaintWidget(pNative, &rect); }
void IFWL_Widget::GetMatrix(CFX_Matrix& matrix, bool bGlobal) { if (!m_pProperties) return; if (!bGlobal) { matrix.SetIdentity(); return; } IFWL_Widget* parent = GetParent(); CFX_ArrayTemplate<IFWL_Widget*> parents; while (parent) { parents.Add(parent); parent = parent->GetParent(); } matrix.SetIdentity(); CFX_Matrix ctmOnParent; CFX_RectF rect; int32_t count = parents.GetSize(); for (int32_t i = count - 2; i >= 0; i--) { parent = parents.GetAt(i); parent->GetMatrix(ctmOnParent, false); parent->GetWidgetRect(rect); matrix.Concat(ctmOnParent, true); matrix.Translate(rect.left, rect.top, true); } CFX_Matrix m; m.SetIdentity(); matrix.Concat(m, true); parents.RemoveAll(); }
void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent, const CFX_RectF& rtClip, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { if (!parent) return; FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled(); IFWL_Widget* pNextChild = m_pWidgetMgr->GetFirstChildWidget(parent); while (pNextChild) { IFWL_Widget* child = pNextChild; pNextChild = m_pWidgetMgr->GetNextSiblingWidget(child); if (child->GetStates() & FWL_WGTSTATE_Invisible) continue; CFX_RectF rtWidget; child->GetWidgetRect(rtWidget); if (rtWidget.IsEmpty()) continue; CFX_Matrix widgetMatrix; CFX_RectF clipBounds(rtWidget); if (!bFormDisable) child->GetMatrix(widgetMatrix, TRUE); if (pMatrix) widgetMatrix.Concat(*pMatrix); if (!bFormDisable) { widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top); clipBounds.Intersect(rtClip); if (clipBounds.IsEmpty()) continue; pGraphics->SaveGraphState(); pGraphics->SetClipRect(clipBounds); } widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE); IFWL_WidgetDelegate* pDelegate = child->SetDelegate(nullptr); if (pDelegate) { if (m_pWidgetMgr->IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip)) { pDelegate->OnDrawWidget(pGraphics, &widgetMatrix); } } if (!bFormDisable) pGraphics->RestoreGraphState(); DrawChild(child, clipBounds, pGraphics, bFormDisable ? &widgetMatrix : pMatrix); child = m_pWidgetMgr->GetNextSiblingWidget(child); } }
CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) { if (pParent == this) return CFX_SizeF(); CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); if (!pWidgetMgr) return CFX_SizeF(); CFX_SizeF szRet(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top); IFWL_Widget* pDstWidget = GetParent(); while (pDstWidget && pDstWidget != pParent) { CFX_RectF rtDst; pDstWidget->GetWidgetRect(rtDst); szRet += CFX_SizeF(rtDst.left, rtDst.top); pDstWidget = pWidgetMgr->GetParentWidget(pDstWidget); } return szRet; }
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); if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) { SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength); } else { if (bLeftMargin && bRightMargin) { SetWidgetActualWidth(pInfo, fColumnWidth - fLeftMargin - fRightMargin); } 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); } else { if (bTopMargin && bBottomMargin) { SetWidgetActualHeight(pInfo, fRowHeight - fTopMargin - fBottomMargin); } 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_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget* pWidget, CFX_Matrix* pMatrix, const CFX_RectF& rtDirty) { CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); if (pItem && pItem->iRedrawCounter > 0) { pItem->iRedrawCounter = 0; return TRUE; } CFX_RectF rtWidget; pWidget->GetWidgetRect(rtWidget); rtWidget.left = rtWidget.top = 0; pMatrix->TransformRect(rtWidget); if (!rtWidget.IntersectWith(rtDirty)) return FALSE; IFWL_Widget* pChild = CFWL_WidgetMgr::GetInstance()->GetFirstChildWidget(pWidget); if (!pChild) return TRUE; CFX_RectF rtChilds; rtChilds.Empty(); FX_BOOL bChildIntersectWithDirty = FALSE; FX_BOOL bOrginPtIntersectWidthChild = FALSE; FX_BOOL bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.left, rtWidget.top); static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints]; FXSYS_memset(hitPoint, 0, sizeof(hitPoint)); FX_FLOAT fxPiece = rtWidget.width / kNeedRepaintHitPiece; FX_FLOAT fyPiece = rtWidget.height / kNeedRepaintHitPiece; hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left; hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x = hitPoint[10].hitPoint.x = fxPiece + rtWidget.left; hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x = hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left; hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x = rtWidget.width + rtWidget.left; hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top; hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y = hitPoint[5].hitPoint.y = fyPiece + rtWidget.top; hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y = hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top; hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y = rtWidget.height + rtWidget.top; do { CFX_RectF rect; pChild->GetWidgetRect(rect); CFX_RectF r = rect; r.left += rtWidget.left; r.top += rtWidget.top; if (r.IsEmpty()) continue; if (r.Contains(rtDirty)) return FALSE; if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) bChildIntersectWithDirty = TRUE; if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) bOrginPtIntersectWidthChild = rect.Contains(0, 0); if (rtChilds.IsEmpty()) rtChilds = rect; else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) rtChilds.Union(rect); for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) { if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) continue; if (!rtDirty.Contains(hitPoint[i].hitPoint)) { hitPoint[i].bNotContainByDirty = true; continue; } if (r.Contains(hitPoint[i].hitPoint)) hitPoint[i].bNotNeedRepaint = true; } pChild = CFWL_WidgetMgr::GetInstance()->GetNextSiblingWidget(pChild); } while (pChild); if (!bChildIntersectWithDirty) return TRUE; if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) return TRUE; if (rtChilds.IsEmpty()) return TRUE; int32_t repaintPoint = kNeedRepaintHitPoints; for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) { if (hitPoint[i].bNotNeedRepaint) repaintPoint--; } if (repaintPoint > 0) return TRUE; pMatrix->TransformRect(rtChilds); if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) return FALSE; return TRUE; }