Loading...
Searching...
No Matches
Accordion.h
Go to the documentation of this file.
1
2#ifndef MALENA_ACCORDION_H
3#define MALENA_ACCORDION_H
4
5#pragma once
6
9#include <Malena/Core/Core.h>
19#include <functional>
20#include <memory>
21#include <string>
22#include <vector>
23
24namespace ml
25{
27 {
28 public:
29 enum class Flag {};
30 enum class State {};
31 };
32
61 class MALENA_API Accordion : public ComponentWith<AccordionManifest>,
62 public AccordionSettings,
63 public AccordionTheme,
64 public Themeable
65 {
66 public:
69
71 {
74 };
75
76 private:
77 struct Section
78 {
79 std::unique_ptr<ListItem> header;
80 std::unique_ptr<List> content;
81 float contentHeight = 120.f;
82 bool expanded = false;
83 };
84
85 std::vector<Section> _sections;
86
87 sf::Vector2f _position = {0.f, 0.f};
88 float _width = 300.f;
89
90 std::function<void(std::size_t, bool)> _onSectionChanged;
91
92 // ── Internal ──────────────────────────────────────────────────────────
93 void layout();
94 int hitTestHeader(const sf::Vector2f& mousePos) const;
95
96 protected:
97 void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
98 void onThemeApplied(const Theme& theme) override;
99
100 public:
102
103 Accordion(const Accordion&) = delete;
104 Accordion& operator=(const Accordion&) = delete;
105
106 // ── Apply ─────────────────────────────────────────────────────────────
107
108 template<typename S>
109 void applySettings(const S& s)
110 {
111 static_assert(std::is_base_of_v<AccordionSettings, S>,
112 "applySettings() requires AccordionSettings");
113 static_cast<AccordionSettings&>(*this) = s;
114 layout();
115 }
116
117 template<typename T>
118 void applyTheme(const T& t)
119 {
120 static_assert(std::is_base_of_v<AccordionTheme, T>,
121 "applyTheme() requires AccordionTheme");
122 static_cast<AccordionTheme&>(*this) = t;
123 }
124
125 template<typename St>
126 void applyStyle(const St& s)
127 {
128 static_assert(std::is_base_of_v<AccordionSettings, St> &&
129 std::is_base_of_v<AccordionTheme, St>,
130 "applyStyle() requires AccordionSettings and AccordionTheme");
131 static_cast<AccordionSettings&>(*this) = s;
132 static_cast<AccordionTheme&>(*this) = s;
133 layout();
134 }
135
136 // ── Section management ────────────────────────────────────────────────
137
151 SectionRef addSection(const std::string& label, float contentHeight = 120.f);
152
154 void removeSection(std::size_t index);
155
157 void expand(std::size_t index);
158
160 void collapse(std::size_t index);
161
163 void toggle(std::size_t index);
164
166 [[nodiscard]] bool isExpanded(std::size_t index) const;
167
169 [[nodiscard]] std::size_t sectionCount() const { return _sections.size(); }
170
172 void onSectionChanged(std::function<void(std::size_t index, bool expanded)> cb);
173
174 // ── Sizing ────────────────────────────────────────────────────────────
175
176 void setWidth(float width);
177 void setSize(const sf::Vector2f& size) { setWidth(size.x); }
178 [[nodiscard]] float getWidth() const { return _width; }
179 [[nodiscard]] float getTotalHeight() const;
180
181 // ── Positionable ──────────────────────────────────────────────────────
182
183 void setPosition(const sf::Vector2f& position) override;
184 sf::Vector2f getPosition() const override;
186 };
187
188 template<typename MANIFEST>
189 class AccordionWith : public Accordion, public Customizable<MANIFEST>
190 { public: using Accordion::Accordion; };
191
192} // namespace ml
193
194#endif // MALENA_ACCORDION_H
void onSectionChanged(std::function< void(std::size_t index, bool expanded)> cb)
Fired when a section is expanded or collapsed.
bool isExpanded(std::size_t index) const
Return whether a section is expanded.
SectionRef addSection(const std::string &label, float contentHeight=120.f)
Add a section, creating its ListItem header and List content.
std::size_t sectionCount() const
Return the number of sections.
Definition Accordion.h:169
void setWidth(float width)
Accordion(const sf::Font &font=FontManager<>::getDefault())
void setPosition(const sf::Vector2f &position) override
sf::Vector2f getPosition() const override
AccordionManifest::State State
Definition Accordion.h:68
void applyStyle(const St &s)
Definition Accordion.h:126
void applySettings(const S &s)
Definition Accordion.h:109
void expand(std::size_t index)
Expand a section by index. Collapses others if exclusive.
AccordionManifest::Flag Flag
Definition Accordion.h:67
float getWidth() const
Definition Accordion.h:178
sf::FloatRect getGlobalBounds() const override
void applyTheme(const T &t)
Definition Accordion.h:118
void setSize(const sf::Vector2f &size)
Definition Accordion.h:177
void onThemeApplied(const Theme &theme) override
Called by ThemeManager when the active theme changes.
void collapse(std::size_t index)
Collapse a section by index.
void toggle(std::size_t index)
Toggle a section's expanded state.
Accordion & operator=(const Accordion &)=delete
float getTotalHeight() const
void removeSection(std::size_t index)
Remove a section by index.
void draw(sf::RenderTarget &target, sf::RenderStates states) const override
Accordion(const Accordion &)=delete
Accordion(const sf::Font &font=FontManager<>::getDefault())
static const sf::Font & getDefault()
Return the built-in Arial font.
A vertically stacked list of rows with optional dividers and background.
Definition List.h:104
A single row in a List with start, content and end slots.
Definition ListItem.h:81
Base class for all Malena manifests.
Definition Manifest.h:51
Component< M, Traits... > ComponentWith
Alias for Component<M, Traits...>.
Definition Component.h:316
#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