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: 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 36 class 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 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: 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 193 template <class TYPE> 194 class 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 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 { 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 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; 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