1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h" 8 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h" 9 10 CPWL_ListCtrl::CPWL_ListCtrl() 11 : m_rcContent(0, 0, 0, 0), 12 m_ptScroll(0, 0), 13 m_fItemSpace(0.0f), 14 m_fTopSpace(0.0f), 15 m_fBottomSpace(0.0f) {} 16 17 CPWL_ListCtrl::~CPWL_ListCtrl() {} 18 19 void CPWL_ListCtrl::SetScrollPos(const CPDF_Point& point) { 20 m_ptScroll = point; 21 22 if (m_ptScroll.x < m_rcContent.left) 23 m_ptScroll.x = m_rcContent.left; 24 25 if (m_ptScroll.x > m_rcContent.right) 26 m_ptScroll.x = m_rcContent.right; 27 28 if (m_ptScroll.y > m_rcContent.top) 29 m_ptScroll.y = m_rcContent.top; 30 31 if (m_ptScroll.y < m_rcContent.bottom) 32 m_ptScroll.y = m_rcContent.bottom; 33 } 34 35 CPDF_Point CPWL_ListCtrl::GetScrollPos() const { 36 return m_ptScroll; 37 } 38 39 CPDF_Rect CPWL_ListCtrl::GetScrollArea() const { 40 return m_rcContent; 41 } 42 43 void CPWL_ListCtrl::ResetFace() { 44 ResetAll(FALSE, 0); 45 } 46 47 void CPWL_ListCtrl::ResetContent(int32_t nStart) { 48 if (nStart < 0) 49 nStart = 0; 50 if (nStart >= 0 && nStart < m_aChildren.GetSize()) 51 ResetAll(TRUE, nStart); 52 } 53 54 FX_FLOAT CPWL_ListCtrl::GetContentsHeight(FX_FLOAT fLimitWidth) { 55 FX_FLOAT fRet = m_fTopSpace; 56 57 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 58 59 if (fLimitWidth > fBorderWidth * 2) { 60 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 61 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 62 FX_FLOAT fLeft = pChild->GetItemLeftMargin(); 63 FX_FLOAT fRight = pChild->GetItemRightMargin(); 64 65 fRet += pChild->GetItemHeight(fLimitWidth - fBorderWidth * 2 - fLeft - 66 fRight); 67 fRet += m_fItemSpace; 68 } 69 } 70 71 fRet -= m_fItemSpace; 72 } 73 74 fRet += m_fBottomSpace; 75 76 return fRet; 77 } 78 79 void CPWL_ListCtrl::ResetAll(FX_BOOL bMove, int32_t nStart) { 80 CPDF_Rect rcClient = GetClientRect(); 81 82 FX_FLOAT fWidth = rcClient.Width(); 83 84 FX_FLOAT fy = 0.0f - m_fTopSpace; 85 86 if (nStart - 1 >= 0 && nStart - 1 < m_aChildren.GetSize()) 87 if (CPWL_Wnd* pChild = m_aChildren.GetAt(nStart - 1)) 88 fy = pChild->GetWindowRect().bottom - m_fItemSpace; 89 90 for (int32_t i = nStart, sz = m_aChildren.GetSize(); i < sz; i++) { 91 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 92 FX_FLOAT fLeft = pChild->GetItemLeftMargin(); 93 FX_FLOAT fRight = pChild->GetItemRightMargin(); 94 95 pChild->SetChildMatrix(CFX_Matrix(1, 0, 0, 1, 96 rcClient.left - m_ptScroll.x, 97 rcClient.top - m_ptScroll.y)); 98 99 if (bMove) { 100 FX_FLOAT fItemHeight = pChild->GetItemHeight(fWidth - fLeft - fRight); 101 pChild->Move(CPDF_Rect(fLeft, fy - fItemHeight, fWidth - fRight, fy), 102 TRUE, FALSE); 103 fy -= fItemHeight; 104 fy -= m_fItemSpace; 105 } 106 } 107 } 108 109 fy += m_fItemSpace; 110 111 fy -= m_fBottomSpace; 112 113 if (bMove) { 114 m_rcContent.left = 0; 115 m_rcContent.top = 0; 116 m_rcContent.right = fWidth; 117 m_rcContent.bottom = fy; 118 } 119 } 120 121 void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) { 122 m_fItemSpace = fSpace; 123 } 124 125 void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) { 126 m_fTopSpace = fSpace; 127 } 128 129 void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) { 130 m_fBottomSpace = fSpace; 131 } 132 133 void CPWL_ListCtrl::RePosChildWnd() { 134 ResetFace(); 135 } 136 137 void CPWL_ListCtrl::DrawChildAppearance(CFX_RenderDevice* pDevice, 138 CFX_Matrix* pUser2Device) { 139 pDevice->SaveState(); 140 CPDF_Rect rcClient = GetClientRect(); 141 CPDF_Rect rcTemp = rcClient; 142 pUser2Device->TransformRect(rcTemp); 143 FX_RECT rcClip((int32_t)rcTemp.left, (int32_t)rcTemp.bottom, 144 (int32_t)rcTemp.right, (int32_t)rcTemp.top); 145 146 pDevice->SetClip_Rect(&rcClip); 147 148 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 149 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 150 CPDF_Rect rcChild = pChild->ChildToParent(pChild->GetWindowRect()); 151 if (!(rcChild.top < rcClient.bottom || rcChild.bottom > rcClient.top)) { 152 CFX_Matrix mt = pChild->GetChildMatrix(); 153 if (mt.IsIdentity()) { 154 pChild->DrawAppearance(pDevice, pUser2Device); 155 } else { 156 mt.Concat(*pUser2Device); 157 pChild->DrawAppearance(pDevice, &mt); 158 } 159 } 160 } 161 } 162 163 pDevice->RestoreState(); 164 } 165 166 int32_t CPWL_ListCtrl::GetItemIndex(CPWL_Wnd* pItem) { 167 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 168 if (pItem == m_aChildren.GetAt(i)) 169 return i; 170 } 171 172 return -1; 173 } 174 175 CPDF_Point CPWL_ListCtrl::InToOut(const CPDF_Point& point) const { 176 CPDF_Rect rcClient = GetClientRect(); 177 178 return CPDF_Point(point.x + rcClient.left - m_ptScroll.x, 179 point.y + rcClient.top - m_ptScroll.y); 180 } 181 182 CPDF_Point CPWL_ListCtrl::OutToIn(const CPDF_Point& point) const { 183 CPDF_Rect rcClient = GetClientRect(); 184 185 return CPDF_Point(point.x - rcClient.left + m_ptScroll.x, 186 point.y - rcClient.top + m_ptScroll.y); 187 } 188 189 CPDF_Rect CPWL_ListCtrl::InToOut(const CPDF_Rect& rect) const { 190 CPDF_Rect rcClient = GetClientRect(); 191 192 return CPDF_Rect(rect.left + rcClient.left - m_ptScroll.x, 193 rect.bottom + rcClient.top - m_ptScroll.y, 194 rect.right + rcClient.left - m_ptScroll.x, 195 rect.top + rcClient.top - m_ptScroll.y); 196 } 197 198 CPDF_Rect CPWL_ListCtrl::OutToIn(const CPDF_Rect& rect) const { 199 CPDF_Rect rcClient = GetClientRect(); 200 201 return CPDF_Rect(rect.left - rcClient.left + m_ptScroll.x, 202 rect.bottom - rcClient.top + m_ptScroll.y, 203 rect.right - rcClient.left + m_ptScroll.x, 204 rect.top - rcClient.top + m_ptScroll.y); 205 } 206