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_FXET_LIST_H_ 8 #define FPDFSDK_FXEDIT_FXET_LIST_H_ 9 10 #include <memory> 11 12 #include "core/fxcrt/fx_coordinates.h" 13 #include "fpdfsdk/fxedit/fx_edit.h" 14 15 class CFX_Edit; 16 class CFX_Edit_Iterator; 17 class CPWL_List_Notify; 18 19 class CLST_Rect : public CFX_FloatRect { 20 public: CLST_Rect()21 CLST_Rect() { left = top = right = bottom = 0.0f; } 22 CLST_Rect(FX_FLOAT other_left,FX_FLOAT other_top,FX_FLOAT other_right,FX_FLOAT other_bottom)23 CLST_Rect(FX_FLOAT other_left, 24 FX_FLOAT other_top, 25 FX_FLOAT other_right, 26 FX_FLOAT other_bottom) { 27 left = other_left; 28 top = other_top; 29 right = other_right; 30 bottom = other_bottom; 31 } 32 CLST_Rect(const CFX_FloatRect & rect)33 explicit CLST_Rect(const CFX_FloatRect& rect) { 34 left = rect.left; 35 top = rect.top; 36 right = rect.right; 37 bottom = rect.bottom; 38 } 39 ~CLST_Rect()40 ~CLST_Rect() {} 41 Default()42 void Default() { left = top = right = bottom = 0.0f; } 43 44 const CLST_Rect operator=(const CFX_FloatRect& rect) { 45 left = rect.left; 46 top = rect.top; 47 right = rect.right; 48 bottom = rect.bottom; 49 50 return *this; 51 } 52 53 bool operator==(const CLST_Rect& rect) const { 54 return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) == 0; 55 } 56 57 bool operator!=(const CLST_Rect& rect) const { return !(*this == rect); } 58 Width()59 FX_FLOAT Width() const { return right - left; } 60 Height()61 FX_FLOAT Height() const { 62 if (top > bottom) 63 return top - bottom; 64 return bottom - top; 65 } 66 LeftTop()67 CFX_PointF LeftTop() const { return CFX_PointF(left, top); } 68 RightBottom()69 CFX_PointF RightBottom() const { return CFX_PointF(right, bottom); } 70 71 const CLST_Rect operator+=(const CFX_PointF& point) { 72 left += point.x; 73 right += point.x; 74 top += point.y; 75 bottom += point.y; 76 77 return *this; 78 } 79 80 const CLST_Rect operator-=(const CFX_PointF& point) { 81 left -= point.x; 82 right -= point.x; 83 top -= point.y; 84 bottom -= point.y; 85 86 return *this; 87 } 88 89 CLST_Rect operator+(const CFX_PointF& point) const { 90 return CLST_Rect(left + point.x, top + point.y, right + point.x, 91 bottom + point.y); 92 } 93 94 CLST_Rect operator-(const CFX_PointF& point) const { 95 return CLST_Rect(left - point.x, top - point.y, right - point.x, 96 bottom - point.y); 97 } 98 }; 99 100 class CFX_ListItem final { 101 public: 102 CFX_ListItem(); 103 ~CFX_ListItem(); 104 105 void SetFontMap(IPVT_FontMap* pFontMap); 106 CFX_Edit* GetEdit() const; 107 108 void SetRect(const CLST_Rect& rect); 109 void SetSelect(bool bSelected); 110 void SetText(const CFX_WideString& text); 111 void SetFontSize(FX_FLOAT fFontSize); 112 CFX_WideString GetText() const; 113 114 CLST_Rect GetRect() const; 115 bool IsSelected() const; 116 FX_FLOAT GetItemHeight() const; 117 uint16_t GetFirstChar() const; 118 119 private: 120 CFX_Edit_Iterator* GetIterator() const; 121 122 std::unique_ptr<CFX_Edit> m_pEdit; 123 bool m_bSelected; 124 CLST_Rect m_rcListItem; 125 }; 126 127 class CFX_ListContainer { 128 public: 129 CFX_ListContainer(); 130 virtual ~CFX_ListContainer(); 131 132 virtual void SetPlateRect(const CFX_FloatRect& rect); 133 GetPlateRect()134 CFX_FloatRect GetPlateRect() const { return m_rcPlate; } SetContentRect(const CLST_Rect & rect)135 void SetContentRect(const CLST_Rect& rect) { m_rcContent = rect; } GetContentRect()136 CLST_Rect GetContentRect() const { return m_rcContent; } GetBTPoint()137 CFX_PointF GetBTPoint() const { 138 return CFX_PointF(m_rcPlate.left, m_rcPlate.top); 139 } GetETPoint()140 CFX_PointF GetETPoint() const { 141 return CFX_PointF(m_rcPlate.right, m_rcPlate.bottom); 142 } 143 144 public: InnerToOuter(const CFX_PointF & point)145 CFX_PointF InnerToOuter(const CFX_PointF& point) const { 146 return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y); 147 } OuterToInner(const CFX_PointF & point)148 CFX_PointF OuterToInner(const CFX_PointF& point) const { 149 return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y); 150 } InnerToOuter(const CLST_Rect & rect)151 CFX_FloatRect InnerToOuter(const CLST_Rect& rect) const { 152 CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top)); 153 CFX_PointF ptRightBottom = 154 InnerToOuter(CFX_PointF(rect.right, rect.bottom)); 155 return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, 156 ptLeftTop.y); 157 } OuterToInner(const CFX_FloatRect & rect)158 CLST_Rect OuterToInner(const CFX_FloatRect& rect) const { 159 CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top)); 160 CFX_PointF ptRightBottom = 161 OuterToInner(CFX_PointF(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 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 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_PointF& point, bool bShift, bool bCtrl); 228 void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); 229 void OnVK_UP(bool bShift, bool bCtrl); 230 void OnVK_DOWN(bool bShift, bool bCtrl); 231 void OnVK_LEFT(bool bShift, bool bCtrl); 232 void OnVK_RIGHT(bool bShift, bool bCtrl); 233 void OnVK_HOME(bool bShift, bool bCtrl); 234 void OnVK_END(bool bShift, bool bCtrl); 235 void OnVK(int32_t nItemIndex, bool bShift, bool bCtrl); 236 bool OnChar(uint16_t nChar, bool bShift, bool bCtrl); 237 238 void SetScrollPos(const CFX_PointF& 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_PointF& point) const; 246 void AddString(const CFX_WideString& 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 bool IsItemSelected(int32_t nIndex) const; 261 FX_FLOAT GetFirstHeight() const; 262 void SetMultipleSel(bool bMultiple); 263 bool IsMultipleSel() const; 264 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_PointF InToOut(const CFX_PointF& point) const; 269 CFX_PointF OutToIn(const CFX_PointF& 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, bool bSelected); 278 void SetSingleSelect(int32_t nItemIndex); 279 void InvalidateItem(int32_t nItemIndex); 280 void SelectItems(); 281 bool IsItemVisible(int32_t nItemIndex) const; 282 void SetScrollInfo(); 283 void SetScrollPosY(FX_FLOAT fy); 284 void AddItem(const CFX_WideString& str); 285 CFX_WideString GetItemText(int32_t nIndex) const; 286 void SetItemSelect(int32_t nItemIndex, bool bSelected); 287 int32_t GetLastSelected() const; 288 FX_WCHAR Toupper(FX_WCHAR c) const; 289 290 CPWL_List_Notify* m_pNotify; 291 bool m_bNotifyFlag; 292 CFX_PointF m_ptScrollPos; 293 CPLST_Select m_aSelItems; // for multiple 294 int32_t m_nSelItem; // for single 295 int32_t m_nFootIndex; // for multiple 296 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 bool m_bMultiple; 302 }; 303 304 #endif // FPDFSDK_FXEDIT_FXET_LIST_H_ 305