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 public:
17  CLST_Size() : x(0.0f), y(0.0f) {}
18
19  CLST_Size(FX_FLOAT other_x, FX_FLOAT other_y) {
20    x = other_x;
21    y = other_y;
22  }
23
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
36class CLST_Rect : public CPDF_Rect {
37 public:
38  CLST_Rect() { left = top = right = bottom = 0.0f; }
39
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
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
57  ~CLST_Rect() {}
58
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
78  FX_FLOAT Width() const { return right - left; }
79
80  FX_FLOAT Height() const {
81    if (top > bottom)
82      return top - bottom;
83    return bottom - top;
84  }
85
86  CPDF_Point LeftTop() const { return CPDF_Point(left, top); }
87
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
119class 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
149class CFX_ListContainer {
150 public:
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) {}
154  virtual ~CFX_ListContainer() {}
155  virtual void SetPlateRect(const CPDF_Rect& rect) { m_rcPlate = rect; }
156  CPDF_Rect GetPlateRect() const { return m_rcPlate; }
157  void SetContentRect(const CLST_Rect& rect) { m_rcContent = rect; }
158  CLST_Rect GetContentRect() const { return m_rcContent; }
159  CPDF_Point GetBTPoint() const {
160    return CPDF_Point(m_rcPlate.left, m_rcPlate.top);
161  }
162  CPDF_Point GetETPoint() const {
163    return CPDF_Point(m_rcPlate.right, m_rcPlate.bottom);
164  }
165
166 public:
167  CPDF_Point InnerToOuter(const CPDF_Point& point) const {
168    return CPDF_Point(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
169  }
170  CPDF_Point OuterToInner(const CPDF_Point& point) const {
171    return CPDF_Point(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
172  }
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  }
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
193template <class TYPE>
194class CLST_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
195 public:
196  FX_BOOL IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
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  }
202  void RemoveAt(int32_t nIndex) {
203    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
204      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
205  }
206};
207
208class 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
248struct CPLST_Select_Item {
249  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
258class 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
280class 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;
305  int32_t GetCaret() const override { return m_nCaretIndex; }
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