Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.24
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParameterSetEditor.hpp
1#pragma once
2#include <Gui/RaGui.hpp>
3
4#include <QGroupBox>
5#include <QLabel>
6#include <QPlainTextEdit>
7#include <QVBoxLayout>
8#include <QWidget>
9
10#include <nlohmann/json.hpp>
11
12#include <Core/Containers/VariableSetEnumManagement.hpp>
13#include <Gui/Widgets/ControlPanel.hpp>
14
15namespace Ra {
16
17namespace Core {
18class VariableSet;
19class DynamicVisitor;
20} // namespace Core
21namespace Engine {
22namespace Data {
23class Material;
24class RenderParameters;
25} // namespace Data
26} // namespace Engine
27
28namespace Gui {
29
36{
37 Q_OBJECT
38 public:
39 explicit VariableSetEditor( const std::string& name, QWidget* parent = nullptr );
40 VariableSetEditor( const VariableSetEditor& ) = delete;
41 VariableSetEditor& operator=( const VariableSetEditor& ) = delete;
43 VariableSetEditor&& operator=( VariableSetEditor&& ) = delete;
44 ~VariableSetEditor() = default;
45
57 void setupUi( Core::VariableSet& params, const nlohmann::json& constraints );
58
63 void setShowUnspecified( bool enable ) { m_showUnspecified = enable; }
64 bool showUnspecified() { return m_showUnspecified; }
65
76 template <typename T>
77 void addEnumWidget( const std::string& name,
78 T& initial,
79 Core::VariableSet& params,
80 const nlohmann::json& paramMetadata );
89 template <typename T>
90 void addNumberWidget( const std::string& name,
91 T& initial,
92 Core::VariableSet& params,
93 const nlohmann::json& metadata );
94
103 template <typename T>
104 void addVectorWidget( const std::string& key,
105 std::vector<T>& initial,
106 Core::VariableSet& params,
107 const nlohmann::json& metadata );
108
117 template <typename T>
118 void addMatrixWidget( const std::string& key,
119 T& initial,
120 Core::VariableSet& params,
121 const nlohmann::json& metadata );
122
123 signals:
127 void parameterModified( const std::string& name );
128
129 private:
131 bool m_showUnspecified = false;
132};
133
134template <typename T>
136 T& initial,
137 Core::VariableSet& params,
138 const nlohmann::json& metadata ) {
139 using namespace Ra::Core::VariableSetEnumManagement;
140 auto m = metadata[key];
141
142 std::string description = m.contains( "description" ) ? m["description"] : "";
143 std::string nm = m.contains( "name" ) ? std::string { m["name"] } : key;
144
145 if ( auto ec = getEnumConverter<T>( params, key ) ) {
146 auto items = ( *ec )->getEnumerators();
147 auto onEnumParameterStringChanged = [this, &params, &key]( const QString& value ) {
148 // params.setVariable( key, value.toStdString() );
149 setEnumVariable( params, key, value.toStdString() );
150 emit parameterModified( key );
151 };
152 addComboBox( nm,
153 onEnumParameterStringChanged,
154 getEnumString( params, key, initial ),
155 items,
156 description );
157 }
158 else {
159 LOG( Core::Utils::logWARNING )
160 << "ParameterSet don't have converter for enum " << key << " use index<>int instead.";
161
162 auto items = std::vector<std::string>();
163 items.reserve( m["values"].size() );
164 for ( const auto& value : m["values"] ) {
165 items.push_back( value );
166 }
167
168 auto onEnumParameterIntChanged = [this, &params, &key]( T value ) {
169 params.setVariable( key, value );
170 emit parameterModified( key );
171 };
172 addComboBox( nm, onEnumParameterIntChanged, initial, items, description );
173 }
174}
175
176template <typename T>
178 T& initial,
179 Core::VariableSet& /*params*/,
180 const nlohmann::json& metadata ) {
181 auto onNumberParameterChanged = [this, &initial, &key]( T value ) {
182 // no need to edit params since initial is a ref
183 initial = value;
184 emit parameterModified( key );
185 };
186
187 if ( metadata.contains( key ) ) {
188 auto m = metadata[key];
190 auto max = std::numeric_limits<T>::max();
191
192 std::string description = m.contains( "description" ) ? m["description"] : "";
193 std::string nm = m.contains( "name" ) ? std::string { m["name"] } : key;
194
195 if ( m.contains( "oneOf" ) ) {
196 // the variable has multiple valid bounds
198 bounds.reserve( m["oneOf"].size() );
199 for ( const auto& bound : m["oneOf"] ) {
200 auto mini = bound.contains( "minimum" ) ? T( bound["minimum"] ) : min;
201 auto maxi = bound.contains( "maximum" ) ? T( bound["maximum"] ) : max;
202 bounds.emplace_back( mini, maxi );
203 }
204 auto predicate = [bounds]( T value ) {
205 bool valid = false;
206 auto it = bounds.begin();
207 while ( !valid && it != bounds.end() ) {
208 valid = value >= ( *it ).first && value <= ( *it ).second;
209 ++it;
210 }
211 return valid;
212 };
213
215 nm, onNumberParameterChanged, initial, predicate, description );
216 }
217 else if ( m.contains( "minimum" ) && m.contains( "maximum" ) ) {
218 min = T( m["minimum"] );
219 max = T( m["maximum"] );
220 if constexpr ( std::is_floating_point_v<T> ) {
221 addPowerSliderInput( nm, onNumberParameterChanged, initial, min, max, description );
222 }
223 else { addSliderInput( nm, onNumberParameterChanged, initial, min, max, description ); }
224 }
225 else {
226 min = m.contains( "minimum" ) ? T( m["minimum"] ) : min;
227 max = m.contains( "maximum" ) ? T( m["maximum"] ) : max;
228 addNumberInput<T>( nm, onNumberParameterChanged, initial, min, max, description );
229 }
230 }
231 else if ( m_showUnspecified ) { addNumberInput<T>( key, onNumberParameterChanged, initial ); }
232}
233
234template <typename T>
236 std::vector<T>& initial,
237 Core::VariableSet& /*params*/,
238 const nlohmann::json& metadata ) {
239 auto onVectorParameterChanged = [this, &initial, &key]( const std::vector<T>& value ) {
240 initial = value;
241 emit parameterModified( key );
242 };
243
244 if ( metadata.contains( key ) ) {
245 auto m = metadata[key];
246 std::string description = m.contains( "description" ) ? m["description"] : "";
247 addVectorInput<T>( m["name"], onVectorParameterChanged, initial, description );
248 }
249 else if ( m_showUnspecified ) { addVectorInput<T>( key, onVectorParameterChanged, initial ); }
250}
251
252template <typename T>
254 T& initial,
255 Core::VariableSet& /*params*/,
256 const nlohmann::json& metadata ) {
257 auto onMatrixParameterChanged = [this, &initial, &key]( const Ra::Core::MatrixN& value ) {
258 initial = T( value );
259 emit parameterModified( key );
260 };
261
262 if ( metadata.contains( key ) ) {
263 auto m = metadata[key];
264 std::string description = m.contains( "description" ) ? m["description"] : "";
265 addMatrixInput( m["name"], onMatrixParameterChanged, initial, 3, description );
266 }
267 else if ( m_showUnspecified ) { addMatrixInput( key, onMatrixParameterChanged, initial ); }
268}
269
270} // namespace Gui
271} // namespace Ra
T begin(T... args)
Heterogeneous container storing "Variables", that maps a name (std::string) to a value (of any type T...
auto setVariable(const std::string &name, const T &value) -> std::pair< VariableHandle< T >, bool >
reset (or set if the variable does not exist yet) the value of the variable.
Simple Widget for RenderParameter editing The editor will expose a control panel containing all of th...
void addNumberWidget(const std::string &name, T &initial, Core::VariableSet &params, const nlohmann::json &metadata)
void addVectorWidget(const std::string &key, std::vector< T > &initial, Core::VariableSet &params, const nlohmann::json &metadata)
void addEnumWidget(const std::string &name, T &initial, Core::VariableSet &params, const nlohmann::json &paramMetadata)
Add a combobox allowing to chose the value of an enumerator.
void addMatrixWidget(const std::string &key, T &initial, Core::VariableSet &params, const nlohmann::json &metadata)
void setShowUnspecified(bool enable)
Wether to show parameters without associated metadata.
void parameterModified(const std::string &name)
void addNumberInput(const std::string &name, std::function< void(T)> callback, T initial, T min=std::numeric_limits< T >::lowest(), T max=std::numeric_limits< T >::max(), const std::string &tooltip="", int dec=3)
void addComboBox(const std::string &name, std::function< void(int)> callback, int initial, const std::vector< std::string > &items, const std::string &tooltip="")
void addSliderInput(const std::string &name, std::function< void(int)> callback, int initial=0, int min=0, int max=100, const std::string &tooltip="")
void addPowerSliderInput(const std::string &name, std::function< void(double)> callback, double initial=0, double min=0, double max=100, const std::string &tooltip="")
void addMatrixInput(const std::string &name, std::function< void(const Ra::Core::MatrixN &)> callback, const Ra::Core::MatrixN &initial, int dec=3, const std::string &tooltip="")
void addVectorInput(const std::string &name, std::function< void(const std::vector< T > &)> callback, const std::vector< T > &initial, const std::string &tooltip="")
void addConstrainedNumberInput(const std::string &name, std::function< void(T)> callback, Scalar initial, std::function< bool(T)> predicate, const std::string &tooltip="", int dec=3)
T emplace_back(T... args)
T end(T... args)
T lowest(T... args)
T max(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
T reserve(T... args)