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 // A header click records the section to toggle here and applies it on the
93 // next update — NOT synchronously inside onClick. Expanding a section
94 // mid-dispatch slides its rows under the cursor, and the same click event
95 // (which fires every hovered Clickable) would then also trigger the
96 // revealed row. Deferring the layout change to after click dispatch avoids
97 // that leak. -1 = nothing pending.
98 int _pendingToggle = -1;
99
100 // ── Internal ──────────────────────────────────────────────────────────
101 void layout();
102 int hitTestHeader(const sf::Vector2f& mousePos) const;
103
104 protected:
105 void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
106 void onThemeApplied(const Theme& theme) override;
107
108 public:
110
111 Accordion(const Accordion&) = delete;
112 Accordion& operator=(const Accordion&) = delete;
113
114 // ── Apply ─────────────────────────────────────────────────────────────
115
116 template<typename S>
117 void applySettings(const S& s)
118 {
119 static_assert(std::is_base_of_v<AccordionSettings, S>,
120 "applySettings() requires AccordionSettings");
121 static_cast<AccordionSettings&>(*this) = s;
122 layout();
123 }
124
125 template<typename T>
126 void applyTheme(const T& t)
127 {
128 static_assert(std::is_base_of_v<AccordionTheme, T>,
129 "applyTheme() requires AccordionTheme");
130 static_cast<AccordionTheme&>(*this) = t;
131 }
132
133 template<typename St>
134 void applyStyle(const St& s)
135 {
136 static_assert(std::is_base_of_v<AccordionSettings, St> &&
137 std::is_base_of_v<AccordionTheme, St>,
138 "applyStyle() requires AccordionSettings and AccordionTheme");
139 static_cast<AccordionSettings&>(*this) = s;
140 static_cast<AccordionTheme&>(*this) = s;
141 layout();
142 }
143
144 // ── Section management ────────────────────────────────────────────────
145
159 SectionRef addSection(const std::string& label, float contentHeight = 120.f);
160
162 void removeSection(std::size_t index);
163
165 void expand(std::size_t index);
166
168 void collapse(std::size_t index);
169
171 void toggle(std::size_t index);
172
174 [[nodiscard]] bool isExpanded(std::size_t index) const;
175
177 [[nodiscard]] std::size_t sectionCount() const { return _sections.size(); }
178
180 void onSectionChanged(std::function<void(std::size_t index, bool expanded)> cb);
181
182 // ── Sizing ────────────────────────────────────────────────────────────
183
184 void setWidth(float width);
185 void setSize(const sf::Vector2f& size) { setWidth(size.x); }
186 [[nodiscard]] float getWidth() const { return _width; }
187 [[nodiscard]] float getTotalHeight() const;
188
189 // ── Positionable ──────────────────────────────────────────────────────
190
191 void setPosition(const sf::Vector2f& position) override;
192 sf::Vector2f getPosition() const override;
194 };
195
196 template<typename MANIFEST>
197 class AccordionWith : public Accordion, public Customizable<MANIFEST>
198 { public: using Accordion::Accordion; };
199
200} // namespace ml
201
202#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:177
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:134
void applySettings(const S &s)
Definition Accordion.h:117
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:186
sf::FloatRect getGlobalBounds() const override
void applyTheme(const T &t)
Definition Accordion.h:126
void setSize(const sf::Vector2f &size)
Definition Accordion.h:185
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:323
#define MALENA_API
Definition Animate.h:25
Rect< float > FloatRect
Vector2< float > Vector2f
const sf::Font * font
Universal design token set applied across all Themeable components.
Definition Theme.h:70