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
13class IFX_Edit;
14
15class CLST_Size
16{
17public:
18	CLST_Size() : x(0.0f), y(0.0f)
19	{
20	}
21
22	CLST_Size(FX_FLOAT x,FX_FLOAT y)
23	{
24		this->x = x;
25		this->y = y;
26	}
27
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
42class CLST_Rect : public CPDF_Rect
43{
44public:
45	CLST_Rect()
46	{
47		left = top = right = bottom = 0.0f;
48	}
49
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
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
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
92	FX_FLOAT Width() const
93	{
94		return this->right - this->left;
95	}
96
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
105	CPDF_Point LeftTop() const
106	{
107		return CPDF_Point(left,top);
108	}
109
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
152class CFX_ListItem
153{
154public:
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
162public:
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
176private:
177	IFX_Edit*						m_pEdit;
178	FX_BOOL							m_bSelected;
179	FX_BOOL							m_bCaret;
180	CLST_Rect						m_rcListItem;
181};
182
183class CFX_ListContainer
184{
185public:
186	CFX_ListContainer() : m_rcPlate(0.0f,0.0f,0.0f,0.0f), m_rcContent(0.0f,0.0f,0.0f,0.0f){}
187	virtual ~CFX_ListContainer(){}
188	virtual void					SetPlateRect(const CPDF_Rect & rect){m_rcPlate = rect;}
189	CPDF_Rect						GetPlateRect() const{return m_rcPlate;}
190	void							SetContentRect(const CLST_Rect & rect){m_rcContent = rect;}
191	CLST_Rect						GetContentRect() const{return m_rcContent;}
192	CPDF_Point						GetBTPoint() const{return CPDF_Point(m_rcPlate.left,m_rcPlate.top);}
193	CPDF_Point						GetETPoint() const{return CPDF_Point(m_rcPlate.right,m_rcPlate.bottom);}
194public:
195	CPDF_Point						InnerToOuter(const CPDF_Point & point) const{return CPDF_Point(point.x + GetBTPoint().x,GetBTPoint().y - point.y);}
196	CPDF_Point						OuterToInner(const CPDF_Point & point) const{return CPDF_Point(point.x - GetBTPoint().x,GetBTPoint().y - point.y);}
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);}
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);}
203private:
204	CPDF_Rect						m_rcPlate;
205	CLST_Rect						m_rcContent;		//positive forever!
206};
207
208template<class TYPE> class CLST_ArrayTemplate : public CFX_ArrayTemplate<TYPE>
209{
210public:
211	FX_BOOL IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
212	TYPE GetAt(FX_INT32 nIndex) const { if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) return CFX_ArrayTemplate<TYPE>::GetAt(nIndex); return NULL;}
213	void RemoveAt(FX_INT32 nIndex){if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);}
214};
215
216class CFX_List : protected CFX_ListContainer , public IFX_List
217{
218public:
219	CFX_List();
220	virtual ~CFX_List();
221
222public:
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
240protected:
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
257private:
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
264struct CPLST_Select_Item
265{
266	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
276class CPLST_Select
277{
278public:
279	CPLST_Select();
280	virtual ~CPLST_Select();
281
282public:
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
295private:
296	CFX_ArrayTemplate<CPLST_Select_Item*>	m_aItems;
297};
298
299class CFX_ListCtrl : public CFX_List
300{
301public:
302	CFX_ListCtrl();
303	virtual ~CFX_ListCtrl();
304
305public:
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;
328	FX_INT32						GetCaret() const {return m_nCaretIndex;}
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
342private:
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
352private:
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