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