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