FINAL CUT
fdialog.h
1 /***********************************************************************
2 * fdialog.h - Widget FDialog *
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  * ▕ FWindow ▏
40  * ▕▁▁▁▁▁▁▁▁▁▏
41  * ▲
42  * │
43  * ▕▔▔▔▔▔▔▔▔▔▏
44  * ▕ FDialog ▏
45  * ▕▁▁▁▁▁▁▁▁▁▏
46  */
47 
48 #ifndef FDIALOG_H
49 #define FDIALOG_H
50 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
51  #error "Only <final/final.h> can be included directly."
52 #endif
53 
54 #include <unordered_map>
55 
56 #include "final/menu/fmenu.h"
57 #include "final/widget/fwindow.h"
58 
59 namespace finalcut
60 {
61 
62 // class forward declaration
63 class FToolTip;
64 
65 //----------------------------------------------------------------------
66 // class FDialog
67 //----------------------------------------------------------------------
68 
69 class FDialog : public FWindow
70 {
71  public:
72  // Using-declaration
73  using FWindow::setResizable;
74  using FWindow::setMinimizable;
75 
76  // Enumeration
77  enum class ResultCode : uInt8
78  {
79  Reject = 0,
80  Accept = 1
81  };
82 
83  // Constructors
84  explicit FDialog (FWidget* = nullptr);
85  explicit FDialog (FString&&, FWidget* = nullptr);
86 
87  // Disable copy constructor
88  FDialog (const FDialog&) = delete;
89 
90  // Disable move constructor
91  FDialog (FDialog&&) noexcept = delete;
92 
93  // Destructor
94  ~FDialog() override;
95 
96  // Disable copy assignment operator (=)
97  auto operator = (const FDialog&) -> FDialog& = delete;
98 
99  // Disable move assignment operator (=)
100  auto operator = (FDialog&&) noexcept -> FDialog& = delete;
101 
102  // Accessors
103  auto getClassName() const -> FString override;
104  virtual auto getText() const -> FString;
105 
106  // Mutators
107  void setDialogWidget (bool = true);
108  void unsetDialogWidget();
109  void setModal (bool = true);
110  void unsetModal();
111  void setResizable (bool = true) override;
112  void setMinimizable (bool = true) override;
113  void setTitleBarButtonVisibility (bool = true);
114  void unsetTitleBarButtonVisibility();
115  void setBorder (bool = true);
116  void unsetBorder();
117  void resetColors() override;
118  virtual void setText (const FString&);
119 
120  // Predicates
121  auto isModal() const -> bool;
122  auto hasBorder() const -> bool;
123 
124  // Methods
125  void show() override;
126  void hide() override;
127  auto exec() -> ResultCode;
128  void setPos (const FPoint&, bool = true) override;
129  void move (const FPoint&) override;
130  auto moveUp (int) -> bool;
131  auto moveDown (int) -> bool;
132  auto moveLeft (int) -> bool;
133  auto moveRight (int) -> bool;
134  void setWidth (std::size_t, bool = true) override;
135  void setHeight (std::size_t, bool = true) override;
136  void setSize (const FSize&, bool = true) override;
137  auto reduceHeight (int) -> bool;
138  auto expandHeight (int) -> bool;
139  auto reduceWidth (int) -> bool;
140  auto expandWidth (int) -> bool;
141  auto zoomWindow() -> bool override;
142  auto minimizeWindow() -> bool override;
143  void flushChanges() override;
144  void activateDialog();
145 
146  // Event handlers
147  void onKeyPress (FKeyEvent*) override;
148  void onMouseDown (FMouseEvent*) override;
149  void onMouseUp (FMouseEvent*) override;
150  void onMouseMove (FMouseEvent*) override;
151  void onMouseDoubleClick (FMouseEvent*) override;
152  void onAccel (FAccelEvent*) override;
153  void onWindowActive (FEvent*) override;
154  void onWindowInactive (FEvent*) override;
155  void onWindowRaised (FEvent*) override;
156  void onWindowLowered (FEvent*) override;
157 
158  protected:
159  // Methods
160  void adjustSize() override;
161  void done (ResultCode);
162  void draw() override;
163  void drawDialogShadow();
164 
165  // Event handlers
166  void onClose (FCloseEvent*) override;
167 
168  private:
169  struct MouseStates
170  {
171  int mouse_x;
172  int mouse_y;
173  FPoint term_pos;
174  std::size_t menu_btn;
175  std::size_t minimize_btn;
176  std::size_t zoom_btn;
177  bool mouse_over_menu;
178  };
179 
180  struct TitleBarFlags
181  {
182  bool buttons{true};
183  bool zoom_button_pressed{false};
184  bool zoom_button_active{false};
185  bool minimize_button_pressed{false};
186  bool minimize_button_active{false};
187  };
188 
189  struct ErrorFlags
190  {
191  bool setPos_error{false};
192  bool setSize_error{false};
193  };
194 
195  struct PositionData
196  {
197  FPoint title_bar_click_pos{};
198  FPoint resize_click_pos{};
199  FPoint new_pos{};
200  };
201 
202  struct SizeData
203  {
204  FSize new_size{};
205  FRect save_geometry{}; // required by keyboard move/size
206  };
207 
208  struct DialogMenu
209  {
210  FMenu* menu{nullptr};
211  FMenuItem* menuitem{nullptr};
212  FMenuItem* move_size_item{nullptr};
213  FMenuItem* zoom_item{nullptr};
214  FMenuItem* minimize_item{nullptr};
215  FMenuItem* close_item{nullptr};
216  };
217 
218  // Using-declaration
219  using KeyMap = std::unordered_map<FKey, std::function<void()>, EnumHash<FKey>>;
220 
221  // Constant
222  static constexpr bool PRINT_WIN_NUMBER = false; // Only for debug
223 
224  // Methods
225  void init();
226  void initDialogMenu();
227  void initMoveSizeMenuItem (FMenu*);
228  void initZoomMenuItem (FMenu*);
229  void initMinimizeMenuItem (FMenu*);
230  void initCloseMenuItem (FMenu*);
231  auto initMouseStates (const FMouseEvent&, bool) const -> MouseStates;
232  void mapKeyFunctions();
233  void recoverBackgroundAfterMove (const FPoint&, const FRect&);
234  void drawBorder() override;
235  void drawTitleBar();
236  void drawBarButton();
237  void drawZoomButton();
238  void drawMinimizeButton();
239  void printRestoreSizeButton();
240  void printZoomedButton();
241  void printMinimizeButton();
242  void drawTextBar();
243  void setTextBarColors() const;
244  void printSpace (std::size_t);
245  void printTitleBarText (std::size_t&, std::size_t);
246  void clearStatusBar() const;
247  void setCursorToFocusWidget();
248  void leaveMenu();
249  void openMenu();
250  void selectFirstMenuItem();
251  void setMoveSizeItem();
252  void setZoomItem();
253  void setMinimizeItem();
254  auto getMenuButtonWidth() const -> std::size_t;
255  auto getZoomButtonWidth() const -> std::size_t;
256  auto getMinimizeButtonWidth() const -> std::size_t;
257  void activateMinimizeButton (const MouseStates&);
258  void deactivateMinimizeButton();
259  void leaveMinimizeButton (const MouseStates&);
260  void pressMinimizeButton (const MouseStates&);
261  void activateZoomButton (const MouseStates&);
262  void deactivateZoomButton();
263  void leaveZoomButton (const MouseStates&);
264  void pressZoomButton (const MouseStates&);
265  auto isMouseOverMenu (const FPoint&) const -> bool;
266  auto isMouseOverMenuButton (const MouseStates&) const -> bool;
267  auto isMouseOverZoomButton (const MouseStates&) const -> bool;
268  auto isMouseOverMinimizeButton (const MouseStates&) const -> bool;
269  auto isMouseOverTitleBar (const MouseStates&) const -> bool;
270  void passEventToSubMenu ( const MouseStates&
271  , const FMouseEvent& );
272  void handleLeftMouseDown (const MouseStates&);
273  auto isClickOnTitleBar (const MouseStates&, int, int) const -> bool;
274  void handleRightAndMiddleMouseDown (const MouseButton&, const MouseStates&);
275  void moveSizeKey (FKeyEvent*);
276  void raiseActivateDialog();
277  void lowerActivateDialog();
278  auto isOutsideTerminal (const FPoint&) const -> bool;
279  auto isLeftOutside() const -> bool;
280  auto isBottomOutside() const -> bool;
281  auto isLowerRightResizeCorner (const MouseStates&) const -> bool;
282  auto noVisibleDialog() const -> bool;
283  void resizeMouseDown (const MouseStates&);
284  void resizeMouseUpMove (const MouseStates&, bool = false);
285  auto calculateNewSize (const MouseStates&) const -> FSize;
286  void cancelMouseResize();
287  void prepareToMove();
288  void handleTooltipDisplay();
289  void acceptMoveSize();
290  void cancelMoveSize();
291  static void addDialog (FWidget*);
292  static void delDialog (const FWidget*);
293 
294  // Callback methods
295  void cb_move();
296  void cb_minimize();
297  void cb_zoom();
298  void cb_close();
299 
300  // Data members
301  TitleBarFlags title_bar{};
302  ErrorFlags error_flags{false, false};
303  PositionData position_data{};
304  SizeData size_data{};
305  DialogMenu dialog_menu{};
306  FToolTip* tooltip{nullptr};
307  KeyMap key_map{};
308  FString tb_text{}; // title bar text
309  ResultCode result_code{ResultCode::Reject};
310 
311  // Friend function from FMenu
312  friend void FMenu::hideSuperMenus() const;
313 };
314 
315 // FDialog inline functions
316 //----------------------------------------------------------------------
317 inline auto FDialog::getClassName() const -> FString
318 { return "FDialog"; }
319 
320 //----------------------------------------------------------------------
321 inline auto FDialog::getText() const -> FString
322 { return tb_text; }
323 
324 //----------------------------------------------------------------------
325 inline void FDialog::unsetDialogWidget()
326 { setDialogWidget(false); }
327 
328 //----------------------------------------------------------------------
329 inline void FDialog::unsetModal()
330 { setModal(false); }
331 
332 //----------------------------------------------------------------------
333 inline void FDialog::setTitleBarButtonVisibility (bool enable)
334 { title_bar.buttons = enable; }
335 
336 //----------------------------------------------------------------------
337 inline void FDialog::unsetTitleBarButtonVisibility()
338 { setTitleBarButtonVisibility(false); }
339 
340 //----------------------------------------------------------------------
341 inline void FDialog::unsetBorder()
342 { setBorder(false); }
343 
344 //----------------------------------------------------------------------
345 inline void FDialog::setText (const FString& txt)
346 { tb_text.setString(txt); }
347 
348 //----------------------------------------------------------------------
349 inline auto FDialog::isModal() const -> bool
350 { return getFlags().visibility.modal; }
351 
352 //----------------------------------------------------------------------
353 inline auto FDialog::hasBorder() const -> bool
354 { return ! getFlags().feature.no_border; }
355 
356 } // namespace finalcut
357 
358 #endif // FDIALOG_H
Definition: fwindow.h:67
Definition: fevent.h:144
Definition: fmenu.h:75
Definition: frect.h:56
Definition: fevent.h:293
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: ftooltip.h:66
Definition: fsize.h:55
Definition: fmenuitem.h:68
Definition: fstring.h:82
Definition: fevent.h:101
Definition: fdialog.h:69
Definition: fwidget.h:129
Definition: fevent.h:231
Definition: fevent.h:124
Definition: ftypes.h:161