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-2024 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
77  {
78  Above = 0,
79  Left = 1
80  };
81 
82  enum class InputType
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  // Inquiry
160  auto hasShadow() const -> bool;
161  auto isReadOnly() const noexcept -> bool;
162 
163  // Methods
164  void hide() override;
165  void clear();
166 
167  // Event handlers
168  void onKeyPress (FKeyEvent*) override;
169  void onMouseDown (FMouseEvent*) override;
170  void onMouseUp (FMouseEvent*) override;
171  void onMouseMove (FMouseEvent*) override;
172  void onWheel (FWheelEvent*) override;
173  void onTimer (FTimerEvent*) override;
174  void onAccel (FAccelEvent*) override;
175  void onHide (FHideEvent*) override;
176  void onFocusIn (FFocusEvent*) override;
177  void onFocusOut (FFocusEvent*) override;
178 
179  protected:
180  void adjustLabel();
181  void adjustSize() override;
182 
183  private:
184  // Using-declaration
185  using offsetPair = std::pair<std::size_t, std::size_t>;
186  using KeyMap = std::unordered_map<FKey, std::function<void()>, EnumHash<FKey>>;
187 
188  // Constants
189  static constexpr auto NOT_SET = static_cast<std::size_t>(-1);
190  static constexpr auto NOT_FOUND = static_cast<std::size_t>(-1);
191 
192  // Methods
193  void init();
194  void mapKeyFunctions();
195  auto hasHotkey() const -> bool;
196  auto getAlignOffset (const std::size_t) const -> std::size_t;
197  void draw() override;
198  void drawInputField();
199  void initializeDrawing();
200  void finalizingDrawing() const;
201  void printTrailingSpaces (std::size_t x_pos);
202  auto choosePrintMethod() -> std::tuple<std::size_t, std::size_t>;
203  auto printTextField() -> std::tuple<std::size_t, std::size_t>;
204  auto printPassword() -> std::tuple<std::size_t, std::size_t>;
205  void drawShadow();
206  auto getCursorColumnPos() const -> std::size_t;
207  auto getPasswordText() const -> FString;
208  auto isPasswordField() const -> bool;
209  auto isFullwidthChar (std::size_t) const -> bool;
210  auto getColumnWidthWithErrorHandling ( FString::const_reference
211  , std::size_t = 0 ) const ->std::size_t;
212  auto endPosToOffset (std::size_t) -> offsetPair;
213  auto clickPosToCursorPos (std::size_t) -> std::size_t;
214  void setCursorPositionByMouseClick (const FMouseEvent*);
215  void handleAutoScroll (const FMouseEvent*);
216  void handleLeftDragScroll();
217  void handleRightDragScroll();
218  void adjustTextOffset();
219  void cursorLeft();
220  void cursorRight();
221  void cursorHome();
222  void cursorEnd();
223  void deleteCurrentCharacter();
224  void deletePreviousCharacter();
225  void switchInsertMode();
226  void acceptInput();
227  auto keyInput (FKey) -> bool;
228  auto characterFilter (const wchar_t) const -> wchar_t;
229  void processActivate();
230  void processChanged() const;
231 
232  // Data members
233  FString text{""};
234  FString print_text{""};
235  FString label_text{""};
236  FLabel* label{};
237  FWidget* label_associated_widget{this};
238  std::wstring input_filter{};
239  KeyMap key_map{};
240  DragScrollMode drag_scroll{DragScrollMode::None};
241  LabelOrientation label_orientation{LabelOrientation::Left};
242  InputType input_type{InputType::Textfield};
243  int scroll_repeat{100};
244  bool scroll_timer{false};
245  bool insert_mode{true};
246  bool read_only{false};
247  Align alignment{Align::Left};
248  std::size_t align_offset{0};
249  std::size_t cursor_pos{NOT_SET};
250  std::size_t text_offset{0};
251  std::size_t char_width_offset{0};
252  std::size_t max_length{std::numeric_limits<std::size_t>::max()};
253 };
254 
255 
256 // FLineEdit inline functions
257 //----------------------------------------------------------------------
258 template <typename typeT>
259 inline auto FLineEdit::operator << (const typeT& s) -> FLineEdit&
260 {
261  FString str{};
262  str << s;
263  setText(text + str);
264  return *this;
265 }
266 
267 //----------------------------------------------------------------------
268 inline auto FLineEdit::getClassName() const -> FString
269 { return "FLineEdit"; }
270 
271 //----------------------------------------------------------------------
272 inline auto FLineEdit::getAlignment() const noexcept -> Align
273 { return alignment; }
274 
275 //----------------------------------------------------------------------
276 inline auto FLineEdit::getText() const -> FString
277 { return text; }
278 
279 //----------------------------------------------------------------------
280 inline auto FLineEdit::getMaxLength() const noexcept -> std::size_t
281 { return max_length; }
282 
283 //----------------------------------------------------------------------
284 inline auto FLineEdit::getCursorPosition() const noexcept -> std::size_t
285 { return cursor_pos; }
286 
287 //----------------------------------------------------------------------
288 inline auto FLineEdit::getLabelObject() const -> FLabel*
289 { return label; }
290 
291 //----------------------------------------------------------------------
292 inline auto FLineEdit::getLabelOrientation() const -> LabelOrientation
293 { return label_orientation; }
294 
295 //----------------------------------------------------------------------
296 inline void FLineEdit::setInputFilter (const FString& regex_string)
297 { input_filter = regex_string.toWString(); }
298 
299 //----------------------------------------------------------------------
300 inline void FLineEdit::clearInputFilter()
301 { input_filter.clear(); }
302 
303 //----------------------------------------------------------------------
304 inline void FLineEdit::setInputType (const InputType type)
305 { input_type = type; }
306 
307 //----------------------------------------------------------------------
308 inline void FLineEdit::setLabelAssociatedWidget (FWidget* w)
309 { label_associated_widget = w; }
310 
311 //----------------------------------------------------------------------
312 inline void FLineEdit::unsetEnable()
313 { setEnable(false); }
314 
315 //----------------------------------------------------------------------
316 inline void FLineEdit::setDisable()
317 { setEnable(false); }
318 
319 //----------------------------------------------------------------------
320 inline void FLineEdit::unsetShadow()
321 { setShadow(false); }
322 
323 //----------------------------------------------------------------------
324 inline void FLineEdit::unsetReadOnly()
325 { setReadOnly(true); }
326 
327 //----------------------------------------------------------------------
328 inline auto FLineEdit::hasShadow() const -> bool
329 { return getFlags().shadow.shadow; }
330 
331 //----------------------------------------------------------------------
332 inline auto FLineEdit::isReadOnly() const noexcept -> bool
333 { return read_only; }
334 
335 } // namespace finalcut
336 
337 #endif // FLINEEDIT_H
Definition: fevent.h:196
Definition: fevent.h:144
Definition: fevent.h:300
Definition: fevent.h:171
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fsize.h:55
Definition: fstring.h:79
Definition: fevent.h:271
Definition: fwidget.h:129
Definition: flineedit.h:67
Definition: fevent.h:220
Definition: fevent.h:124
Definition: ftypes.h:160
Definition: flabel.h:62