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
CPWL_ListCtrl()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
~CPWL_ListCtrl()17 CPWL_ListCtrl::~CPWL_ListCtrl() {}
18
SetScrollPos(const CPDF_Point & point)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
GetScrollPos() const35 CPDF_Point CPWL_ListCtrl::GetScrollPos() const {
36 return m_ptScroll;
37 }
38
GetScrollArea() const39 CPDF_Rect CPWL_ListCtrl::GetScrollArea() const {
40 return m_rcContent;
41 }
42
ResetFace()43 void CPWL_ListCtrl::ResetFace() {
44 ResetAll(FALSE, 0);
45 }
46
ResetContent(int32_t nStart)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
GetContentsHeight(FX_FLOAT fLimitWidth)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
ResetAll(FX_BOOL bMove,int32_t nStart)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
SetItemSpace(FX_FLOAT fSpace)121 void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) {
122 m_fItemSpace = fSpace;
123 }
124
SetTopSpace(FX_FLOAT fSpace)125 void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) {
126 m_fTopSpace = fSpace;
127 }
128
SetBottomSpace(FX_FLOAT fSpace)129 void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) {
130 m_fBottomSpace = fSpace;
131 }
132
RePosChildWnd()133 void CPWL_ListCtrl::RePosChildWnd() {
134 ResetFace();
135 }
136
DrawChildAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)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
GetItemIndex(CPWL_Wnd * pItem)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
InToOut(const CPDF_Point & point) const175 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
OutToIn(const CPDF_Point & point) const182 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
InToOut(const CPDF_Rect & rect) const189 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
OutToIn(const CPDF_Rect & rect) const198 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