FINAL CUT
flineedit.h
1 /***********************************************************************
2 * flineedit.h - Widget FLineEdit *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2012-2026 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Inheritance diagram
24  * ═══════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏
27  * ▕ FVTerm ▏ ▕ FObject ▏
28  * ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏
29  * ▲ ▲
30  * │ │
31  * └─────┬─────┘
32  * │
33  * ▕▔▔▔▔▔▔▔▔▔▏
34  * ▕ FWidget ▏
35  * ▕▁▁▁▁▁▁▁▁▁▏
36  * ▲
37  * │
38  * ▕▔▔▔▔▔▔▔▔▔▔▔▏
39  * ▕ FLineEdit ▏
40  * ▕▁▁▁▁▁▁▁▁▁▁▁▏
41  */
42 
43 #ifndef FLINEEDIT_H
44 #define FLINEEDIT_H
45 
46 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
47  #error "Only <final/final.h> can be included directly."
48 #endif
49 
50 #include <limits>
51 #include <tuple>
52 #include <unordered_map>
53 #include <utility>
54 
55 #include "final/fwidget.h"
56 
57 namespace finalcut
58 {
59 
60 // class forward declaration
61 class FLabel;
62 
63 //----------------------------------------------------------------------
64 // class FLineEdit
65 //----------------------------------------------------------------------
66 
67 class FLineEdit : public FWidget
68 {
69  public:
70  // Using-declaration
71  using FWidget::setGeometry;
72  using FWidget::setVisibleCursor;
73  using FWidget::unsetVisibleCursor;
74 
75  // Enumerations
76  enum class LabelOrientation : uInt8
77  {
78  Above = 0,
79  Left = 1
80  };
81 
82  enum class InputType : uInt8
83  {
84  Textfield = 0,
85  Password = 1
86  };
87 
88  // Constructor
89  explicit FLineEdit (FWidget* = nullptr);
90  explicit FLineEdit (const FString&, FWidget* = nullptr);
91 
92  // Disable copy constructor
93  FLineEdit (const FLineEdit&) = delete;
94 
95  // Disable move constructor
96  FLineEdit (FLineEdit&&) noexcept = delete;
97 
98  // Destructor
99  ~FLineEdit() override;
100 
101  // Disable copy assignment operator (=)
102  auto operator = (const FLineEdit&) -> FLineEdit& = delete;
103 
104  // Disable move assignment operator (=)
105  auto operator = (FLineEdit&&) noexcept -> FLineEdit& = delete;
106 
107  // Overloaded operators
108  auto operator = (const FString&) -> FLineEdit&;
109  template <typename typeT>
110  auto operator << (const typeT&) -> FLineEdit&;
111  auto operator << (UniChar) -> FLineEdit&;
112  auto operator << (const wchar_t) -> FLineEdit&;
113 
114  friend auto operator >> (const FLineEdit& lhs, FString& rhs) -> const FLineEdit&
115  {
116  rhs += lhs.text;
117  return lhs;
118  }
119 
120  // Accessors
121  auto getClassName() const -> FString override;
122  auto getAlignment() const noexcept -> Align;
123  auto getText() const -> FString;
124  auto getMaxLength() const noexcept -> std::size_t;
125  auto getCursorPosition() const noexcept -> std::size_t;
126  auto getLabelObject() const -> FLabel*;
127  auto getLabelOrientation() const -> LabelOrientation;
128 
129  // Mutators
130  void setAlignment (Align) noexcept;
131  void setText (const FString&);
132  void inputText (const FString&);
133  void deletesCharacter();
134  void setInputFilter (const FString&);
135  void clearInputFilter();
136  void setMaxLength (std::size_t);
137  void setCursorPosition (std::size_t);
138  void moveCursorToBegin();
139  void moveCursorToEnd();
140  void stepCursorForward (std::size_t = 1);
141  void stepCursorBackward (std::size_t = 1);
142  void setLabelText (const FString&);
143  void setInputType (const InputType);
144  void setOverwriteMode (bool = true);
145  void setLabelOrientation (const LabelOrientation);
146  void setLabelAssociatedWidget (FWidget*);
147  void resetColors() override;
148  void setSize (const FSize&, bool = true) override;
149  void setGeometry ( const FPoint&, const FSize&
150  , bool = true ) override;
151  void setEnable (bool = true) override;
152  void unsetEnable() override;
153  void setDisable() override;
154  void setShadow (bool = true);
155  void unsetShadow();
156  void setReadOnly (bool = true);
157  void unsetReadOnly();
158 
159  // Predicate
160  auto hasShadow() const -> bool;
161  auto isReadOnly() const noexcept -> bool;
162 
163  // Methods
164  void show() override;
165  void hide() override;
166  void clear();
167 
168  // Event handlers
169  void onKeyPress (FKeyEvent*) override;
170  void onMouseDown (FMouseEvent*) override;
171  void onMouseUp (FMouseEvent*) override;
172  void onMouseMove (FMouseEvent*) override;
173  void onWheel (FWheelEvent*) override;
174  void onTimer (FTimerEvent*) override;
175  void onAccel (FAccelEvent*) override;
176  void onHide (FHideEvent*) override;
177  void onFocusIn (FFocusEvent*) override;
178  void onFocusOut (FFocusEvent*) override;
179 
180  protected:
181  void adjustLabel();
182  void adjustSize() override;
183 
184  private:
185  // Using-declaration
186  using offsetPair = std::pair<std::size_t, std::size_t>;
187  using KeyMap = std::unordered_map<FKey, std::function<void()>, EnumHash<FKey>>;
188 
189  // Constants
190  static constexpr auto NOT_SET = static_cast<std::size_t>(-1);
191  static constexpr auto NOT_FOUND = static_cast<std::size_t>(-1);
192 
193  // Methods
194  void init();
195  void mapKeyFunctions();
196  auto hasHotkey() const -> bool;
197  auto getAlignOffset (const std::size_t) const -> std::size_t;
198  void draw() override;
199  void drawInputField();
200  void initializeDrawing();
201  void finalizingDrawing() const;
202  void printTrailingSpaces (std::size_t x_pos);
203  auto choosePrintMethod() -> std::tuple<std::size_t, std::size_t>;
204  auto printTextField() -> std::tuple<std::size_t, std::size_t>;
205  auto printPassword() -> std::tuple<std::size_t, std::size_t>;
206  void drawShadow();
207  auto getCursorColumnPos() const -> std::size_t;
208  auto getPasswordText() const -> FString;
209  auto isPasswordField() const -> bool;
210  auto isFullwidthChar (std::size_t) const -> bool;
211  auto getColumnWidthWithErrorHandling ( FString::const_reference
212  , std::size_t = 0 ) const ->std::size_t;
213  auto endPosToOffset (std::size_t) -> offsetPair;
214  auto clickPosToCursorPos (std::size_t) -> std::size_t;
215  void setCursorPositionByMouseClick (const FMouseEvent*);
216  void handleAutoScroll (const FMouseEvent*);
217  void handleLeftDragScroll();
218  void handleRightDragScroll();
219  void adjustTextOffset();
220  auto isRightCursorOverflow (std::size_t, std::size_t) const -> bool;
221  auto isRightFullWidthCursorOverflow (std::size_t, std::size_t, std::size_t) const -> bool;
222  auto isLeftCursorUnderflow() const -> bool;
223  void cursorLeft();
224  void cursorRight();
225  void cursorHome();
226  void cursorEnd();
227  void deleteCurrentCharacter();
228  void deletePreviousCharacter();
229  void switchInsertMode();
230  void acceptInput();
231  auto keyInput (FKey) -> bool;
232  auto characterFilter (const wchar_t) const -> wchar_t;
233  void processActivate();
234  void processChanged() const;
235 
236  // Data members
237  FString text{""};
238  FString print_text{""};
239  FString label_text{""};
240  FLabel* label{};
241  FWidget* label_associated_widget{this};
242  std::wstring input_filter{};
243  KeyMap key_map{};
244  DragScrollMode drag_scroll{DragScrollMode::None};
245  LabelOrientation label_orientation{LabelOrientation::Left};
246  InputType input_type{InputType::Textfield};
247  int scroll_repeat{100};
248  bool scroll_timer{false};
249  bool insert_mode{true};
250  bool read_only{false};
251  Align alignment{Align::Left};
252  std::size_t align_offset{0};
253  std::size_t cursor_pos{NOT_SET};
254  std::size_t text_offset{0};
255  std::size_t char_width_offset{0};
256  std::size_t max_length{std::numeric_limits<std::size_t>::max()};
257 };
258 
259 
260 // FLineEdit inline functions
261 //----------------------------------------------------------------------
262 template <typename typeT>
263 inline auto FLineEdit::operator << (const typeT& s) -> FLineEdit&
264 {
265  FString str{};
266  str << s;
267  setText(text + str);
268  return *this;
269 }
270 
271 //----------------------------------------------------------------------
272 inline auto FLineEdit::getClassName() const -> FString
273 { return "FLineEdit"; }
274 
275 //----------------------------------------------------------------------
276 inline auto FLineEdit::getAlignment() const noexcept -> Align
277 { return alignment; }
278 
279 //----------------------------------------------------------------------
280 inline auto FLineEdit::getText() const -> FString
281 { return text; }
282 
283 //----------------------------------------------------------------------
284 inline auto FLineEdit::getMaxLength() const noexcept -> std::size_t
285 { return max_length; }
286 
287 //----------------------------------------------------------------------
288 inline auto FLineEdit::getCursorPosition() const noexcept -> std::size_t
289 { return cursor_pos; }
290 
291 //----------------------------------------------------------------------
292 inline auto FLineEdit::getLabelObject() const -> FLabel*
293 { return label; }
294 
295 //----------------------------------------------------------------------
296 inline auto FLineEdit::getLabelOrientation() const -> LabelOrientation
297 { return label_orientation; }
298 
299 //----------------------------------------------------------------------
300 inline void FLineEdit::setInputFilter (const FString& regex_string)
301 { input_filter = regex_string.toWString(); }
302 
303 //----------------------------------------------------------------------
304 inline void FLineEdit::clearInputFilter()
305 { input_filter.clear(); }
306 
307 //----------------------------------------------------------------------
308 inline void FLineEdit::setInputType (const InputType type)
309 { input_type = type; }
310 
311 //----------------------------------------------------------------------
312 inline void FLineEdit::setLabelAssociatedWidget (FWidget* w)
313 { label_associated_widget = w; }
314 
315 //----------------------------------------------------------------------
316 inline void FLineEdit::unsetEnable()
317 { setEnable(false); }
318 
319 //----------------------------------------------------------------------
320 inline void FLineEdit::setDisable()
321 { setEnable(false); }
322 
323 //----------------------------------------------------------------------
324 inline void FLineEdit::unsetShadow()
325 { setShadow(false); }
326 
327 //----------------------------------------------------------------------
328 inline void FLineEdit::unsetReadOnly()
329 { setReadOnly(true); }
330 
331 //----------------------------------------------------------------------
332 inline auto FLineEdit::hasShadow() const -> bool
333 { return getFlags().shadow.shadow; }
334 
335 //----------------------------------------------------------------------
336 inline auto FLineEdit::isReadOnly() const noexcept -> bool
337 { return read_only; }
338 
339 } // namespace finalcut
340 
341 #endif // FLINEEDIT_H
Definition: fevent.h:207
Definition: fevent.h:144
Definition: fevent.h:311
Definition: fevent.h:182
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fstring.h:82
Definition: fevent.h:282
Definition: fwidget.h:129
Definition: flineedit.h:67
Definition: fevent.h:231
Definition: fevent.h:124
Definition: ftypes.h:161
Definition: flabel.h:62