예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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();
}
예제 #4
0
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);
  }
}
예제 #5
0
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;
}
예제 #6
0
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();
  }
}
예제 #7
0
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;
}