feat: add bool switch

This commit is contained in:
parker
2025-08-12 03:00:23 +01:00
parent 63ce4c7694
commit 98b2121e3e
10 changed files with 222 additions and 15 deletions

View File

@@ -55,6 +55,7 @@ set(GUI_SOURCES
src/Gui/ParametersPanel/ParametersPanel.cpp src/Gui/ParametersPanel/ParametersPanel.cpp
src/Gui/Parameters/FloatSliderParm.cpp src/Gui/Parameters/FloatSliderParm.cpp
src/Gui/Parameters/IntSliderParm.cpp src/Gui/Parameters/IntSliderParm.cpp
src/Gui/Parameters/BoolSwitchParm.cpp
src/Gui/Parameters/FormParm.cpp src/Gui/Parameters/FormParm.cpp
src/Gui/Parameters/StringParm.cpp src/Gui/Parameters/StringParm.cpp
) )

View File

@@ -1,6 +1,7 @@
#include "Engine/Operator/Context.h" #include "Engine/Operator/Context.h"
#include "Engine/Network/NetworkManager.h" #include "Engine/Network/NetworkManager.h"
#include "Engine/Parameter/Parameter.h" #include "Engine/Parameter/Parameter.h"
#include "Engine/Types.h"
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
@@ -51,6 +52,38 @@ enzo::bt::floatT enzo::op::Context::evalFloatParm(const char* parmName, const un
} }
} }
// TODO: cache value
enzo::bt::intT enzo::op::Context::evalIntParm(const char* parmName, const unsigned int index) const
{
enzo::nt::GeometryOperator& selfOp = networkManager_.getGeoOperator(opId_);
std::weak_ptr<prm::Parameter> parameter = selfOp.getParameter(parmName);
if(auto sharedParm = parameter.lock())
{
return sharedParm->evalInt(index);
}
else
{
throw std::runtime_error("Parameter weak ptr invalid");
}
}
// TODO: cache value
enzo::bt::boolT enzo::op::Context::evalBoolParm(const char* parmName, const unsigned int index) const
{
enzo::nt::GeometryOperator& selfOp = networkManager_.getGeoOperator(opId_);
std::weak_ptr<prm::Parameter> parameter = selfOp.getParameter(parmName);
if(auto sharedParm = parameter.lock())
{
return sharedParm->evalInt(index);
}
else
{
throw std::runtime_error("Parameter weak ptr invalid");
}
}
// TODO: cache value // TODO: cache value
enzo::bt::String enzo::op::Context::evalStringParm(const char* parmName, const unsigned int index) const enzo::bt::String enzo::op::Context::evalStringParm(const char* parmName, const unsigned int index) const
{ {

View File

@@ -16,6 +16,8 @@ public:
Context(enzo::nt::OpId opId, enzo::nt::NetworkManager& networkManager); Context(enzo::nt::OpId opId, enzo::nt::NetworkManager& networkManager);
enzo::geo::Geometry cloneInputGeo(unsigned int inputIndex); enzo::geo::Geometry cloneInputGeo(unsigned int inputIndex);
bt::floatT evalFloatParm(const char* parmName, const unsigned int index=0) const; bt::floatT evalFloatParm(const char* parmName, const unsigned int index=0) const;
bt::intT evalIntParm(const char* parmName, const unsigned int index=0) const;
bt::boolT evalBoolParm(const char* parmName, const unsigned int index=0) const;
bt::String evalStringParm(const char* parmName, const unsigned int index=0) const; bt::String evalStringParm(const char* parmName, const unsigned int index=0) const;
private: private:
enzo::nt::OpId opId_; enzo::nt::OpId opId_;

View File

@@ -41,8 +41,9 @@ namespace enzo
{ {
LIST_TERMINATOR, LIST_TERMINATOR,
STRING, STRING,
XYZ,
FLOAT, FLOAT,
BOOL,
XYZ,
INT, INT,
TOGGLE TOGGLE
}; };

View File

@@ -0,0 +1,82 @@
#include "Gui/Parameters/BoolSwitchParm.h"
#include <qnamespace.h>
#include <qpushbutton.h>
#include <QPainter>
#include <QParallelAnimationGroup>
enzo::ui::BoolSwitchParm::BoolSwitchParm(std::weak_ptr<enzo::prm::Parameter> parameter, QWidget *parent)
: QPushButton(parent), parameter_{parameter}
{
setFixedWidth(40);
parameter_ = parameter;
setCheckable(true);
setProperty("class", "BoolSwitchParm");
setStyleSheet(R"(
.BoolSwitchParm
{
border-radius: 8px;
border: 1px solid #383838;
}
)");
if(auto parameterShared = parameter_.lock())
{
bool toggled = parameterShared->evalInt();
setChecked(toggled);
switchXEnd_=width() - 20 - 4;
switchColor_= toggled ? switchColorOn_ : switchColorOff_;
switchX_= toggled ? switchXEnd_ : 0;
}
connect(this, &QPushButton::toggled, this, &BoolSwitchParm::onToggle);
}
void enzo::ui::BoolSwitchParm::onToggle(bool checked)
{
animateSwitch(checked);
setValue(checked);
}
void enzo::ui::BoolSwitchParm::paintEvent(QPaintEvent* event)
{
QPushButton::paintEvent(event); // paint bg
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QRect bgRect = rect();
painter.setPen(Qt::NoPen);
painter.setBrush(switchColor_);
constexpr int borderRadius = 7;
constexpr int margin = 2;
painter.drawRoundedRect(QRectF(bgRect.left()+margin+switchX_, bgRect.top()+margin, 20, bgRect.height()-margin*2), borderRadius, borderRadius);
}
void enzo::ui::BoolSwitchParm::setValue(bt::intT value)
{
setChecked(value);
valueChanged(value);
}
void enzo::ui::BoolSwitchParm::animateSwitch(bool checked)
{
auto posAnim = new QPropertyAnimation(this, "switchX");
posAnim->setDuration(200);
posAnim->setEasingCurve(QEasingCurve::InOutQuad);
posAnim->setStartValue(switchX_);
posAnim->setEndValue(checked ? switchXEnd_ : 0);
auto colorAnim = new QPropertyAnimation(this, "switchColor");
colorAnim->setDuration(200);
colorAnim->setEasingCurve(QEasingCurve::InOutQuad);
colorAnim->setStartValue(switchColor_);
colorAnim->setEndValue(checked ? switchColorOn_ : switchColorOff_);
auto group = new QParallelAnimationGroup(this);
group->addAnimation(posAnim);
group->addAnimation(colorAnim);
group->start(QAbstractAnimation::DeleteWhenStopped);
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "Engine/Parameter/Parameter.h"
#include "Engine/Types.h"
#include <memory>
#include <QWidget>
#include <qpushbutton.h>
#include <QPropertyAnimation>
#include <icecream.hpp>
namespace enzo::ui
{
class BoolSwitchParm
: public QPushButton
{
Q_OBJECT
Q_PROPERTY(qreal switchX READ switchX WRITE setSwitchX)
Q_PROPERTY(QColor switchColor READ switchColor WRITE setSwitchColor)
public:
BoolSwitchParm(std::weak_ptr<enzo::prm::Parameter> parameter, QWidget *parent = nullptr);
private:
std::weak_ptr<enzo::prm::Parameter> parameter_;
qreal switchX_=0;
qreal switchXEnd_;
QColor switchColorOff_=QColor("#383838");
QColor switchColorOn_=QColor("#B3B3B3");
QColor switchColor_;
void setValue(bt::intT);
void onToggle(bool checked);
qreal switchX() const { return switchX_; }
void setSwitchX(qreal x) { switchX_ = x; update(); }
QColor switchColor() const { return switchColor_; }
void setSwitchColor(const QColor &c) { switchColor_ = c; update(); }
protected:
void paintEvent(QPaintEvent *) override;
private Q_SLOTS:
void animateSwitch(bool checked);
Q_SIGNALS:
void valueChanged(bt::intT value);
};
}

View File

@@ -2,6 +2,7 @@
#include "Gui/Parameters/IntSliderParm.h" #include "Gui/Parameters/IntSliderParm.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include "Gui/Parameters/FloatSliderParm.h" #include "Gui/Parameters/FloatSliderParm.h"
#include "Gui/Parameters/BoolSwitchParm.h"
#include "Gui/Parameters/StringParm.h" #include "Gui/Parameters/StringParm.h"
#include <qboxlayout.h> #include <qboxlayout.h>
#include <QLabel> #include <QLabel>
@@ -41,6 +42,14 @@ enzo::ui::FormParm::FormParm(std::weak_ptr<prm::Parameter> parameter)
connect(slider, &IntSliderParm::valueChanged, this, [this](bt::intT value){this->changeValue(value, 0);}); connect(slider, &IntSliderParm::valueChanged, this, [this](bt::intT value){this->changeValue(value, 0);});
break; break;
} }
case prm::Type::BOOL:
{
BoolSwitchParm* switchParm = new BoolSwitchParm(parameter_);
mainLayout_->addWidget(switchParm);
mainLayout_->addStretch();
connect(switchParm, &BoolSwitchParm::valueChanged, this, [this](bt::intT value){this->changeValue(value, 0);});
break;
}
case prm::Type::XYZ: case prm::Type::XYZ:
{ {
const unsigned int vectorSize = sharedParameter->getVectorSize(); const unsigned int vectorSize = sharedParameter->getVectorSize();
@@ -96,6 +105,19 @@ void enzo::ui::FormParm::setLeftPadding(int padding)
} }
void enzo::ui::FormParm::changeValue(enzo::bt::intT value, unsigned int index)
{
if(auto sharedParameter=parameter_.lock())
{
sharedParameter->setInt(value, index);
}
else
{
std::cout << "ERROR: parameter no longer exists\n";
}
}
void enzo::ui::FormParm::changeValue(enzo::bt::floatT value, unsigned int index) void enzo::ui::FormParm::changeValue(enzo::bt::floatT value, unsigned int index)
{ {

View File

@@ -18,6 +18,7 @@ public:
void setLeftPadding(int padding); void setLeftPadding(int padding);
protected Q_SLOTS: protected Q_SLOTS:
void changeValue(bt::intT value, unsigned int index=0);
void changeValue(bt::floatT value, unsigned int index=0); void changeValue(bt::floatT value, unsigned int index=0);
void changeValue(bt::String value, unsigned int index=0); void changeValue(bt::String value, unsigned int index=0);

View File

@@ -24,8 +24,8 @@ void GopGrid::cookOp(enzo::op::Context context)
bt::floatT width = context.evalFloatParm("size", 0); bt::floatT width = context.evalFloatParm("size", 0);
bt::floatT height = context.evalFloatParm("size", 1); bt::floatT height = context.evalFloatParm("size", 1);
const bt::intT columns = context.evalFloatParm("columns"); const bt::intT columns = context.evalIntParm("columns");
const bt::intT rows = context.evalFloatParm("rows"); const bt::intT rows = context.evalIntParm("rows");
if(columns<=0 || rows<=0) if(columns<=0 || rows<=0)
{ {
setOutputGeometry(0, geo); setOutputGeometry(0, geo);
@@ -35,13 +35,15 @@ void GopGrid::cookOp(enzo::op::Context context)
const bt::floatT centerOffsetX = width/2.0; const bt::floatT centerOffsetX = width/2.0;
const bt::floatT centerOffsetY = height/2.0; const bt::floatT centerOffsetY = height/2.0;
const bt::floatT columnDivisor = std::max<bt::floatT>(columns-1, 1);
const bt::floatT rowDivisor = std::max<bt::floatT>(rows-1, 1);
// add points // add points
for(int i=0;i<columns;i++) for(int i=0;i<columns;i++)
{ {
for(int j=0;j<rows;++j) for(int j=0;j<rows;++j)
{ {
const bt::floatT x = static_cast<bt::floatT>(i)/(columns-1)*width-centerOffsetX; const bt::floatT x = i/columnDivisor*width-centerOffsetX;
const bt::floatT z = static_cast<bt::floatT>(j)/(rows-1)*height-centerOffsetY; const bt::floatT z = j/rowDivisor*height-centerOffsetY;
geo.addPoint(bt::Vector3(x, 0, z)); geo.addPoint(bt::Vector3(x, 0, z));
} }
} }
@@ -80,14 +82,14 @@ enzo::prm::Template GopGrid::parameterList[] =
enzo::prm::Name("rows", "Rows"), enzo::prm::Name("rows", "Rows"),
enzo::prm::Default(10), enzo::prm::Default(10),
1, 1,
enzo::prm::Range(0, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED) enzo::prm::Range(1, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)
), ),
enzo::prm::Template( enzo::prm::Template(
enzo::prm::Type::INT, enzo::prm::Type::INT,
enzo::prm::Name("columns", "Columns"), enzo::prm::Name("columns", "Columns"),
enzo::prm::Default(10), enzo::prm::Default(10),
1, 1,
enzo::prm::Range(0, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED) enzo::prm::Range(1, enzo::prm::RangeFlag::LOCKED, 100, enzo::prm::RangeFlag::UNLOCKED)
), ),
enzo::prm::Terminator enzo::prm::Terminator
}; };

View File

@@ -25,14 +25,30 @@ void GopSineWave::cookOp(enzo::op::Context context)
const ga::Offset pointCount = geo.getNumPoints(); const ga::Offset pointCount = geo.getNumPoints();
const bt::floatT frequency = context.evalFloatParm("frequency"); const bt::floatT frequency = context.evalFloatParm("frequency");
tbb::parallel_for(tbb::blocked_range<ga::Offset>(0, pointCount), [&geo, frequency](tbb::blocked_range<ga::Offset> range){ const bool radial = context.evalBoolParm("radial");
for(ga::Offset i=range.begin(); i!=range.end(); ++i) if(radial)
{ {
bt::Vector3 pos = geo.getPointPos(i); const bt::Vector3 center(context.evalFloatParm("center", 0), context.evalFloatParm("center", 1), context.evalFloatParm("center", 2));
pos += bt::Vector3(0, sin(pos.x()*frequency), 0); tbb::parallel_for(tbb::blocked_range<ga::Offset>(0, pointCount), [&geo, frequency, center](tbb::blocked_range<ga::Offset> range){
geo.setPointPos(i, pos); for(ga::Offset i=range.begin(); i!=range.end(); ++i)
} {
}); bt::Vector3 pos = geo.getPointPos(i);
pos += bt::Vector3(0, sin((pos-center).norm()*frequency), 0);
geo.setPointPos(i, pos);
}
});
}
else
{
tbb::parallel_for(tbb::blocked_range<ga::Offset>(0, pointCount), [&geo, frequency] (tbb::blocked_range<ga::Offset> range){
for(ga::Offset i=range.begin(); i!=range.end(); ++i)
{
bt::Vector3 pos = geo.getPointPos(i);
pos += bt::Vector3(0, sin(pos.x()*frequency), 0);
geo.setPointPos(i, pos);
}
});
}
setOutputGeometry(0, geo); setOutputGeometry(0, geo);
} }
@@ -41,6 +57,8 @@ void GopSineWave::cookOp(enzo::op::Context context)
enzo::prm::Template GopSineWave::parameterList[] = enzo::prm::Template GopSineWave::parameterList[] =
{ {
enzo::prm::Template(enzo::prm::Type::BOOL, enzo::prm::Name("radial", "Radial Mode")),
enzo::prm::Template(enzo::prm::Type::XYZ, enzo::prm::Name("center", "Center"), 3),
enzo::prm::Template(enzo::prm::Type::FLOAT, enzo::prm::Name("frequency", "Frequency"), enzo::prm::Default(1), 1), enzo::prm::Template(enzo::prm::Type::FLOAT, enzo::prm::Name("frequency", "Frequency"), enzo::prm::Default(1), 1),
enzo::prm::Terminator enzo::prm::Terminator
}; };