53 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) 54 #error "Only <final/final.h> can be included directly." 60 #include "final/fevent.h" 61 #include "final/menu/fmenulist.h" 62 #include "final/widget/fwindow.h" 80 using FMenuList::getItem;
81 using FMenuList::isSelected;
97 auto operator = (
const FMenu&) ->
FMenu& =
delete;
100 auto operator = (
FMenu&&) noexcept ->
FMenu& =
delete;
103 auto getClassName()
const ->
FString override;
104 auto getText()
const ->
FString;
108 void setEnable (
bool =
true)
override;
109 void unsetEnable()
override;
110 void setDisable()
override;
112 void unsetSelected();
113 void setMenuWidget (
bool =
true);
114 void unsetMenuWidget();
115 void setStatusBarMessage (
const FString&)
override;
116 void setMenu (
FMenu*);
118 void resetColors()
override;
121 auto isSelected()
const -> bool;
122 auto hasHotkey()
const -> bool;
123 auto hasMenu()
const -> bool;
126 void show()
override;
127 void hide()
override;
137 void cb_menuitemEnabled();
138 void cb_menuitemDisabled();
139 void cb_menuitemToggled (
const FMenuItem*)
const;
143 using KeyMap = std::unordered_map<FKey, std::function<void(FKeyEvent*)>,
EnumHash<FKey>>;
146 enum class SelectItem : bool { No, Yes };
150 uChar focus_changed : 1;
151 uChar hide_sub_menu : 1;
152 uChar mouse_over_menu : 1;
153 uChar mouse_over_submenu : 1;
154 uChar mouse_over_supermenu : 1;
155 uChar mouse_over_menubar : 1;
162 std::size_t hotkeypos;
167 static constexpr
auto NOT_SET =
static_cast<std::size_t
>(-1);
170 auto getSuperMenu()
const ->
FWidget*;
176 auto isDialog (
const FWidget*)
const -> bool;
177 auto isMenuBar (
const FWidget*)
const -> bool;
178 auto isMenu (
const FWidget*)
const -> bool;
179 auto isRadioMenuItem (
const FWidget*)
const -> bool;
180 auto isSubMenu()
const -> bool;
181 auto isDialogMenu()
const -> bool;
182 auto isMouseOverMenu (
const FPoint&) -> bool;
183 auto isMouseOverSubMenu (
const FPoint&) -> bool;
184 auto isMouseOverSuperMenu (
const FPoint&) -> bool;
185 auto isMouseOverMenuBar (
const FPoint&)
const -> bool;
186 auto isMetaNumberKey (
const FKey&)
const -> bool;
190 void handleParentWidget();
191 void initCallbacks();
192 void mapKeyFunctions();
193 void calculateDimensions();
194 auto calculateMaxItemWidth()
const -> std::size_t;
195 void setPositionsOfAllItems()
const;
196 void adjustItems()
const;
197 auto adjustX (
int)
const -> int;
198 void openSubMenu (
FMenu*, SelectItem);
199 void closeOpenedSubMenu();
201 void hideSuperMenus()
const;
203 auto mouseDownOverList (
const FPoint&) -> bool;
204 void mouseDownSubmenu (
const FMenuItem*);
205 void mouseDownSelection (
FMenuItem*,
bool&);
206 auto mouseUpOverList (
const FPoint&) -> bool;
207 auto initializeMouseStates (
const FMouseEvent*) -> MouseStates;
208 void handleCloseSubMenu (
const MouseStates&);
210 void mouseMoveOverList (
const FPoint&, MouseStates&);
211 auto handleMenuHierarchyEvents (
const MouseStates&,
const FMouseEvent*) -> bool;
212 void processMenuBorderEvents (MouseStates&)
const;
213 void mouseMoveSelection (
FMenuItem*, MouseStates&);
214 void mouseMoveDeselection (
FMenuItem*, MouseStates&);
215 void mouseUpOverBorder();
216 void mouseMoveOverBorder (MouseStates&)
const;
217 auto handleSubMenuEvent (
const MouseStates&,
const FMouseEvent&)
const -> bool;
218 void passEventToSubMenu (
const FMouseEvent&)
const;
219 auto handleSuperMenuEvent (
const MouseStates&,
const FMouseEvent&) -> bool;
221 auto handleMenuBarEvent (
const MouseStates&,
const FMouseEvent&)
const -> bool;
222 void passEventToMenuBar (
const FMouseEvent&)
const;
223 template <
typename W
idgetT>
224 void passEventToWidget (WidgetT,
const FMouseEvent&)
const;
225 auto containsMenuStructure (
const FPoint&) -> bool;
226 auto containsMenuStructure (
int,
int) -> bool;
228 auto superMenuAt (
int,
int) ->
FMenu*;
229 void selectItem_PostProcessing (
FMenuItem*)
override;
231 auto hotkeyFound (FKey,
const FKeyEvent&)
const -> bool;
233 void draw()
override;
235 void drawSeparator (
int);
237 void drawCheckMarkPrefix (
const FMenuItem*);
238 void printChecked (
bool);
239 void printUnchecked();
241 void printCheckMark();
242 void drawMenuText (MenuText&);
243 auto isCharacterInvalid (
wchar_t)
const -> bool;
244 void printHotkey (
const MenuText&,
wchar_t);
245 void drawSubMenuIndicator (std::size_t&);
246 void drawAcceleratorKey (std::size_t&, FKey);
247 void drawTrailingSpaces (std::size_t);
248 void setLineAttributes (
const FMenuItem*,
int);
249 void setCursorToHotkeyPosition (
FMenuItem*)
const;
252 void acceptSelection();
254 void processActivate()
const;
260 FMenu* opened_sub_menu{
nullptr};
261 FMenu* shown_sub_menu{
nullptr};
262 std::size_t max_item_width{0};
263 std::size_t hotkeypos{NOT_SET};
264 bool mouse_down{
false};
265 bool has_checkable_items{
false};
268 friend auto closeOpenMenus (
FMenu*,
const FPoint&) -> std::tuple<bool, bool>;
281 auto closeOpenMenus (
FMenu*,
const FPoint&) -> std::tuple<bool, bool>;
286 inline auto FMenu::getClassName()
const ->
FString 290 inline auto FMenu::getText()
const ->
FString 291 {
return menuitem.getText(); }
294 inline auto FMenu::getItem() ->
FMenuItem*
295 {
return &menuitem; }
298 inline void FMenu::setEnable (
bool enable)
299 { menuitem.setEnable(enable); }
302 inline void FMenu::unsetEnable()
303 { menuitem.unsetEnable(); }
306 inline void FMenu::setDisable()
307 { menuitem.setDisable(); }
310 inline void FMenu::setSelected()
311 { menuitem.setSelected(); }
314 inline void FMenu::unsetSelected()
315 { menuitem.unsetSelected(); }
318 inline void FMenu::unsetMenuWidget()
319 { setMenuWidget(
false); }
322 inline void FMenu::setMenu (
FMenu* m)
323 { menuitem.setMenu(m); }
326 inline void FMenu::setText (
const FString& txt)
327 { menuitem.setText(txt); }
330 inline auto FMenu::isSelected()
const ->
bool 331 {
return menuitem.isSelected(); }
334 inline auto FMenu::hasHotkey()
const ->
bool 335 {
return menuitem.hasHotkey(); }
338 inline auto FMenu::hasMenu()
const ->
bool 339 {
return menuitem.hasMenu(); }
342 inline auto FMenu::getSuperMenu()
const ->
FWidget*
343 {
return super_menu; }
346 inline void FMenu::setSuperMenu (
FWidget* smenu)
347 { super_menu = smenu; }
350 template <
typename W
idgetT>
351 inline void FMenu::passEventToWidget (WidgetT widget,
const FMouseEvent& ev)
const 355 const auto& type = ev.getType();
356 const auto& tpos = ev.getTermPos();
357 const auto& par = widget->termToWidgetPos(tpos);
358 const MouseButton btn = ev.getButton();
359 const auto& new_ev = \
360 std::make_shared<FMouseEvent>(type, par, tpos, btn);
361 setClickedWidget(widget);
362 widget->mouse_down =
true;
363 widget->onMouseMove(new_ev.get());
367 inline auto FMenu::containsMenuStructure (
const FPoint& p) ->
bool 368 {
return containsMenuStructure (p.getX(), p.getY()); }
371 inline auto FMenu::superMenuAt (
const FPoint& p) ->
FMenu*
372 {
return superMenuAt (p.getX(), p.getY()); }
376 { menuitem.onAccel(ev); }
Definition: class_template.cpp:25