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