// 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 "../../include/pdfwindow/PDFWindow.h" #include "../../include/pdfwindow/PWL_Wnd.h" #include "../../include/pdfwindow/PWL_ListCtrl.h" /* ---------------------------- CPWL_ListCtrl ---------------------------- */ CPWL_ListCtrl::CPWL_ListCtrl() : m_rcContent(0,0,0,0), m_ptScroll(0,0), m_fItemSpace(0.0f), m_fTopSpace(0.0f), m_fBottomSpace(0.0f) { } CPWL_ListCtrl::~CPWL_ListCtrl() { } void CPWL_ListCtrl::SetScrollPos(const CPDF_Point& point) { m_ptScroll = point; if (m_ptScroll.x < m_rcContent.left) m_ptScroll.x = m_rcContent.left; if (m_ptScroll.x > m_rcContent.right) m_ptScroll.x = m_rcContent.right; if (m_ptScroll.y > m_rcContent.top) m_ptScroll.y = m_rcContent.top; if (m_ptScroll.y < m_rcContent.bottom) m_ptScroll.y = m_rcContent.bottom; } CPDF_Point CPWL_ListCtrl::GetScrollPos() const { return m_ptScroll; } CPDF_Rect CPWL_ListCtrl::GetScrollArea() const { return m_rcContent; } void CPWL_ListCtrl::ResetFace() { ResetAll(FALSE, 0); } void CPWL_ListCtrl::ResetContent(FX_INT32 nStart) { if (nStart < 0) nStart = 0; if (nStart >= 0 && nStart < m_aChildren.GetSize()) ResetAll(TRUE, nStart); } FX_FLOAT CPWL_ListCtrl::GetContentsHeight(FX_FLOAT fLimitWidth) { FX_FLOAT fRet = m_fTopSpace; FX_FLOAT fBorderWidth = (FX_FLOAT)this->GetBorderWidth(); if (fLimitWidth > fBorderWidth* 2) { for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) { if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { FX_FLOAT fLeft = pChild->GetItemLeftMargin(); FX_FLOAT fRight = pChild->GetItemRightMargin(); fRet += pChild->GetItemHeight(fLimitWidth - fBorderWidth* 2 - fLeft - fRight); fRet += m_fItemSpace; } } fRet -= m_fItemSpace; } fRet += m_fBottomSpace; return fRet; } void CPWL_ListCtrl::ResetAll(FX_BOOL bMove, FX_INT32 nStart) { CPDF_Rect rcClient = GetClientRect(); FX_FLOAT fWidth = rcClient.Width(); FX_FLOAT fy = 0.0f - m_fTopSpace; if (nStart-1 >= 0 && nStart-1 < m_aChildren.GetSize()) if (CPWL_Wnd* pChild = m_aChildren.GetAt(nStart-1)) fy = pChild->GetWindowRect().bottom - m_fItemSpace; for (FX_INT32 i=nStart,sz=m_aChildren.GetSize(); i<sz; i++) { if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { FX_FLOAT fLeft = pChild->GetItemLeftMargin(); FX_FLOAT fRight = pChild->GetItemRightMargin(); pChild->SetChildMatrix( CPDF_Matrix(1,0,0,1, rcClient.left - m_ptScroll.x, rcClient.top - m_ptScroll.y) ); if (bMove) { FX_FLOAT fItemHeight = pChild->GetItemHeight(fWidth - fLeft - fRight); pChild->Move(CPDF_Rect(fLeft, fy-fItemHeight, fWidth - fRight, fy), TRUE, FALSE); fy -= fItemHeight; fy -= m_fItemSpace; } } } fy += m_fItemSpace; fy -= m_fBottomSpace; if (bMove) { m_rcContent.left = 0; m_rcContent.top = 0; m_rcContent.right = fWidth; m_rcContent.bottom = fy; } } void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) { m_fItemSpace = fSpace; } void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) { m_fTopSpace = fSpace; } void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) { m_fBottomSpace = fSpace; } void CPWL_ListCtrl::RePosChildWnd() { ResetFace(); } void CPWL_ListCtrl::DrawChildAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) { pDevice->SaveState(); CPDF_Rect rcClient = GetClientRect(); CPDF_Rect rcTemp = rcClient; pUser2Device->TransformRect(rcTemp); FX_RECT rcClip((FX_INT32)rcTemp.left, (FX_INT32)rcTemp.bottom, (FX_INT32)rcTemp.right, (FX_INT32)rcTemp.top); pDevice->SetClip_Rect(&rcClip); for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) { if (CPWL_Wnd * pChild = m_aChildren.GetAt(i)) { CPDF_Rect rcChild = pChild->ChildToParent(pChild->GetWindowRect()); if (!(rcChild.top < rcClient.bottom || rcChild.bottom > rcClient.top)) { CPDF_Matrix mt = pChild->GetChildMatrix(); if (mt.IsIdentity()) { pChild->DrawAppearance(pDevice,pUser2Device); } else { mt.Concat(*pUser2Device); pChild->DrawAppearance(pDevice,&mt); } } } } pDevice->RestoreState(); } FX_INT32 CPWL_ListCtrl::GetItemIndex(CPWL_Wnd* pItem) { for (FX_INT32 i=0, sz=m_aChildren.GetSize(); i<sz; i++) { if (pItem == m_aChildren.GetAt(i)) return i; } return -1; } CPDF_Point CPWL_ListCtrl::InToOut(const CPDF_Point& point) const { CPDF_Rect rcClient = GetClientRect(); return CPDF_Point(point.x + rcClient.left - m_ptScroll.x, point.y + rcClient.top - m_ptScroll.y); } CPDF_Point CPWL_ListCtrl::OutToIn(const CPDF_Point& point) const { CPDF_Rect rcClient = GetClientRect(); return CPDF_Point(point.x - rcClient.left + m_ptScroll.x, point.y - rcClient.top + m_ptScroll.y); } CPDF_Rect CPWL_ListCtrl::InToOut(const CPDF_Rect& rect) const { CPDF_Rect rcClient = GetClientRect(); return CPDF_Rect(rect.left + rcClient.left - m_ptScroll.x, rect.bottom + rcClient.top - m_ptScroll.y, rect.right + rcClient.left - m_ptScroll.x, rect.top + rcClient.top - m_ptScroll.y); } CPDF_Rect CPWL_ListCtrl::OutToIn(const CPDF_Rect& rect) const { CPDF_Rect rcClient = GetClientRect(); return CPDF_Rect(rect.left - rcClient.left + m_ptScroll.x, rect.bottom - rcClient.top + m_ptScroll.y, rect.right - rcClient.left + m_ptScroll.x, rect.top - rcClient.top + m_ptScroll.y); }