Loading...
Searching...
No Matches
MenuBar.h
Go to the documentation of this file.
1//
2// MenuBar.h
3//
4
5#ifndef MALENA_MENUBAR_H
6#define MALENA_MENUBAR_H
7
8#pragma once
9
26#include <functional>
27#include <memory>
28#include <string>
29#include <vector>
30#include <type_traits>
31
32namespace ml
33{
35 {
36 public:
37 enum class Flag { OPEN };
38 enum class State { IDLE, OPEN };
39 };
40
75 class MALENA_API MenuBar : public ComponentWith<MenuBarManifest>,
76 public MenuBarSettings,
77 public MenuBarTheme,
78 public Themeable
79 {
80 public:
83
84 private:
85 struct MenuEntry
86 {
87 std::string label;
88 std::vector<MenuItem> items;
89 float labelX = 0.f;
90 float labelW = 0.f;
91
92 // List-based dropdown (off-screen when closed)
93 std::unique_ptr<ml::List> dropdown;
94
95 // Parallel to items — null for separators
96 std::vector<ml::ListItem*> listItems;
97 std::vector<std::unique_ptr<ml::Text>> checkmarkTexts;
98 std::vector<std::unique_ptr<ml::Text>> endTexts;
99
100 // Separator helper objects (kept alive for list layout)
101 std::vector<std::unique_ptr<ml::Core>> separatorRects;
102 };
103
104 std::vector<MenuEntry> _entries;
105 int _openEntry = -1;
106 int _hoveredItem = -1;
107 int _openSubmenu = -1;
108 sf::Vector2f _position = {0.f, 0.f};
109 float _width = 0.f;
110
115 struct OldDropdown
116 {
117 std::unique_ptr<ml::List> dropdown;
118 std::vector<std::unique_ptr<ml::Text>> checkmarkTexts;
119 std::vector<std::unique_ptr<ml::Text>> endTexts;
120 std::vector<std::unique_ptr<ml::Core>> separatorRects;
121 };
122 std::vector<OldDropdown> _pendingDelete;
123
124 // ── Internal ──────────────────────────────────────────────────────────
125 void computeLayout();
126 void closeAll();
127 void buildDropdown(int entryIdx);
128 int hitTestBar(const sf::Vector2f& wp) const;
129 int hitTestDropdown(const sf::Vector2f& wp) const;
130 float dropdownWidth(int entryIdx) const;
131 float dropdownHeight(int entryIdx) const;
132 float dropdownX(int entryIdx) const;
133 float dropdownY() const;
134 void drawSubmenu(sf::RenderTarget& target,
135 const sf::RenderStates& states,
136 int entryIdx, int itemIdx) const;
137 void activateItem(int entryIdx, int itemIdx);
138
139 protected:
140 void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
141 void onThemeApplied(const Theme& theme) override;
142
143 public:
145
146 MenuBar(const MenuBar&) = delete;
147 MenuBar& operator=(const MenuBar&) = delete;
148
149 // ── Apply ─────────────────────────────────────────────────────────────
150
151 template<typename S>
152 void applySettings(const S& s)
153 {
154 static_assert(std::is_base_of_v<MenuBarSettings, S>,
155 "applySettings() requires MenuBarSettings");
156 static_cast<MenuBarSettings&>(*this) = s;
157 computeLayout();
158 }
159
160 template<typename T>
161 void applyTheme(const T& t)
162 {
163 static_assert(std::is_base_of_v<MenuBarTheme, T>,
164 "applyTheme() requires MenuBarTheme");
165 static_cast<MenuBarTheme&>(*this) = t;
166 }
167
168 template<typename St>
169 void applyStyle(const St& s)
170 {
171 static_assert(std::is_base_of_v<MenuBarSettings, St> &&
172 std::is_base_of_v<MenuBarTheme, St>,
173 "applyStyle() requires MenuBarSettings and MenuBarTheme");
174 static_cast<MenuBarSettings&>(*this) = s;
175 static_cast<MenuBarTheme&>(*this) = s;
176 computeLayout();
177 }
178
179 // ── Menu management ───────────────────────────────────────────────────
180
182 void addMenu(const std::string& label, std::vector<MenuItem> items);
183
185 void setMenuItems(std::size_t menuIndex, std::vector<MenuItem> items);
186
188 void setItemChecked(std::size_t menuIndex, std::size_t itemIndex, bool checked);
189
191 void setItemEnabled(std::size_t menuIndex, std::size_t itemIndex, bool enabled);
192
195
197 [[nodiscard]] std::size_t menuCount() const { return _entries.size(); }
198
199 // ── Positionable ──────────────────────────────────────────────────────
200
201 void setPosition(const sf::Vector2f& position) override;
202 sf::Vector2f getPosition() const override;
204 };
205
206 template<typename MANIFEST>
207 class MenuBarWith : public MenuBar, public Customizable<MANIFEST>
208 { public: using MenuBar::MenuBar; };
209
210} // namespace ml
211#endif // MALENA_MENUBAR_H
static const sf::Font & getDefault()
Return the built-in Arial font.
Base class for all Malena manifests.
Definition Manifest.h:51
MenuBar(const sf::Font &font=FontManager<>::getDefault())
void applyStyle(const St &s)
Definition MenuBar.h:169
void draw(sf::RenderTarget &target, sf::RenderStates states) const override
void setItemEnabled(std::size_t menuIndex, std::size_t itemIndex, bool enabled)
Enable or disable a specific item.
void setMenuItems(std::size_t menuIndex, std::vector< MenuItem > items)
Replace the items of an existing menu by index.
void applyTheme(const T &t)
Definition MenuBar.h:161
MenuBar(const MenuBar &)=delete
void applySettings(const S &s)
Definition MenuBar.h:152
MenuBar & operator=(const MenuBar &)=delete
MenuBarManifest::State State
Definition MenuBar.h:82
void onThemeApplied(const Theme &theme) override
Called by ThemeManager when the active theme changes.
void addMenu(const std::string &label, std::vector< MenuItem > items)
Add a top-level menu entry with its dropdown items.
void closeMenus()
Close all open dropdowns programmatically.
MenuBarManifest::Flag Flag
Definition MenuBar.h:81
std::size_t menuCount() const
Return the number of top-level menu entries.
Definition MenuBar.h:197
void setItemChecked(std::size_t menuIndex, std::size_t itemIndex, bool checked)
Set checked state on a specific item.
sf::FloatRect getGlobalBounds() const override
void setPosition(const sf::Vector2f &position) override
sf::Vector2f getPosition() const override
MenuBar(const sf::Font &font=FontManager<>::getDefault())
Component< M, Traits... > ComponentWith
Alias for Component<M, Traits...>.
Definition Component.h:299
#define MALENA_API
Definition Component.h:22
Rect< float > FloatRect
Vector2< float > Vector2f
const sf::Font * font
Universal design token set applied across all Themeable components.
Definition Theme.h:70