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 #ifndef FPDFSDK_INCLUDE_FXEDIT_FXET_LIST_H_
8 #define FPDFSDK_INCLUDE_FXEDIT_FXET_LIST_H_
9 
10 #include "../../../core/include/fpdfapi/fpdf_parser.h"  // For CPDF_Point.
11 #include "fx_edit.h"
12 
13 class IFX_Edit;
14 
15 class CLST_Size
16 {
17 public:
CLST_Size()18 	CLST_Size() : x(0.0f), y(0.0f)
19 	{
20 	}
21 
CLST_Size(FX_FLOAT x,FX_FLOAT y)22 	CLST_Size(FX_FLOAT x,FX_FLOAT y)
23 	{
24 		this->x = x;
25 		this->y = y;
26 	}
27 
Default()28 	void Default()
29 	{
30 		x = 0.0f;
31 		y = 0.0f;
32 	}
33 
34 	FX_BOOL operator != (const CLST_Size & size) const
35 	{
36 		return FXSYS_memcmp(this, &size, sizeof(CLST_Size)) != 0;
37 	}
38 
39 	FX_FLOAT x,y;
40 };
41 
42 class CLST_Rect : public CPDF_Rect
43 {
44 public:
CLST_Rect()45 	CLST_Rect()
46 	{
47 		left = top = right = bottom = 0.0f;
48 	}
49 
CLST_Rect(FX_FLOAT left,FX_FLOAT top,FX_FLOAT right,FX_FLOAT bottom)50 	CLST_Rect(FX_FLOAT left,FX_FLOAT top,
51 						FX_FLOAT right,FX_FLOAT bottom)
52 	{
53 		this->left = left;
54 		this->top = top;
55 		this->right = right;
56 		this->bottom = bottom;
57 	}
58 
CLST_Rect(const CPDF_Rect & rect)59 	CLST_Rect(const CPDF_Rect & rect)
60 	{
61 		this->left = rect.left;
62 		this->top = rect.top;
63 		this->right = rect.right;
64 		this->bottom = rect.bottom;
65 	}
66 
Default()67 	void Default()
68 	{
69 		left = top = right = bottom = 0.0f;
70 	}
71 
72 	const CLST_Rect operator = (const CPDF_Rect & rect)
73 	{
74 		this->left = rect.left;
75 		this->top = rect.top;
76 		this->right = rect.right;
77 		this->bottom = rect.bottom;
78 
79 		return *this;
80 	}
81 
82 	FX_BOOL operator == (const CLST_Rect & rect) const
83 	{
84 		return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) == 0;
85 	}
86 
87 	FX_BOOL operator != (const CLST_Rect & rect) const
88 	{
89 		return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) != 0;
90 	}
91 
Width()92 	FX_FLOAT Width() const
93 	{
94 		return this->right - this->left;
95 	}
96 
Height()97 	FX_FLOAT Height() const
98 	{
99 		if (this->top > this->bottom)
100 			return this->top - this->bottom;
101 		else
102 			return this->bottom - this->top;
103 	}
104 
LeftTop()105 	CPDF_Point LeftTop() const
106 	{
107 		return CPDF_Point(left,top);
108 	}
109 
RightBottom()110 	CPDF_Point RightBottom() const
111 	{
112 		return CPDF_Point(right,bottom);
113 	}
114 
115 	const CLST_Rect operator += (const CPDF_Point & point)
116 	{
117 		this->left += point.x;
118 		this->right += point.x;
119 		this->top += point.y;
120 		this->bottom += point.y;
121 
122 		return *this;
123 	}
124 
125 	const CLST_Rect operator -= (const CPDF_Point & point)
126 	{
127 		this->left -= point.x;
128 		this->right -= point.x;
129 		this->top -= point.y;
130 		this->bottom -= point.y;
131 
132 		return *this;
133 	}
134 
135 	CLST_Rect operator + (const CPDF_Point & point) const
136 	{
137 		return CLST_Rect(left + point.x,
138 					top + point.y,
139 					right + point.x,
140 					bottom + point.y);
141 	}
142 
143 	CLST_Rect operator - (const CPDF_Point & point) const
144 	{
145 		return CLST_Rect(left - point.x,
146 					top - point.y,
147 					right - point.x,
148 					bottom - point.y);
149 	}
150 };
151 
152 class CFX_ListItem
153 {
154 public:
155 	CFX_ListItem();
156 	virtual ~CFX_ListItem();
157 
158 	void							SetFontMap(IFX_Edit_FontMap * pFontMap);
159 	IFX_Edit_Iterator*				GetIterator() const;
160 	IFX_Edit*						GetEdit() const;
161 
162 public:
163 	void							SetRect(const CLST_Rect & rect);
164 	void							SetSelect(FX_BOOL bSelected);
165 	void							SetCaret(FX_BOOL bCaret);
166 	void							SetText(FX_LPCWSTR text);
167 	void							SetFontSize(FX_FLOAT fFontSize);
168 	CFX_WideString					GetText() const;
169 
170 	CLST_Rect						GetRect() const;
171 	FX_BOOL							IsSelected() const;
172 	FX_BOOL							IsCaret() const;
173 	FX_FLOAT						GetItemHeight() const;
174 	FX_WORD							GetFirstChar() const;
175 
176 private:
177 	IFX_Edit*						m_pEdit;
178 	FX_BOOL							m_bSelected;
179 	FX_BOOL							m_bCaret;
180 	CLST_Rect						m_rcListItem;
181 };
182 
183 class CFX_ListContainer
184 {
185 public:
CFX_ListContainer()186 	CFX_ListContainer() : m_rcPlate(0.0f,0.0f,0.0f,0.0f), m_rcContent(0.0f,0.0f,0.0f,0.0f){}
~CFX_ListContainer()187 	virtual ~CFX_ListContainer(){}
SetPlateRect(const CPDF_Rect & rect)188 	virtual void					SetPlateRect(const CPDF_Rect & rect){m_rcPlate = rect;}
GetPlateRect()189 	CPDF_Rect						GetPlateRect() const{return m_rcPlate;}
SetContentRect(const CLST_Rect & rect)190 	void							SetContentRect(const CLST_Rect & rect){m_rcContent = rect;}
GetContentRect()191 	CLST_Rect						GetContentRect() const{return m_rcContent;}
GetBTPoint()192 	CPDF_Point						GetBTPoint() const{return CPDF_Point(m_rcPlate.left,m_rcPlate.top);}
GetETPoint()193 	CPDF_Point						GetETPoint() const{return CPDF_Point(m_rcPlate.right,m_rcPlate.bottom);}
194 public:
InnerToOuter(const CPDF_Point & point)195 	CPDF_Point						InnerToOuter(const CPDF_Point & point) const{return CPDF_Point(point.x + GetBTPoint().x,GetBTPoint().y - point.y);}
OuterToInner(const CPDF_Point & point)196 	CPDF_Point						OuterToInner(const CPDF_Point & point) const{return CPDF_Point(point.x - GetBTPoint().x,GetBTPoint().y - point.y);}
InnerToOuter(const CLST_Rect & rect)197 	CPDF_Rect						InnerToOuter(const CLST_Rect & rect) const{CPDF_Point ptLeftTop = InnerToOuter(CPDF_Point(rect.left,rect.top));
198 																			CPDF_Point ptRightBottom = InnerToOuter(CPDF_Point(rect.right,rect.bottom));
199 																			return CPDF_Rect(ptLeftTop.x,ptRightBottom.y,ptRightBottom.x,ptLeftTop.y);}
OuterToInner(const CPDF_Rect & rect)200 	CLST_Rect						OuterToInner(const CPDF_Rect & rect) const{CPDF_Point ptLeftTop = OuterToInner(CPDF_Point(rect.left,rect.top));
201 																			CPDF_Point ptRightBottom = OuterToInner(CPDF_Point(rect.right,rect.bottom));
202 																			return CLST_Rect(ptLeftTop.x,ptLeftTop.y,ptRightBottom.x,ptRightBottom.y);}
203 private:
204 	CPDF_Rect						m_rcPlate;
205 	CLST_Rect						m_rcContent;		//positive forever!
206 };
207 
208 template<class TYPE> class CLST_ArrayTemplate : public CFX_ArrayTemplate<TYPE>
209 {
210 public:
IsEmpty()211 	FX_BOOL IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
GetAt(FX_INT32 nIndex)212 	TYPE GetAt(FX_INT32 nIndex) const { if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) return CFX_ArrayTemplate<TYPE>::GetAt(nIndex); return NULL;}
RemoveAt(FX_INT32 nIndex)213 	void RemoveAt(FX_INT32 nIndex){if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);}
214 };
215 
216 class CFX_List : protected CFX_ListContainer , public IFX_List
217 {
218 public:
219 	CFX_List();
220 	virtual ~CFX_List();
221 
222 public:
223 	virtual void					SetFontMap(IFX_Edit_FontMap * pFontMap);
224 	virtual void					SetFontSize(FX_FLOAT fFontSize);
225 
226 	virtual CPDF_Rect				GetPlateRect() const;
227 	virtual CPDF_Rect				GetContentRect() const;
228 
229 	virtual FX_FLOAT				GetFontSize() const;
230 	virtual IFX_Edit*				GetItemEdit(FX_INT32 nIndex) const;
231 	virtual FX_INT32				GetCount() const;
232 	virtual FX_BOOL					IsItemSelected(FX_INT32 nIndex) const;
233 	virtual FX_FLOAT				GetFirstHeight() const;
234 
235 	virtual void					SetMultipleSel(FX_BOOL bMultiple);
236 	virtual FX_BOOL					IsMultipleSel() const;
237 	virtual FX_BOOL					IsValid(FX_INT32 nItemIndex) const;
238 	virtual FX_INT32				FindNext(FX_INT32 nIndex,FX_WCHAR nChar) const;
239 
240 protected:
241 	virtual void					Empty();
242 
243 	void							AddItem(FX_LPCWSTR str);
244 	virtual void					ReArrange(FX_INT32 nItemIndex);
245 
246 	virtual CPDF_Rect				GetItemRect(FX_INT32 nIndex) const;
247 	CFX_WideString					GetItemText(FX_INT32 nIndex) const;
248 
249 	void							SetItemSelect(FX_INT32 nItemIndex, FX_BOOL bSelected);
250 	void							SetItemCaret(FX_INT32 nItemIndex, FX_BOOL bCaret);
251 
252 	virtual FX_INT32				GetItemIndex(const CPDF_Point & point) const;
253 	FX_INT32						GetFirstSelected() const;
254 	FX_INT32						GetLastSelected() const;
255 	FX_WCHAR						Toupper(FX_WCHAR c) const;
256 
257 private:
258 	CLST_ArrayTemplate<CFX_ListItem*>	m_aListItems;
259 	FX_FLOAT							m_fFontSize;
260 	IFX_Edit_FontMap*					m_pFontMap;
261 	FX_BOOL								m_bMultiple;
262 };
263 
264 struct CPLST_Select_Item
265 {
CPLST_Select_ItemCPLST_Select_Item266 	CPLST_Select_Item(FX_INT32 nItemIndex,FX_INT32 nState)
267 	{
268 		this->nItemIndex = nItemIndex;
269 		this->nState = nState;
270 	}
271 
272 	FX_INT32		nItemIndex;
273 	FX_INT32		nState; //0:normal select -1:to deselect 1: to select
274 };
275 
276 class CPLST_Select
277 {
278 public:
279 	CPLST_Select();
280 	virtual ~CPLST_Select();
281 
282 public:
283 	void							Add(FX_INT32 nItemIndex);
284 	void							Add(FX_INT32 nBeginIndex, FX_INT32 nEndIndex);
285 	void							Sub(FX_INT32 nItemIndex);
286 	void							Sub(FX_INT32 nBeginIndex, FX_INT32 nEndIndex);
287 	FX_BOOL							IsExist(FX_INT32 nItemIndex) const;
288 	FX_INT32						Find(FX_INT32 nItemIndex) const;
289 	FX_INT32						GetCount() const;
290 	FX_INT32						GetItemIndex(FX_INT32 nIndex) const;
291 	FX_INT32						GetState(FX_INT32 nIndex) const;
292 	void							Done();
293 	void							DeselectAll();
294 
295 private:
296 	CFX_ArrayTemplate<CPLST_Select_Item*>	m_aItems;
297 };
298 
299 class CFX_ListCtrl : public CFX_List
300 {
301 public:
302 	CFX_ListCtrl();
303 	virtual ~CFX_ListCtrl();
304 
305 public:
306 	void							SetNotify(IFX_List_Notify * pNotify);
307 
308 	void							OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl);
309 	void							OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl);
310 	void							OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl);
311 	void							OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl);
312 	void							OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl);
313 	void							OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl);
314 	void							OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl);
315 	void							OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl);
316 	void							OnVK(FX_INT32 nItemIndex,FX_BOOL bShift,FX_BOOL bCtrl);
317 	FX_BOOL							OnChar(FX_WORD nChar,FX_BOOL bShift,FX_BOOL bCtrl);
318 
319 	virtual CPDF_Point				InToOut(const CPDF_Point & point) const;
320 	virtual CPDF_Point				OutToIn(const CPDF_Point & point) const;
321 	virtual CPDF_Rect				InToOut(const CPDF_Rect & rect) const;
322 	virtual CPDF_Rect				OutToIn(const CPDF_Rect & rect) const;
323 
324 	virtual void					SetPlateRect(const CPDF_Rect & rect);
325 	void							SetScrollPos(const CPDF_Point & point);
326 	void							ScrollToListItem(FX_INT32 nItemIndex);
327 	virtual CPDF_Rect				GetItemRect(FX_INT32 nIndex) const;
GetCaret()328 	FX_INT32						GetCaret() const {return m_nCaretIndex;}
GetSelect()329 	FX_INT32						GetSelect() const {return m_nSelItem;}
330 	FX_INT32						GetTopItem() const;
331 	virtual CPDF_Rect				GetContentRect() const;
332 	virtual FX_INT32				GetItemIndex(const CPDF_Point & point) const;
333 
334 	void							AddString(FX_LPCWSTR string);
335 	void							SetTopItem(FX_INT32 nIndex);
336 	void							Select(FX_INT32 nItemIndex);
337 	virtual void					SetCaret(FX_INT32 nItemIndex);
338 	virtual void					Empty();
339 	virtual void					Cancel();
340 	CFX_WideString					GetText() const;
341 
342 private:
343 	void							SetMultipleSelect(FX_INT32 nItemIndex, FX_BOOL bSelected);
344 	void							SetSingleSelect(FX_INT32 nItemIndex);
345 	void							InvalidateItem(FX_INT32 nItemIndex);
346 	void							SelectItems();
347 	FX_BOOL							IsItemVisible(FX_INT32 nItemIndex) const;
348 	void							SetScrollInfo();
349 	void							SetScrollPosY(FX_FLOAT fy);
350 	virtual void					ReArrange(FX_INT32 nItemIndex);
351 
352 private:
353 	IFX_List_Notify*				m_pNotify;
354 	FX_BOOL							m_bNotifyFlag;
355 	CPDF_Point						m_ptScrollPos;
356 	CPLST_Select					m_aSelItems;	//for multiple
357 	FX_INT32						m_nSelItem;		//for single
358 	FX_INT32						m_nFootIndex;	//for multiple
359 	FX_BOOL							m_bCtrlSel;		//for multiple
360 	FX_INT32						m_nCaretIndex;	//for multiple
361 };
362 
363 #endif  // FPDFSDK_INCLUDE_FXEDIT_FXET_LIST_H_
364