// 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 <algorithm>

#include "xfa/src/foxitlib.h"
#include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
#include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
#include "xfa/src/fwl/src/core/include/fwl_appimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
FWL_ERR IFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->GetWidgetRect(rect, bAutoSize);
}
FWL_ERR IFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetGlobalRect(rect);
}
FWL_ERR IFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetWidgetRect(rect);
}
FWL_ERR IFWL_Widget::GetClientRect(CFX_RectF& rect) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetClientRect(rect);
}
IFWL_Widget* IFWL_Widget::GetParent() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetParent();
}
FWL_ERR IFWL_Widget::SetParent(IFWL_Widget* pParent) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetParent(pParent);
}
IFWL_Widget* IFWL_Widget::GetOwner() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwner();
}
FWL_ERR IFWL_Widget::SetOwner(IFWL_Widget* pOwner) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetOwner(pOwner);
}
IFWL_Widget* IFWL_Widget::GetOuter() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOuter();
}
FX_DWORD IFWL_Widget::GetStyles() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStyles();
}
FWL_ERR IFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded,
                                  FX_DWORD dwStylesRemoved) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->ModifyStyles(dwStylesAdded, dwStylesRemoved);
}
FX_DWORD IFWL_Widget::GetStylesEx() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStylesEx();
}
FWL_ERR IFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded,
                                    FX_DWORD dwStylesExRemoved) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
}
FX_DWORD IFWL_Widget::GetStates() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStates();
}
FWL_ERR IFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetStates(dwStates, bSet);
}
FWL_ERR IFWL_Widget::SetPrivateData(void* module_id,
                                    void* pData,
                                    PD_CALLBACK_FREEDATA callback) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->SetPrivateData(module_id, pData, callback);
}
void* IFWL_Widget::GetPrivateData(void* module_id) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetPrivateData(module_id);
}
FWL_ERR IFWL_Widget::Update() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->Update();
}
FWL_ERR IFWL_Widget::LockUpdate() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->LockUpdate();
}
FWL_ERR IFWL_Widget::UnlockUpdate() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->UnlockUpdate();
}
FX_DWORD IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->HitTest(fx, fy);
}
FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget,
                                 FX_FLOAT& fx,
                                 FX_FLOAT& fy) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, fx, fy);
}
FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, rt);
}
FWL_ERR IFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetMatrix(matrix, bGlobal);
}
FWL_ERR IFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetMatrix(matrix);
}
FWL_ERR IFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
                                const CFX_Matrix* pMatrix) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->DrawWidget(pGraphics, pMatrix);
}
IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetThemeProvider();
}
FWL_ERR IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->SetThemeProvider(pThemeProvider);
}
FWL_ERR IFWL_Widget::SetDataProvider(IFWL_DataProvider* pDataProvider) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())
      ->SetDataProvider(pDataProvider);
}
IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->SetDelegate(pDelegate);
}
IFWL_NoteThread* IFWL_Widget::GetOwnerThread() const {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwnerThread();
}
CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) {
  return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOffsetFromParent(pParent);
}
FWL_ERR CFWL_WidgetImp::Initialize() {
  IFWL_App* pApp = FWL_GetApp();
  if (!pApp)
    return FWL_ERR_Indefinite;
  IFWL_AdapterNative* pAdapter = pApp->GetAdapterNative();
  if (!pAdapter)
    return FWL_ERR_Indefinite;
  IFWL_AdapterThreadMgr* pAdapterThread = pAdapter->GetThreadMgr();
  if (!pAdapterThread)
    return FWL_ERR_Indefinite;
  SetOwnerThread(static_cast<CFWL_NoteThreadImp*>(
      pAdapterThread->GetCurrentThread()->GetImpl()));
  IFWL_Widget* pParent = m_pProperties->m_pParent;
  m_pWidgetMgr->InsertWidget(pParent, m_pInterface);
  if (!IsChild()) {
    {
      IFWL_Widget* pOwner = m_pProperties->m_pOwner;
      if (pOwner) {
        m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
      }
    }
    m_pWidgetMgr->CreateWidget_Native(m_pInterface);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::Finalize() {
  NotifyDriver();
  IFWL_Form* pForm = static_cast<IFWL_Form*>(
      FWL_GetWidgetMgr()->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm));
  if (pForm && pForm != m_pInterface) {
    IFWL_Content* pContent = pForm->GetContent();
    if (pContent) {
      pContent->RemoveWidget(m_pInterface);
    }
  }
  if (!IsChild()) {
    m_pWidgetMgr->DestroyWidget_Native(m_pInterface);
  }
  m_pWidgetMgr->RemoveWidget(m_pInterface);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
  if (bAutoSize) {
    if (HasEdge()) {
      FX_FLOAT fEdge = GetEdgeWidth();
      rect.Inflate(fEdge, fEdge);
    }
    if (HasBorder()) {
      FX_FLOAT fBorder = GetBorderSize();
      rect.Inflate(fBorder, fBorder);
    }
  } else {
    rect = m_pProperties->m_rtWidget;
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::GetGlobalRect(CFX_RectF& rect) {
  IFWL_Widget* pForm =
      m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
  if (!pForm)
    return FWL_ERR_Indefinite;
  rect.Set(0, 0, m_pProperties->m_rtWidget.width,
           m_pProperties->m_rtWidget.height);
  if (pForm == m_pInterface) {
    return FWL_ERR_Succeeded;
  }
  return TransformTo(pForm, rect);
}
FWL_ERR CFWL_WidgetImp::SetWidgetRect(const CFX_RectF& rect) {
  CFX_RectF rtOld = m_pProperties->m_rtWidget;
  m_pProperties->m_rtWidget = rect;
  if (IsChild()) {
    if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f ||
        FXSYS_fabs(rtOld.height - rect.height) > 0.5f) {
      CFWL_EvtSizeChanged ev;
      ev.m_pSrcTarget = m_pInterface;
      ev.m_rtOld = rtOld;
      ev.m_rtNew = rect;
      IFWL_WidgetDelegate* pDelegate = SetDelegate(NULL);
      if (pDelegate) {
        pDelegate->OnProcessEvent(&ev);
      }
    }
    return FWL_ERR_Succeeded;
  }
  m_pWidgetMgr->SetWidgetRect_Native(m_pInterface, rect);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::GetClientRect(CFX_RectF& rect) {
  GetEdgeRect(rect);
  if (HasEdge()) {
    FX_FLOAT fEdge = GetEdgeWidth();
    rect.Deflate(fEdge, fEdge);
  }
  return FWL_ERR_Succeeded;
}
IFWL_Widget* CFWL_WidgetImp::GetParent() {
  return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Parent);
}
FWL_ERR CFWL_WidgetImp::SetParent(IFWL_Widget* pParent) {
  m_pProperties->m_pParent = pParent;
  m_pWidgetMgr->SetParent(pParent, m_pInterface);
  return FWL_ERR_Succeeded;
}
IFWL_Widget* CFWL_WidgetImp::GetOwner() {
  return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Owner);
}
FWL_ERR CFWL_WidgetImp::SetOwner(IFWL_Widget* pOwner) {
  m_pProperties->m_pOwner = pOwner;
  m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
  return FWL_ERR_Succeeded;
}
IFWL_Widget* CFWL_WidgetImp::GetOuter() {
  return m_pOuter;
}
FX_DWORD CFWL_WidgetImp::GetStyles() {
  return m_pProperties->m_dwStyles;
}
FWL_ERR CFWL_WidgetImp::ModifyStyles(FX_DWORD dwStylesAdded,
                                     FX_DWORD dwStylesRemoved) {
  m_pProperties->m_dwStyles =
      (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_WidgetImp::GetStylesEx() {
  return m_pProperties->m_dwStyleExes;
}
FWL_ERR CFWL_WidgetImp::ModifyStylesEx(FX_DWORD dwStylesExAdded,
                                       FX_DWORD dwStylesExRemoved) {
  m_pProperties->m_dwStyleExes =
      (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_WidgetImp::GetStates() {
  return m_pProperties->m_dwStates;
}
static void NotifyHideChildWidget(IFWL_WidgetMgr* widgetMgr,
                                  IFWL_Widget* widget,
                                  CFWL_NoteDriver* noteDriver) {
  IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
  while (child) {
    noteDriver->NotifyTargetHide(child);
    NotifyHideChildWidget(widgetMgr, child, noteDriver);
    child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
}
FWL_ERR CFWL_WidgetImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
  bSet ? (m_pProperties->m_dwStates |= dwStates)
       : (m_pProperties->m_dwStates &= ~dwStates);
  FWL_ERR ret = FWL_ERR_Succeeded;
  if (dwStates & FWL_WGTSTATE_Invisible) {
    if (bSet) {
      ret = m_pWidgetMgr->HideWidget_Native(m_pInterface);
      CFWL_NoteDriver* noteDriver =
          static_cast<CFWL_NoteDriver*>(GetOwnerThread()->GetNoteDriver());
      IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
      noteDriver->NotifyTargetHide(m_pInterface);
      IFWL_Widget* child =
          widgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_FirstChild);
      while (child) {
        noteDriver->NotifyTargetHide(child);
        NotifyHideChildWidget(widgetMgr, child, noteDriver);
        child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
      }
    } else {
      ret = m_pWidgetMgr->ShowWidget_Native(m_pInterface);
    }
  }
  return ret;
}
FWL_ERR CFWL_WidgetImp::SetPrivateData(void* module_id,
                                       void* pData,
                                       PD_CALLBACK_FREEDATA callback) {
  if (!m_pPrivateData) {
    m_pPrivateData = new CFX_PrivateData;
  }
  m_pPrivateData->SetPrivateData(module_id, pData, callback);
  return FWL_ERR_Succeeded;
}
void* CFWL_WidgetImp::GetPrivateData(void* module_id) {
  if (!m_pPrivateData)
    return NULL;
  return m_pPrivateData->GetPrivateData(module_id);
}
FWL_ERR CFWL_WidgetImp::Update() {
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::LockUpdate() {
  m_iLock++;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::UnlockUpdate() {
  if (IsLocked()) {
    m_iLock--;
  }
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
  CFX_RectF rtClient;
  GetClientRect(rtClient);
  if (rtClient.Contains(fx, fy)) {
    return FWL_WGTHITTEST_Client;
  }
  if (HasEdge()) {
    CFX_RectF rtEdge;
    GetEdgeRect(rtEdge);
    if (rtEdge.Contains(fx, fy)) {
      return FWL_WGTHITTEST_Edge;
    }
  }
  if (HasBorder()) {
    CFX_RectF rtRelative;
    GetRelativeRect(rtRelative);
    if (rtRelative.Contains(fx, fy)) {
      return FWL_WGTHITTEST_Border;
    }
  }
  return FWL_WGTHITTEST_Unknown;
}
FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
                                    FX_FLOAT& fx,
                                    FX_FLOAT& fy) {
  if (m_pWidgetMgr->IsFormDisabled()) {
    CFX_SizeF szOffset;
    if (IsParent(pWidget)) {
      szOffset = GetOffsetFromParent(pWidget);
    } else {
      szOffset = pWidget->GetOffsetFromParent(m_pInterface);
      szOffset.x = -szOffset.x;
      szOffset.y = -szOffset.y;
    }
    fx += szOffset.x;
    fy += szOffset.y;
    return FWL_ERR_Succeeded;
  }
  CFX_RectF r;
  CFX_Matrix m;
  IFWL_Widget* parent = GetParent();
  if (parent) {
    GetWidgetRect(r);
    fx += r.left;
    fy += r.top;
    GetMatrix(m, TRUE);
    m.TransformPoint(fx, fy);
  }
  IFWL_Widget* form1 =
      m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
  if (!form1)
    return FWL_ERR_Indefinite;
  if (!pWidget) {
    form1->GetWidgetRect(r);
    fx += r.left;
    fy += r.top;
#ifdef FWL_UseMacSystemBorder
    if (form1->GetStyles() & FWL_WGTSTYLE_Caption) {
      FX_FLOAT l, t, r, b;
      l = t = r = b = 0;
      FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
      fy += t;
    }
#endif
    return FWL_ERR_Succeeded;
  }
  IFWL_Widget* form2 =
      m_pWidgetMgr->GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
  if (!form2)
    return FWL_ERR_Indefinite;
  if (form1 != form2) {
    form1->GetWidgetRect(r);
    fx += r.left;
    fy += r.top;
    form2->GetWidgetRect(r);
    fx -= r.left;
    fy -= r.top;
#ifdef FWL_UseMacSystemBorder
    if ((form1->GetStyles() & FWL_WGTSTYLE_Caption) !=
        (form2->GetStyles() & FWL_WGTSTYLE_Caption)) {
      FX_FLOAT l, t, r, b;
      l = t = r = b = 0;
      FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
      (form1->GetStyles() & FWL_WGTSTYLE_Caption) ? (fy += t) : (fy -= t);
    }
#endif
  }
  parent = pWidget->GetParent();
  if (parent) {
    pWidget->GetMatrix(m, TRUE);
    CFX_Matrix m1;
    m1.SetIdentity();
    m1.SetReverse(m);
    m1.TransformPoint(fx, fy);
    pWidget->GetWidgetRect(r);
    fx -= r.left;
    fy -= r.top;
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
  return TransformTo(pWidget, rt.left, rt.top);
}
FWL_ERR CFWL_WidgetImp::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
  if (!m_pProperties)
    return FWL_ERR_Indefinite;
  if (bGlobal) {
    IFWL_Widget* parent = GetParent();
    CFX_PtrArray 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 = static_cast<IFWL_Widget*>(parents.GetAt(i));
      parent->GetMatrix(ctmOnParent, FALSE);
      parent->GetWidgetRect(rect);
      matrix.Concat(ctmOnParent, TRUE);
      matrix.Translate(rect.left, rect.top, TRUE);
    }
    matrix.Concat(m_pProperties->m_ctmOnParent, TRUE);
    parents.RemoveAll();
  } else {
    matrix = m_pProperties->m_ctmOnParent;
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::SetMatrix(const CFX_Matrix& matrix) {
  if (!m_pProperties)
    return FWL_ERR_Indefinite;
  IFWL_Widget* parent = GetParent();
  if (!parent) {
    return FWL_ERR_Indefinite;
  }
  m_pProperties->m_ctmOnParent = matrix;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::DrawWidget(CFX_Graphics* pGraphics,
                                   const CFX_Matrix* pMatrix) {
  return FWL_ERR_Indefinite;
}
IFWL_ThemeProvider* CFWL_WidgetImp::GetThemeProvider() {
  return m_pProperties->m_pThemeProvider;
}
FWL_ERR CFWL_WidgetImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
  m_pProperties->m_pThemeProvider = pThemeProvider;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImp::SetDataProvider(IFWL_DataProvider* pDataProvider) {
  m_pProperties->m_pDataProvider = pDataProvider;
  return FWL_ERR_Succeeded;
}
IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(
    IFWL_WidgetDelegate* pDelegate) {
  if (!m_pCurDelegate) {
    m_pCurDelegate = m_pDelegate;
  }
  if (!pDelegate) {
    return m_pCurDelegate;
  }
  IFWL_WidgetDelegate* pOldDelegate = m_pCurDelegate;
  m_pCurDelegate = pDelegate;
  return pOldDelegate;
}
IFWL_NoteThread* CFWL_WidgetImp::GetOwnerThread() const {
  return static_cast<IFWL_NoteThread*>(m_pOwnerThread->GetInterface());
}
FWL_ERR CFWL_WidgetImp::SetOwnerThread(CFWL_NoteThreadImp* pOwnerThread) {
  m_pOwnerThread = pOwnerThread;
  return FWL_ERR_Succeeded;
}
IFWL_Widget* CFWL_WidgetImp::GetInterface() const {
  return m_pInterface;
}
void CFWL_WidgetImp::SetInterface(IFWL_Widget* pInterface) {
  m_pInterface = pInterface;
}
CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
                               IFWL_Widget* pOuter)
    : m_pProperties(new CFWL_WidgetImpProperties),
      m_pPrivateData(NULL),
      m_pDelegate(NULL),
      m_pCurDelegate(NULL),
      m_pOuter(pOuter),
      m_pInterface(NULL),
      m_iLock(0) {
  *m_pProperties = properties;
  m_pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
  FXSYS_assert(m_pWidgetMgr != NULL);
}
CFWL_WidgetImp::~CFWL_WidgetImp() {
  if (m_pPrivateData) {
    delete m_pPrivateData;
    m_pPrivateData = NULL;
  }
  if (m_pProperties) {
    delete m_pProperties;
    m_pProperties = NULL;
  }
}
FX_BOOL CFWL_WidgetImp::IsEnabled() const {
  return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
}
FX_BOOL CFWL_WidgetImp::IsVisible() const {
  return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
}
FX_BOOL CFWL_WidgetImp::IsActive() const {
  return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0;
}
FX_BOOL CFWL_WidgetImp::IsOverLapper() const {
  return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
         FWL_WGTSTYLE_OverLapper;
}
FX_BOOL CFWL_WidgetImp::IsPopup() const {
  return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
}
FX_BOOL CFWL_WidgetImp::IsChild() const {
  return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
}
FX_BOOL CFWL_WidgetImp::IsLocked() const {
  return m_iLock > 0;
}
FX_BOOL CFWL_WidgetImp::IsOffscreen() const {
  return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen);
}
FX_BOOL CFWL_WidgetImp::HasBorder() const {
  return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
}
FX_BOOL CFWL_WidgetImp::HasEdge() const {
  return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask);
}
void CFWL_WidgetImp::GetEdgeRect(CFX_RectF& rtEdge) {
  rtEdge = m_pProperties->m_rtWidget;
  rtEdge.left = rtEdge.top = 0;
  if (HasBorder()) {
    FX_FLOAT fCX = GetBorderSize();
    FX_FLOAT fCY = GetBorderSize(FALSE);
    rtEdge.Deflate(fCX, fCY);
  }
}
FX_FLOAT CFWL_WidgetImp::GetBorderSize(FX_BOOL bCX) {
  FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity(
      bCX ? FWL_WGTCAPACITY_CXBorder : FWL_WGTCAPACITY_CYBorder));
  if (!pfBorder)
    return 0;
  return *pfBorder;
}
FX_FLOAT CFWL_WidgetImp::GetEdgeWidth() {
  FX_DWORD dwCapacity = 0;
  switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) {
    case FWL_WGTSTYLE_EdgeFlat: {
      dwCapacity = FWL_WGTCAPACITY_EdgeFlat;
      break;
    }
    case FWL_WGTSTYLE_EdgeRaised: {
      dwCapacity = FWL_WGTCAPACITY_EdgeRaised;
      break;
    }
    case FWL_WGTSTYLE_EdgeSunken: {
      dwCapacity = FWL_WGTCAPACITY_EdgeSunken;
      break;
    }
  }
  if (dwCapacity > 0) {
    FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity));
    return fRet ? *fRet : 0;
  }
  return 0;
}
void CFWL_WidgetImp::GetRelativeRect(CFX_RectF& rect) {
  rect = m_pProperties->m_rtWidget;
  rect.left = rect.top = 0;
}
void* CFWL_WidgetImp::GetThemeCapacity(FX_DWORD dwCapacity) {
  IFWL_ThemeProvider* pTheme = GetAvailableTheme();
  if (!pTheme)
    return NULL;
  CFWL_ThemePart part;
  part.m_pWidget = m_pInterface;
  return pTheme->GetCapacity(&part, dwCapacity);
}
IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme() {
  if (m_pProperties->m_pThemeProvider) {
    return m_pProperties->m_pThemeProvider;
  }
  IFWL_Widget* pUp = m_pInterface;
  do {
    FWL_WGTRELATION relation = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
                                   ? FWL_WGTRELATION_Owner
                                   : FWL_WGTRELATION_Parent;
    pUp = m_pWidgetMgr->GetWidget(pUp, relation);
    if (pUp) {
      IFWL_ThemeProvider* pRet = pUp->GetThemeProvider();
      if (pRet && pRet->IsValidWidget(m_pInterface)) {
        return pRet;
      }
    }
  } while (pUp);
  return FWL_GetApp()->GetThemeProvider();
}
CFWL_WidgetImp* CFWL_WidgetImp::GetRootOuter() {
  IFWL_Widget* pRet = m_pOuter;
  if (!pRet)
    return nullptr;
  while (IFWL_Widget* pOuter = pRet->GetOuter()) {
    pRet = pOuter;
  }
  return static_cast<CFWL_WidgetImp*>(pRet->GetImpl());
}
#define FWL_WGT_CalcHeight 2048
#define FWL_WGT_CalcWidth 2048
#define FWL_WGT_CalcMultiLineDefWidth 120.0f
CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString& wsText,
                                       IFWL_ThemeProvider* pTheme,
                                       FX_BOOL bMultiLine,
                                       int32_t iLineWidth) {
  CFX_SizeF sz;
  sz.Set(0, 0);
  if (!pTheme)
    return sz;
  CFWL_ThemeText calPart;
  calPart.m_pWidget = m_pInterface;
  calPart.m_wsText = wsText;
  calPart.m_dwTTOStyles =
      bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
  calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
  CFX_RectF rect;
  FX_FLOAT fWidth = bMultiLine
                        ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth
                                          : FWL_WGT_CalcMultiLineDefWidth)
                        : FWL_WGT_CalcWidth;
  rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
  pTheme->CalcTextRect(&calPart, rect);
  sz.x = rect.width;
  sz.y = rect.height;
  return sz;
}
void CFWL_WidgetImp::CalcTextRect(const CFX_WideString& wsText,
                                  IFWL_ThemeProvider* pTheme,
                                  FX_DWORD dwTTOStyles,
                                  int32_t iTTOAlign,
                                  CFX_RectF& rect) {
  CFWL_ThemeText calPart;
  calPart.m_pWidget = m_pInterface;
  calPart.m_wsText = wsText;
  calPart.m_dwTTOStyles = dwTTOStyles;
  calPart.m_iTTOAlign = iTTOAlign;
  pTheme->CalcTextRect(&calPart, rect);
}
void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus) {
  if (m_pWidgetMgr->IsFormDisabled())
    return;
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  CFWL_NoteDriver* pDriver =
      static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
  if (!pDriver)
    return;
  IFWL_Widget* curFocus = pDriver->GetFocus();
  if (bFocus && curFocus != m_pInterface) {
    pDriver->SetFocus(m_pInterface);
  } else if (!bFocus && curFocus == m_pInterface) {
    pDriver->SetFocus(NULL);
  }
}
void CFWL_WidgetImp::SetGrab(FX_BOOL bSet) {
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  CFWL_NoteDriver* pDriver =
      static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
  pDriver->SetGrab(m_pInterface, bSet);
}
FX_BOOL CFWL_WidgetImp::GetPopupPos(FX_FLOAT fMinHeight,
                                    FX_FLOAT fMaxHeight,
                                    const CFX_RectF& rtAnchor,
                                    CFX_RectF& rtPopup) {
  if (GetClassID() == FWL_CLASSHASH_Menu) {
    return GetPopupPosMenu(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
  } else {
    if (GetClassID() == FWL_CLASSHASH_ComboBox) {
      if (m_pWidgetMgr->IsFormDisabled()) {
        return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
                                                fMaxHeight, rtAnchor, rtPopup);
      } else {
        return GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
      }
    } else if (GetClassID() == FWL_CLASSHASH_DateTimePicker &&
               m_pWidgetMgr->IsFormDisabled()) {
      return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
                                              fMaxHeight, rtAnchor, rtPopup);
    } else {
      return GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
    }
  }
  return FALSE;
}
FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight,
                                        FX_FLOAT fMaxHeight,
                                        const CFX_RectF& rtAnchor,
                                        CFX_RectF& rtPopup) {
  FX_FLOAT fx = 0;
  FX_FLOAT fy = 0;
  FX_FLOAT fScreenWidth = 0;
  FX_FLOAT fScreenHeight = 0;
  GetScreenSize(fScreenWidth, fScreenHeight);
  if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
    FX_BOOL bLeft = m_pProperties->m_rtWidget.left < 0;
    FX_FLOAT fRight = rtAnchor.right() + rtPopup.width;
    TransformTo(NULL, fx, fy);
    if (fRight + fx > fScreenWidth || bLeft) {
      rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width,
                  rtPopup.height);
    } else {
      rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width,
                  rtPopup.height);
    }
  } else {
    FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height;
    TransformTo(NULL, fx, fy);
    if (fBottom + fy > fScreenHeight) {
      rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
                  rtPopup.height);
    } else {
      rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
                  rtPopup.height);
    }
  }
  rtPopup.Offset(fx, fy);
  return TRUE;
}
FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight,
                                            FX_FLOAT fMaxHeight,
                                            const CFX_RectF& rtAnchor,
                                            CFX_RectF& rtPopup) {
  FX_FLOAT fx = 0;
  FX_FLOAT fy = 0;
  FX_FLOAT fScreenWidth = 0;
  FX_FLOAT fScreenHeight = 0;
  GetScreenSize(fScreenWidth, fScreenHeight);
  FX_FLOAT fPopHeight = rtPopup.height;
  if (rtPopup.height > fMaxHeight) {
    fPopHeight = fMaxHeight;
  } else if (rtPopup.height < fMinHeight) {
    fPopHeight = fMinHeight;
  }
  FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width);
  FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight;
  TransformTo(NULL, fx, fy);
  if (fBottom + fy > fScreenHeight) {
    rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
  } else {
    rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
  }
  rtPopup.Offset(fx, fy);
  return TRUE;
}
FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight,
                                           FX_FLOAT fMaxHeight,
                                           const CFX_RectF& rtAnchor,
                                           CFX_RectF& rtPopup) {
  FX_FLOAT fx = 0;
  FX_FLOAT fy = 0;
  FX_FLOAT fScreenWidth = 0;
  FX_FLOAT fScreenHeight = 0;
  GetScreenSize(fScreenWidth, fScreenHeight);
  TransformTo(NULL, fx, fy);
  if (rtAnchor.bottom() + fy > fScreenHeight) {
    rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
                rtPopup.height);
  } else {
    rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
                rtPopup.height);
  }
  rtPopup.Offset(fx, fy);
  return TRUE;
}
FX_BOOL CFWL_WidgetImp::GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy) {
  IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
  IFWL_AdapterMonitorMgr* pMonitorMgr = pNative->GetMonitorMgr();
  if (!pMonitorMgr)
    return FALSE;
  FWL_HMONITOR hMonitor = pMonitorMgr->GetMonitorByPoint(fx, fy);
  pMonitorMgr->GetMonitorSize(hMonitor, fx, fy);
  return TRUE;
}
void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget* pEventSource,
                                         FX_DWORD dwFilter) {
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
  if (!pNoteDriver)
    return;
  pNoteDriver->RegisterEventTarget(m_pInterface, pEventSource, dwFilter);
}
void CFWL_WidgetImp::UnregisterEventTarget() {
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
  if (!pNoteDriver)
    return;
  pNoteDriver->UnregisterEventTarget(m_pInterface);
}
void CFWL_WidgetImp::DispatchKeyEvent(CFWL_MsgKey* pNote) {
  if (!pNote)
    return;
  CFWL_EvtKey* pEvent = new CFWL_EvtKey;
  pEvent->m_pSrcTarget = m_pInterface;
  pEvent->m_dwCmd = pNote->m_dwCmd;
  pEvent->m_dwKeyCode = pNote->m_dwKeyCode;
  pEvent->m_dwFlags = pNote->m_dwFlags;
  DispatchEvent(pEvent);
  pEvent->Release();
}
void CFWL_WidgetImp::DispatchEvent(CFWL_Event* pEvent) {
  if (m_pOuter) {
    IFWL_WidgetDelegate* pDelegate = m_pOuter->SetDelegate(NULL);
    pDelegate->OnProcessEvent(pEvent);
    return;
  }
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
  if (!pNoteDriver)
    return;
  pNoteDriver->SendNote(pEvent);
}
void CFWL_WidgetImp::Repaint(const CFX_RectF* pRect) {
  if (pRect) {
    m_pWidgetMgr->RepaintWidget(m_pInterface, pRect);
    return;
  }
  CFX_RectF rect;
  rect = m_pProperties->m_rtWidget;
  rect.left = rect.top = 0;
  m_pWidgetMgr->RepaintWidget(m_pInterface, &rect);
}
void CFWL_WidgetImp::DrawBackground(CFX_Graphics* pGraphics,
                                    int32_t iPartBk,
                                    IFWL_ThemeProvider* pTheme,
                                    const CFX_Matrix* pMatrix) {
  CFX_RectF rtRelative;
  GetRelativeRect(rtRelative);
  CFWL_ThemeBackground param;
  param.m_pWidget = m_pInterface;
  param.m_iPart = iPartBk;
  param.m_pGraphics = pGraphics;
  if (pMatrix) {
    param.m_matrix.Concat(*pMatrix, TRUE);
  }
  param.m_rtPart = rtRelative;
  pTheme->DrawBackground(&param);
}
void CFWL_WidgetImp::DrawBorder(CFX_Graphics* pGraphics,
                                int32_t iPartBorder,
                                IFWL_ThemeProvider* pTheme,
                                const CFX_Matrix* pMatrix) {
  CFX_RectF rtRelative;
  GetRelativeRect(rtRelative);
  CFWL_ThemeBackground param;
  param.m_pWidget = m_pInterface;
  param.m_iPart = iPartBorder;
  param.m_pGraphics = pGraphics;
  if (pMatrix) {
    param.m_matrix.Concat(*pMatrix, TRUE);
  }
  param.m_rtPart = rtRelative;
  pTheme->DrawBackground(&param);
}
void CFWL_WidgetImp::DrawEdge(CFX_Graphics* pGraphics,
                              int32_t iPartEdge,
                              IFWL_ThemeProvider* pTheme,
                              const CFX_Matrix* pMatrix) {
  CFX_RectF rtEdge;
  GetEdgeRect(rtEdge);
  CFWL_ThemeBackground param;
  param.m_pWidget = m_pInterface;
  param.m_iPart = iPartEdge;
  param.m_pGraphics = pGraphics;
  if (pMatrix) {
    param.m_matrix.Concat(*pMatrix, TRUE);
  }
  param.m_rtPart = rtEdge;
  pTheme->DrawBackground(&param);
}
void CFWL_WidgetImp::NotifyDriver() {
  IFWL_NoteThread* pThread = GetOwnerThread();
  if (!pThread)
    return;
  CFWL_NoteDriver* pDriver =
      static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
  if (!pDriver)
    return;
  pDriver->NotifyTargetDestroy(m_pInterface);
}
CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget* pParent) {
  CFX_SizeF szRet;
  szRet.Set(0, 0);
  if (pParent == GetInterface()) {
    return szRet;
  }
  IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr();
  if (!pWidgetMgr)
    return szRet;
  szRet.x += m_pProperties->m_rtWidget.left;
  szRet.y += m_pProperties->m_rtWidget.top;
  IFWL_Widget* pDstWidget = GetParent();
  while (pDstWidget && pDstWidget != pParent) {
    CFX_RectF rtDst;
    pDstWidget->GetWidgetRect(rtDst);
    szRet.x += rtDst.left;
    szRet.y += rtDst.top;
    pDstWidget = pWidgetMgr->GetWidget(pDstWidget, FWL_WGTRELATION_Parent);
  }
  return szRet;
}
FX_BOOL CFWL_WidgetImp::IsParent(IFWL_Widget* pParent) {
  IFWL_Widget* pUpWidget = GetParent();
  while (pUpWidget) {
    if (pUpWidget == pParent)
      return TRUE;
    pUpWidget = pUpWidget->GetParent();
  }
  return FALSE;
}
CFWL_WidgetImpDelegate::CFWL_WidgetImpDelegate() {}
int32_t CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage->m_pDstTarget)
    return 0;
  CFWL_WidgetImp* pWidget =
      static_cast<CFWL_WidgetImp*>(pMessage->m_pDstTarget->GetImpl());
  FX_DWORD dwMsgCode = pMessage->GetClassID();
  switch (dwMsgCode) {
    case FWL_MSGHASH_Mouse: {
      CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage);
      CFWL_EvtMouse evt;
      evt.m_pSrcTarget = pWidget->m_pInterface;
      evt.m_pDstTarget = pWidget->m_pInterface;
      evt.m_dwCmd = pMsgMouse->m_dwCmd;
      evt.m_dwFlags = pMsgMouse->m_dwFlags;
      evt.m_fx = pMsgMouse->m_fx;
      evt.m_fy = pMsgMouse->m_fy;
      pWidget->DispatchEvent(&evt);
      break;
    }
    case FWL_MSGHASH_MouseWheel: {
      CFWL_MsgMouseWheel* pMsgMouseWheel =
          static_cast<CFWL_MsgMouseWheel*>(pMessage);
      CFWL_EvtMouseWheel evt;
      evt.m_pSrcTarget = pWidget->m_pInterface;
      evt.m_pDstTarget = pWidget->m_pInterface;
      evt.m_dwFlags = pMsgMouseWheel->m_dwFlags;
      evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX;
      evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY;
      evt.m_fx = pMsgMouseWheel->m_fx;
      evt.m_fy = pMsgMouseWheel->m_fy;
      pWidget->DispatchEvent(&evt);
      break;
    }
    case FWL_MSGHASH_Key: {
      CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage);
      CFWL_EvtKey evt;
      evt.m_pSrcTarget = pWidget->m_pInterface;
      evt.m_pDstTarget = pWidget->m_pInterface;
      evt.m_dwKeyCode = pMsgKey->m_dwKeyCode;
      evt.m_dwFlags = pMsgKey->m_dwFlags;
      evt.m_dwCmd = pMsgKey->m_dwCmd;
      pWidget->DispatchEvent(&evt);
      break;
    }
    case FWL_MSGHASH_SetFocus: {
      CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage);
      CFWL_EvtSetFocus evt;
      evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget;
      evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget;
      evt.m_pSetFocus = pWidget->m_pInterface;
      pWidget->DispatchEvent(&evt);
      break;
    }
    case FWL_MSGHASH_KillFocus: {
      CFWL_MsgKillFocus* pMsgKillFocus =
          static_cast<CFWL_MsgKillFocus*>(pMessage);
      CFWL_EvtKillFocus evt;
      evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget;
      evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget;
      evt.m_pKillFocus = pWidget->m_pInterface;
      pWidget->DispatchEvent(&evt);
      break;
    }
    default: {}
  }
  return 1;
}
FWL_ERR CFWL_WidgetImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
                                             const CFX_Matrix* pMatrix) {
  CFWL_EvtDraw evt;
  evt.m_pGraphics = pGraphics;
  return FWL_ERR_Succeeded;
}
class CFWL_CustomImp : public CFWL_WidgetImp {
 public:
  CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
                 IFWL_Widget* pOuter);
  virtual FWL_ERR GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
  virtual FWL_ERR Update();
  virtual FWL_ERR SetProxy(IFWL_Proxy* pProxy);

 protected:
  IFWL_Proxy* m_pProxy;
};
CFWL_CustomImp::CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
                               IFWL_Widget* pOuter)
    : CFWL_WidgetImp(properties, pOuter), m_pProxy(NULL) {}
FWL_ERR CFWL_CustomImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
  if (m_pProxy &&
      (m_pProxy->GetWidgetRect(rect, bAutoSize) == FWL_ERR_Succeeded)) {
    return FWL_ERR_Succeeded;
  }
  return CFWL_WidgetImp::GetWidgetRect(rect, bAutoSize);
}
FWL_ERR CFWL_CustomImp::Update() {
  if (m_pProxy) {
    return m_pProxy->Update();
  }
  return CFWL_WidgetImp::Update();
}
FWL_ERR CFWL_CustomImp::SetProxy(IFWL_Proxy* pProxy) {
  m_pProxy = pProxy;
  return FWL_ERR_Succeeded;
}

// static
IFWL_Custom* IFWL_Custom::Create(const CFWL_WidgetImpProperties& properties,
                                 IFWL_Widget* pOuter) {
  IFWL_Custom* pCustom = new IFWL_Custom;
  CFWL_CustomImp* pCustomImpl = new CFWL_CustomImp(properties, pOuter);
  pCustom->SetImpl(pCustomImpl);
  pCustomImpl->SetInterface(pCustom);
  return pCustom;
}
IFWL_Custom::IFWL_Custom() {}
FWL_ERR IFWL_Custom::SetProxy(IFWL_Proxy* pProxy) {
  return static_cast<CFWL_CustomImp*>(GetImpl())->SetProxy(pProxy);
}
void FWL_SetWidgetRect(IFWL_Widget* widget, const CFX_RectF& rect) {
  static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_rtWidget =
      rect;
}
void FWL_SetWidgetStates(IFWL_Widget* widget, FX_DWORD dwStates) {
  static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStates =
      dwStates;
}
void FWL_SetWidgetStyles(IFWL_Widget* widget, FX_DWORD dwStyles) {
  static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStyles =
      dwStyles;
}
FWL_ERR FWL_EnabelWidget(IFWL_Widget* widget, FX_BOOL bEnable) {
  widget->SetStates(FWL_WGTSTATE_Disabled, !bEnable);
  IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
  IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
  while (child) {
    FWL_EnabelWidget(child, bEnable);
    child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
  }
  return FWL_ERR_Succeeded;
}
