1 #include <Gui/ParameterSetEditor/ParameterSetEditor.hpp>
3 #include <Gui/Widgets/ControlPanel.hpp>
6 #include <Engine/Data/Material.hpp>
14 using json = nlohmann::json;
17 using namespace Engine;
21 class RenderParameterUiBuilder
27 m_pse { pse }, m_constraints { constraints } {}
30 auto onBoolParameterChanged = [pse = this->m_pse, &p, nm = name](
bool val ) {
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"] :
"";
38 std::string nm = m.contains(
"name" ) ? std::string { m[
"name"] } : name;
39 m_pse->addOption( nm, onBoolParameterChanged, p, description );
42 else if ( m_pse->m_showUnspecified ) {
43 m_pse->addOption( name, onBoolParameterChanged, p );
47 template <typename TParam, std::enable_if_t<std::is_arithmetic<TParam>::value,
bool> =
true>
49 if ( params.getEnumConverter<TParam>( name ) ) {
50 m_pse->addEnumParameterWidget( name, p, params, m_constraints );
54 m_pse->addNumberParameterWidget( name, p, params, m_constraints );
58 template <
typename TParam,
60 std::enable_if_t<std::is_arithmetic<TParam>::value,
bool> =
true>
61 void operator()(
const std::string& name,
62 std::vector<TParam, TAllocator>& p,
64 m_pse->addVectorParameterWidget( name, p, params, m_constraints );
67 void operator()(
const std::string& name,
70 auto onColorParameterChanged =
72 params.addParameter( nm, val );
75 if ( m_constraints.contains( name ) ) {
76 const auto& m = m_constraints[name];
77 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
78 std::string nm = m.contains(
"name" ) ? std::string { m[
"name"] } : name;
79 m_pse->addColorInput( nm, onColorParameterChanged, p, m[
"maxItems"] == 4, description );
81 else if ( m_pse->m_showUnspecified ) {
82 m_pse->addColorInput( name, onColorParameterChanged, p );
86 template <
template <
typename,
int...>
typename M,
typename T,
int... dim>
88 m_pse->addMatrixParameterWidget( name, p, params, m_constraints );
91 void operator()(
const std::string& ,
98 void operator()(
const std::string& ,
99 std::reference_wrapper<T>& ,
106 const json& m_constraints;
111 ControlPanel( name, !name.empty(), parent ) {}
113 template <
typename T>
114 void ParameterSetEditor::addEnumParameterWidget(
const std::string& key,
117 const json& metadata ) {
118 auto m = metadata[key];
120 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
121 std::string nm = m.contains(
"name" ) ? std::string { m[
"name"] } : key;
123 auto items = ( *ec )->getEnumerators();
124 auto onEnumParameterStringChanged = [
this, ¶ms, &key](
const QString& value ) {
129 onEnumParameterStringChanged,
135 LOG( Core::Utils::logWARNING )
136 <<
"ParameterSet don't have converter for enum " << key <<
" use index<>int instead.";
138 auto items = std::vector<std::string>();
139 items.reserve( m[
"values"].size() );
140 for (
const auto& value : m[
"values"] ) {
141 items.push_back( value );
144 auto onEnumParameterIntChanged = [
this, ¶ms, &key]( T value ) {
148 addComboBox( nm, onEnumParameterIntChanged, initial, items, description );
152 template <
typename T>
153 void ParameterSetEditor::addNumberParameterWidget(
const std::string& key,
156 const json& metadata ) {
158 auto onNumberParameterChanged = [
this, &initial, &key]( T value ) {
162 if ( metadata.contains( key ) ) {
163 auto m = metadata[key];
164 auto min = std::numeric_limits<T>::lowest();
165 auto max = std::numeric_limits<T>::max();
167 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
168 std::string nm = m.contains(
"name" ) ? std::string { m[
"name"] } : key;
170 if ( m.contains(
"oneOf" ) ) {
172 std::vector<std::pair<T, T>> bounds;
173 bounds.reserve( m[
"oneOf"].size() );
174 for (
const auto& bound : m[
"oneOf"] ) {
175 auto mini = bound.contains(
"minimum" ) ? T( bound[
"minimum"] ) : min;
176 auto maxi = bound.contains(
"maximum" ) ? T( bound[
"maximum"] ) : max;
177 bounds.emplace_back( mini, maxi );
179 auto predicate = [bounds]( T value ) {
181 auto it = bounds.begin();
182 while ( !valid && it != bounds.end() ) {
183 valid = value >= ( *it ).first && value <= ( *it ).second;
189 addConstrainedNumberInput<T>(
190 nm, onNumberParameterChanged, initial, predicate, description );
192 else if ( m.contains(
"minimum" ) && m.contains(
"maximum" ) ) {
193 min = T( m[
"minimum"] );
194 max = T( m[
"maximum"] );
195 if constexpr ( std::is_floating_point_v<T> ) {
198 else {
addSliderInput( nm, onNumberParameterChanged, initial, min, max, description ); }
201 min = m.contains(
"minimum" ) ? T( m[
"minimum"] ) : min;
202 max = m.contains(
"maximum" ) ? T( m[
"maximum"] ) : max;
203 addNumberInput<T>( nm, onNumberParameterChanged, initial, min, max, description );
206 else if ( m_showUnspecified ) { addNumberInput<T>( key, onNumberParameterChanged, initial ); }
209 template <
typename T>
210 void ParameterSetEditor::addVectorParameterWidget(
const std::string& key,
211 std::vector<T>& initial,
213 const json& metadata ) {
214 auto onVectorParameterChanged = [
this, &initial, &key](
const std::vector<T>& value ) {
219 if ( metadata.contains( key ) ) {
220 auto m = metadata[key];
221 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
222 addVectorInput<T>( m[
"name"], onVectorParameterChanged, initial, description );
224 else if ( m_showUnspecified ) { addVectorInput<T>( key, onVectorParameterChanged, initial ); }
227 template <
typename T>
228 void ParameterSetEditor::addMatrixParameterWidget(
const std::string& key,
231 const json& metadata ) {
232 auto onMatrixParameterChanged = [
this, &initial, &key](
const Ra::Core::MatrixN& value ) {
233 initial = T( value );
237 if ( metadata.contains( key ) ) {
238 auto m = metadata[key];
239 std::string description = m.contains(
"description" ) ? m[
"description"] :
"";
240 addMatrixInput( m[
"name"], onMatrixParameterChanged, initial, 3, description );
242 else if ( m_showUnspecified ) {
addMatrixInput( key, onMatrixParameterChanged, initial ); }
246 const nlohmann::json& constraints ) {
248 internal::RenderParameterUiBuilder uiBuilder {
this, constraints };
249 params.
visit( uiBuilder, params );
255 m_showUnspecified = enable;
void addParameter(const std::string &name, T value, typename std::enable_if<!std::is_class< T > {}, bool >::type=true)
Add a parameter by value.
std::pair< Data::Texture *, int > TextureInfo
Special type for Texture parameter.
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
Aliases for bindable parameter types.
Core::Utils::optional< std::shared_ptr< Core::Utils::EnumConverter< EnumBaseType > > > getEnumConverter(const std::string &name)
Search for a converter associated with an enumeration parameter.
std::string getEnumString(const std::string &name, Enum value)
Return the string associated to the actual value of a parameter.
void visit(V &&visitor) const
Simple Widget for RenderParameter edition The editor will expose a control panel containing all of th...
ParameterSetEditor(const std::string &name, QWidget *parent=nullptr)
void parameterModified(const std::string &name)
void showUnspecified(bool enable)
void setupFromParameters(Engine::Data::RenderParameters ¶ms, const nlohmann::json &constraints)
Update the different UI element with the given renderParameter, using the given constraints.