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