Loading...
Searching...
No Matches
EditableList.h
Go to the documentation of this file.
1// Copyright (c) 2025 Dave R. Smith.
2// Malena Framework — Licensed under PolyForm Noncommercial 1.0.0; commercial use requires a paid license. See LICENSE.
3
4#ifndef MALENA_EDITABLELIST_H
5#define MALENA_EDITABLELIST_H
6
7#pragma once
8
10#include <Malena/Core/Core.h>
14#include <functional>
15#include <memory>
16#include <string>
17#include <vector>
18
19namespace ml
20{
56 {
57 public:
58 enum class SelectionMode { None, Single, Multi };
59
62 using ContentFactory = std::function<std::unique_ptr<Core>()>;
63
65 ~EditableList() override; // out-of-line for the pimpl-style Row
66
67 // Non-copyable. Required, not stylistic: __declspec(dllexport) on a class
68 // instantiates EVERY member, including the implicit copy assignment — and
69 // that cannot be formed for a std::vector<std::unique_ptr<...>> member, so
70 // MSVC fails the shared/DLL build with C2280. (Static builds and Clang/GCC
71 // never instantiate it, which is why this only broke Windows Shared.)
72 // Copying a scene-graph node was never valid anyway.
73 EditableList(const EditableList&) = delete;
75
76 // ── Configuration ──────────────────────────────────────────────────────
79 void setPlaceholder(const std::string& text); // default TextInput content
80 void setShowActions(bool show); // per-row delete button
81 void setShowAddButton(bool show);
82 void setAddButtonLabel(const std::string& label);
83 void setMinRows(int n);
84 void setMaxRows(int n);
85 void setRowHeight(float h);
86
87 // ── Rows ────────────────────────────────────────────────────────────────
88 int addRow(); // append; returns its index
89 void removeRow(int index);
90 void clearRows();
91 [[nodiscard]] int rowCount() const;
92 [[nodiscard]] Core* contentAt(int index) const; // the row's content widget
93
94 // ── Selection ─────────────────────────────────────────────────────────--
95 void setSelected(int index, bool selected);
96 [[nodiscard]] std::vector<int> selectedIndices() const;
97
98 // ── Text convenience (default TextInput content) ─────────────────────────
100 void setValues(const std::vector<std::string>& values,
101 const std::vector<int>& selected = {});
103 [[nodiscard]] std::vector<std::string> values() const;
104
105 // ── Callbacks ─────────────────────────────────────────────────────────--
106 void onChange(std::function<void()> cb);
107
108 // ── Layout ────────────────────────────────────────────────────────────--
109 void setPosition(const sf::Vector2f& pos) override;
110 void setSize(const sf::Vector2f& size);
111 void setVisible(bool visible) override;
112
113 protected:
114 // Rows live in the ScrollPane (not this Panel's child list), so mirror the
115 // enabled state onto them here — fires on both direct and cascade paths.
116 void onEnabledChanged(bool enabled) override;
117
118 private:
119 struct Row; // defined in the .cpp
120
121 std::unique_ptr<Core> makeContent() const; // factory or default TextInput
122 void relayout();
123 void onSelectorClicked(Row* row);
124 void refreshSelectors();
125 int indexOf(const Row* row) const;
126 void fireChange() const;
127
128 ScrollPane _scroll{ 10.f, 10.f };
129 RectangleButton _addBtn;
130 std::vector<std::unique_ptr<Row>> _rows;
131
132 SelectionMode _mode = SelectionMode::Single;
133 ContentFactory _contentFactory;
134 std::string _placeholder;
135 std::string _addLabel = "+ Add";
136 bool _showActions = true;
137 bool _showAdd = true;
138 int _minRows = 0;
139 int _maxRows = 100;
140 float _rowHeight = 34.f;
141
142 std::function<void()> _onChange;
143 };
144
145} // namespace ml
146
147#endif // MALENA_EDITABLELIST_H
Virtual base class for all Malena framework objects.
Definition Core.h:97
void onChange(std::function< void()> cb)
void removeRow(int index)
void setContentFactory(ContentFactory factory)
std::vector< int > selectedIndices() const
EditableList(const EditableList &)=delete
~EditableList() override
void setPosition(const sf::Vector2f &pos) override
Set the world-space position immediately (no animation).
void setSize(const sf::Vector2f &size)
void setMaxRows(int n)
std::vector< std::string > values() const
Text of every row, in order (includes empty rows — caller filters).
std::function< std::unique_ptr< Core >()> ContentFactory
void setSelected(int index, bool selected)
void setValues(const std::vector< std::string > &values, const std::vector< int > &selected={})
Replace all rows with one per value; selected marks the chosen rows.
void setPlaceholder(const std::string &text)
int rowCount() const
void setSelectionMode(SelectionMode mode)
void setShowAddButton(bool show)
void setShowActions(bool show)
void onEnabledChanged(bool enabled) override
void setAddButtonLabel(const std::string &label)
void setMinRows(int n)
EditableList & operator=(const EditableList &)=delete
void setVisible(bool visible) override
void setRowHeight(float h)
Core * contentAt(int index) const
A rectangular button with a centered text label.
#define MALENA_API
Definition Animate.h:25
Vector2< float > Vector2f