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