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/TabMenu.cpp
src/Gui/ParametersPanel/ParametersPanel.cpp
src/Gui/Parameters/AbstractSliderParm.cpp
src/Gui/Parameters/AbstractFormParm.cpp
src/Gui/Parameters/FloatParm.cpp
src/Gui/Parameters/FloatSliderParm.cpp
src/Gui/Parameters/IntSliderParm.cpp
src/Gui/Parameters/FormParm.cpp
src/Gui/Parameters/StringParm.cpp
)
set(ENGINE_INCLUDE_DIRECTORIES

View File

@@ -9,18 +9,18 @@
enzo::prm::Parameter::Parameter(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 numDefaults = prmTemplate.getNumDefaults();
floatValues_.reserve(templateSize);
stringValues_.reserve(templateSize);
intValues_.reserve(templateSize);
if(numDefaults==1)
{
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());
}
@@ -33,6 +33,7 @@ enzo::prm::Parameter::Parameter(Template prmTemplate)
}
floatValues_.push_back(prmDefault.getFloat());
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];
}
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
{
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)
{
if(index >= floatValues_.size())

View File

@@ -14,7 +14,9 @@ public:
bt::floatT evalFloat(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 setString(bt::String value, unsigned int index=0);
@@ -23,6 +25,7 @@ private:
Template template_;
std::vector<bt::floatT> floatValues_;
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 <QPainter>
#include <QPaintEvent>
@@ -10,7 +10,7 @@
#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)
{
// 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);
}
void enzo::ui::AbstractSliderParm::paintEvent(QPaintEvent *event)
void enzo::ui::FloatSliderParm::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
painter.setBrush(QColor("#383838"));
QRectF fillRect = event->rect();
float fillPercent = value_/maxValue_;
std::cout << "fill percent" << fillPercent << "\n";
float margin = 3;
fillRect.adjust(margin, margin, std::max<float>(-fillRect.width()+margin, -fillRect.width()*(1-fillPercent)-margin), -margin);
const int valueRange = maxValue_-minValue_;
float fillPercent = static_cast<float>(value_-minValue_)/valueRange;
constexpr 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.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(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);
@@ -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
{
class AbstractSliderParm
class FloatSliderParm
: public QWidget
{
Q_OBJECT
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);
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 "Gui/Parameters/AbstractSliderParm.h"
#include "Gui/Parameters/FloatSliderParm.h"
#include "Gui/Parameters/StringParm.h"
#include <qboxlayout.h>
#include <QLabel>
@@ -9,7 +10,7 @@
#include <string>
enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> parameter)
enzo::ui::FormParm::FormParm(std::weak_ptr<prm::Parameter> parameter)
: parameter_{parameter}
{
if(auto sharedParameter=parameter_.lock())
@@ -27,25 +28,31 @@ enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> param
{
case prm::Type::FLOAT:
{
AbstractSliderParm* slider;
slider = new AbstractSliderParm(sharedParameter->evalFloat());
FloatSliderParm* slider = new FloatSliderParm(sharedParameter->evalFloat());
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;
}
case prm::Type::XYZ:
{
AbstractSliderParm* slider1 = new AbstractSliderParm(sharedParameter->evalFloat(0));
AbstractSliderParm* slider2 = new AbstractSliderParm(sharedParameter->evalFloat(1));
AbstractSliderParm* slider3 = new AbstractSliderParm(sharedParameter->evalFloat(2));
FloatSliderParm* slider1 = new FloatSliderParm(sharedParameter->evalFloat(0));
FloatSliderParm* slider2 = new FloatSliderParm(sharedParameter->evalFloat(1));
FloatSliderParm* slider3 = new FloatSliderParm(sharedParameter->evalFloat(2));
QHBoxLayout* vectorLayout = new QHBoxLayout();
vectorLayout->addWidget(slider1);
vectorLayout->addWidget(slider2);
vectorLayout->addWidget(slider3);
mainLayout_->addLayout(vectorLayout);
connect(slider1, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);});
connect(slider2, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 1);});
connect(slider3, &AbstractSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 2);});
connect(slider1, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 0);});
connect(slider2, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 1);});
connect(slider3, &FloatSliderParm::valueChanged, this, [this](bt::floatT value){this->changeValue(value, 2);});
break;
}
case prm::Type::STRING:
@@ -61,7 +68,7 @@ enzo::ui::AbstractFormParm::AbstractFormParm(std::weak_ptr<prm::Parameter> param
}
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();
}
void enzo::ui::AbstractFormParm::setLeftPadding(int padding)
void enzo::ui::FormParm::setLeftPadding(int 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())
{
@@ -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())
{

View File

@@ -8,12 +8,12 @@
namespace enzo::ui
{
class AbstractFormParm
class FormParm
: public QWidget
{
Q_OBJECT
public:
AbstractFormParm(std::weak_ptr<prm::Parameter> parameter);
FormParm(std::weak_ptr<prm::Parameter> parameter);
int getLeftPadding();
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 "Engine/Operator/GeometryOperator.h"
#include "Engine/Types.h"
#include "Gui/Parameters/AbstractSliderParm.h"
#include "Gui/Parameters/AbstractFormParm.h"
#include "Gui/Parameters/FloatParm.h"
#include "Gui/Parameters/FloatSliderParm.h"
#include "Gui/Parameters/FormParm.h"
#include "Engine/Network/NetworkManager.h"
#include <memory>
#include <qboxlayout.h>
@@ -52,7 +51,7 @@ void ParametersPanel::selectionChanged(enzo::nt::OpId opId)
enzo::nt::GeometryOperator& displayOp = nm.getGeoOperator(displayOpId);
auto parameters = displayOp.getParameters();
std::vector<enzo::ui::AbstractFormParm*> parameterWidgets;
std::vector<enzo::ui::FormParm*> parameterWidgets;
parameterWidgets.reserve(parameters.size());
int maxLeftPadding = 0;
@@ -62,7 +61,7 @@ void ParametersPanel::selectionChanged(enzo::nt::OpId opId)
auto parameterShared = parameter.lock();
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();
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, "height", enzo::prm::Default(1)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "rows", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::FLOAT, "columns", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::INT, "rows", enzo::prm::Default(10)),
enzo::prm::Template(enzo::prm::Type::INT, "columns", enzo::prm::Default(10)),
enzo::prm::Terminator
};