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-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  * ▕ 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::setResizeable;
74  using FWindow::setMinimizable;
75 
76  // Enumeration
77  enum class ResultCode : int
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 setResizeable (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  // Inquiries
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 termPos;
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 titlebar_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 clearStatusBar() const;
244  void setCursorToFocusWidget();
245  void leaveMenu();
246  void openMenu();
247  void selectFirstMenuItem();
248  void setMinimizeItem();
249  void setZoomItem();
250  auto getMenuButtonWidth() const -> std::size_t;
251  auto getZoomButtonWidth() const -> std::size_t;
252  auto getMinimizeButtonWidth() const -> std::size_t;
253  void activateMinimizeButton (const MouseStates&);
254  void deactivateMinimizeButton();
255  void leaveMinimizeButton (const MouseStates&);
256  void pressMinimizeButton (const MouseStates&);
257  void activateZoomButton (const MouseStates&);
258  void deactivateZoomButton();
259  void leaveZoomButton (const MouseStates&);
260  void pressZoomButton (const MouseStates&);
261  auto isMouseOverMenu (const FPoint&) const -> bool;
262  auto isMouseOverMenuButton (const MouseStates&) const -> bool;
263  auto isMouseOverZoomButton (const MouseStates&) const -> bool;
264  auto isMouseOverMinimizeButton (const MouseStates&) const -> bool;
265  auto isMouseOverTitlebar (const MouseStates&) const -> bool;
266  void passEventToSubMenu ( const MouseStates&
267  , const FMouseEvent& );
268  void handleLeftMouseDown (const MouseStates&);
269  auto isClickOnTitleBar (const MouseStates&, int, int) const -> bool;
270  void handleRightAndMiddleMouseDown (const MouseButton&, const MouseStates&);
271  void moveSizeKey (FKeyEvent*);
272  void raiseActivateDialog();
273  void lowerActivateDialog();
274  auto isOutsideTerminal (const FPoint&) const -> bool;
275  auto isLeftOutside() const -> bool;
276  auto isBottomOutside() const -> bool;
277  auto isLowerRightResizeCorner (const MouseStates&) const -> bool;
278  auto noVisibleDialog() const -> bool;
279  void resizeMouseDown (const MouseStates&);
280  void resizeMouseUpMove (const MouseStates&, bool = false);
281  void cancelMouseResize();
282  void acceptMoveSize();
283  void cancelMoveSize();
284  static void addDialog (FWidget*);
285  static void delDialog (const FWidget*);
286 
287  // Callback methods
288  void cb_move();
289  void cb_minimize();
290  void cb_zoom();
291  void cb_close();
292 
293  // Data members
294  TitleBarFlags titlebar{};
295  ErrorFlags error_flags{false, false};
296  PositionData position_data{};
297  SizeData size_data{};
298  DialogMenu dialog_menu{};
299  FToolTip* tooltip{nullptr};
300  KeyMap key_map{};
301  FString tb_text{}; // title bar text
302  ResultCode result_code{ResultCode::Reject};
303 
304  // Friend function from FMenu
305  friend void FMenu::hideSuperMenus() const;
306 };
307 
308 // FDialog inline functions
309 //----------------------------------------------------------------------
310 inline auto FDialog::getClassName() const -> FString
311 { return "FDialog"; }
312 
313 //----------------------------------------------------------------------
314 inline auto FDialog::getText() const -> FString
315 { return tb_text; }
316 
317 //----------------------------------------------------------------------
318 inline void FDialog::unsetDialogWidget()
319 { setDialogWidget(false); }
320 
321 //----------------------------------------------------------------------
322 inline void FDialog::unsetModal()
323 { setModal(false); }
324 
325 //----------------------------------------------------------------------
326 inline void FDialog::setTitlebarButtonVisibility (bool enable)
327 { titlebar.buttons = enable; }
328 
329 //----------------------------------------------------------------------
330 inline void FDialog::unsetTitlebarButtonVisibility()
331 { setTitlebarButtonVisibility(false); }
332 
333 //----------------------------------------------------------------------
334 inline void FDialog::unsetBorder()
335 { setBorder(false); }
336 
337 //----------------------------------------------------------------------
338 inline void FDialog::setText (const FString& txt)
339 { tb_text.setString(txt); }
340 
341 //----------------------------------------------------------------------
342 inline auto FDialog::isModal() const -> bool
343 { return getFlags().visibility.modal; }
344 
345 //----------------------------------------------------------------------
346 inline auto FDialog::hasBorder() const -> bool
347 { return ! getFlags().feature.no_border; }
348 
349 } // namespace finalcut
350 
351 #endif // FDIALOG_H
Definition: fwindow.h:67
Definition: fevent.h:144
Definition: fmenu.h:75
Definition: frect.h:56
Definition: fevent.h:282
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: ftooltip.h:66
Definition: fsize.h:55
Definition: fmenuitem.h:68
Definition: fstring.h:79
Definition: fevent.h:101
Definition: fdialog.h:69
Definition: fwidget.h:129
Definition: fevent.h:220
Definition: fevent.h:124
Definition: ftypes.h:160