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 "../../include/pdfwindow/PDFWindow.h" 8 #include "../../include/pdfwindow/PWL_Wnd.h" 9 #include "../../include/pdfwindow/PWL_ListCtrl.h" 10 11 /* ---------------------------- CPWL_ListCtrl ---------------------------- */ 12 13 CPWL_ListCtrl::CPWL_ListCtrl() : 14 m_rcContent(0,0,0,0), 15 m_ptScroll(0,0), 16 m_fItemSpace(0.0f), 17 m_fTopSpace(0.0f), 18 m_fBottomSpace(0.0f) 19 { 20 } 21 22 CPWL_ListCtrl::~CPWL_ListCtrl() 23 { 24 } 25 26 void CPWL_ListCtrl::SetScrollPos(const CPDF_Point& point) 27 { 28 m_ptScroll = point; 29 30 if (m_ptScroll.x < m_rcContent.left) 31 m_ptScroll.x = m_rcContent.left; 32 33 if (m_ptScroll.x > m_rcContent.right) 34 m_ptScroll.x = m_rcContent.right; 35 36 if (m_ptScroll.y > m_rcContent.top) 37 m_ptScroll.y = m_rcContent.top; 38 39 if (m_ptScroll.y < m_rcContent.bottom) 40 m_ptScroll.y = m_rcContent.bottom; 41 } 42 43 CPDF_Point CPWL_ListCtrl::GetScrollPos() const 44 { 45 return m_ptScroll; 46 } 47 48 CPDF_Rect CPWL_ListCtrl::GetScrollArea() const 49 { 50 return m_rcContent; 51 } 52 53 void CPWL_ListCtrl::ResetFace() 54 { 55 ResetAll(FALSE, 0); 56 } 57 58 void CPWL_ListCtrl::ResetContent(FX_INT32 nStart) 59 { 60 if (nStart < 0) 61 nStart = 0; 62 if (nStart >= 0 && nStart < m_aChildren.GetSize()) 63 ResetAll(TRUE, nStart); 64 } 65 66 FX_FLOAT CPWL_ListCtrl::GetContentsHeight(FX_FLOAT fLimitWidth) 67 { 68 FX_FLOAT fRet = m_fTopSpace; 69 70 FX_FLOAT fBorderWidth = (FX_FLOAT)this->GetBorderWidth(); 71 72 if (fLimitWidth > fBorderWidth* 2) 73 { 74 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 75 { 76 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 77 { 78 FX_FLOAT fLeft = pChild->GetItemLeftMargin(); 79 FX_FLOAT fRight = pChild->GetItemRightMargin(); 80 81 fRet += pChild->GetItemHeight(fLimitWidth - fBorderWidth* 2 - fLeft - fRight); 82 fRet += m_fItemSpace; 83 } 84 } 85 86 fRet -= m_fItemSpace; 87 } 88 89 fRet += m_fBottomSpace; 90 91 return fRet; 92 } 93 94 void CPWL_ListCtrl::ResetAll(FX_BOOL bMove, FX_INT32 nStart) 95 { 96 CPDF_Rect rcClient = GetClientRect(); 97 98 FX_FLOAT fWidth = rcClient.Width(); 99 100 FX_FLOAT fy = 0.0f - m_fTopSpace; 101 102 if (nStart-1 >= 0 && nStart-1 < m_aChildren.GetSize()) 103 if (CPWL_Wnd* pChild = m_aChildren.GetAt(nStart-1)) 104 fy = pChild->GetWindowRect().bottom - m_fItemSpace; 105 106 for (FX_INT32 i=nStart,sz=m_aChildren.GetSize(); i<sz; i++) 107 { 108 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 109 { 110 FX_FLOAT fLeft = pChild->GetItemLeftMargin(); 111 FX_FLOAT fRight = pChild->GetItemRightMargin(); 112 113 pChild->SetChildMatrix( 114 CPDF_Matrix(1,0,0,1, 115 rcClient.left - m_ptScroll.x, 116 rcClient.top - m_ptScroll.y) 117 ); 118 119 if (bMove) 120 { 121 FX_FLOAT fItemHeight = pChild->GetItemHeight(fWidth - fLeft - fRight); 122 pChild->Move(CPDF_Rect(fLeft, fy-fItemHeight, fWidth - fRight, fy), TRUE, FALSE); 123 fy -= fItemHeight; 124 fy -= m_fItemSpace; 125 } 126 } 127 } 128 129 fy += m_fItemSpace; 130 131 fy -= m_fBottomSpace; 132 133 if (bMove) 134 { 135 m_rcContent.left = 0; 136 m_rcContent.top = 0; 137 m_rcContent.right = fWidth; 138 m_rcContent.bottom = fy; 139 } 140 } 141 142 void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) 143 { 144 m_fItemSpace = fSpace; 145 } 146 147 void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) 148 { 149 m_fTopSpace = fSpace; 150 } 151 152 void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) 153 { 154 m_fBottomSpace = fSpace; 155 } 156 157 void CPWL_ListCtrl::RePosChildWnd() 158 { 159 ResetFace(); 160 } 161 162 void CPWL_ListCtrl::DrawChildAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) 163 { 164 pDevice->SaveState(); 165 CPDF_Rect rcClient = GetClientRect(); 166 CPDF_Rect rcTemp = rcClient; 167 pUser2Device->TransformRect(rcTemp); 168 FX_RECT rcClip((FX_INT32)rcTemp.left, 169 (FX_INT32)rcTemp.bottom, 170 (FX_INT32)rcTemp.right, 171 (FX_INT32)rcTemp.top); 172 173 pDevice->SetClip_Rect(&rcClip); 174 175 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 176 { 177 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i)) 178 { 179 CPDF_Rect rcChild = pChild->ChildToParent(pChild->GetWindowRect()); 180 if (!(rcChild.top < rcClient.bottom || rcChild.bottom > rcClient.top)) 181 { 182 CPDF_Matrix mt = pChild->GetChildMatrix(); 183 if (mt.IsIdentity()) 184 { 185 pChild->DrawAppearance(pDevice,pUser2Device); 186 } 187 else 188 { 189 mt.Concat(*pUser2Device); 190 pChild->DrawAppearance(pDevice,&mt); 191 } 192 } 193 } 194 } 195 196 pDevice->RestoreState(); 197 } 198 199 FX_INT32 CPWL_ListCtrl::GetItemIndex(CPWL_Wnd* pItem) 200 { 201 for (FX_INT32 i=0, sz=m_aChildren.GetSize(); i<sz; i++) 202 { 203 if (pItem == m_aChildren.GetAt(i)) 204 return i; 205 } 206 207 return -1; 208 } 209 210 CPDF_Point CPWL_ListCtrl::InToOut(const CPDF_Point& point) const 211 { 212 CPDF_Rect rcClient = GetClientRect(); 213 214 return CPDF_Point(point.x + rcClient.left - m_ptScroll.x, 215 point.y + rcClient.top - m_ptScroll.y); 216 } 217 218 CPDF_Point CPWL_ListCtrl::OutToIn(const CPDF_Point& point) const 219 { 220 CPDF_Rect rcClient = GetClientRect(); 221 222 return CPDF_Point(point.x - rcClient.left + m_ptScroll.x, 223 point.y - rcClient.top + m_ptScroll.y); 224 } 225 226 CPDF_Rect CPWL_ListCtrl::InToOut(const CPDF_Rect& rect) const 227 { 228 CPDF_Rect rcClient = GetClientRect(); 229 230 return CPDF_Rect(rect.left + rcClient.left - m_ptScroll.x, 231 rect.bottom + rcClient.top - m_ptScroll.y, 232 rect.right + rcClient.left - m_ptScroll.x, 233 rect.top + rcClient.top - m_ptScroll.y); 234 } 235 236 CPDF_Rect CPWL_ListCtrl::OutToIn(const CPDF_Rect& rect) const 237 { 238 CPDF_Rect rcClient = GetClientRect(); 239 240 return CPDF_Rect(rect.left - rcClient.left + m_ptScroll.x, 241 rect.bottom - rcClient.top + m_ptScroll.y, 242 rect.right - rcClient.left + m_ptScroll.x, 243 rect.top - rcClient.top + m_ptScroll.y); 244 } 245 246