Loading...
Searching...
No Matches
List.h
Go to the documentation of this file.
1//
2// List.h
3//
4
5#ifndef MALENA_LIST_H
6#define MALENA_LIST_H
7
8#pragma once
9
12#include <Malena/Core/Core.h>
21#include <functional>
22#include <memory>
23#include <string>
24#include <vector>
25#include <type_traits>
26
27namespace ml
28{
29 // ── ListManifest ──────────────────────────────────────────────────────────
30
32 {
33 public:
34 enum class Flag {};
35 enum class State {};
36 };
37
38 // ── List ──────────────────────────────────────────────────────────────────
39
100 class MALENA_API List : public ComponentWith<ListManifest>,
101 public ListSettings,
102 public ListTheme,
103 public Themeable
104 {
105 public:
108
109 private:
110 // ── Row storage ───────────────────────────────────────────────────────
111 struct Row
112 {
113 ml::Core* component = nullptr;
114 std::unique_ptr<ListItem> owned;
115 };
116
117 std::vector<Row> _rows;
118 std::vector<sf::RectangleShape> _dividers;
119 Row _pinnedBottom;
120 bool _hasPinnedBottom = false;
121
122 // ── Layout ────────────────────────────────────────────────────────────
123 sf::RectangleShape _background;
124 sf::Vector2f _position = {0.f, 0.f};
125 float _width = 300.f;
126 float _indent = 0.f;
127
128 // ── Internal helpers ──────────────────────────────────────────────────
129 void layout();
130 void rebuildDividers();
131 void applyThemeToOwnedItems();
132 void applySettingsToOwnedItems();
133
134 protected:
135 void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
136 void onThemeApplied(const Theme& theme) override;
137
138 public:
140
141 List(const List&) = delete;
142 List& operator=(const List&) = delete;
143
144 // ── Apply ─────────────────────────────────────────────────────────────
145
146 template<typename S>
147 void applySettings(const S& s)
148 {
149 static_assert(std::is_base_of_v<ListSettings, S>,
150 "applySettings() requires a type derived from ListSettings");
151 static_cast<ListSettings&>(*this) = s;
152 applySettingsToOwnedItems();
153 layout();
154 }
155
156 template<typename T>
157 void applyTheme(const T& t)
158 {
159 static_assert(std::is_base_of_v<ListTheme, T>,
160 "applyTheme() requires a type derived from ListTheme");
161 static_cast<ListTheme&>(*this) = t;
162 applyThemeToOwnedItems();
163 layout();
164 }
165
166 template<typename St>
167 void applyStyle(const St& s)
168 {
169 static_assert(std::is_base_of_v<ListSettings, St> &&
170 std::is_base_of_v<ListTheme, St>,
171 "applyStyle() requires ListSettings and ListTheme");
172 static_cast<ListSettings&>(*this) = s;
173 static_cast<ListTheme&>(*this) = s;
174 applyThemeToOwnedItems();
175 applySettingsToOwnedItems();
176 layout();
177 }
178
179 // ── Adding rows ───────────────────────────────────────────────────────
180
193 ListItem& addItem(const std::string& label,
194 const std::string& description = "",
195 std::function<void()> onClick = nullptr);
196
206 void add(ml::Core& component);
207
214 ListItem& addPinnedBottom(const std::string& label,
215 std::function<void()> onClick = nullptr);
216
226 bool removeAt(std::size_t index);
227
237 bool remove(const ml::Core* component);
238
240 void clear();
241
243 [[nodiscard]] std::size_t rowCount() const { return _rows.size(); }
244
254 [[nodiscard]] ListItem* back()
255 {
256 if (_rows.empty()) return nullptr;
257 return dynamic_cast<ListItem*>(_rows.back().component);
258 }
259
260 // ── Sizing ────────────────────────────────────────────────────────────
261
270 void setWidth(float width);
271 void setSize(const sf::Vector2f& size) { setWidth(size.x); }
272 [[nodiscard]] float getWidth() const { return _width; }
273 [[nodiscard]] float getTotalHeight() const;
274
275 // ── Indent (for nested lists) ─────────────────────────────────────────
276
281 void setIndentOffset(float offset) { _indent = offset; layout(); }
282
283 // ── Positionable ──────────────────────────────────────────────────────
284
285 void setPosition(const sf::Vector2f& position) override;
286 sf::Vector2f getPosition() const override;
288 };
289
290 // ── ListWith ──────────────────────────────────────────────────────────────
291
292 template<typename MANIFEST>
293 class ListWith : public List, public Customizable<MANIFEST>
294 { public: using List::List; };
295
296} // namespace ml
297
298#endif // MALENA_LIST_H
Virtual base class for all Malena framework objects.
Definition Core.h:97
static const sf::Font & getDefault()
Return the built-in Arial font.
sf::Vector2f getPosition() const override
void applyTheme(const T &t)
Definition List.h:157
float getWidth() const
Definition List.h:272
std::size_t rowCount() const
Return the number of rows.
Definition List.h:243
ListItem & addItem(const std::string &label, const std::string &description="", std::function< void()> onClick=nullptr)
Create and own a ListItem with a label.
float getTotalHeight() const
void applyStyle(const St &s)
Definition List.h:167
void setIndentOffset(float offset)
Set the current indentation offset in pixels. Called automatically by a parent List when nesting.
Definition List.h:281
void setSize(const sf::Vector2f &size)
Definition List.h:271
void draw(sf::RenderTarget &target, sf::RenderStates states) const override
void clear()
Remove all rows. Owned ListItem objects are destroyed.
void setPosition(const sf::Vector2f &position) override
ListItem & addPinnedBottom(const std::string &label, std::function< void()> onClick=nullptr)
Create a ListItem pinned to the bottom of the list.
List & operator=(const List &)=delete
ListManifest::Flag Flag
Definition List.h:106
void setWidth(float width)
Set the total width of the list.
bool remove(const ml::Core *component)
Remove a row by component pointer.
sf::FloatRect getGlobalBounds() const override
void add(ml::Core &component)
Add any ml::Core component as a row.
List(const List &)=delete
bool removeAt(std::size_t index)
Remove a row by index.
ListManifest::State State
Definition List.h:107
ListItem * back()
Return a pointer to the last added owned ListItem, or nullptr if the list is empty or the last row is...
Definition List.h:254
void applySettings(const S &s)
Definition List.h:147
void onThemeApplied(const Theme &theme) override
Called by ThemeManager when the active theme changes.
List(const sf::Font &font=FontManager<>::getDefault())
A single row in a List with start, content and end slots.
Definition ListItem.h:81
List(const sf::Font &font=FontManager<>::getDefault())
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
Layout and behaviour settings for List.
Color tokens for List.
Definition ListTheme.h:24
Universal design token set applied across all Themeable components.
Definition Theme.h:70