Fcitx
candidatelist.h
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_CANDIDATELIST_H_
8 #define _FCITX_CANDIDATELIST_H_
9 
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 #include <fcitx-utils/key.h>
15 #include <fcitx-utils/macros.h>
16 #include <fcitx/candidateaction.h>
17 #include <fcitx/fcitxcore_export.h>
18 #include <fcitx/text.h>
19 
20 namespace fcitx {
21 
22 class InputContext;
23 class PageableCandidateList;
24 class BulkCandidateList;
25 class ModifiableCandidateList;
26 class CursorMovableCandidateList;
27 class CursorModifiableCandidateList;
28 class BulkCursorCandidateList;
29 class ActionableCandidateList;
30 
31 class CandidateListPrivate;
32 
33 enum class CandidateLayoutHint { NotSet, Vertical, Horizontal };
34 
35 class CandidateWordPrivate;
36 
37 /// Base class of candidate word.
38 class FCITXCORE_EXPORT CandidateWord {
39 public:
40  CandidateWord(Text text = {});
41  virtual ~CandidateWord();
42  /**
43  * Called when candidate is selected by user.
44  *
45  * @param inputContext the associated input context for the candidate.
46  */
47  virtual void select(InputContext *inputContext) const = 0;
48 
49  const Text &text() const;
50  /**
51  * Whether the candidate is only a place holder.
52  *
53  * If candidate is a place holder, it will not be displayed by UI, but it
54  * will still take one place in the candidate list.
55  */
56  bool isPlaceHolder() const;
57  bool hasCustomLabel() const;
58  const Text &customLabel() const;
59  /**
60  * Return comment corresponding to the candidate.
61  *
62  * @return value of comment.
63  * @since 5.1.9
64  */
65  const Text &comment() const;
66  /**
67  * Return text with comment.
68  *
69  * @param separator separator between text and comment.
70  * @return value of comment.
71  * @since 5.1.9
72  */
73  Text textWithComment(std::string separator = " ") const;
74 
75 protected:
76  void setText(Text text);
77  void setPlaceHolder(bool placeHolder);
78  void resetCustomLabel();
79  void setCustomLabel(Text text);
80  void setComment(Text comment);
81 
82 private:
83  std::unique_ptr<CandidateWordPrivate> d_ptr;
84  FCITX_DECLARE_PRIVATE(CandidateWord);
85 };
86 
87 // basic stuff
88 class FCITXCORE_EXPORT CandidateList {
89 public:
90  CandidateList();
91  virtual ~CandidateList();
92 
93  virtual const Text &label(int idx) const = 0;
94  virtual const CandidateWord &candidate(int idx) const = 0;
95  virtual int size() const = 0;
96  virtual int cursorIndex() const = 0;
97  virtual CandidateLayoutHint layoutHint() const = 0;
98 
99  bool empty() const;
100 
101  PageableCandidateList *toPageable() const;
102  BulkCandidateList *toBulk() const;
103  ModifiableCandidateList *toModifiable() const;
104  CursorMovableCandidateList *toCursorMovable() const;
105  CursorModifiableCandidateList *toCursorModifiable() const;
106  BulkCursorCandidateList *toBulkCursor() const;
107  ActionableCandidateList *toActionable() const;
108 
109 protected:
110  void setPageable(PageableCandidateList *list);
111  void setBulk(BulkCandidateList *list);
112  void setModifiable(ModifiableCandidateList *list);
113  void setCursorMovable(CursorMovableCandidateList *list);
114  void setCursorModifiable(CursorModifiableCandidateList *list);
115  void setBulkCursor(BulkCursorCandidateList *list);
116  void setActionable(ActionableCandidateList *list);
117 
118 private:
119  std::unique_ptr<CandidateListPrivate> d_ptr;
120  FCITX_DECLARE_PRIVATE(CandidateList);
121 };
122 
123 // useful for regular input method
124 class FCITXCORE_EXPORT PageableCandidateList {
125 public:
126  // Need for paging
127  virtual bool hasPrev() const = 0;
128  virtual bool hasNext() const = 0;
129  virtual void prev() = 0;
130  virtual void next() = 0;
131 
132  virtual bool usedNextBefore() const = 0;
133 
134  // Following are optional.
135  virtual int totalPages() const { return -1; }
136  virtual int currentPage() const { return -1; }
137  virtual void setPage(int /*unused*/) {}
138 };
139 
140 class FCITXCORE_EXPORT CursorMovableCandidateList {
141 public:
142  virtual void prevCandidate() = 0;
143  virtual void nextCandidate() = 0;
144 };
145 
146 class FCITXCORE_EXPORT CursorModifiableCandidateList {
147 public:
148  virtual void setCursorIndex(int index) = 0;
149 };
150 
151 // useful for virtual keyboard
152 class FCITXCORE_EXPORT BulkCandidateList {
153 public:
154  /**
155  * If idx is out of range, it may raise exception. Catching the exception is
156  * useful to iterate over all candidate list for candidate list has no total
157  * size.
158  */
159  virtual const CandidateWord &candidateFromAll(int idx) const = 0;
160  /**
161  * It's possible for this function to return -1 if the implement has no
162  * clear number how many candidates are available.
163  */
164  virtual int totalSize() const = 0;
165 };
166 
167 // useful for module other than input method
168 class FCITXCORE_EXPORT ModifiableCandidateList : public BulkCandidateList {
169 public:
170  // All index used there are global index
171  virtual void insert(int idx, std::unique_ptr<CandidateWord> word) = 0;
172  virtual void remove(int idx) = 0;
173  virtual void replace(int idx, std::unique_ptr<CandidateWord> word) = 0;
174  virtual void move(int from, int to) = 0;
175 
176  void append(std::unique_ptr<CandidateWord> word) {
177  insert(totalSize(), std::move(word));
178  }
179 
180  template <typename CandidateWordType, typename... Args>
181  void append(Args &&...args) {
182  append(
183  std::make_unique<CandidateWordType>(std::forward<Args>(args)...));
184  }
185 };
186 
187 class FCITXCORE_EXPORT DisplayOnlyCandidateWord : public CandidateWord {
188 public:
189  DisplayOnlyCandidateWord(Text text) : CandidateWord(std::move(text)) {}
190  DisplayOnlyCandidateWord(Text text, Text comment)
191  : CandidateWord(std::move(text)) {
192  setComment(std::move(comment));
193  }
194 
195  void select(InputContext * /*inputContext*/) const override {}
196 };
197 
198 class FCITXCORE_EXPORT BulkCursorCandidateList {
199 public:
200  virtual int globalCursorIndex() const = 0;
201  virtual void setGlobalCursorIndex(int index) = 0;
202 };
203 
204 /**
205  * Interface for trigger actions on candidates.
206  *
207  * @since 5.1.10
208  */
209 class FCITXCORE_EXPORT ActionableCandidateList {
210 public:
211  virtual ~ActionableCandidateList();
212 
213  /**
214  * Check whether this candidate has action.
215  *
216  * This function should be fast and guarantee that candidateActions return a
217  * not empty vector.
218  */
219  virtual bool hasAction(const CandidateWord &candidate) const = 0;
220 
221  /**
222  * Return a list of actions.
223  */
224  virtual std::vector<CandidateAction>
225  candidateActions(const CandidateWord &candidate) const = 0;
226 
227  /**
228  * Trigger the action based on the index returned from candidateActions.
229  */
230  virtual void triggerAction(const CandidateWord &candidate, int id) = 0;
231 };
232 
234 
235 class FCITXCORE_EXPORT DisplayOnlyCandidateList : public CandidateList {
236 public:
239 
240  void setContent(const std::vector<std::string> &content);
241  void setContent(std::vector<Text> content);
242  void setLayoutHint(CandidateLayoutHint hint);
243  void setCursorIndex(int index);
244 
245  // CandidateList
246  const fcitx::Text &label(int idx) const override;
247  const CandidateWord &candidate(int idx) const override;
248  int cursorIndex() const override;
249  int size() const override;
250  CandidateLayoutHint layoutHint() const override;
251 
252 private:
253  std::unique_ptr<DisplayOnlyCandidateListPrivate> d_ptr;
254  FCITX_DECLARE_PRIVATE(DisplayOnlyCandidateList);
255 };
256 
258 
259 enum class CursorPositionAfterPaging { SameAsLast, DonotChange, ResetToFirst };
260 
261 /**
262  * A common simple candidate list that serves most of the purpose.
263  */
264 class FCITXCORE_EXPORT CommonCandidateList : public CandidateList,
265  public PageableCandidateList,
268 public:
271 
272  void clear();
273 
274  /**
275  * Set the label of candidate list.
276  *
277  * The labels less than 10 will be automatically filled with to empty ones
278  * up to 10 to be more error prone.
279  *
280  * @param labels list of labels.
281  *
282  * @since 5.0.4
283  */
284  void setLabels(const std::vector<std::string> &labels = {});
285 
286  /**
287  * Set the label of candidate list by key.
288  *
289  * @param keyList list of selection key
290  */
291  void setSelectionKey(const KeyList &keyList);
292 
293  void setPageSize(int size);
294  int pageSize() const;
295  void setLayoutHint(CandidateLayoutHint hint);
296  void setGlobalCursorIndex(int index);
297  /**
298  * Return Global cursor index.
299  *
300  * -1 means it is not selected.
301  *
302  * @return cursor index.
303  * @since 5.0.4
304  */
305  int globalCursorIndex() const;
306 
307  /**
308  * Set cursor index on current page.
309  *
310  * @param index index on current page;
311  * @since 5.1.9
312  */
313  void setCursorIndex(int index);
314 
315  // CandidateList
316  const fcitx::Text &label(int idx) const override;
317  const CandidateWord &candidate(int idx) const override;
318  int cursorIndex() const override;
319  int size() const override;
320 
321  // PageableCandidateList
322  bool hasPrev() const override;
323  bool hasNext() const override;
324  void prev() override;
325  void next() override;
326 
327  bool usedNextBefore() const override;
328 
329  int totalPages() const override;
330  int currentPage() const override;
331  void setPage(int page) override;
332 
333  CandidateLayoutHint layoutHint() const override;
334 
335  // BulkCandidateList
336  const CandidateWord &candidateFromAll(int idx) const override;
337  int totalSize() const override;
338 
339  // ModifiableCandidateList
340  void insert(int idx, std::unique_ptr<CandidateWord> word) override;
341  void remove(int idx) override;
342  void replace(int idx, std::unique_ptr<CandidateWord> word) override;
343  void move(int from, int to) override;
344 
345  // CursorMovableCandidateList
346  void prevCandidate() override;
347  void nextCandidate() override;
348 
349  // A simple switch to change the behavior of prevCandidate and nextCandidate
350  void setCursorIncludeUnselected(bool);
351  void setCursorKeepInSamePage(bool);
352  void setCursorPositionAfterPaging(CursorPositionAfterPaging afterPaging);
353 
354  /**
355  * Set an optional implemenation of actionable candidate list
356  *
357  * @since 5.1.10
358  */
359  void setActionableImpl(std::unique_ptr<ActionableCandidateList> actionable);
360 
361 private:
362  void fixAfterUpdate();
363  void moveCursor(bool prev);
364 
365  std::unique_ptr<CommonCandidateListPrivate> d_ptr;
366  FCITX_DECLARE_PRIVATE(CommonCandidateList);
367 };
368 } // namespace fcitx
369 
370 #endif // _FCITX_CANDIDATELIST_H_
Formatted string commonly used in user interface.
Definition: action.cpp:17
A class represents a formatted string.
Definition: text.h:27
void select(InputContext *) const override
Called when candidate is selected by user.
Interface for trigger actions on candidates.
Base class of candidate word.
Definition: candidatelist.h:38
A common simple candidate list that serves most of the purpose.
An input context represents a client of Fcitx.
Definition: inputcontext.h:47
Class to represent a key.