FINAL CUT
fapplication.h
1 /***********************************************************************
2 * fapplication.h - Manages the application events *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2013-2025 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  * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▏
39  * ▕ FApplication ▏-┬- - - -▕ FLog ▏
40  * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ : ▕▁▁▁▁▁▁▏
41  * :
42  * : *▕▔▔▔▔▔▔▔▔▏
43  * :- - - -▕ FEvent ▏
44  * : ▕▁▁▁▁▁▁▁▁▏
45  * :
46  * : *▕▔▔▔▔▔▔▔▔▏
47  * :- - - -▕ FPoint ▏
48  * : ▕▁▁▁▁▁▁▁▁▏
49  * :
50  * : *▕▔▔▔▔▔▔▔▔▔▏
51  * └- - - -▕ FWidget ▏
52  * ▕▁▁▁▁▁▁▁▁▁▏
53  */
54 
55 #ifndef FAPPLICATION_H
56 #define FAPPLICATION_H
57 
58 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
59  #error "Only <final/final.h> can be included directly."
60 #endif
61 
62 #include <getopt.h>
63 #include <deque>
64 #include <memory>
65 #include <string>
66 #include <unordered_map>
67 #include <utility>
68 #include <vector>
69 
70 #include "final/ftypes.h"
71 #include "final/fwidget.h"
72 
73 namespace finalcut
74 {
75 
76 // class forward declaration
77 class FAccelEvent;
78 class FCloseEvent;
79 class FEvent;
80 class FFocusEvent;
81 class FKeyEvent;
82 class FLog;
83 class FMouseData;
84 class FMouseEvent;
85 class FStartOptions;
86 class FTimerEvent;
87 class FWheelEvent;
88 class FMouseControl;
89 class FPoint;
90 class FObject;
91 
92 //----------------------------------------------------------------------
93 // class FApplication
94 //----------------------------------------------------------------------
95 
96 class FApplication : public FWidget
97 {
98  public:
99  // Typedef
100  using FLogPtr = std::shared_ptr<FLog>;
101  using Args = std::vector<std::string>;
102  using FMouseHandler = std::function<void(FMouseData)>;
103 
104  // Constructor
105  FApplication (const int&, char*[]);
106 
107  // Disable copy constructor
108  FApplication (const FApplication&) = delete;
109 
110  // Disable move constructor
111  FApplication (FApplication&&) noexcept = delete;
112 
113  // Destructor
114  ~FApplication() override;
115 
116  // Disable copy assignment operator (=)
117  auto operator = (const FApplication&) -> FApplication& = delete;
118 
119  // Disable move assignment operator (=)
120  auto operator = (FApplication&&) noexcept -> FApplication& = delete;
121 
122  // Accessors
123  auto getClassName() const -> FString override;
124  auto getArgs() const -> Args;
125  static auto getApplicationObject() -> FApplication*;
126  static auto getKeyboardWidget() -> FWidget*;
127  static auto getLog() -> FLogPtr&;
128 
129  // Mutator
130  static void setLog (const FLogPtr&);
131 
132  // Predicate
133  static auto isQuit() -> bool;
134 
135  // Methods
136 #if defined(UNIT_TEST)
137  static void start(); // Simulates application start
138 #endif
139  auto exec() -> int; // run
140  auto enterLoop() -> int;
141  void exitLoop() const;
142  static void exit (int = EXIT_SUCCESS);
143  void quit() const;
144  static auto sendEvent (FObject*, FEvent*) -> bool;
145  void queueEvent (FObject*, FEvent*);
146  void sendQueuedEvents();
147  auto eventInQueue() const -> bool;
148  auto removeQueuedEvent (const FObject*) -> bool;
149  void registerMouseHandler (const FMouseHandler&);
150  void initTerminal() override;
151  static void setDefaultTheme();
152  static void setDarkTheme();
153  static void setLogFile (const FString&);
154  static void setKeyboardWidget (FWidget*);
155  static void closeConfirmationDialog (FWidget*, FCloseEvent*);
156 
157  // Callback method
158  void cb_exitApp (FWidget*) const;
159 
160  protected:
161  virtual void processExternalUserEvent();
162 
163  private:
164  // Using-declaration
165  using CmdOption = struct option;
166  using EventPair = std::pair<FObject*, FEvent*>;
167  using FEventQueue = std::deque<EventPair>;
168  using FMouseHandlerList = std::vector<FMouseHandler>;
169  using CmdMap = std::unordered_map<int, std::function<void(char*)>>;
170  using rdbuf = std::streambuf*;
171 
172  // Methods
173  void init();
174  static void setTerminalEncoding (const FString&);
175  static auto getLongOptions() -> const std::vector<struct option>&;
176  static void setCmdOptionsMap (CmdMap&);
177  static void cmdOptions (const Args&);
178  static auto getStartOptions() -> FStartOptions&;
179  static void showParameterUsage();
180  void resetLog() const;
181  void findKeyboardWidget() const;
182  auto isKeyPressed (uInt64 = 0U) const -> bool;
183  void keyPressed();
184  void keyReleased() const;
185  void escapeKeyPressed() const;
186  void mouseTracking() const;
187  void performKeyboardAction();
188  void performMouseAction() const;
189  void mouseEvent (const FMouseData&) const;
190  void sendEscapeKeyPressEvent() const;
191  auto sendKeyDownEvent (FWidget*) const -> bool;
192  auto sendKeyPressEvent (FWidget*) const -> bool;
193  auto sendKeyUpEvent (FWidget*) const -> bool;
194  void sendKeyboardAccelerator() const;
195  auto hasDataInQueue() const -> bool;
196  void queuingKeyboardInput() const;
197  void queuingMouseInput() const;
198  void processKeyboardEvent() const;
199  void processMouseEvent() const;
200  void processInput() const;
201  auto processDialogSwitchAccelerator() const -> bool;
202  auto processAccelerator (const FWidget&) const -> bool;
203  void processTerminalFocus (const FKey&) const;
204  static void determineClickedWidget (const FMouseData&);
205  static void determineWheelWidget (const FMouseData&);
206  static auto isNonActivatingMouseEvent (const FMouseData&) -> bool;
207  static auto isWheelEvent (const FMouseData&) -> bool;
208  static void unsetMoveResizeMode (const FMouseData&);
209  void sendMouseEvent (const FMouseData&) const;
210  void sendMouseWheelEvent (const FMouseData&) const;
211  void sendMouseMoveEvent ( const FMouseData&
212  , const FPoint&
213  , const FPoint&
214  , MouseButton ) const;
215  void sendMouseLeftClickEvent ( const FMouseData&
216  , const FPoint&
217  , const FPoint&
218  , MouseButton ) const;
219  void sendMouseRightClickEvent ( const FMouseData&
220  , const FPoint&
221  , const FPoint&
222  , MouseButton ) const;
223  void sendMouseMiddleClickEvent ( const FMouseData&
224  , const FPoint&
225  , const FPoint&
226  , MouseButton ) const;
227  void sendWheelEvent ( const FMouseData&
228  , const FPoint&
229  , const FPoint& ) const;
230  static auto processParameters (const Args&) -> FWidget*;
231  void processResizeEvent();
232  void processCloseWidget();
233  void processDialogResizeMove() const;
234  void processLogger() const;
235  auto processNextEvent() -> bool;
236  void performTimerAction (FObject*, FEvent*) override;
237  auto hasTerminalResized() -> bool;
238  static auto isEventProcessable (FObject*, const FEvent*) -> bool;
239  static auto isNextEventTimeout() -> bool;
240 
241  // Data members
242  Args app_args{};
243  uInt64 key_timeout{100'000}; // 100 ms
244  uInt64 dblclick_interval{500'000}; // 500 ms
245  FEventQueue event_queue{};
246  FMouseHandlerList mouse_handler_list{};
247  bool has_terminal_resized{false};
248  static uInt64 next_event_wait;
249  static TimeValue time_last_event;
250  static rdbuf default_clog_rdbuf;
251  static int loop_level;
252  static int quit_code;
253  static bool quit_now;
254  static FWidget* clicked_widget;
255  static FWidget* wheel_widget;
256  static FWidget* keyboard_widget;
257 };
258 
259 // non-member function forward declarations
260 // implemented in fwidget_functions.cpp
261 //----------------------------------------------------------------------
262 auto getFApplication() noexcept -> FApplication*;
263 
264 
265 // FApplication inline functions
266 //----------------------------------------------------------------------
267 inline auto FApplication::getClassName() const -> FString
268 { return "FApplication"; }
269 
270 //----------------------------------------------------------------------
271 inline auto FApplication::getArgs() const -> Args
272 { return app_args; }
273 
274 //----------------------------------------------------------------------
275 inline void FApplication::cb_exitApp (FWidget* w) const
276 { w->close(); }
277 
278 } // namespace finalcut
279 
280 #endif // FAPPLICATION_H
Definition: fapplication.h:96
Definition: fevent.h:293
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fmouse.h:92
Definition: fobject.h:79
Definition: fstartoptions.h:52
Definition: fstring.h:82
Definition: fevent.h:101
Definition: fwidget.h:129