FINAL CUT
fmenuitem.h
1 /***********************************************************************
2 * fmenuitem.h - Widget FMenuItem *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2015-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  * ▕▔▔▔▔▔▔▔▔▔▔▔▏* 1▕▔▔▔▔▔▔▔▏
39  * ▕ FMenuItem ▏-┬- - - -▕ FMenu ▏
40  * ▕▁▁▁▁▁▁▁▁▁▁▁▏ : ▕▁▁▁▁▁▁▁▏
41  * :
42  * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏
43  * └- - - -▕ FMenuList ▏
44  * ▕▁▁▁▁▁▁▁▁▁▁▁▏
45  */
46 
47 #ifndef FMENUITEM_H
48 #define FMENUITEM_H
49 
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 "final/fwidget.h"
55 
56 namespace finalcut
57 {
58 
59 // class forward declaration
60 class FDialog;
61 class FMenu;
62 class FMenuList;
63 
64 //----------------------------------------------------------------------
65 // class FMenuItem
66 //----------------------------------------------------------------------
67 
68 class FMenuItem : public FWidget
69 {
70  public:
71  // Using-declarations
72  using FWidget::addAccelerator;
73  using FWidget::delAccelerator;
74  using FWidget::setEnable;
75 
76  // Constructor
77  explicit FMenuItem (FWidget* = nullptr);
78  explicit FMenuItem (FString&&, FWidget* = nullptr);
79  FMenuItem (FKey, FString&&, FWidget* = nullptr);
80 
81  // Disable copy constructor
82  FMenuItem (const FMenuItem&) = delete;
83 
84  // Disable move constructor
85  FMenuItem (FMenuItem&&) noexcept = delete;
86 
87  // Destructor
88  ~FMenuItem() override;
89 
90  // Disable copy assignment operator (=)
91  auto operator = (const FMenuItem&) -> FMenuItem& = delete;
92 
93  // Disable move assignment operator (=)
94  auto operator = (FMenuItem&&) noexcept -> FMenuItem& = delete;
95  // Accessors
96  auto getClassName() const -> FString override;
97  auto getHotkey() const noexcept -> FKey;
98  auto getMenu() const -> FMenu*;
99  auto getTextLength() const noexcept -> std::size_t;
100  auto getTextWidth() const noexcept -> std::size_t;
101  auto getText() const -> FString;
102 
103  // Mutators
104  void setEnable (bool = true) override;
105  void setSelected();
106  void unsetSelected();
107  void setSeparator();
108  void unsetSeparator();
109  void setCheckable() noexcept;
110  void unsetCheckable() noexcept;
111  void setChecked() noexcept;
112  void unsetChecked() noexcept;
113  void setRadioButton() noexcept;
114  void unsetRadioButton() noexcept;
115  void setMenu (FMenu*);
116  void setText (const FString&);
117 
118  // Predicates
119  auto isSelected() const -> bool;
120  auto isSeparator() const -> bool;
121  auto isCheckable() const -> bool;
122  auto isChecked() const -> bool;
123  auto isRadioButton() const -> bool;
124  auto hasHotkey() const -> bool;
125  auto hasMenu() const -> bool;
126 
127  // Methods
128  void addAccelerator (FKey, FWidget*) & final;
129  void delAccelerator (FWidget*) & final;
130  void openMenu() const;
131 
132  // Event handlers
133  void onKeyPress (FKeyEvent*) override;
134  void onMouseDoubleClick (FMouseEvent*) override;
135  void onMouseDown (FMouseEvent*) override;
136  void onMouseUp (FMouseEvent*) override;
137  void onMouseMove (FMouseEvent*) override;
138  void onAccel (FAccelEvent*) override;
139  void onFocusIn (FFocusEvent*) override;
140  void onFocusOut (FFocusEvent*) override;
141 
142  protected:
143  // Accessor
144  auto getSuperMenu() const -> FWidget*;
145 
146  // Mutator
147  void setSuperMenu (FWidget*);
148 
149  // Predicates
150  auto isDialog (const FWidget*) const -> bool;
151  auto isMenuBar (const FWidget*) const -> bool;
152  auto isMenu (const FWidget*) const -> bool;
153 
154  // Method
155  void initLayout() override;
156 
157  private:
158  struct DialogItemData
159  {
160  FDialog* dialog;
161  const FString& name;
162  FString state;
163  uInt32 index;
164  };
165 
166  // Accessor
167  auto getFMenuList (FWidget&) -> FMenuList*;
168 
169  // Methods
170  void init();
171  void initTextProperties();
172  void initAccelerator();
173  void initMenuBar (FMenuBar&);
174  void initMenu (FMenu&) const;
175  void calculateTextDimensions();
176  void updateSuperMenuDimensions();
177  void updateMenubarDimensions() const;
178  void handleMenuSelection (FMenuBar*, const FAccelEvent*);
179  void updateMenuSelection (const FAccelEvent*) const;
180  void handleMenuBarSelection (FMenuBar*);
181  void processEnable() const;
182  void processDisable() const;
183  void processActivate() const;
184  void processDeactivate() const;
185  void createDialogList (FMenu*) const;
186  void createDialogItem (FMenu*, const DialogItemData&) const;
187  void configDialogItem (FMenuItem*, const DialogItemData&) const;
188  template <typename T>
189  void passMouseEvent (T, const FMouseEvent*, Event) const;
190  void resetSelectedItem (const FMenuList*) const;
191 
192  // Callback methods
193  void cb_switchToDialog (FDialog*) const;
194  void cb_destroyDialog (FDialog*);
195 
196  virtual void processClicked();
197 
198  // Data members
199  FString text{};
200  FMenu* menu{nullptr};
201  FWidget* super_menu{nullptr};
202  FDialog* associated_window{nullptr};
203  std::size_t text_length{0};
204  std::size_t text_width{0};
205  FKey accel_key{FKey::None};
206  FKey hotkey{FKey::None};
207  bool selected{false};
208  bool separator{false};
209  bool checkable{false};
210  bool checked{false};
211  bool radio_button{false};
212  bool dialog_index{false};
213 
214  // Friend classes
215  friend class FDialogListMenu;
216  friend class FMenuList;
217  friend class FMenuBar;
218  friend class FMenu;
219 };
220 
221 
222 // FMenuItem inline functions
223 //----------------------------------------------------------------------
224 inline auto FMenuItem::getClassName() const -> FString
225 { return "FMenuItem"; }
226 
227 //----------------------------------------------------------------------
228 inline auto FMenuItem::getHotkey() const noexcept -> FKey
229 { return hotkey; }
230 
231 //----------------------------------------------------------------------
232 inline auto FMenuItem::getMenu() const -> FMenu*
233 { return menu; }
234 
235 //----------------------------------------------------------------------
236 inline auto FMenuItem::getTextLength() const noexcept -> std::size_t
237 { return text_length; }
238 
239 //----------------------------------------------------------------------
240 inline auto FMenuItem::getTextWidth() const noexcept -> std::size_t
241 { return text_width; }
242 
243 //----------------------------------------------------------------------
244 inline auto FMenuItem::getText() const -> FString
245 { return text; }
246 
247 //----------------------------------------------------------------------
248 inline void FMenuItem::setSeparator()
249 {
250  separator = true;
251  unsetFocusable();
252 }
253 
254 //----------------------------------------------------------------------
255 inline void FMenuItem::unsetSeparator()
256 {
257  separator = false;
258  setFocusable();
259 }
260 
261 //----------------------------------------------------------------------
262 inline void FMenuItem::setCheckable() noexcept
263 { checkable = true; }
264 
265 //----------------------------------------------------------------------
266 inline void FMenuItem::unsetCheckable() noexcept
267 { checkable = false; }
268 
269 //----------------------------------------------------------------------
270 inline void FMenuItem::setChecked() noexcept
271 { checked = true; }
272 
273 //----------------------------------------------------------------------
274 inline void FMenuItem::unsetChecked() noexcept
275 { checked = false; }
276 
277 //----------------------------------------------------------------------
278 inline void FMenuItem::setRadioButton() noexcept
279 { radio_button = true; }
280 
281 //----------------------------------------------------------------------
282 inline void FMenuItem::unsetRadioButton() noexcept
283 { radio_button = false; }
284 
285 //----------------------------------------------------------------------
286 inline void FMenuItem::setMenu (FMenu* m)
287 { menu = m; }
288 
289 //----------------------------------------------------------------------
290 inline auto FMenuItem::isSelected() const -> bool
291 { return selected; }
292 
293 //----------------------------------------------------------------------
294 inline auto FMenuItem::isSeparator() const -> bool
295 { return separator; }
296 
297 //----------------------------------------------------------------------
298 inline auto FMenuItem::isCheckable() const -> bool
299 { return checkable; }
300 
301 //----------------------------------------------------------------------
302 inline auto FMenuItem::isChecked() const -> bool
303 { return checked; }
304 
305 //----------------------------------------------------------------------
306 inline auto FMenuItem::isRadioButton() const -> bool
307 { return radio_button; }
308 
309 //----------------------------------------------------------------------
310 inline auto FMenuItem::hasHotkey() const -> bool
311 { return hotkey != FKey::None; }
312 
313 //----------------------------------------------------------------------
314 inline auto FMenuItem::hasMenu() const -> bool
315 { return menu != nullptr; }
316 
317 //----------------------------------------------------------------------
318 inline auto FMenuItem::getSuperMenu() const -> FWidget*
319 { return super_menu; }
320 
321 //----------------------------------------------------------------------
322 inline void FMenuItem::setSuperMenu (FWidget* smenu)
323 { super_menu = smenu; }
324 
325 } // namespace finalcut
326 
327 #endif // FMENUITEM_H
Definition: fevent.h:207
Definition: fmenulist.h:58
Definition: fevent.h:144
Definition: fmenu.h:75
Definition: fmenubar.h:70
Definition: class_template.cpp:25
Definition: fmenuitem.h:68
Definition: fdialoglistmenu.h:70
Definition: fstring.h:82
Definition: fdialog.h:69
Definition: fwidget.h:129
Definition: fevent.h:231
Definition: fevent.h:124