1#include <Gui/ParameterSetEditor/ParameterSetEditor.hpp>
3#include <Core/Containers/VariableSetEnumManagement.hpp>
4#include <Engine/Data/Material.hpp>
5#include <Gui/Widgets/ControlPanel.hpp>
14using json = nlohmann::json;
17using namespace Engine;
21class RenderParameterUiBuilder
26 RenderParameterUiBuilder( VariableSetEditor* pse,
const json& constraints ) :
27 m_pse { pse }, m_constraints { constraints } {}
29 void operator()(
const std::string& name,
bool& p, Core::VariableSet&& ) {
30 auto onBoolParameterChanged = [pse = this->m_pse, &p, nm = name](
bool val ) {
32 emit pse->parameterModified( nm );
34 if ( m_constraints.contains( name ) ) {
35 if ( m_constraints[name][
"editable"] ) {
36 const auto& m = m_constraints[name];
37 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
39 m_pse->
addOption( nm, onBoolParameterChanged, p, description );
42 else if ( m_pse->showUnspecified() ) {
43 m_pse->
addOption( name, onBoolParameterChanged, p );
47 template <typename TParam, std::enable_if_t<std::is_arithmetic<TParam>::value,
bool> =
true>
48 void operator()(
const std::string& name, TParam& p, Core::VariableSet&& params ) {
49 using namespace Ra::Core::VariableSetEnumManagement;
50 if ( getEnumConverter<TParam>( params, name ) ) {
59 template <
typename TParam,
61 std::enable_if_t<std::is_arithmetic<TParam>::value,
bool> =
true>
70 auto onColorParameterChanged =
72 params.setVariable( nm, val );
73 emit pse->parameterModified( nm );
75 if ( m_constraints.contains( name ) ) {
76 const auto& m = m_constraints[name];
77 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
79 m_pse->
addColorInput( nm, onColorParameterChanged, p, m[
"maxItems"] == 4, description );
81 else if ( m_pse->showUnspecified() ) {
86 template <
template <
typename,
int...>
typename M,
typename T,
int... dim>
102 if constexpr ( std::is_assignable_v<Core::VariableSet, typename std::decay<T>::type> ) {
103 if constexpr ( std::is_const_v<T> ) {
104 p.
get().visit( *
this,
114 const json& m_constraints;
118VariableSetEditor::VariableSetEditor(
const std::string& name, QWidget* parent ) :
119 ControlPanel( name, !name.empty(), parent ) {}
125 const json& metadata ) {
126 using namespace Ra::Core::VariableSetEnumManagement;
127 auto m = metadata[key];
129 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
131 if (
auto ec = getEnumConverter<T>( params, key ) ) {
132 auto items = ( *ec )->getEnumerators();
133 auto onEnumParameterStringChanged = [
this, ¶ms, &key](
const QString& value ) {
135 emit parameterModified( key );
138 onEnumParameterStringChanged,
139 getEnumString( params, key, initial ),
144 LOG( Core::Utils::logWARNING )
145 <<
"ParameterSet don't have converter for enum " << key <<
" use index<>int instead.";
148 items.reserve( m[
"values"].size() );
149 for (
const auto& value : m[
"values"] ) {
150 items.push_back( value );
153 auto onEnumParameterIntChanged = [
this, ¶ms, &key]( T value ) {
155 emit parameterModified( key );
157 addComboBox( nm, onEnumParameterIntChanged, initial, items, description );
165 const json& metadata ) {
167 auto onNumberParameterChanged = [
this, &initial, &key]( T value ) {
169 emit parameterModified( key );
171 if ( metadata.contains( key ) ) {
172 auto m = metadata[key];
176 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
179 if ( m.contains(
"oneOf" ) ) {
182 bounds.
reserve( m[
"oneOf"].size() );
183 for (
const auto& bound : m[
"oneOf"] ) {
184 auto mini = bound.contains(
"minimum" ) ? T( bound[
"minimum"] ) : min;
185 auto maxi = bound.contains(
"maximum" ) ? T( bound[
"maximum"] ) : max;
188 auto predicate = [bounds]( T value ) {
190 auto it = bounds.
begin();
191 while ( !valid && it != bounds.
end() ) {
192 valid = value >= ( *it ).first && value <= ( *it ).second;
198 addConstrainedNumberInput<T>(
199 nm, onNumberParameterChanged, initial, predicate, description );
201 else if ( m.contains(
"minimum" ) && m.contains(
"maximum" ) ) {
202 min = T( m[
"minimum"] );
203 max = T( m[
"maximum"] );
204 if constexpr ( std::is_floating_point_v<T> ) {
205 addPowerSliderInput( nm, onNumberParameterChanged, initial, min, max, description );
207 else { addSliderInput( nm, onNumberParameterChanged, initial, min, max, description ); }
210 min = m.contains(
"minimum" ) ? T( m[
"minimum"] ) : min;
211 max = m.contains(
"maximum" ) ? T( m[
"maximum"] ) : max;
212 addNumberInput<T>( nm, onNumberParameterChanged, initial, min, max, description );
215 else if ( m_showUnspecified ) { addNumberInput<T>( key, onNumberParameterChanged, initial ); }
222 const json& metadata ) {
223 auto onVectorParameterChanged = [
this, &initial, &key](
const std::vector<T>& value ) {
225 emit parameterModified( key );
228 if ( metadata.contains( key ) ) {
229 auto m = metadata[key];
230 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
231 addVectorInput<T>( m[
"name"], onVectorParameterChanged, initial, description );
233 else if ( m_showUnspecified ) { addVectorInput<T>( key, onVectorParameterChanged, initial ); }
240 const json& metadata ) {
241 auto onMatrixParameterChanged = [
this, &initial, &key](
const Ra::Core::MatrixN& value ) {
242 initial = T( value );
243 emit parameterModified( key );
246 if ( metadata.contains( key ) ) {
247 auto m = metadata[key];
248 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
249 addMatrixInput( m[
"name"], onMatrixParameterChanged, initial, 3, description );
251 else if ( m_showUnspecified ) { addMatrixInput( key, onMatrixParameterChanged, initial ); }
254void VariableSetEditor::setupUi(
Core::VariableSet& params,
const nlohmann::json& constraints ) {
256 internal::RenderParameterUiBuilder uiBuilder {
this, constraints };
257 params.
visit( uiBuilder, params );
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.
void visit(F &&visitor) const
Visit the container using a user defined visitor.
Core::Utils::TypeList< bool, Core::Utils::Color, int, uint, Scalar, TextureInfo, std::vector< int >, std::vector< uint >, std::vector< Scalar >, Core::Vector2, Core::Vector3, Core::Vector4, Core::Matrix2, Core::Matrix3, Core::Matrix4, std::reference_wrapper< RenderParameters >, std::reference_wrapper< const RenderParameters > > BindableTypes
List of bindable types, to be used with static visitors.
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 ¶ms, const nlohmann::json &metadata)
void addVectorWidget(const std::string &key, std::vector< T > &initial, Core::VariableSet ¶ms, const nlohmann::json &metadata)
void addEnumWidget(const std::string &name, T &initial, Core::VariableSet ¶ms, const nlohmann::json ¶mMetadata)
Add a combobox allowing to chose the value of an enumerator.
void addMatrixWidget(const std::string &key, T &initial, Core::VariableSet ¶ms, const nlohmann::json &metadata)
T emplace_back(T... args)
hepler function to manage enum as underlying types in VariableSet