feat: add int slider, fix float slider rang

This commit is contained in:
parker
2025-08-11 18:39:52 +01:00
parent 5ac023e637
commit 1268de4f97
13 changed files with 249 additions and 67 deletions

View File

@@ -51,9 +51,9 @@ set(GUI_SOURCES
src/Gui/Network/NodeIconGraphic.cpp src/Gui/Network/NodeIconGraphic.cpp
src/Gui/Network/TabMenu.cpp src/Gui/Network/TabMenu.cpp
src/Gui/ParametersPanel/ParametersPanel.cpp src/Gui/ParametersPanel/ParametersPanel.cpp
src/Gui/Parameters/AbstractSliderParm.cpp src/Gui/Parameters/FloatSliderParm.cpp
src/Gui/Parameters/AbstractFormParm.cpp src/Gui/Parameters/IntSliderParm.cpp
src/Gui/Parameters/FloatParm.cpp src/Gui/Parameters/FormParm.cpp
src/Gui/Parameters/StringParm.cpp src/Gui/Parameters/StringParm.cpp
) )
set(ENGINE_INCLUDE_DIRECTORIES set(ENGINE_INCLUDE_DIRECTORIES

View File

@@ -9,18 +9,18 @@
enzo::prm::Parameter::Parameter(Template prmTemplate) enzo::prm::Parameter::Parameter(Template prmTemplate)
: template_{prmTemplate} : template_{prmTemplate}
{ {
floatValues_ = std::vector<bt::floatT>();
floatValues_.reserve(prmTemplate.getSize());
stringValues_ = std::vector<bt::String>(prmTemplate.getSize(), prmTemplate.getDefault().getString());
stringValues_.reserve(prmTemplate.getSize());
const unsigned int templateSize = prmTemplate.getSize(); const unsigned int templateSize = prmTemplate.getSize();
const unsigned int numDefaults = prmTemplate.getNumDefaults(); const unsigned int numDefaults = prmTemplate.getNumDefaults();
floatValues_.reserve(templateSize);
stringValues_.reserve(templateSize);
intValues_.reserve(templateSize);
if(numDefaults==1) if(numDefaults==1)
{ {
floatValues_ = std::vector<bt::floatT>(templateSize, prmTemplate.getDefault().getFloat()); floatValues_ = std::vector<bt::floatT>(templateSize, prmTemplate.getDefault().getFloat());
intValues_ = std::vector<bt::intT>(templateSize, prmTemplate.getDefault().getInt());
stringValues_ = std::vector<bt::String>(templateSize, prmTemplate.getDefault().getString()); stringValues_ = std::vector<bt::String>(templateSize, prmTemplate.getDefault().getString());
} }
@@ -33,6 +33,7 @@ enzo::prm::Parameter::Parameter(Template prmTemplate)
} }
floatValues_.push_back(prmDefault.getFloat()); floatValues_.push_back(prmDefault.getFloat());
stringValues_.push_back(prmDefault.getString()); stringValues_.push_back(prmDefault.getString());
intValues_.push_back(prmDefault.getInt());
} }
@@ -51,6 +52,13 @@ enzo::bt::floatT enzo::prm::Parameter::evalFloat(unsigned int index) const
return floatValues_[index]; return floatValues_[index];
} }
enzo::bt::intT enzo::prm::Parameter::evalInt(unsigned int index) const
{
if(index >= intValues_.size())
throw std::out_of_range("Cannot access index: " + std::to_string(index) + " for parameter: " + getName());
return intValues_[index];
}
enzo::bt::String enzo::prm::Parameter::evalString(unsigned int index) const enzo::bt::String enzo::prm::Parameter::evalString(unsigned int index) const
{ {
if(index >= stringValues_.size()) if(index >= stringValues_.size())
@@ -66,6 +74,14 @@ enzo::prm::Type enzo::prm::Parameter::getType() const
} }
void enzo::prm::Parameter::setInt(bt::intT value, unsigned int index)
{
if(index >= intValues_.size())
throw std::out_of_range("Cannot access index: " + std::to_string(index) + " for parameter: " + getName());
intValues_[index] = value;
valueChanged();
}
void enzo::prm::Parameter::setFloat(bt::floatT value, unsigned int index) void enzo::prm::Parameter::setFloat(bt::floatT value, unsigned int index)
{ {
if(index >= floatValues_.size()) if(index >= floatValues_.size())

View File

@@ -14,7 +14,9 @@ public:
bt::floatT evalFloat(unsigned int index=0) const; bt::floatT evalFloat(unsigned int index=0) const;
bt::String evalString(unsigned int index=0) const; bt::String evalString(unsigned int index=0) const;
bt::intT evalInt(unsigned int index=0) const;
void setInt(bt::intT value, unsigned int index=0);
void setFloat(bt::floatT value, unsigned int index=0); void setFloat(bt::floatT value, unsigned int index=0);
void setString(bt::String value, unsigned int index=0); void setString(bt::String value, unsigned int index=0);
@@ -23,6 +25,7 @@ private:
Template template_; Template template_;
std::vector<bt::floatT> floatValues_; std::vector<bt::floatT> floatValues_;
std::vector<bt::String> stringValues_; std::vector<bt::String> stringValues_;
std::vector<bt::intT> intValues_;
}; };
} }

View File

@@ -1,3 +0,0 @@
#include "Gui/Parameters/FloatParm.h"

View File

@@ -1,13 +0,0 @@
#include "Gui/Parameters/AbstractSliderParm.h"
namespace enzo::ui
{
class FloatParm
: public AbstractSliderParm
{
using AbstractSliderParm = AbstractSliderParm;
};
}

View File

@@ -1,4 +1,4 @@
#include "Gui/Parameters/AbstractSliderParm.h" #include "Gui/Parameters/FloatSliderParm.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include <QPainter> #include <QPainter>
#include <QPaintEvent> #include <QPaintEvent>
@@ -10,7 +10,7 @@
#include <string> #include <string>
enzo::ui::AbstractSliderParm::AbstractSliderParm(bt::floatT value, QWidget *parent, Qt::WindowFlags f) enzo::ui::FloatSliderParm::FloatSliderParm(bt::floatT value, QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f) : QWidget(parent, f)
{ {
// tells qt to style the widget even though it's a Q_OBJECT // tells qt to style the widget even though it's a Q_OBJECT
@@ -37,23 +37,26 @@ enzo::ui::AbstractSliderParm::AbstractSliderParm(bt::floatT value, QWidget *pare
setValueImpl(value); setValueImpl(value);
} }
void enzo::ui::AbstractSliderParm::paintEvent(QPaintEvent *event) void enzo::ui::FloatSliderParm::paintEvent(QPaintEvent *event)
{ {
QPainter painter(this); QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
painter.setBrush(QColor("#383838")); painter.setBrush(QColor("#383838"));
QRectF fillRect = event->rect(); const int valueRange = maxValue_-minValue_;
float fillPercent = value_/maxValue_; float fillPercent = static_cast<float>(value_-minValue_)/valueRange;
std::cout << "fill percent" << fillPercent << "\n";
float margin = 3; constexpr float margin = 3;
fillRect.adjust(margin, margin, std::max<float>(-fillRect.width()+margin, -fillRect.width()*(1-fillPercent)-margin), -margin); float fillWidth = rect().width()-margin*2;
fillWidth *= fillPercent;
QRectF fillRect = {rect().left()+margin, rect().top()+margin, fillWidth, rect().height()-margin*2};
painter.drawRoundedRect(fillRect, 6, 6); painter.drawRoundedRect(fillRect, 6, 6);
} }
void enzo::ui::AbstractSliderParm::setValueImpl(bt::floatT value) void enzo::ui::FloatSliderParm::setValueImpl(bt::floatT value)
{ {
if(clampMin_ && value<minValue_) { value = minValue_; } if(clampMin_ && value<minValue_) { value = minValue_; }
if(clampMax_ && value>maxValue_) { value = maxValue_; } if(clampMax_ && value>maxValue_) { value = maxValue_; }
@@ -66,7 +69,7 @@ void enzo::ui::AbstractSliderParm::setValueImpl(bt::floatT value)
} }
void enzo::ui::AbstractSliderParm::setValue(bt::floatT value) void enzo::ui::FloatSliderParm::setValue(bt::floatT value)
{ {
setValueImpl(value); setValueImpl(value);
@@ -76,13 +79,21 @@ void enzo::ui::AbstractSliderParm::setValue(bt::floatT value)
} }
void enzo::ui::AbstractSliderParm::mouseMoveEvent(QMouseEvent *event) void enzo::ui::FloatSliderParm::mouseMoveEvent(QMouseEvent *event)
{ {
setValue(static_cast<float>(event->pos().x())/rect().width() * maxValue_); // normalized
float value = static_cast<float>(event->pos().x())/rect().width();
//remap
value = minValue_+(maxValue_-minValue_)*value;
setValue(value);
} }
void enzo::ui::AbstractSliderParm::mousePressEvent(QMouseEvent *event) void enzo::ui::FloatSliderParm::mousePressEvent(QMouseEvent *event)
{ {
setValue(static_cast<float>(event->pos().x())/rect().width() * maxValue_); // normalized
float value = static_cast<float>(event->pos().x())/rect().width();
//remap
value = minValue_+(maxValue_-minValue_)*value;
setValue(value);
} }

View File

@@ -7,12 +7,12 @@
namespace enzo::ui namespace enzo::ui
{ {
class AbstractSliderParm class FloatSliderParm
: public QWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
AbstractSliderParm(bt::floatT value, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); FloatSliderParm(bt::floatT value, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
void setValue(bt::floatT value); void setValue(bt::floatT value);
Q_SIGNALS: Q_SIGNALS:

View File

@@ -1,6 +1,7 @@
#include "Gui/Parameters/AbstractFormParm.h" #include "Gui/Parameters/FormParm.h"
#include "Gui/Parameters/IntSliderParm.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include "Gui/Parameters/AbstractSliderParm.h" #include "Gui/Parameters/FloatSliderParm.h"
#include "Gui/Parameters/StringParm.h" #include "Gui/Parameters/StringParm.h"
#include <qboxlayout.h> #include <qboxlayout.h>
#include <QLabel> #include <QLabel>
@@ -9,7 +10,7 @@
#include <string> #include <string>
enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> parameter) enzo::ui::FormParm::FormParm(std::weak_ptr<prm::Parameter> parameter)
: parameter_{parameter} : parameter_{parameter}
{ {
if(auto sharedParameter=parameter_.lock()) if(auto sharedParameter=parameter_.lock())
@@ -27,25 +28,31 @@ enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> param
{ {
case prm::Type::FLOAT: case prm::Type::FLOAT:
{ {
AbstractSliderParm* slider; FloatSliderParm* slider = new FloatSliderParm(sharedParameter->evalFloat());
slider = new AbstractSliderParm(sharedParameter->evalFloat());
mainLayout_->addWidget(slider); mainLayout_->addWidget(slider);
connect(slider, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);}); connect(slider, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);});
break;
}
case prm::Type::INT:
{
IntSliderParm* slider = new IntSliderParm(sharedParameter->evalInt());
mainLayout_->addWidget(slider);
connect(slider, &IntSliderParm::valueChanged, this, [this](bt::intT value){this->changeValue(value, 0);});
break; break;
} }
case prm::Type::XYZ: case prm::Type::XYZ:
{ {
AbstractSliderParm* slider1 = new AbstractSliderParm(sharedParameter->evalFloat(0)); FloatSliderParm* slider1 = new FloatSliderParm(sharedParameter->evalFloat(0));
AbstractSliderParm* slider2 = new AbstractSliderParm(sharedParameter->evalFloat(1)); FloatSliderParm* slider2 = new FloatSliderParm(sharedParameter->evalFloat(1));
AbstractSliderParm* slider3 = new AbstractSliderParm(sharedParameter->evalFloat(2)); FloatSliderParm* slider3 = new FloatSliderParm(sharedParameter->evalFloat(2));
QHBoxLayout* vectorLayout = new QHBoxLayout(); QHBoxLayout* vectorLayout = new QHBoxLayout();
vectorLayout->addWidget(slider1); vectorLayout->addWidget(slider1);
vectorLayout->addWidget(slider2); vectorLayout->addWidget(slider2);
vectorLayout->addWidget(slider3); vectorLayout->addWidget(slider3);
mainLayout_->addLayout(vectorLayout); mainLayout_->addLayout(vectorLayout);
connect(slider1, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);}); connect(slider1, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);});
connect(slider2, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 1);}); connect(slider2, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 1);});
connect(slider3, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 2);}); connect(slider3, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 2);});
break; break;
} }
case prm::Type::STRING: case prm::Type::STRING:
@@ -61,7 +68,7 @@ enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> param
} }
default: default:
throw std::runtime_error("Parameter panel: paremeter type not accounted for " + std::to_string(static_cast<int>(sharedParameter->getType()))); throw std::runtime_error("Form parm: paremeter type not accounted for " + std::to_string(static_cast<int>(sharedParameter->getType())));
} }
@@ -77,20 +84,20 @@ enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> param
} }
int enzo::ui::AbstractFormParm::getLeftPadding() int enzo::ui::FormParm::getLeftPadding()
{ {
return label_->minimumSizeHint().width(); return label_->minimumSizeHint().width();
} }
void enzo::ui::AbstractFormParm::setLeftPadding(int padding) void enzo::ui::FormParm::setLeftPadding(int padding)
{ {
label_->setFixedWidth(padding); label_->setFixedWidth(padding);
} }
void enzo::ui::AbstractFormParm::changeValue(enzo::bt::floatT value, unsigned int index) void enzo::ui::FormParm::changeValue(enzo::bt::floatT value, unsigned int index)
{ {
if(auto sharedParameter=parameter_.lock()) if(auto sharedParameter=parameter_.lock())
{ {
@@ -104,7 +111,7 @@ void enzo::ui::AbstractFormParm::changeValue(enzo::bt::floatT value, unsigned in
} }
void enzo::ui::AbstractFormParm::changeValue(enzo::bt::String value, unsigned int index) void enzo::ui::FormParm::changeValue(enzo::bt::String value, unsigned int index)
{ {
if(auto sharedParameter=parameter_.lock()) if(auto sharedParameter=parameter_.lock())
{ {

View File

@@ -8,12 +8,12 @@
namespace enzo::ui namespace enzo::ui
{ {
class AbstractFormParm class FormParm
: public QWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
AbstractFormParm(std::weak_ptr<prm::Parameter> parameter); FormParm(std::weak_ptr<prm::Parameter> parameter);
int getLeftPadding(); int getLeftPadding();
void setLeftPadding(int padding); void setLeftPadding(int padding);

View File

@@ -0,0 +1,117 @@
#include "Gui/Parameters/IntSliderParm.h"
#include "Engine/Types.h"
#include <QPainter>
#include <QPaintEvent>
#include <QLabel>
#include <cmath>
#include <iostream>
#include <qboxlayout.h>
#include <qnamespace.h>
#include <algorithm>
#include <string>
#include <icecream.hpp>
enzo::ui::IntSliderParm::IntSliderParm(bt::intT value, QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
// tells qt to style the widget even though it's a Q_OBJECT
setAttribute(Qt::WA_StyledBackground, true);
setFixedHeight(24);
notchPen_ = QPen(QColor("#383838"), notchWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
mainLayout_ = new QVBoxLayout();
setLayout(mainLayout_);
valueLabel_ = new QLabel();
valueLabel_->setAlignment(Qt::AlignCenter);
valueLabel_->setStyleSheet("background-color: none;");
setProperty("type", "SliderParm");
setStyleSheet(R"(
QWidget[type="SliderParm"]
{
border-radius: 6px;
border: 1px solid #383838;
}
)");
mainLayout_->addWidget(valueLabel_);
setValueImpl(value);
}
void enzo::ui::IntSliderParm::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
const int valueRange = maxValue_-minValue_;
float fillPercent = static_cast<float>(value_-minValue_)/valueRange;
IC(value_, fillPercent);
float margin = 3;
float fillWidth = rect().width()-margin*2;
fillWidth *= fillPercent;
QRectF fillRect = {rect().left()+margin, rect().top()+margin, fillWidth, rect().height()-margin*2};
painter.setPen(notchPen_);
QRectF markerLinesRect = rect();
markerLinesRect.adjust(margin, margin, -margin, -margin);
for(int i=minValue_+1;i<maxValue_; ++i)
{
float x = ((i-minValue_)*markerLinesRect.width())/valueRange;
x += notchWidth+4; // offset
const float y = markerLinesRect.bottom()-2;
painter.drawLine(x, y, x, y-5);
}
painter.setPen(Qt::NoPen);
painter.setBrush(QColor("#383838"));
painter.drawRoundedRect(fillRect, 6, 6);
}
void enzo::ui::IntSliderParm::setValueImpl(bt::intT value)
{
if(clampMin_ && value<minValue_) { value = minValue_; }
if(clampMax_ && value>maxValue_) { value = maxValue_; }
value_ = value;
QString valStr = QString::number(value_);
valStr.truncate(4);
valueLabel_->setText(valStr);
}
void enzo::ui::IntSliderParm::setValue(bt::intT value)
{
setValueImpl(value);
update();
valueChanged(value_);
}
void enzo::ui::IntSliderParm::mouseMoveEvent(QMouseEvent *event)
{
// normalized
float value = static_cast<float>(event->pos().x())/rect().width();
//remap
value = minValue_+(maxValue_-minValue_)*value;
setValue(rint(value));
}
void enzo::ui::IntSliderParm::mousePressEvent(QMouseEvent *event)
{
// normalized
float value = static_cast<float>(event->pos().x())/rect().width();
//remap
value = minValue_+(maxValue_-minValue_)*value;
setValue(rint(value));
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "Engine/Types.h"
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPen>
namespace enzo::ui
{
class IntSliderParm
: public QWidget
{
Q_OBJECT
public:
IntSliderParm(bt::intT value, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
void setValue(bt::intT value);
Q_SIGNALS:
void valueChanged(bt::intT value);
private:
QVBoxLayout* mainLayout_;
QLabel* valueLabel_;
bt::intT value_;
bool clampMin_ = true;
bool clampMax_ = true;
bt::intT minValue_=-5;
bt::intT maxValue_=10;
QPen notchPen_;
static constexpr int notchWidth = 2;
void setValueImpl(bt::intT value);
protected:
void paintEvent(QPaintEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
};
}

View File

@@ -1,9 +1,8 @@
#include "Gui/ParametersPanel/ParametersPanel.h" #include "Gui/ParametersPanel/ParametersPanel.h"
#include "Engine/Operator/GeometryOperator.h" #include "Engine/Operator/GeometryOperator.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include "Gui/Parameters/AbstractSliderParm.h" #include "Gui/Parameters/FloatSliderParm.h"
#include "Gui/Parameters/AbstractFormParm.h" #include "Gui/Parameters/FormParm.h"
#include "Gui/Parameters/FloatParm.h"
#include "Engine/Network/NetworkManager.h" #include "Engine/Network/NetworkManager.h"
#include <memory> #include <memory>
#include <qboxlayout.h> #include <qboxlayout.h>
@@ -52,7 +51,7 @@ void ParametersPanel::selectionChanged(enzo::nt::OpId opId)
enzo::nt::GeometryOperator& displayOp = nm.getGeoOperator(displayOpId); enzo::nt::GeometryOperator& displayOp = nm.getGeoOperator(displayOpId);
auto parameters = displayOp.getParameters(); auto parameters = displayOp.getParameters();
std::vector<enzo::ui::AbstractFormParm*> parameterWidgets; std::vector<enzo::ui::FormParm*> parameterWidgets;
parameterWidgets.reserve(parameters.size()); parameterWidgets.reserve(parameters.size());
int maxLeftPadding = 0; int maxLeftPadding = 0;
@@ -62,7 +61,7 @@ void ParametersPanel::selectionChanged(enzo::nt::OpId opId)
auto parameterShared = parameter.lock(); auto parameterShared = parameter.lock();
if(!parameterShared) throw std::runtime_error("Failed to lock parameter"); if(!parameterShared) throw std::runtime_error("Failed to lock parameter");
enzo::ui::AbstractFormParm* parameterWidget = new enzo::ui::AbstractFormParm(parameter); enzo::ui::FormParm* parameterWidget = new enzo::ui::FormParm(parameter);
int leftPadding = parameterWidget->getLeftPadding(); int leftPadding = parameterWidget->getLeftPadding();
if(leftPadding > maxLeftPadding) maxLeftPadding = leftPadding; if(leftPadding > maxLeftPadding) maxLeftPadding = leftPadding;

View File

@@ -59,7 +59,7 @@ enzo::prm::Template GopGrid::parameterList[] =
{ {
enzo::prm::Template(enzo::prm::Type::FLOAT, "width", enzo::prm::Default(1)), enzo::prm::Template(enzo::prm::Type::FLOAT, "width", enzo::prm::Default(1)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "height", enzo::prm::Default(1)), enzo::prm::Template(enzo::prm::Type::FLOAT, "height", enzo::prm::Default(1)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "rows", enzo::prm::Default(10)), enzo::prm::Template(enzo::prm::Type::INT, "rows", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "columns", enzo::prm::Default(10)), enzo::prm::Template(enzo::prm::Type::INT, "columns", enzo::prm::Default(10)),
enzo::prm::Terminator enzo::prm::Terminator
}; };